1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- begin                                   host_arm_defs.c ---*/
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file is part of Valgrind, a dynamic binary instrumentation
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   framework.
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Copyright (C) 2004-2013 OpenWorks LLP
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      info@open-works.net
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   NEON support is
14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Copyright (C) 2010-2013 Samsung Electronics
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   contributed by Dmitry Zhurikhin <zhur@ispras.ru>
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              and Kirill Batuzov <batuzovk@ispras.ru>
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is free software; you can redistribute it and/or
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   modify it under the terms of the GNU General Public License as
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   published by the Free Software Foundation; either version 2 of the
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   License, or (at your option) any later version.
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is distributed in the hope that it will be useful, but
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   WITHOUT ANY WARRANTY; without even the implied warranty of
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   General Public License for more details.
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   You should have received a copy of the GNU General Public License
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   along with this program; if not, write to the Free Software
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   02110-1301, USA.
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The GNU General Public License is contained in the file COPYING.
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_basictypes.h"
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex.h"
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_trc_values.h"
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "main_util.h"
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "host_generic_regs.h"
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "host_arm_defs.h"
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownUInt arm_hwcaps = 0;
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Registers. --------- */
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The usual HReg abstraction.
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   There are 16 general purpose regs.
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ppHRegARM ( HReg reg )  {
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int r;
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Be generic for all virtual regs. */
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (hregIsVirtual(reg)) {
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ppHReg(reg);
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* But specific for real regs. */
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (hregClass(reg)) {
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case HRcInt32:
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         r = hregNumber(reg);
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(r >= 0 && r < 16);
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("r%d", r);
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case HRcFlt64:
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         r = hregNumber(reg);
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(r >= 0 && r < 32);
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("d%d", r);
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case HRcFlt32:
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         r = hregNumber(reg);
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(r >= 0 && r < 32);
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("s%d", r);
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case HRcVec128:
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         r = hregNumber(reg);
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(r >= 0 && r < 16);
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("q%d", r);
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("ppHRegARM");
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R0  ( void ) { return mkHReg(0,  HRcInt32, False); }
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R1  ( void ) { return mkHReg(1,  HRcInt32, False); }
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R2  ( void ) { return mkHReg(2,  HRcInt32, False); }
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R3  ( void ) { return mkHReg(3,  HRcInt32, False); }
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R4  ( void ) { return mkHReg(4,  HRcInt32, False); }
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R5  ( void ) { return mkHReg(5,  HRcInt32, False); }
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R6  ( void ) { return mkHReg(6,  HRcInt32, False); }
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R7  ( void ) { return mkHReg(7,  HRcInt32, False); }
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R8  ( void ) { return mkHReg(8,  HRcInt32, False); }
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R9  ( void ) { return mkHReg(9,  HRcInt32, False); }
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R10 ( void ) { return mkHReg(10, HRcInt32, False); }
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R11 ( void ) { return mkHReg(11, HRcInt32, False); }
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R12 ( void ) { return mkHReg(12, HRcInt32, False); }
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R13 ( void ) { return mkHReg(13, HRcInt32, False); }
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R14 ( void ) { return mkHReg(14, HRcInt32, False); }
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_R15 ( void ) { return mkHReg(15, HRcInt32, False); }
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_D8  ( void ) { return mkHReg(8,  HRcFlt64, False); }
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_D9  ( void ) { return mkHReg(9,  HRcFlt64, False); }
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_D10 ( void ) { return mkHReg(10, HRcFlt64, False); }
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_D11 ( void ) { return mkHReg(11, HRcFlt64, False); }
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_D12 ( void ) { return mkHReg(12, HRcFlt64, False); }
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_S26 ( void ) { return mkHReg(26, HRcFlt32, False); }
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_S27 ( void ) { return mkHReg(27, HRcFlt32, False); }
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_S28 ( void ) { return mkHReg(28, HRcFlt32, False); }
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_S29 ( void ) { return mkHReg(29, HRcFlt32, False); }
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_S30 ( void ) { return mkHReg(30, HRcFlt32, False); }
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_Q8  ( void ) { return mkHReg(8,  HRcVec128, False); }
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_Q9  ( void ) { return mkHReg(9,  HRcVec128, False); }
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_Q10 ( void ) { return mkHReg(10, HRcVec128, False); }
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_Q11 ( void ) { return mkHReg(11, HRcVec128, False); }
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_Q12 ( void ) { return mkHReg(12, HRcVec128, False); }
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_Q13 ( void ) { return mkHReg(13, HRcVec128, False); }
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_Q14 ( void ) { return mkHReg(14, HRcVec128, False); }
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHReg hregARM_Q15 ( void ) { return mkHReg(15, HRcVec128, False); }
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid getAllocableRegs_ARM ( Int* nregs, HReg** arr )
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int i = 0;
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *nregs = 26;
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *arr = LibVEX_Alloc(*nregs * sizeof(HReg));
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // callee saves ones are listed first, since we prefer them
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // if they're available
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_R4();
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_R5();
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_R6();
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_R7();
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_R10();
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_R11();
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // otherwise we'll have to slum it out with caller-saves ones
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_R0();
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_R1();
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_R2();
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_R3();
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_R9();
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // FP hreegisters.  Note: these are all callee-save.  Yay!
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Hence we don't need to mention them as trashed in
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // getHRegUsage for ARMInstr_Call.
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_D8();
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_D9();
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_D10();
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_D11();
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_D12();
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_S26();
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_S27();
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_S28();
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_S29();
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_S30();
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_Q8();
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_Q9();
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_Q10();
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_Q11();
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (*arr)[i++] = hregARM_Q12();
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //(*arr)[i++] = hregARM_Q13();
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //(*arr)[i++] = hregARM_Q14();
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //(*arr)[i++] = hregARM_Q15();
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // unavail: r8 as GSP
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // r12 is used as a spill/reload temporary
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // r13 as SP
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // r14 as LR
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // r15 as PC
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // All in all, we have 11 allocatable integer registers:
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // 0 1 2 3 4 5 6 7 9 10 11, with r8 dedicated as GSP
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // and r12 dedicated as a spill temporary.
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // 13 14 and 15 are not under the allocator's control.
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Hence for the allocatable registers we have:
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // callee-saved: 4 5 6 7 (8) 9 10 11
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // caller-saved: 0 1 2 3
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Note 9 is ambiguous: the base EABI does not give an e/r-saved
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // designation for it, but the Linux instantiation of the ABI
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // specifies it as callee-saved.
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // If the set of available registers changes or if the e/r status
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // changes, be sure to re-check/sync the definition of
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // getHRegUsage for ARMInstr_Call too.
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(i == *nregs);
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Condition codes, ARM encoding. --------- */
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMCondCode ( ARMCondCode cond ) {
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (cond) {
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_EQ:  return "eq";
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_NE:  return "ne";
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_HS:  return "hs";
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_LO:  return "lo";
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_MI:  return "mi";
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_PL:  return "pl";
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_VS:  return "vs";
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_VC:  return "vc";
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_HI:  return "hi";
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_LS:  return "ls";
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_GE:  return "ge";
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_LT:  return "lt";
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_GT:  return "gt";
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_LE:  return "le";
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_AL:  return "al"; // default
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       case ARMcc_NV:  return "nv";
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       default: vpanic("showARMCondCode");
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Mem AModes: Addressing Mode 1 --------- */
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMAMode1* ARMAMode1_RI  ( HReg reg, Int simm13 ) {
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMAMode1* am        = LibVEX_Alloc(sizeof(ARMAMode1));
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->tag              = ARMam1_RI;
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->ARMam1.RI.reg    = reg;
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->ARMam1.RI.simm13 = simm13;
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(-4095 <= simm13 && simm13 <= 4095);
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return am;
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift ) {
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMAMode1* am        = LibVEX_Alloc(sizeof(ARMAMode1));
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->tag              = ARMam1_RRS;
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->ARMam1.RRS.base  = base;
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->ARMam1.RRS.index = index;
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->ARMam1.RRS.shift = shift;
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(0 <= shift && shift <= 3);
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return am;
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ppARMAMode1 ( ARMAMode1* am ) {
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (am->tag) {
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMam1_RI:
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%d(", am->ARMam1.RI.simm13);
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(am->ARMam1.RI.reg);
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(")");
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMam1_RRS:
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("(");
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(am->ARMam1.RRS.base);
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(",");
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(am->ARMam1.RRS.index);
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(",%u)", am->ARMam1.RRS.shift);
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0);
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void addRegUsage_ARMAMode1 ( HRegUsage* u, ARMAMode1* am ) {
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (am->tag) {
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMam1_RI:
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, am->ARMam1.RI.reg);
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMam1_RRS:
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //    addHRegUse(u, HRmRead, am->ARMam1.RRS.base);
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //    addHRegUse(u, HRmRead, am->ARMam1.RRS.index);
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //   return;
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("addRegUsage_ARMAmode1");
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void mapRegs_ARMAMode1 ( HRegRemap* m, ARMAMode1* am ) {
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (am->tag) {
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMam1_RI:
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         am->ARMam1.RI.reg = lookupHRegRemap(m, am->ARMam1.RI.reg);
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMam1_RRS:
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //am->ARMam1.RR.base =lookupHRegRemap(m, am->ARMam1.RR.base);
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //am->ARMam1.RR.index = lookupHRegRemap(m, am->ARMam1.RR.index);
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //return;
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("mapRegs_ARMAmode1");
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Mem AModes: Addressing Mode 2 --------- */
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 ) {
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMAMode2* am       = LibVEX_Alloc(sizeof(ARMAMode2));
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->tag             = ARMam2_RI;
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->ARMam2.RI.reg   = reg;
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->ARMam2.RI.simm9 = simm9;
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(-255 <= simm9 && simm9 <= 255);
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return am;
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMAMode2* ARMAMode2_RR ( HReg base, HReg index ) {
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMAMode2* am       = LibVEX_Alloc(sizeof(ARMAMode2));
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->tag             = ARMam2_RR;
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->ARMam2.RR.base  = base;
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->ARMam2.RR.index = index;
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return am;
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ppARMAMode2 ( ARMAMode2* am ) {
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (am->tag) {
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMam2_RI:
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%d(", am->ARMam2.RI.simm9);
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(am->ARMam2.RI.reg);
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(")");
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMam2_RR:
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("(");
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(am->ARMam2.RR.base);
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(",");
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(am->ARMam2.RR.index);
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(")");
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0);
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void addRegUsage_ARMAMode2 ( HRegUsage* u, ARMAMode2* am ) {
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (am->tag) {
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMam2_RI:
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, am->ARMam2.RI.reg);
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMam2_RR:
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //    addHRegUse(u, HRmRead, am->ARMam2.RR.base);
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //    addHRegUse(u, HRmRead, am->ARMam2.RR.index);
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //   return;
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("addRegUsage_ARMAmode2");
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void mapRegs_ARMAMode2 ( HRegRemap* m, ARMAMode2* am ) {
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (am->tag) {
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMam2_RI:
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         am->ARMam2.RI.reg = lookupHRegRemap(m, am->ARMam2.RI.reg);
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMam2_RR:
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //am->ARMam2.RR.base =lookupHRegRemap(m, am->ARMam2.RR.base);
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //am->ARMam2.RR.index = lookupHRegRemap(m, am->ARMam2.RR.index);
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //return;
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("mapRegs_ARMAmode2");
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Mem AModes: Addressing Mode VFP --------- */
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMAModeV* mkARMAModeV ( HReg reg, Int simm11 ) {
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMAModeV* am = LibVEX_Alloc(sizeof(ARMAModeV));
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(simm11 >= -1020 && simm11 <= 1020);
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(0 == (simm11 & 3));
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->reg    = reg;
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->simm11 = simm11;
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return am;
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ppARMAModeV ( ARMAModeV* am ) {
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_printf("%d(", am->simm11);
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ppHRegARM(am->reg);
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_printf(")");
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void addRegUsage_ARMAModeV ( HRegUsage* u, ARMAModeV* am ) {
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   addHRegUse(u, HRmRead, am->reg);
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void mapRegs_ARMAModeV ( HRegRemap* m, ARMAModeV* am ) {
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->reg = lookupHRegRemap(m, am->reg);
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Mem AModes: Addressing Mode Neon ------- */
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMAModeN *mkARMAModeN_RR ( HReg rN, HReg rM ) {
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMAModeN* am = LibVEX_Alloc(sizeof(ARMAModeN));
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->tag = ARMamN_RR;
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->ARMamN.RR.rN = rN;
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->ARMamN.RR.rM = rM;
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return am;
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMAModeN *mkARMAModeN_R ( HReg rN ) {
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMAModeN* am = LibVEX_Alloc(sizeof(ARMAModeN));
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->tag = ARMamN_R;
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   am->ARMamN.R.rN = rN;
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return am;
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void addRegUsage_ARMAModeN ( HRegUsage* u, ARMAModeN* am ) {
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (am->tag == ARMamN_R) {
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      addHRegUse(u, HRmRead, am->ARMamN.R.rN);
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      addHRegUse(u, HRmRead, am->ARMamN.RR.rN);
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      addHRegUse(u, HRmRead, am->ARMamN.RR.rM);
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void mapRegs_ARMAModeN ( HRegRemap* m, ARMAModeN* am ) {
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (am->tag == ARMamN_R) {
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      am->ARMamN.R.rN = lookupHRegRemap(m, am->ARMamN.R.rN);
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      am->ARMamN.RR.rN = lookupHRegRemap(m, am->ARMamN.RR.rN);
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      am->ARMamN.RR.rM = lookupHRegRemap(m, am->ARMamN.RR.rM);
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ppARMAModeN ( ARMAModeN* am ) {
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_printf("[");
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (am->tag == ARMamN_R) {
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ppHRegARM(am->ARMamN.R.rN);
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ppHRegARM(am->ARMamN.RR.rN);
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_printf("]");
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (am->tag == ARMamN_RR) {
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf(", ");
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ppHRegARM(am->ARMamN.RR.rM);
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Reg or imm-8x4 operands --------- */
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt ROR32 ( UInt x, UInt sh ) {
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(sh >= 0 && sh < 32);
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (sh == 0)
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return x;
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   else
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return (x << (32-sh)) | (x >> sh);
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 ) {
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMRI84* ri84          = LibVEX_Alloc(sizeof(ARMRI84));
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ri84->tag              = ARMri84_I84;
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ri84->ARMri84.I84.imm8 = imm8;
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ri84->ARMri84.I84.imm4 = imm4;
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(imm8 >= 0 && imm8 <= 255);
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(imm4 >= 0 && imm4 <= 15);
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return ri84;
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMRI84* ARMRI84_R ( HReg reg ) {
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMRI84* ri84       = LibVEX_Alloc(sizeof(ARMRI84));
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ri84->tag           = ARMri84_R;
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ri84->ARMri84.R.reg = reg;
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return ri84;
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ppARMRI84 ( ARMRI84* ri84 ) {
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ri84->tag) {
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMri84_I84:
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("0x%x", ROR32(ri84->ARMri84.I84.imm8,
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  2 * ri84->ARMri84.I84.imm4));
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMri84_R:
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(ri84->ARMri84.R.reg);
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0);
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void addRegUsage_ARMRI84 ( HRegUsage* u, ARMRI84* ri84 ) {
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ri84->tag) {
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMri84_I84:
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMri84_R:
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, ri84->ARMri84.R.reg);
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("addRegUsage_ARMRI84");
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void mapRegs_ARMRI84 ( HRegRemap* m, ARMRI84* ri84 ) {
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ri84->tag) {
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMri84_I84:
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMri84_R:
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ri84->ARMri84.R.reg = lookupHRegRemap(m, ri84->ARMri84.R.reg);
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("mapRegs_ARMRI84");
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Reg or imm5 operands --------- */
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMRI5* ARMRI5_I5 ( UInt imm5 ) {
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMRI5* ri5         = LibVEX_Alloc(sizeof(ARMRI5));
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ri5->tag            = ARMri5_I5;
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ri5->ARMri5.I5.imm5 = imm5;
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(imm5 > 0 && imm5 <= 31); // zero is not allowed
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return ri5;
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMRI5* ARMRI5_R ( HReg reg ) {
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMRI5* ri5       = LibVEX_Alloc(sizeof(ARMRI5));
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ri5->tag          = ARMri5_R;
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ri5->ARMri5.R.reg = reg;
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return ri5;
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ppARMRI5 ( ARMRI5* ri5 ) {
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ri5->tag) {
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMri5_I5:
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%u", ri5->ARMri5.I5.imm5);
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMri5_R:
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(ri5->ARMri5.R.reg);
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0);
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void addRegUsage_ARMRI5 ( HRegUsage* u, ARMRI5* ri5 ) {
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ri5->tag) {
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMri5_I5:
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMri5_R:
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, ri5->ARMri5.R.reg);
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("addRegUsage_ARMRI5");
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void mapRegs_ARMRI5 ( HRegRemap* m, ARMRI5* ri5 ) {
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ri5->tag) {
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMri5_I5:
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMri5_R:
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ri5->ARMri5.R.reg = lookupHRegRemap(m, ri5->ARMri5.R.reg);
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("mapRegs_ARMRI5");
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* -------- Neon Immediate operatnd --------- */
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMNImm* ARMNImm_TI ( UInt type, UInt imm8 ) {
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMNImm* i = LibVEX_Alloc(sizeof(ARMNImm));
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->type = type;
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->imm8 = imm8;
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong ARMNImm_to_Imm64 ( ARMNImm* imm ) {
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   int i, j;
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong y, x = imm->imm8;
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (imm->type) {
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 3:
559436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         x = x << 8; /* fallthrough */
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 2:
561436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         x = x << 8; /* fallthrough */
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 1:
563436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         x = x << 8; /* fallthrough */
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0:
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return (x << 32) | x;
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 5:
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 6:
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (imm->type == 5)
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            x = x << 8;
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            x = (x << 8) | x;
572436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         /* fallthrough */
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 4:
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         x = (x << 16) | x;
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return (x << 32) | x;
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 8:
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         x = (x << 8) | 0xFF;
578436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         /* fallthrough */
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 7:
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         x = (x << 8) | 0xFF;
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return (x << 32) | x;
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 9:
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         x = 0;
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (i = 7; i >= 0; i--) {
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            y = ((ULong)imm->imm8 >> i) & 1;
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            for (j = 0; j < 8; j++) {
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               x = (x << 1) | y;
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return x;
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 10:
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         x |= (x & 0x80) << 5;
593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         x |= (~x & 0x40) << 5;
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         x &= 0x187F; /* 0001 1000 0111 1111 */
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         x |= (x & 0x40) << 4;
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         x |= (x & 0x40) << 3;
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         x |= (x & 0x40) << 2;
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         x |= (x & 0x40) << 1;
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         x = x << 19;
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         x = (x << 32) | x;
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return x;
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("ARMNImm_to_Imm64");
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMNImm* Imm64_to_ARMNImm ( ULong x ) {
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMNImm tmp;
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if ((x & 0xFFFFFFFF) == (x >> 32)) {
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((x & 0xFFFFFF00) == 0)
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ARMNImm_TI(0, x & 0xFF);
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((x & 0xFFFF00FF) == 0)
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ARMNImm_TI(1, (x >> 8) & 0xFF);
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((x & 0xFF00FFFF) == 0)
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ARMNImm_TI(2, (x >> 16) & 0xFF);
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((x & 0x00FFFFFF) == 0)
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ARMNImm_TI(3, (x >> 24) & 0xFF);
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((x & 0xFFFF00FF) == 0xFF)
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ARMNImm_TI(7, (x >> 8) & 0xFF);
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((x & 0xFF00FFFF) == 0xFFFF)
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ARMNImm_TI(8, (x >> 16) & 0xFF);
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((x & 0xFFFF) == ((x >> 16) & 0xFFFF)) {
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if ((x & 0xFF00) == 0)
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return ARMNImm_TI(4, x & 0xFF);
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if ((x & 0x00FF) == 0)
626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return ARMNImm_TI(5, (x >> 8) & 0xFF);
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if ((x & 0xFF) == ((x >> 8) & 0xFF))
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return ARMNImm_TI(6, x & 0xFF);
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((x & 0x7FFFF) == 0) {
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tmp.type = 10;
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tmp.imm8 = ((x >> 19) & 0x7F) | ((x >> 24) & 0x80);
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (ARMNImm_to_Imm64(&tmp) == x)
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return ARMNImm_TI(tmp.type, tmp.imm8);
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* This can only be type 9. */
638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tmp.imm8 = (((x >> 56) & 1) << 7)
639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               | (((x >> 48) & 1) << 6)
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               | (((x >> 40) & 1) << 5)
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               | (((x >> 32) & 1) << 4)
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               | (((x >> 24) & 1) << 3)
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               | (((x >> 16) & 1) << 2)
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               | (((x >>  8) & 1) << 1)
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               | (((x >>  0) & 1) << 0);
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tmp.type = 9;
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ARMNImm_to_Imm64 (&tmp) == x)
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ARMNImm_TI(tmp.type, tmp.imm8);
649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return NULL;
651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ppARMNImm (ARMNImm* i) {
654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong x = ARMNImm_to_Imm64(i);
655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vex_printf("0x%llX%llX", x, x);
656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* -- Register or scalar operand --- */
659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMNRS* mkARMNRS(ARMNRS_tag tag, HReg reg, UInt index)
661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMNRS *p = LibVEX_Alloc(sizeof(ARMNRS));
663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   p->tag = tag;
664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   p->reg = reg;
665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   p->index = index;
666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return p;
667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ppARMNRS(ARMNRS *p)
670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ppHRegARM(p->reg);
672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (p->tag == ARMNRS_Scalar) {
673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vex_printf("[%d]", p->index);
674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Instructions. --------- */
678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
679436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMAluOp ( ARMAluOp op ) {
680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMalu_ADD:  return "add";
682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMalu_ADDS: return "adds";
683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMalu_ADC:  return "adc";
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMalu_SUB:  return "sub";
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMalu_SUBS: return "subs";
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMalu_SBC:  return "sbc";
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMalu_AND:  return "and";
688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMalu_BIC:  return "bic";
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMalu_OR:   return "orr";
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMalu_XOR:  return "xor";
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMAluOp");
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
695436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMShiftOp ( ARMShiftOp op ) {
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMsh_SHL: return "shl";
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMsh_SHR: return "shr";
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMsh_SAR: return "sar";
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMShiftOp");
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
704436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMUnaryOp ( ARMUnaryOp op ) {
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMun_NEG: return "neg";
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMun_NOT: return "not";
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMun_CLZ: return "clz";
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMUnaryOp");
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
713436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMMulOp ( ARMMulOp op ) {
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMmul_PLAIN: return "mul";
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMmul_ZX:    return "umull";
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMmul_SX:    return "smull";
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMMulOp");
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
722436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMVfpOp ( ARMVfpOp op ) {
723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMvfp_ADD: return "add";
725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMvfp_SUB: return "sub";
726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMvfp_MUL: return "mul";
727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMvfp_DIV: return "div";
728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMVfpOp");
729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
732436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op ) {
733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMvfpu_COPY: return "cpy";
735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMvfpu_NEG:  return "neg";
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMvfpu_ABS:  return "abs";
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMvfpu_SQRT: return "sqrt";
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMVfpUnaryOp");
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
742436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMNeonBinOp ( ARMNeonBinOp op ) {
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VAND: return "vand";
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VORR: return "vorr";
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VXOR: return "veor";
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VADD: return "vadd";
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRHADDS: return "vrhadd";
749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRHADDU: return "vrhadd";
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VADDFP: return "vadd";
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPADDFP: return "vpadd";
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VABDFP: return "vabd";
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VSUB: return "vsub";
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VSUBFP: return "vsub";
755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMINU: return "vmin";
756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMINS: return "vmin";
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMINF: return "vmin";
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMAXU: return "vmax";
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMAXS: return "vmax";
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMAXF: return "vmax";
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQADDU: return "vqadd";
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQADDS: return "vqadd";
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSUBU: return "vqsub";
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSUBS: return "vqsub";
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCGTU:  return "vcgt";
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCGTS:  return "vcgt";
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCGTF:  return "vcgt";
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCGEF:  return "vcgt";
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCGEU:  return "vcge";
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCGES:  return "vcge";
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCEQ:  return "vceq";
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCEQF:  return "vceq";
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPADD:   return "vpadd";
774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPMINU:   return "vpmin";
775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPMINS:   return "vpmin";
776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPMINF:   return "vpmin";
777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPMAXU:   return "vpmax";
778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPMAXS:   return "vpmax";
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPMAXF:   return "vpmax";
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VEXT:   return "vext";
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMUL:   return "vmuli";
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMULLU:   return "vmull";
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMULLS:   return "vmull";
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMULP:  return "vmul";
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMULFP:  return "vmul";
786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMULLP:  return "vmul";
787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQDMULH: return "vqdmulh";
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQRDMULH: return "vqrdmulh";
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQDMULL: return "vqdmull";
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VTBL: return "vtbl";
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRECPS: return "vrecps";
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRSQRTS: return "vrecps";
7932ca80a6a6fc069acdb73186e8e578dbf8f46af80Dmitriy Ivanov      case ARMneon_INVALID: return "??invalid??";
794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... */
795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMNeonBinOp");
796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
799436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op ) {
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VAND:
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VORR:
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VXOR:
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return "";
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VADD:
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VSUB:
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VEXT:
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMUL:
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPADD:
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VTBL:
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCEQ:
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".i";
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRHADDU:
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMINU:
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMAXU:
816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQADDU:
817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSUBU:
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCGTU:
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCGEU:
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMULLU:
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPMINU:
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPMAXU:
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".u";
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRHADDS:
825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMINS:
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMAXS:
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQADDS:
828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSUBS:
829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCGTS:
830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCGES:
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQDMULL:
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMULLS:
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPMINS:
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPMAXS:
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQDMULH:
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQRDMULH:
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".s";
838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMULP:
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMULLP:
840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".p";
841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VADDFP:
842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VABDFP:
843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPADDFP:
844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VSUBFP:
845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMULFP:
846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMINF:
847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VMAXF:
848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPMINF:
849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VPMAXF:
850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCGTF:
851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCGEF:
852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCEQF:
853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRECPS:
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRSQRTS:
855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".f";
856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... */
857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMNeonBinOpDataType");
858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
861436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMNeonUnOp ( ARMNeonUnOp op ) {
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPY: return "vmov";
864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPYLS: return "vmov";
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPYLU: return "vmov";
866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPYN: return "vmov";
867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPYQNSS: return "vqmovn";
868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPYQNUS: return "vqmovun";
869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPYQNUU: return "vqmovn";
870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_NOT: return "vmvn";
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_EQZ: return "vceq";
872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_CNT: return "vcnt";
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_CLS: return "vcls";
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_CLZ: return "vclz";
875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_DUP: return "vdup";
876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_PADDLS: return "vpaddl";
877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_PADDLU: return "vpaddl";
878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSHLNSS: return "vqshl";
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSHLNUU: return "vqshl";
880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSHLNUS: return "vqshlu";
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_REV16: return "vrev16";
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_REV32: return "vrev32";
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_REV64: return "vrev64";
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTFtoU: return "vcvt";
885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTFtoS: return "vcvt";
886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTUtoF: return "vcvt";
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTStoF: return "vcvt";
888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTFtoFixedU: return "vcvt";
889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTFtoFixedS: return "vcvt";
890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTFixedUtoF: return "vcvt";
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTFixedStoF: return "vcvt";
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTF32toF16: return "vcvt";
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTF16toF32: return "vcvt";
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRECIP: return "vrecip";
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRECIPF: return "vrecipf";
896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VNEGF: return "vneg";
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_ABS: return "vabs";
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VABSFP: return "vabsfp";
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRSQRTEFP: return "vrsqrtefp";
900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRSQRTE: return "vrsqrte";
901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... */
902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMNeonUnOp");
903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
906436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op ) {
907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPY:
909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_NOT:
910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return "";
911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPYN:
912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_EQZ:
913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_CNT:
914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_DUP:
915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_REV16:
916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_REV32:
917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_REV64:
918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".i";
919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPYLU:
920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_PADDLU:
921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPYQNUU:
922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSHLNUU:
923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRECIP:
924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRSQRTE:
925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".u";
926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_CLS:
927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_CLZ:
928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPYLS:
929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_PADDLS:
930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPYQNSS:
931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_COPYQNUS:
932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSHLNSS:
933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSHLNUS:
934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_ABS:
935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".s";
936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRECIPF:
937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VNEGF:
938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VABSFP:
939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VRSQRTEFP:
940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".f";
941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTFtoU: return ".u32.f32";
942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTFtoS: return ".s32.f32";
943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTUtoF: return ".f32.u32";
944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTStoF: return ".f32.s32";
945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTF16toF32: return ".f32.f16";
946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTF32toF16: return ".f16.f32";
947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTFtoFixedU: return ".u32.f32";
948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTFtoFixedS: return ".s32.f32";
949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTFixedUtoF: return ".f32.u32";
950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VCVTFixedStoF: return ".f32.s32";
951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... */
952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMNeonUnOpDataType");
953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
956436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMNeonUnOpS ( ARMNeonUnOpS op ) {
957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_SETELEM: return "vmov";
959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_GETELEMU: return "vmov";
960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_GETELEMS: return "vmov";
961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VDUP: return "vdup";
962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... */
963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMNeonUnarySOp");
964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
967436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op ) {
968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_SETELEM:
970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VDUP:
971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".i";
972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_GETELEMS:
973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".s";
974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_GETELEMU:
975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".u";
976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... */
977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMNeonUnarySOp");
978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
981436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMNeonShiftOp ( ARMNeonShiftOp op ) {
982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VSHL: return "vshl";
984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VSAL: return "vshl";
985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSHL: return "vqshl";
986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSAL: return "vqshl";
987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... */
988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMNeonShiftOp");
989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
992436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op ) {
993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VSHL:
995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSHL:
996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".u";
997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VSAL:
998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_VQSAL:
999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return ".s";
1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... */
1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMNeonShiftOpDataType");
1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1005436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMNeonDualOp ( ARMNeonDualOp op ) {
1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_TRN: return "vtrn";
1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_ZIP: return "vzip";
1009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_UZP: return "vuzp";
1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... */
1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMNeonDualOp");
1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1015436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op ) {
1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_TRN:
1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_ZIP:
1019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMneon_UZP:
1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return "i";
1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... */
1022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMNeonDualOp");
1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1026436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* showARMNeonDataSize_wrk ( UInt size )
1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (size) {
1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0: return "8";
1030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 1: return "16";
1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 2: return "32";
1032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 3: return "64";
1033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: vpanic("showARMNeonDataSize");
1034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1037436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* showARMNeonDataSize ( ARMInstr* i )
1038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (i->tag) {
1040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NBinary:
1041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NBinary.op == ARMneon_VEXT)
1042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return "8";
1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NBinary.op == ARMneon_VAND ||
1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NBinary.op == ARMneon_VORR ||
1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NBinary.op == ARMneon_VXOR)
1046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return "";
1047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return showARMNeonDataSize_wrk(i->ARMin.NBinary.size);
1048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NUnary:
1049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NUnary.op == ARMneon_COPY ||
1050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_NOT ||
1051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTF32toF16||
1052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTF16toF32||
1053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTFtoFixedS ||
1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTFtoFixedU ||
1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTFixedStoF ||
1056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTFixedUtoF ||
1057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTFtoS ||
1058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTFtoU ||
1059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTStoF ||
1060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTUtoF)
1061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return "";
1062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NUnary.op == ARMneon_VQSHLNSS ||
1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VQSHLNUU ||
1064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VQSHLNUS) {
1065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt size;
1066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            size = i->ARMin.NUnary.size;
1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (size & 0x40)
1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               return "64";
1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (size & 0x20)
1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               return "32";
1071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (size & 0x10)
1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               return "16";
1073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (size & 0x08)
1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               return "8";
1075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vpanic("showARMNeonDataSize");
1076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return showARMNeonDataSize_wrk(i->ARMin.NUnary.size);
1078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NUnaryS:
1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NUnaryS.op == ARMneon_VDUP) {
1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            int size;
1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            size = i->ARMin.NUnaryS.size;
1082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if ((size & 1) == 1)
1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               return "8";
1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if ((size & 3) == 2)
1085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               return "16";
1086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if ((size & 7) == 4)
1087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               return "32";
1088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vpanic("showARMNeonDataSize");
1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return showARMNeonDataSize_wrk(i->ARMin.NUnaryS.size);
1091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NShift:
1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return showARMNeonDataSize_wrk(i->ARMin.NShift.size);
1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NDual:
1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return showARMNeonDataSize_wrk(i->ARMin.NDual.size);
1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("showARMNeonDataSize");
1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_Alu ( ARMAluOp op,
1101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         HReg dst, HReg argL, ARMRI84* argR ) {
1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag            = ARMin_Alu;
1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Alu.op   = op;
1105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Alu.dst  = dst;
1106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Alu.argL = argL;
1107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Alu.argR = argR;
1108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_Shift  ( ARMShiftOp op,
1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            HReg dst, HReg argL, ARMRI5* argR ) {
1112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag              = ARMin_Shift;
1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Shift.op   = op;
1115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Shift.dst  = dst;
1116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Shift.argL = argL;
1117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Shift.argR = argR;
1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_Unary ( ARMUnaryOp op, HReg dst, HReg src ) {
1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag             = ARMin_Unary;
1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Unary.op  = op;
1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Unary.dst = dst;
1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Unary.src = src;
1126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg argL, ARMRI84* argR ) {
1129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                  = ARMin_CmpOrTst;
1131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.CmpOrTst.isCmp = isCmp;
1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.CmpOrTst.argL  = argL;
1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.CmpOrTst.argR  = argR;
1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_Mov ( HReg dst, ARMRI84* src ) {
1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag           = ARMin_Mov;
1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Mov.dst = dst;
1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Mov.src = src;
1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_Imm32  ( HReg dst, UInt imm32 ) {
1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag               = ARMin_Imm32;
1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Imm32.dst   = dst;
1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Imm32.imm32 = imm32;
1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovARMInstr* ARMInstr_LdSt32 ( ARMCondCode cc,
1151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                            Bool isLoad, HReg rD, ARMAMode1* amode ) {
1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                 = ARMin_LdSt32;
1154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i->ARMin.LdSt32.cc     = cc;
1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.LdSt32.isLoad = isLoad;
1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.LdSt32.rD     = rD;
1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.LdSt32.amode  = amode;
1158436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vassert(cc != ARMcc_NV);
1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1161436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovARMInstr* ARMInstr_LdSt16 ( ARMCondCode cc,
1162436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                            Bool isLoad, Bool signedLoad,
1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            HReg rD, ARMAMode2* amode ) {
1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                     = ARMin_LdSt16;
1166436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i->ARMin.LdSt16.cc         = cc;
1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.LdSt16.isLoad     = isLoad;
1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.LdSt16.signedLoad = signedLoad;
1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.LdSt16.rD         = rD;
1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.LdSt16.amode      = amode;
1171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vassert(cc != ARMcc_NV);
1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovARMInstr* ARMInstr_LdSt8U ( ARMCondCode cc,
1175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                            Bool isLoad, HReg rD, ARMAMode1* amode ) {
1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                 = ARMin_LdSt8U;
1178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i->ARMin.LdSt8U.cc     = cc;
1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.LdSt8U.isLoad = isLoad;
1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.LdSt8U.rD     = rD;
1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.LdSt8U.amode  = amode;
1182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vassert(cc != ARMcc_NV);
1183436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return i;
1184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
1185436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovARMInstr* ARMInstr_Ld8S ( ARMCondCode cc, HReg rD, ARMAMode2* amode ) {
1186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   ARMInstr* i         = LibVEX_Alloc(sizeof(ARMInstr));
1187436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i->tag              = ARMin_Ld8S;
1188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i->ARMin.Ld8S.cc    = cc;
1189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i->ARMin.Ld8S.rD    = rD;
1190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i->ARMin.Ld8S.amode = amode;
1191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vassert(cc != ARMcc_NV);
1192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1194663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengARMInstr* ARMInstr_XDirect ( Addr32 dstGA, ARMAMode1* amR15T,
1195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                             ARMCondCode cond, Bool toFastEP ) {
1196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   ARMInstr* i               = LibVEX_Alloc(sizeof(ARMInstr));
1197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->tag                    = ARMin_XDirect;
1198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.XDirect.dstGA    = dstGA;
1199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.XDirect.amR15T   = amR15T;
1200663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.XDirect.cond     = cond;
1201663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.XDirect.toFastEP = toFastEP;
1202663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return i;
1203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
1204663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengARMInstr* ARMInstr_XIndir ( HReg dstGA, ARMAMode1* amR15T,
1205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                            ARMCondCode cond ) {
1206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   ARMInstr* i            = LibVEX_Alloc(sizeof(ARMInstr));
1207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->tag                 = ARMin_XIndir;
1208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.XIndir.dstGA  = dstGA;
1209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.XIndir.amR15T = amR15T;
1210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.XIndir.cond   = cond;
1211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return i;
1212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
1213663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengARMInstr* ARMInstr_XAssisted ( HReg dstGA, ARMAMode1* amR15T,
1214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                               ARMCondCode cond, IRJumpKind jk ) {
1215663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   ARMInstr* i               = LibVEX_Alloc(sizeof(ARMInstr));
1216663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->tag                    = ARMin_XAssisted;
1217663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.XAssisted.dstGA  = dstGA;
1218663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.XAssisted.amR15T = amR15T;
1219663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.XAssisted.cond   = cond;
1220663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.XAssisted.jk     = jk;
1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_CMov ( ARMCondCode cond, HReg dst, ARMRI84* src ) {
1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag             = ARMin_CMov;
1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.CMov.cond = cond;
1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.CMov.dst  = dst;
1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.CMov.src  = src;
1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(cond != ARMcc_AL);
1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovARMInstr* ARMInstr_Call ( ARMCondCode cond, HWord target, Int nArgRegs,
1233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                          RetLoc rloc ) {
1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                 = ARMin_Call;
1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Call.cond     = cond;
1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Call.target   = target;
1238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Call.nArgRegs = nArgRegs;
1239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i->ARMin.Call.rloc     = rloc;
1240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vassert(is_sane_RetLoc(rloc));
1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovARMInstr* ARMInstr_Mul ( ARMMulOp op ) {
1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag          = ARMin_Mul;
1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.Mul.op = op;
1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_LdrEX ( Int szB ) {
1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag             = ARMin_LdrEX;
1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.LdrEX.szB = szB;
1253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vassert(szB == 8 || szB == 4 || szB == 2 || szB == 1);
1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_StrEX ( Int szB ) {
1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag             = ARMin_StrEX;
1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.StrEX.szB = szB;
1260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vassert(szB == 8 || szB == 4 || szB == 2 || szB == 1);
1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg dD, ARMAModeV* am ) {
1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                 = ARMin_VLdStD;
1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VLdStD.isLoad = isLoad;
1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VLdStD.dD     = dD;
1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VLdStD.amode  = am;
1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg fD, ARMAModeV* am ) {
1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                 = ARMin_VLdStS;
1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VLdStS.isLoad = isLoad;
1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VLdStS.fD     = fD;
1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VLdStS.amode  = am;
1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg dst, HReg argL, HReg argR ) {
1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag              = ARMin_VAluD;
1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VAluD.op   = op;
1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VAluD.dst  = dst;
1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VAluD.argL = argL;
1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VAluD.argR = argR;
1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg dst, HReg argL, HReg argR ) {
1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag              = ARMin_VAluS;
1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VAluS.op   = op;
1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VAluS.dst  = dst;
1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VAluS.argL = argL;
1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VAluS.argR = argR;
1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp op, HReg dst, HReg src ) {
1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag               = ARMin_VUnaryD;
1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VUnaryD.op  = op;
1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VUnaryD.dst = dst;
1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VUnaryD.src = src;
1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp op, HReg dst, HReg src ) {
1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag               = ARMin_VUnaryS;
1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VUnaryS.op  = op;
1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VUnaryS.dst = dst;
1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VUnaryS.src = src;
1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR ) {
1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag              = ARMin_VCmpD;
1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCmpD.argL = argL;
1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCmpD.argR = argR;
1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VCMovD ( ARMCondCode cond, HReg dst, HReg src ) {
1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag               = ARMin_VCMovD;
1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCMovD.cond = cond;
1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCMovD.dst  = dst;
1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCMovD.src  = src;
1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(cond != ARMcc_AL);
1327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VCMovS ( ARMCondCode cond, HReg dst, HReg src ) {
1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag               = ARMin_VCMovS;
1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCMovS.cond = cond;
1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCMovS.dst  = dst;
1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCMovS.src  = src;
1335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(cond != ARMcc_AL);
1336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src ) {
1339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag               = ARMin_VCvtSD;
1341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCvtSD.sToD = sToD;
1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCvtSD.dst  = dst;
1343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCvtSD.src  = src;
1344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo ) {
1347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag              = ARMin_VXferD;
1349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VXferD.toD = toD;
1350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VXferD.dD  = dD;
1351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VXferD.rHi = rHi;
1352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VXferD.rLo = rLo;
1353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo ) {
1356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag              = ARMin_VXferS;
1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VXferS.toS = toS;
1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VXferS.fD  = fD;
1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VXferS.rLo = rLo;
1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned,
1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            HReg dst, HReg src ) {
1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                = ARMin_VCvtID;
1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCvtID.iToD  = iToD;
1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCvtID.syned = syned;
1369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCvtID.dst   = dst;
1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.VCvtID.src   = src;
1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg ) {
1374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                 = ARMin_FPSCR;
1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.FPSCR.toFPSCR = toFPSCR;
1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.FPSCR.iReg    = iReg;
1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_MFence ( void ) {
1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag      = ARMin_MFence;
1383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovARMInstr* ARMInstr_CLREX( void ) {
1386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   i->tag      = ARMin_CLREX;
1388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return i;
1389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_NLdStQ ( Bool isLoad, HReg dQ, ARMAModeN *amode ) {
1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                  = ARMin_NLdStQ;
1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NLdStQ.isLoad  = isLoad;
1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NLdStQ.dQ      = dQ;
1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NLdStQ.amode   = amode;
1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_NLdStD ( Bool isLoad, HReg dD, ARMAModeN *amode ) {
1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                  = ARMin_NLdStD;
1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NLdStD.isLoad  = isLoad;
1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NLdStD.dD      = dD;
1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NLdStD.amode   = amode;
1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_NUnary ( ARMNeonUnOp op, HReg dQ, HReg nQ,
1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            UInt size, Bool Q ) {
1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                = ARMin_NUnary;
1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NUnary.op   = op;
1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NUnary.src  = nQ;
1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NUnary.dst  = dQ;
1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NUnary.size = size;
1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NUnary.Q    = Q;
1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovARMInstr* ARMInstr_NUnaryS ( ARMNeonUnOpS op, ARMNRS* dst, ARMNRS* src,
1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             UInt size, Bool Q ) {
1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                = ARMin_NUnaryS;
1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NUnaryS.op   = op;
1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NUnaryS.src  = src;
1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NUnaryS.dst  = dst;
1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NUnaryS.size = size;
1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NUnaryS.Q    = Q;
1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_NDual ( ARMNeonDualOp op, HReg nQ, HReg mQ,
1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           UInt size, Bool Q ) {
1435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                = ARMin_NDual;
1437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NDual.op   = op;
1438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NDual.arg1 = nQ;
1439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NDual.arg2 = mQ;
1440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NDual.size = size;
1441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NDual.Q    = Q;
1442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_NBinary ( ARMNeonBinOp op,
1446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             HReg dst, HReg argL, HReg argR,
1447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             UInt size, Bool Q ) {
1448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                = ARMin_NBinary;
1450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NBinary.op   = op;
1451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NBinary.argL = argL;
1452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NBinary.argR = argR;
1453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NBinary.dst  = dst;
1454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NBinary.size = size;
1455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NBinary.Q    = Q;
1456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_NeonImm (HReg dst, ARMNImm* imm ) {
1460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr *i = LibVEX_Alloc(sizeof(ARMInstr));
1461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag         = ARMin_NeonImm;
1462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NeonImm.dst = dst;
1463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NeonImm.imm = imm;
1464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_NCMovQ ( ARMCondCode cond, HReg dst, HReg src ) {
1468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag               = ARMin_NCMovQ;
1470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NCMovQ.cond = cond;
1471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NCMovQ.dst  = dst;
1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NCMovQ.src  = src;
1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(cond != ARMcc_AL);
1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_NShift ( ARMNeonShiftOp op,
1478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            HReg dst, HReg argL, HReg argR,
1479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            UInt size, Bool Q ) {
1480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->tag                = ARMin_NShift;
1482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NShift.op   = op;
1483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NShift.argL = argL;
1484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NShift.argR = argR;
1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NShift.dst  = dst;
1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NShift.size = size;
1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->ARMin.NShift.Q    = Q;
1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1491436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovARMInstr* ARMInstr_NShl64 ( HReg dst, HReg src, UInt amt )
1492436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
1493436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1494436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i->tag              = ARMin_NShl64;
1495436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i->ARMin.NShl64.dst = dst;
1496436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i->ARMin.NShl64.src = src;
1497436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   i->ARMin.NShl64.amt = amt;
1498436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vassert(amt >= 1 && amt <= 63);
1499436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return i;
1500436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
1501436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
1502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Helper copy-pasted from isel.c */
1503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool fitsIn8x4 ( UInt* u8, UInt* u4, UInt u )
1504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt i;
1506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < 16; i++) {
1507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (0 == (u & 0xFFFFFF00)) {
1508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *u8 = u;
1509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *u4 = i;
1510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return True;
1511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      u = ROR32(u, 30);
1513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(i == 16);
1515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return False;
1516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownARMInstr* ARMInstr_Add32 ( HReg rD, HReg rN, UInt imm32 ) {
1519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt u8, u4;
1520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARMInstr *i = LibVEX_Alloc(sizeof(ARMInstr));
1521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Try to generate single ADD if possible */
1522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (fitsIn8x4(&u8, &u4, imm32)) {
1523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->tag            = ARMin_Alu;
1524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->ARMin.Alu.op   = ARMalu_ADD;
1525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->ARMin.Alu.dst  = rD;
1526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->ARMin.Alu.argL = rN;
1527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->ARMin.Alu.argR = ARMRI84_I84(u8, u4);
1528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
1529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->tag               = ARMin_Add32;
1530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->ARMin.Add32.rD    = rD;
1531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->ARMin.Add32.rN    = rN;
1532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->ARMin.Add32.imm32 = imm32;
1533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return i;
1535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1537663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengARMInstr* ARMInstr_EvCheck ( ARMAMode1* amCounter,
1538663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                             ARMAMode1* amFailAddr ) {
1539663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   ARMInstr* i                 = LibVEX_Alloc(sizeof(ARMInstr));
1540663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->tag                      = ARMin_EvCheck;
1541663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.EvCheck.amCounter  = amCounter;
1542663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->ARMin.EvCheck.amFailAddr = amFailAddr;
1543663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return i;
1544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
1545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1546663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengARMInstr* ARMInstr_ProfInc ( void ) {
1547663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr));
1548663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   i->tag      = ARMin_ProfInc;
1549663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return i;
1550663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
1551663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ... */
1553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ppARMInstr ( ARMInstr* i ) {
1555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (i->tag) {
1556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Alu:
1557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%-4s  ", showARMAluOp(i->ARMin.Alu.op));
1558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.Alu.dst);
1559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.Alu.argL);
1561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppARMRI84(i->ARMin.Alu.argR);
1563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Shift:
1565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%s   ", showARMShiftOp(i->ARMin.Shift.op));
1566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.Shift.dst);
1567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.Shift.argL);
1569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppARMRI5(i->ARMin.Shift.argR);
1571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Unary:
1573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%s   ", showARMUnaryOp(i->ARMin.Unary.op));
1574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.Unary.dst);
1575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.Unary.src);
1577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_CmpOrTst:
1579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%s   ", i->ARMin.CmpOrTst.isCmp ? "cmp" : "tst");
1580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.CmpOrTst.argL);
1581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppARMRI84(i->ARMin.CmpOrTst.argR);
1583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Mov:
1585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("mov   ");
1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.Mov.dst);
1587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppARMRI84(i->ARMin.Mov.src);
1589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Imm32:
1591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("imm   ");
1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.Imm32.dst);
1593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", 0x%x", i->ARMin.Imm32.imm32);
1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdSt32:
1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.LdSt32.isLoad) {
1597436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            vex_printf("ldr%s ", i->ARMin.LdSt32.cc == ARMcc_AL ? "  "
1598436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                    : showARMCondCode(i->ARMin.LdSt32.cc));
1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.LdSt32.rD);
1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppARMAMode1(i->ARMin.LdSt32.amode);
1602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
1603436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            vex_printf("str%s ", i->ARMin.LdSt32.cc == ARMcc_AL ? "  "
1604436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                    : showARMCondCode(i->ARMin.LdSt32.cc));
1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppARMAMode1(i->ARMin.LdSt32.amode);
1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.LdSt32.rD);
1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdSt16:
1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.LdSt16.isLoad) {
1612436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            vex_printf("%s%s%s",
1613436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                       i->ARMin.LdSt16.signedLoad ? "ldrsh" : "ldrh",
1614436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                       i->ARMin.LdSt16.cc == ARMcc_AL ? "  "
1615436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                          : showARMCondCode(i->ARMin.LdSt16.cc),
1616436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                       i->ARMin.LdSt16.signedLoad ? " " : "  ");
1617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.LdSt16.rD);
1618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppARMAMode2(i->ARMin.LdSt16.amode);
1620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
1621436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            vex_printf("strh%s  ",
1622436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                       i->ARMin.LdSt16.cc == ARMcc_AL ? "  "
1623436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                          : showARMCondCode(i->ARMin.LdSt16.cc));
1624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppARMAMode2(i->ARMin.LdSt16.amode);
1625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.LdSt16.rD);
1627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdSt8U:
1630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.LdSt8U.isLoad) {
1631436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            vex_printf("ldrb%s  ", i->ARMin.LdSt8U.cc == ARMcc_AL ? "  "
1632436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                      : showARMCondCode(i->ARMin.LdSt8U.cc));
1633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.LdSt8U.rD);
1634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppARMAMode1(i->ARMin.LdSt8U.amode);
1636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
1637436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            vex_printf("strb%s  ", i->ARMin.LdSt8U.cc == ARMcc_AL ? "  "
1638436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                      : showARMCondCode(i->ARMin.LdSt8U.cc));
1639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppARMAMode1(i->ARMin.LdSt8U.amode);
1640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.LdSt8U.rD);
1642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Ld8S:
1645436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vex_printf("ldrsb%s ", i->ARMin.Ld8S.cc == ARMcc_AL ? "  "
1646436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                   : showARMCondCode(i->ARMin.Ld8S.cc));
1647436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ppARMAMode2(i->ARMin.Ld8S.amode);
1648436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vex_printf(", ");
1649436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ppHRegARM(i->ARMin.Ld8S.rD);
1650436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return;
1651663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_XDirect:
1652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("(xDirect) ");
1653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("if (%%cpsr.%s) { ",
1654663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    showARMCondCode(i->ARMin.XDirect.cond));
1655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("movw r12,0x%x; ",
1656663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    (UInt)(i->ARMin.XDirect.dstGA & 0xFFFF));
1657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("movt r12,0x%x; ",
1658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    (UInt)((i->ARMin.XDirect.dstGA >> 16) & 0xFFFF));
1659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("str r12,");
1660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         ppARMAMode1(i->ARMin.XDirect.amR15T);
1661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("; movw r12,LO16($disp_cp_chain_me_to_%sEP); ",
1662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    i->ARMin.XDirect.toFastEP ? "fast" : "slow");
1663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("movt r12,HI16($disp_cp_chain_me_to_%sEP); ",
1664663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    i->ARMin.XDirect.toFastEP ? "fast" : "slow");
1665663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("blx r12 }");
1666663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
1667663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_XIndir:
1668663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("(xIndir) ");
1669663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("if (%%cpsr.%s) { ",
1670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    showARMCondCode(i->ARMin.XIndir.cond));
1671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("str ");
1672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         ppHRegARM(i->ARMin.XIndir.dstGA);
1673663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf(",");
1674663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         ppARMAMode1(i->ARMin.XIndir.amR15T);
1675663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("; movw r12,LO16($disp_cp_xindir); ");
1676663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("movt r12,HI16($disp_cp_xindir); ");
1677663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("blx r12 }");
1678663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
1679663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_XAssisted:
1680663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("(xAssisted) ");
1681663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("if (%%cpsr.%s) { ",
1682663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    showARMCondCode(i->ARMin.XAssisted.cond));
1683663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("str ");
1684663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         ppHRegARM(i->ARMin.XAssisted.dstGA);
1685663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf(",");
1686663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         ppARMAMode1(i->ARMin.XAssisted.amR15T);
1687663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("movw r8,$IRJumpKind_to_TRCVAL(%d); ",
1688663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    (Int)i->ARMin.XAssisted.jk);
1689663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("movw r12,LO16($disp_cp_xassisted); ");
1690663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("movt r12,HI16($disp_cp_xassisted); ");
1691663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("blx r12 }");
1692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_CMov:
1694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("mov%s ", showARMCondCode(i->ARMin.CMov.cond));
1695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.CMov.dst);
1696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppARMRI84(i->ARMin.CMov.src);
1698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Call:
1700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("call%s  ",
1701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    i->ARMin.Call.cond==ARMcc_AL
1702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ? "" : showARMCondCode(i->ARMin.Call.cond));
1703436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vex_printf("0x%lx [nArgRegs=%d, ",
1704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    i->ARMin.Call.target, i->ARMin.Call.nArgRegs);
1705436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ppRetLoc(i->ARMin.Call.rloc);
1706436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vex_printf("]");
1707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Mul:
1709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%-5s ", showARMMulOp(i->ARMin.Mul.op));
1710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.Mul.op == ARMmul_PLAIN) {
1711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("r0, r2, r3");
1712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
1713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("r1:r0, r2, r3");
1714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1716b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case ARMin_LdrEX: {
1717436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         const HChar* sz = "";
1718b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         switch (i->ARMin.LdrEX.szB) {
1719b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            case 1: sz = "b"; break; case 2: sz = "h"; break;
1720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            case 8: sz = "d"; break; case 4: break;
1721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            default: vassert(0);
1722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
1723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vex_printf("ldrex%s %sr2, [r4]",
1724b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    sz, i->ARMin.LdrEX.szB == 8 ? "r3:" : "");
1725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
1727b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case ARMin_StrEX: {
1728436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         const HChar* sz = "";
1729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         switch (i->ARMin.StrEX.szB) {
1730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            case 1: sz = "b"; break; case 2: sz = "h"; break;
1731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            case 8: sz = "d"; break; case 4: break;
1732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            default: vassert(0);
1733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
1734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vex_printf("strex%s r0, %sr2, [r4]",
1735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    sz, i->ARMin.StrEX.szB == 8 ? "r3:" : "");
1736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1737b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
1738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VLdStD:
1739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.VLdStD.isLoad) {
1740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("fldd  ");
1741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VLdStD.dD);
1742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppARMAModeV(i->ARMin.VLdStD.amode);
1744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
1745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("fstd  ");
1746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppARMAModeV(i->ARMin.VLdStD.amode);
1747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VLdStD.dD);
1749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VLdStS:
1752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.VLdStS.isLoad) {
1753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("flds  ");
1754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VLdStS.fD);
1755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppARMAModeV(i->ARMin.VLdStS.amode);
1757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
1758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("fsts  ");
1759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppARMAModeV(i->ARMin.VLdStS.amode);
1760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VLdStS.fD);
1762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VAluD:
1765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("f%-3sd ", showARMVfpOp(i->ARMin.VAluD.op));
1766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VAluD.dst);
1767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VAluD.argL);
1769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VAluD.argR);
1771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VAluS:
1773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("f%-3ss ", showARMVfpOp(i->ARMin.VAluS.op));
1774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VAluS.dst);
1775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VAluS.argL);
1777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VAluS.argR);
1779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VUnaryD:
1781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("f%-3sd ", showARMVfpUnaryOp(i->ARMin.VUnaryD.op));
1782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VUnaryD.dst);
1783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VUnaryD.src);
1785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VUnaryS:
1787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("f%-3ss ", showARMVfpUnaryOp(i->ARMin.VUnaryS.op));
1788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VUnaryS.dst);
1789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VUnaryS.src);
1791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCmpD:
1793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("fcmpd ");
1794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VCmpD.argL);
1795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VCmpD.argR);
1797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(" ; fmstat");
1798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCMovD:
1800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("fcpyd%s ", showARMCondCode(i->ARMin.VCMovD.cond));
1801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VCMovD.dst);
1802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VCMovD.src);
1804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCMovS:
1806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("fcpys%s ", showARMCondCode(i->ARMin.VCMovS.cond));
1807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VCMovS.dst);
1808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VCMovS.src);
1810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCvtSD:
1812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("fcvt%s ", i->ARMin.VCvtSD.sToD ? "ds" : "sd");
1813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VCvtSD.dst);
1814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VCvtSD.src);
1816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VXferD:
1818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("vmov  ");
1819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.VXferD.toD) {
1820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VXferD.dD);
1821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VXferD.rLo);
1823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VXferD.rHi);
1825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
1826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VXferD.rLo);
1827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VXferD.rHi);
1829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VXferD.dD);
1831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VXferS:
1834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("vmov  ");
1835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.VXferS.toS) {
1836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VXferS.fD);
1837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VXferS.rLo);
1839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
1840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VXferS.rLo);
1841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", ");
1842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.VXferS.fD);
1843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCvtID: {
1846436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         const HChar* nm = "?";
1847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.VCvtID.iToD) {
1848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            nm = i->ARMin.VCvtID.syned ? "fsitod" : "fuitod";
1849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
1850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            nm = i->ARMin.VCvtID.syned ? "ftosid" : "ftouid";
1851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%s ", nm);
1853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VCvtID.dst);
1854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.VCvtID.src);
1856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_FPSCR:
1859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.FPSCR.toFPSCR) {
1860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("fmxr  fpscr, ");
1861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.FPSCR.iReg);
1862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
1863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("fmrx  ");
1864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppHRegARM(i->ARMin.FPSCR.iReg);
1865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", fpscr");
1866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_MFence:
1869663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("(mfence) dsb sy; dmb sy; isb");
1870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1871b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case ARMin_CLREX:
1872b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vex_printf("clrex");
1873b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
1874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NLdStQ:
1875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NLdStQ.isLoad)
1876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("vld1.32 {");
1877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else
1878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("vst1.32 {");
1879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NLdStQ.dQ);
1880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("} ");
1881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppARMAModeN(i->ARMin.NLdStQ.amode);
1882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NLdStD:
1884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NLdStD.isLoad)
1885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("vld1.32 {");
1886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else
1887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("vst1.32 {");
1888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NLdStD.dD);
1889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("} ");
1890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppARMAModeN(i->ARMin.NLdStD.amode);
1891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NUnary:
1893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%s%s%s  ",
1894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonUnOp(i->ARMin.NUnary.op),
1895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonUnOpDataType(i->ARMin.NUnary.op),
1896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonDataSize(i));
1897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NUnary.dst);
1898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NUnary.src);
1900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NUnary.op == ARMneon_EQZ)
1901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", #0");
1902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NUnary.op == ARMneon_VCVTFtoFixedS ||
1903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTFtoFixedU ||
1904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTFixedStoF ||
1905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VCVTFixedUtoF) {
1906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf(", #%d", i->ARMin.NUnary.size);
1907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NUnary.op == ARMneon_VQSHLNSS ||
1909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VQSHLNUU ||
1910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             i->ARMin.NUnary.op == ARMneon_VQSHLNUS) {
1911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt size;
1912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            size = i->ARMin.NUnary.size;
1913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (size & 0x40) {
1914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               vex_printf(", #%d", size - 64);
1915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } else if (size & 0x20) {
1916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               vex_printf(", #%d", size - 32);
1917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } else if (size & 0x10) {
1918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               vex_printf(", #%d", size - 16);
1919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } else if (size & 0x08) {
1920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               vex_printf(", #%d", size - 8);
1921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
1922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NUnaryS:
1925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%s%s%s  ",
1926b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    showARMNeonUnOpS(i->ARMin.NUnaryS.op),
1927b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    showARMNeonUnOpSDataType(i->ARMin.NUnaryS.op),
1928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonDataSize(i));
1929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppARMNRS(i->ARMin.NUnaryS.dst);
1930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppARMNRS(i->ARMin.NUnaryS.src);
1932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NShift:
1934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%s%s%s  ",
1935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonShiftOp(i->ARMin.NShift.op),
1936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonShiftOpDataType(i->ARMin.NShift.op),
1937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonDataSize(i));
1938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NShift.dst);
1939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NShift.argL);
1941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NShift.argR);
1943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1944436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case ARMin_NShl64:
1945436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vex_printf("vshl.i64 ");
1946436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ppHRegARM(i->ARMin.NShl64.dst);
1947436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vex_printf(", ");
1948436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ppHRegARM(i->ARMin.NShl64.src);
1949436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vex_printf(", #%u", i->ARMin.NShl64.amt);
1950436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return;
1951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NDual:
1952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%s%s%s  ",
1953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonDualOp(i->ARMin.NDual.op),
1954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonDualOpDataType(i->ARMin.NDual.op),
1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonDataSize(i));
1956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NDual.arg1);
1957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NDual.arg2);
1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NBinary:
1961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%s%s%s",
1962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonBinOp(i->ARMin.NBinary.op),
1963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonBinOpDataType(i->ARMin.NBinary.op),
1964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    showARMNeonDataSize(i));
1965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("  ");
1966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NBinary.dst);
1967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NBinary.argL);
1969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NBinary.argR);
1971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NeonImm:
1973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("vmov  ");
1974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NeonImm.dst);
1975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppARMNImm(i->ARMin.NeonImm.imm);
1977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NCMovQ:
1979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("vmov%s ", showARMCondCode(i->ARMin.NCMovQ.cond));
1980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NCMovQ.dst);
1981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.NCMovQ.src);
1983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Add32:
1985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("add32 ");
1986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.Add32.rD);
1987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegARM(i->ARMin.Add32.rN);
1989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf(", ");
1990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("%d", i->ARMin.Add32.imm32);
1991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_EvCheck:
1993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("(evCheck) ldr r12,");
1994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         ppARMAMode1(i->ARMin.EvCheck.amCounter);
1995663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("; subs r12,r12,$1; str r12,");
1996663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         ppARMAMode1(i->ARMin.EvCheck.amCounter);
1997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("; bpl nofail; ldr r12,");
1998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         ppARMAMode1(i->ARMin.EvCheck.amFailAddr);
1999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("; bx r12; nofail:");
2000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
2001663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_ProfInc:
2002663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("(profInc) movw r12,LO16($NotKnownYet); "
2003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    "movw r12,HI16($NotKnownYet); "
2004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    "ldr r11,[r12]; "
2005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    "adds r11,r11,$1; "
2006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    "str r11,[r12]; "
2007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    "ldr r11,[r12+4]; "
2008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    "adc r11,r11,$0; "
2009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    "str r11,[r12+4]");
2010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
2011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
2012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vex_printf("ppARMInstr: unhandled case (tag %d)", (Int)i->tag);
2013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("ppARMInstr(1)");
2014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------- Helpers for register allocation. --------- */
2020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid getRegUsage_ARMInstr ( HRegUsage* u, ARMInstr* i, Bool mode64 )
2022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(mode64 == False);
2024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   initHRegUsage(u);
2025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (i->tag) {
2026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Alu:
2027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.Alu.dst);
2028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.Alu.argL);
2029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addRegUsage_ARMRI84(u, i->ARMin.Alu.argR);
2030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Shift:
2032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.Shift.dst);
2033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.Shift.argL);
2034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addRegUsage_ARMRI5(u, i->ARMin.Shift.argR);
2035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Unary:
2037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.Unary.dst);
2038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.Unary.src);
2039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_CmpOrTst:
2041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.CmpOrTst.argL);
2042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addRegUsage_ARMRI84(u, i->ARMin.CmpOrTst.argR);
2043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Mov:
2045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.Mov.dst);
2046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addRegUsage_ARMRI84(u, i->ARMin.Mov.src);
2047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Imm32:
2049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.Imm32.dst);
2050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdSt32:
2052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addRegUsage_ARMAMode1(u, i->ARMin.LdSt32.amode);
2053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.LdSt32.isLoad) {
2054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.LdSt32.rD);
2055436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (i->ARMin.LdSt32.cc != ARMcc_AL)
2056436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               addHRegUse(u, HRmRead, i->ARMin.LdSt32.rD);
2057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
2058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead, i->ARMin.LdSt32.rD);
2059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdSt16:
2062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addRegUsage_ARMAMode2(u, i->ARMin.LdSt16.amode);
2063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.LdSt16.isLoad) {
2064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.LdSt16.rD);
2065436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (i->ARMin.LdSt16.cc != ARMcc_AL)
2066436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               addHRegUse(u, HRmRead, i->ARMin.LdSt16.rD);
2067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
2068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead, i->ARMin.LdSt16.rD);
2069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdSt8U:
2072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addRegUsage_ARMAMode1(u, i->ARMin.LdSt8U.amode);
2073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.LdSt8U.isLoad) {
2074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.LdSt8U.rD);
2075436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (i->ARMin.LdSt8U.cc != ARMcc_AL)
2076436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               addHRegUse(u, HRmRead, i->ARMin.LdSt8U.rD);
2077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
2078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead, i->ARMin.LdSt8U.rD);
2079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Ld8S:
2082436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         addRegUsage_ARMAMode2(u, i->ARMin.Ld8S.amode);
2083436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         addHRegUse(u, HRmWrite, i->ARMin.Ld8S.rD);
2084436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (i->ARMin.Ld8S.cc != ARMcc_AL)
2085436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            addHRegUse(u, HRmRead, i->ARMin.Ld8S.rD);
2086436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return;
2087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* XDirect/XIndir/XAssisted are also a bit subtle.  They
2088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         conditionally exit the block.  Hence we only need to list (1)
2089663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         the registers that they read, and (2) the registers that they
2090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         write in the case where the block is not exited.  (2) is
2091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         empty, hence only (1) is relevant here. */
2092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_XDirect:
2093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         addRegUsage_ARMAMode1(u, i->ARMin.XDirect.amR15T);
2094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
2095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_XIndir:
2096663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         addHRegUse(u, HRmRead, i->ARMin.XIndir.dstGA);
2097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         addRegUsage_ARMAMode1(u, i->ARMin.XIndir.amR15T);
2098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
2099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_XAssisted:
2100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         addHRegUse(u, HRmRead, i->ARMin.XAssisted.dstGA);
2101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         addRegUsage_ARMAMode1(u, i->ARMin.XAssisted.amR15T);
2102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_CMov:
2104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.CMov.dst);
2105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead,  i->ARMin.CMov.dst);
2106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addRegUsage_ARMRI84(u, i->ARMin.CMov.src);
2107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Call:
2109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* logic and comments copied/modified from x86 back end */
2110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* This is a bit subtle. */
2111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* First off, claim it trashes all the caller-saved regs
2112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            which fall within the register allocator's jurisdiction.
2113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            These I believe to be r0,1,2,3.  If it turns out that r9
2114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            is also caller-saved, then we'll have to add that here
2115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            too. */
2116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, hregARM_R0());
2117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, hregARM_R1());
2118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, hregARM_R2());
2119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, hregARM_R3());
2120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Now we have to state any parameter-carrying registers
2121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            which might be read.  This depends on nArgRegs. */
2122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.Call.nArgRegs) {
2123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 4: addHRegUse(u, HRmRead, hregARM_R3()); /*fallthru*/
2124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 3: addHRegUse(u, HRmRead, hregARM_R2()); /*fallthru*/
2125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 2: addHRegUse(u, HRmRead, hregARM_R1()); /*fallthru*/
2126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 1: addHRegUse(u, HRmRead, hregARM_R0()); break;
2127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 0: break;
2128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default: vpanic("getRegUsage_ARM:Call:regparms");
2129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Finally, there is the issue that the insn trashes a
2131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            register because the literal target address has to be
2132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            loaded into a register.  Fortunately, for the nArgRegs=
2133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            0/1/2/3 case, we can use r0, r1, r2 or r3 respectively, so
2134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            this does not cause any further damage.  For the
2135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            nArgRegs=4 case, we'll have to choose another register
2136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            arbitrarily since all the caller saved regs are used for
2137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            parameters, and so we might as well choose r11.
2138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            */
2139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.Call.nArgRegs == 4)
2140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, hregARM_R11());
2141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Upshot of this is that the assembler really must observe
2142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            the here-stated convention of which register to use as an
2143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            address temporary, depending on nArgRegs: 0==r0,
2144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            1==r1, 2==r2, 3==r3, 4==r11 */
2145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Mul:
2147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, hregARM_R2());
2148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, hregARM_R3());
2149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, hregARM_R0());
2150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.Mul.op != ARMmul_PLAIN)
2151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, hregARM_R1());
2152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdrEX:
2154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         addHRegUse(u, HRmRead, hregARM_R4());
2155584369aa497a47058d868ea1330f92df8bc6c7c5Kenny Root         addHRegUse(u, HRmWrite, hregARM_R2());
2156584369aa497a47058d868ea1330f92df8bc6c7c5Kenny Root         if (i->ARMin.LdrEX.szB == 8)
2157584369aa497a47058d868ea1330f92df8bc6c7c5Kenny Root            addHRegUse(u, HRmWrite, hregARM_R3());
2158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_StrEX:
2160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         addHRegUse(u, HRmRead, hregARM_R4());
2161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         addHRegUse(u, HRmWrite, hregARM_R0());
2162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, hregARM_R2());
2163584369aa497a47058d868ea1330f92df8bc6c7c5Kenny Root         if (i->ARMin.StrEX.szB == 8)
2164584369aa497a47058d868ea1330f92df8bc6c7c5Kenny Root            addHRegUse(u, HRmRead, hregARM_R3());
2165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VLdStD:
2167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addRegUsage_ARMAModeV(u, i->ARMin.VLdStD.amode);
2168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.VLdStD.isLoad) {
2169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.VLdStD.dD);
2170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
2171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead, i->ARMin.VLdStD.dD);
2172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VLdStS:
2175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addRegUsage_ARMAModeV(u, i->ARMin.VLdStS.amode);
2176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.VLdStS.isLoad) {
2177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.VLdStS.fD);
2178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
2179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead, i->ARMin.VLdStS.fD);
2180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VAluD:
2183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.VAluD.dst);
2184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.VAluD.argL);
2185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.VAluD.argR);
2186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VAluS:
2188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.VAluS.dst);
2189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.VAluS.argL);
2190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.VAluS.argR);
2191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VUnaryD:
2193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.VUnaryD.dst);
2194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.VUnaryD.src);
2195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VUnaryS:
2197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.VUnaryS.dst);
2198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.VUnaryS.src);
2199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCmpD:
2201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.VCmpD.argL);
2202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.VCmpD.argR);
2203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCMovD:
2205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.VCMovD.dst);
2206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead,  i->ARMin.VCMovD.dst);
2207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead,  i->ARMin.VCMovD.src);
2208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCMovS:
2210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.VCMovS.dst);
2211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead,  i->ARMin.VCMovS.dst);
2212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead,  i->ARMin.VCMovS.src);
2213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCvtSD:
2215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.VCvtSD.dst);
2216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead,  i->ARMin.VCvtSD.src);
2217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VXferD:
2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.VXferD.toD) {
2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.VXferD.dD);
2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead,  i->ARMin.VXferD.rHi);
2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead,  i->ARMin.VXferD.rLo);
2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead,  i->ARMin.VXferD.dD);
2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.VXferD.rHi);
2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.VXferD.rLo);
2227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VXferS:
2230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.VXferS.toS) {
2231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.VXferS.fD);
2232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead,  i->ARMin.VXferS.rLo);
2233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
2234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead,  i->ARMin.VXferS.fD);
2235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.VXferS.rLo);
2236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCvtID:
2239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.VCvtID.dst);
2240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead,  i->ARMin.VCvtID.src);
2241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_FPSCR:
2243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.FPSCR.toFPSCR)
2244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead, i->ARMin.FPSCR.iReg);
2245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else
2246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.FPSCR.iReg);
2247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_MFence:
2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case ARMin_CLREX:
2251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
2252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NLdStQ:
2253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NLdStQ.isLoad)
2254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.NLdStQ.dQ);
2255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else
2256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead, i->ARMin.NLdStQ.dQ);
2257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addRegUsage_ARMAModeN(u, i->ARMin.NLdStQ.amode);
2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NLdStD:
2260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NLdStD.isLoad)
2261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmWrite, i->ARMin.NLdStD.dD);
2262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else
2263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            addHRegUse(u, HRmRead, i->ARMin.NLdStD.dD);
2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addRegUsage_ARMAModeN(u, i->ARMin.NLdStD.amode);
2265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NUnary:
2267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.NUnary.dst);
2268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.NUnary.src);
2269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NUnaryS:
2271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.NUnaryS.dst->reg);
2272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.NUnaryS.src->reg);
2273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NShift:
2275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.NShift.dst);
2276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.NShift.argL);
2277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.NShift.argR);
2278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2279436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case ARMin_NShl64:
2280436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         addHRegUse(u, HRmWrite, i->ARMin.NShl64.dst);
2281436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         addHRegUse(u, HRmRead, i->ARMin.NShl64.src);
2282436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return;
2283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NDual:
2284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.NDual.arg1);
2285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.NDual.arg2);
2286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.NDual.arg1);
2287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.NDual.arg2);
2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NBinary:
2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.NBinary.dst);
2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* TODO: sometimes dst is also being read! */
2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // XXX fix this
2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.NBinary.argL);
2294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.NBinary.argR);
2295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NeonImm:
2297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.NeonImm.dst);
2298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NCMovQ:
2300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.NCMovQ.dst);
2301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead,  i->ARMin.NCMovQ.dst);
2302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead,  i->ARMin.NCMovQ.src);
2303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Add32:
2305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmWrite, i->ARMin.Add32.rD);
2306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         addHRegUse(u, HRmRead, i->ARMin.Add32.rN);
2307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_EvCheck:
2309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* We expect both amodes only to mention r8, so this is in
2310663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            fact pointless, since r8 isn't allocatable, but
2311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            anyway.. */
2312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         addRegUsage_ARMAMode1(u, i->ARMin.EvCheck.amCounter);
2313663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         addRegUsage_ARMAMode1(u, i->ARMin.EvCheck.amFailAddr);
2314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         addHRegUse(u, HRmWrite, hregARM_R12()); /* also unavail to RA */
2315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
2316663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_ProfInc:
2317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         addHRegUse(u, HRmWrite, hregARM_R12());
2318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         addHRegUse(u, HRmWrite, hregARM_R11());
2319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
2320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
2321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppARMInstr(i);
2322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("getRegUsage_ARMInstr");
2323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid mapRegs_ARMInstr ( HRegRemap* m, ARMInstr* i, Bool mode64 )
2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(mode64 == False);
2330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (i->tag) {
2331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Alu:
2332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.Alu.dst = lookupHRegRemap(m, i->ARMin.Alu.dst);
2333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.Alu.argL = lookupHRegRemap(m, i->ARMin.Alu.argL);
2334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs_ARMRI84(m, i->ARMin.Alu.argR);
2335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Shift:
2337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.Shift.dst = lookupHRegRemap(m, i->ARMin.Shift.dst);
2338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.Shift.argL = lookupHRegRemap(m, i->ARMin.Shift.argL);
2339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs_ARMRI5(m, i->ARMin.Shift.argR);
2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Unary:
2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.Unary.dst = lookupHRegRemap(m, i->ARMin.Unary.dst);
2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.Unary.src = lookupHRegRemap(m, i->ARMin.Unary.src);
2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_CmpOrTst:
2346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.CmpOrTst.argL = lookupHRegRemap(m, i->ARMin.CmpOrTst.argL);
2347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs_ARMRI84(m, i->ARMin.CmpOrTst.argR);
2348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Mov:
2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.Mov.dst = lookupHRegRemap(m, i->ARMin.Mov.dst);
2351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs_ARMRI84(m, i->ARMin.Mov.src);
2352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Imm32:
2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.Imm32.dst = lookupHRegRemap(m, i->ARMin.Imm32.dst);
2355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdSt32:
2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.LdSt32.rD = lookupHRegRemap(m, i->ARMin.LdSt32.rD);
2358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs_ARMAMode1(m, i->ARMin.LdSt32.amode);
2359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdSt16:
2361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.LdSt16.rD = lookupHRegRemap(m, i->ARMin.LdSt16.rD);
2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs_ARMAMode2(m, i->ARMin.LdSt16.amode);
2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdSt8U:
2365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.LdSt8U.rD = lookupHRegRemap(m, i->ARMin.LdSt8U.rD);
2366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs_ARMAMode1(m, i->ARMin.LdSt8U.amode);
2367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Ld8S:
2369436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         i->ARMin.Ld8S.rD = lookupHRegRemap(m, i->ARMin.Ld8S.rD);
2370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         mapRegs_ARMAMode2(m, i->ARMin.Ld8S.amode);
2371436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return;
2372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_XDirect:
2373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         mapRegs_ARMAMode1(m, i->ARMin.XDirect.amR15T);
2374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
2375663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_XIndir:
2376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         i->ARMin.XIndir.dstGA
2377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            = lookupHRegRemap(m, i->ARMin.XIndir.dstGA);
2378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         mapRegs_ARMAMode1(m, i->ARMin.XIndir.amR15T);
2379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
2380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_XAssisted:
2381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         i->ARMin.XAssisted.dstGA
2382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            = lookupHRegRemap(m, i->ARMin.XAssisted.dstGA);
2383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         mapRegs_ARMAMode1(m, i->ARMin.XAssisted.amR15T);
2384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_CMov:
2386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.CMov.dst = lookupHRegRemap(m, i->ARMin.CMov.dst);
2387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs_ARMRI84(m, i->ARMin.CMov.src);
2388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Call:
2390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Mul:
2392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdrEX:
2394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_StrEX:
2396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VLdStD:
2398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VLdStD.dD = lookupHRegRemap(m, i->ARMin.VLdStD.dD);
2399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs_ARMAModeV(m, i->ARMin.VLdStD.amode);
2400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VLdStS:
2402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VLdStS.fD = lookupHRegRemap(m, i->ARMin.VLdStS.fD);
2403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs_ARMAModeV(m, i->ARMin.VLdStS.amode);
2404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VAluD:
2406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VAluD.dst  = lookupHRegRemap(m, i->ARMin.VAluD.dst);
2407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VAluD.argL = lookupHRegRemap(m, i->ARMin.VAluD.argL);
2408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VAluD.argR = lookupHRegRemap(m, i->ARMin.VAluD.argR);
2409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VAluS:
2411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VAluS.dst  = lookupHRegRemap(m, i->ARMin.VAluS.dst);
2412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VAluS.argL = lookupHRegRemap(m, i->ARMin.VAluS.argL);
2413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VAluS.argR = lookupHRegRemap(m, i->ARMin.VAluS.argR);
2414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VUnaryD:
2416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VUnaryD.dst = lookupHRegRemap(m, i->ARMin.VUnaryD.dst);
2417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VUnaryD.src = lookupHRegRemap(m, i->ARMin.VUnaryD.src);
2418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VUnaryS:
2420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VUnaryS.dst = lookupHRegRemap(m, i->ARMin.VUnaryS.dst);
2421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VUnaryS.src = lookupHRegRemap(m, i->ARMin.VUnaryS.src);
2422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCmpD:
2424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VCmpD.argL = lookupHRegRemap(m, i->ARMin.VCmpD.argL);
2425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VCmpD.argR = lookupHRegRemap(m, i->ARMin.VCmpD.argR);
2426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCMovD:
2428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VCMovD.dst = lookupHRegRemap(m, i->ARMin.VCMovD.dst);
2429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VCMovD.src = lookupHRegRemap(m, i->ARMin.VCMovD.src);
2430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCMovS:
2432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VCMovS.dst = lookupHRegRemap(m, i->ARMin.VCMovS.dst);
2433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VCMovS.src = lookupHRegRemap(m, i->ARMin.VCMovS.src);
2434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCvtSD:
2436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VCvtSD.dst = lookupHRegRemap(m, i->ARMin.VCvtSD.dst);
2437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VCvtSD.src = lookupHRegRemap(m, i->ARMin.VCvtSD.src);
2438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VXferD:
2440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VXferD.dD  = lookupHRegRemap(m, i->ARMin.VXferD.dD);
2441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VXferD.rHi = lookupHRegRemap(m, i->ARMin.VXferD.rHi);
2442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VXferD.rLo = lookupHRegRemap(m, i->ARMin.VXferD.rLo);
2443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VXferS:
2445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VXferS.fD  = lookupHRegRemap(m, i->ARMin.VXferS.fD);
2446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VXferS.rLo = lookupHRegRemap(m, i->ARMin.VXferS.rLo);
2447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCvtID:
2449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VCvtID.dst = lookupHRegRemap(m, i->ARMin.VCvtID.dst);
2450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.VCvtID.src = lookupHRegRemap(m, i->ARMin.VCvtID.src);
2451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_FPSCR:
2453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.FPSCR.iReg = lookupHRegRemap(m, i->ARMin.FPSCR.iReg);
2454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_MFence:
2456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case ARMin_CLREX:
2458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return;
2459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NLdStQ:
2460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NLdStQ.dQ = lookupHRegRemap(m, i->ARMin.NLdStQ.dQ);
2461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs_ARMAModeN(m, i->ARMin.NLdStQ.amode);
2462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NLdStD:
2464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NLdStD.dD = lookupHRegRemap(m, i->ARMin.NLdStD.dD);
2465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mapRegs_ARMAModeN(m, i->ARMin.NLdStD.amode);
2466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NUnary:
2468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NUnary.src = lookupHRegRemap(m, i->ARMin.NUnary.src);
2469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NUnary.dst = lookupHRegRemap(m, i->ARMin.NUnary.dst);
2470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NUnaryS:
2472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NUnaryS.src->reg
2473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = lookupHRegRemap(m, i->ARMin.NUnaryS.src->reg);
2474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NUnaryS.dst->reg
2475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = lookupHRegRemap(m, i->ARMin.NUnaryS.dst->reg);
2476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NShift:
2478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NShift.dst = lookupHRegRemap(m, i->ARMin.NShift.dst);
2479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NShift.argL = lookupHRegRemap(m, i->ARMin.NShift.argL);
2480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NShift.argR = lookupHRegRemap(m, i->ARMin.NShift.argR);
2481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2482436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case ARMin_NShl64:
2483436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         i->ARMin.NShl64.dst = lookupHRegRemap(m, i->ARMin.NShl64.dst);
2484436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         i->ARMin.NShl64.src = lookupHRegRemap(m, i->ARMin.NShl64.src);
2485436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         return;
2486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NDual:
2487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NDual.arg1 = lookupHRegRemap(m, i->ARMin.NDual.arg1);
2488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NDual.arg2 = lookupHRegRemap(m, i->ARMin.NDual.arg2);
2489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NBinary:
2491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NBinary.argL = lookupHRegRemap(m, i->ARMin.NBinary.argL);
2492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NBinary.argR = lookupHRegRemap(m, i->ARMin.NBinary.argR);
2493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NBinary.dst  = lookupHRegRemap(m, i->ARMin.NBinary.dst);
2494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NeonImm:
2496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NeonImm.dst = lookupHRegRemap(m, i->ARMin.NeonImm.dst);
2497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NCMovQ:
2499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NCMovQ.dst = lookupHRegRemap(m, i->ARMin.NCMovQ.dst);
2500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.NCMovQ.src = lookupHRegRemap(m, i->ARMin.NCMovQ.src);
2501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Add32:
2503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.Add32.rD = lookupHRegRemap(m, i->ARMin.Add32.rD);
2504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->ARMin.Add32.rN = lookupHRegRemap(m, i->ARMin.Add32.rN);
2505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
2506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_EvCheck:
2507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* We expect both amodes only to mention r8, so this is in
2508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            fact pointless, since r8 isn't allocatable, but
2509663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            anyway.. */
2510663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         mapRegs_ARMAMode1(m, i->ARMin.EvCheck.amCounter);
2511663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         mapRegs_ARMAMode1(m, i->ARMin.EvCheck.amFailAddr);
2512663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
2513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_ProfInc:
2514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* hardwires r11 and r12 -- nothing to modify. */
2515663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         return;
2516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
2517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppARMInstr(i);
2518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("mapRegs_ARMInstr");
2519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Figure out if i represents a reg-reg move, and if so assign the
2523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   source and destination to *src and *dst.  If in doubt say No.  Used
2524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   by the register allocator to do move coalescing.
2525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool isMove_ARMInstr ( ARMInstr* i, HReg* src, HReg* dst )
2527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Moves between integer regs */
2529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (i->tag) {
2530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Mov:
2531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.Mov.src->tag == ARMri84_R) {
2532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *src = i->ARMin.Mov.src->ARMri84.R.reg;
2533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *dst = i->ARMin.Mov.dst;
2534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return True;
2535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VUnaryD:
2538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.VUnaryD.op == ARMvfpu_COPY) {
2539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *src = i->ARMin.VUnaryD.src;
2540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *dst = i->ARMin.VUnaryD.dst;
2541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return True;
2542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VUnaryS:
2545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.VUnaryS.op == ARMvfpu_COPY) {
2546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *src = i->ARMin.VUnaryS.src;
2547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *dst = i->ARMin.VUnaryS.dst;
2548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return True;
2549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case ARMin_NUnary:
2552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (i->ARMin.NUnary.op == ARMneon_COPY) {
2553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            *src = i->ARMin.NUnary.src;
2554b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            *dst = i->ARMin.NUnary.dst;
2555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            return True;
2556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
2557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         break;
2558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
2559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return False;
2563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Generate arm spill/reload instructions under the direction of the
2567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   register allocator.  Note it's critical these don't write the
2568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   condition codes. */
2569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
2571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    HReg rreg, Int offsetB, Bool mode64 )
2572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   HRegClass rclass;
2574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(offsetB >= 0);
2575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(!hregIsVirtual(rreg));
2576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(mode64 == False);
2577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *i1 = *i2 = NULL;
2578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   rclass = hregClass(rreg);
2579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (rclass) {
2580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case HRcInt32:
2581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(offsetB <= 4095);
2582436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         *i1 = ARMInstr_LdSt32( ARMcc_AL, False/*!isLoad*/,
2583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                rreg,
2584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                ARMAMode1_RI(hregARM_R8(), offsetB) );
2585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case HRcFlt32:
2587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case HRcFlt64: {
2588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         HReg r8   = hregARM_R8();  /* baseblock */
2589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         HReg r12  = hregARM_R12(); /* spill temp */
2590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         HReg base = r8;
2591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0 == (offsetB & 3));
2592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (offsetB >= 1024) {
2593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int offsetKB = offsetB / 1024;
2594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* r12 = r8 + (1024 * offsetKB) */
2595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *i1 = ARMInstr_Alu(ARMalu_ADD, r12, r8,
2596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               ARMRI84_I84(offsetKB, 11));
2597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            offsetB -= (1024 * offsetKB);
2598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            base = r12;
2599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(offsetB <= 1020);
2601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (rclass == HRcFlt32) {
2602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *i2 = ARMInstr_VLdStS( False/*!isLoad*/,
2603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   rreg,
2604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   mkARMAModeV(base, offsetB) );
2605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
2606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *i2 = ARMInstr_VLdStD( False/*!isLoad*/,
2607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   rreg,
2608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   mkARMAModeV(base, offsetB) );
2609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case HRcVec128: {
2613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         HReg r8  = hregARM_R8();
2614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         HReg r12 = hregARM_R12();
2615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *i1 = ARMInstr_Add32(r12, r8, offsetB);
2616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *i2 = ARMInstr_NLdStQ(False, rreg, mkARMAModeN_R(r12));
2617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
2620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegClass(rclass);
2621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("genSpill_ARM: unimplemented regclass");
2622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
2626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     HReg rreg, Int offsetB, Bool mode64 )
2627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   HRegClass rclass;
2629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(offsetB >= 0);
2630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(!hregIsVirtual(rreg));
2631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(mode64 == False);
2632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *i1 = *i2 = NULL;
2633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   rclass = hregClass(rreg);
2634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (rclass) {
2635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case HRcInt32:
2636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(offsetB <= 4095);
2637436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         *i1 = ARMInstr_LdSt32( ARMcc_AL, True/*isLoad*/,
2638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                rreg,
2639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                ARMAMode1_RI(hregARM_R8(), offsetB) );
2640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case HRcFlt32:
2642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case HRcFlt64: {
2643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         HReg r8   = hregARM_R8();  /* baseblock */
2644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         HReg r12  = hregARM_R12(); /* spill temp */
2645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         HReg base = r8;
2646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0 == (offsetB & 3));
2647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (offsetB >= 1024) {
2648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int offsetKB = offsetB / 1024;
2649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* r12 = r8 + (1024 * offsetKB) */
2650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *i1 = ARMInstr_Alu(ARMalu_ADD, r12, r8,
2651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               ARMRI84_I84(offsetKB, 11));
2652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            offsetB -= (1024 * offsetKB);
2653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            base = r12;
2654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(offsetB <= 1020);
2656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (rclass == HRcFlt32) {
2657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *i2 = ARMInstr_VLdStS( True/*isLoad*/,
2658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   rreg,
2659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   mkARMAModeV(base, offsetB) );
2660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
2661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *i2 = ARMInstr_VLdStD( True/*isLoad*/,
2662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   rreg,
2663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   mkARMAModeV(base, offsetB) );
2664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case HRcVec128: {
2668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         HReg r8  = hregARM_R8();
2669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         HReg r12 = hregARM_R12();
2670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *i1 = ARMInstr_Add32(r12, r8, offsetB);
2671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *i2 = ARMInstr_NLdStQ(True, rreg, mkARMAModeN_R(r12));
2672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
2673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
2675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ppHRegClass(rclass);
2676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vpanic("genReload_ARM: unimplemented regclass");
2677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Emit an instruction into buf and return the number of bytes used.
2682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Note that buf is not the insn's final place, and therefore it is
2683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   imperative to emit position-independent code. */
2684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar iregNo ( HReg r )
2686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt n;
2688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(hregClass(r) == HRcInt32);
2689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(!hregIsVirtual(r));
2690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = hregNumber(r);
2691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(n <= 15);
2692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return toUChar(n);
2693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar dregNo ( HReg r )
2696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt n;
2698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (hregClass(r) != HRcFlt64)
2699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ppHRegClass(hregClass(r));
2700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(hregClass(r) == HRcFlt64);
2701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(!hregIsVirtual(r));
2702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = hregNumber(r);
2703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(n <= 31);
2704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return toUChar(n);
2705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar fregNo ( HReg r )
2708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt n;
2710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(hregClass(r) == HRcFlt32);
2711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(!hregIsVirtual(r));
2712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = hregNumber(r);
2713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(n <= 31);
2714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return toUChar(n);
2715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar qregNo ( HReg r )
2718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt n;
2720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(hregClass(r) == HRcVec128);
2721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(!hregIsVirtual(r));
2722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = hregNumber(r);
2723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(n <= 15);
2724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return toUChar(n);
2725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define BITS4(zzb3,zzb2,zzb1,zzb0) \
2728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (((zzb3) << 3) | ((zzb2) << 2) | ((zzb1) << 1) | (zzb0))
2729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X0000  BITS4(0,0,0,0)
2730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X0001  BITS4(0,0,0,1)
2731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X0010  BITS4(0,0,1,0)
2732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X0011  BITS4(0,0,1,1)
2733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X0100  BITS4(0,1,0,0)
2734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X0101  BITS4(0,1,0,1)
2735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X0110  BITS4(0,1,1,0)
2736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X0111  BITS4(0,1,1,1)
2737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X1000  BITS4(1,0,0,0)
2738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X1001  BITS4(1,0,0,1)
2739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X1010  BITS4(1,0,1,0)
2740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X1011  BITS4(1,0,1,1)
2741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X1100  BITS4(1,1,0,0)
2742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X1101  BITS4(1,1,0,1)
2743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X1110  BITS4(1,1,1,0)
2744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define X1111  BITS4(1,1,1,1)
2745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define XXXXX___(zzx7,zzx6,zzx5,zzx4,zzx3) \
2747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ((((zzx7) & 0xF) << 28) | (((zzx6) & 0xF) << 24) |  \
2748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (((zzx5) & 0xF) << 20) | (((zzx4) & 0xF) << 16) |  \
2749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (((zzx3) & 0xF) << 12))
2750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define XXXXXX__(zzx7,zzx6,zzx5,zzx4,zzx3,zzx2)        \
2752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ((((zzx7) & 0xF) << 28) | (((zzx6) & 0xF) << 24) |  \
2753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (((zzx5) & 0xF) << 20) | (((zzx4) & 0xF) << 16) |  \
2754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (((zzx3) & 0xF) << 12) | (((zzx2) & 0xF) <<  8))
2755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define XXXXX__X(zzx7,zzx6,zzx5,zzx4,zzx3,zzx0)        \
2757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ((((zzx7) & 0xF) << 28) | (((zzx6) & 0xF) << 24) |  \
2758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (((zzx5) & 0xF) << 20) | (((zzx4) & 0xF) << 16) |  \
2759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (((zzx3) & 0xF) << 12) | (((zzx0) & 0xF) <<  0))
2760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define XXX___XX(zzx7,zzx6,zzx5,zzx1,zzx0) \
2762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ((((zzx7) & 0xF) << 28) | (((zzx6) & 0xF) << 24) | \
2763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (((zzx5) & 0xF) << 20) | (((zzx1) & 0xF) << 4) | \
2764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (((zzx0) & 0xF) << 0))
2765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define XXXXXXXX(zzx7,zzx6,zzx5,zzx4,zzx3,zzx2,zzx1,zzx0)  \
2767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ((((zzx7) & 0xF) << 28) | (((zzx6) & 0xF) << 24) |  \
2768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (((zzx5) & 0xF) << 20) | (((zzx4) & 0xF) << 16) |  \
2769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (((zzx3) & 0xF) << 12) | (((zzx2) & 0xF) <<  8) |  \
2770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (((zzx1) & 0xF) <<  4) | (((zzx0) & 0xF) <<  0))
2771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2772663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define XX______(zzx7,zzx6) \
2773663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   ((((zzx7) & 0xF) << 28) | (((zzx6) & 0xF) << 24))
2774663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Generate a skeletal insn that involves an a RI84 shifter operand.
2776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Returns a word which is all zeroes apart from bits 25 and 11..0,
2777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   since it is those that encode the shifter operand (at least to the
2778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   extent that we care about it.) */
2779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt skeletal_RI84 ( ARMRI84* ri )
2780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt instr;
2782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ri->tag == ARMri84_I84) {
2783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(0 == (ri->ARMri84.I84.imm4 & ~0x0F));
2784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(0 == (ri->ARMri84.I84.imm8 & ~0xFF));
2785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr = 1 << 25;
2786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr |= (ri->ARMri84.I84.imm4 << 8);
2787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr |= ri->ARMri84.I84.imm8;
2788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
2789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr = 0 << 25;
2790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr |= iregNo(ri->ARMri84.R.reg);
2791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return instr;
2793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Ditto for RI5.  Resulting word is zeroes apart from bit 4 and bits
2796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   11..7. */
2797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt skeletal_RI5 ( ARMRI5* ri )
2798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt instr;
2800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ri->tag == ARMri5_I5) {
2801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt imm5 = ri->ARMri5.I5.imm5;
2802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(imm5 >= 1 && imm5 <= 31);
2803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr = 0 << 4;
2804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr |= imm5 << 7;
2805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
2806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr = 1 << 4;
2807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr |= iregNo(ri->ARMri5.R.reg) << 8;
2808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return instr;
2810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Get an immediate into a register, using only that
2814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   register.  (very lame..) */
2815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt* imm32_to_iregNo ( UInt* p, Int rD, UInt imm32 )
2816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt instr;
2818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(rD >= 0 && rD <= 14); // r15 not good to mess with!
2819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0
2820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0 == (imm32 & ~0xFF)) {
2821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* mov with a immediate shifter operand of (0, imm32) (??) */
2822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr = XXXXXX__(X1110,X0011,X1010,X0000,rD,X0000);
2823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr |= imm32;
2824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *p++ = instr;
2825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
2826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // this is very bad; causes Dcache pollution
2827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // ldr  rD, [pc]
2828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr = XXXXX___(X1110,X0101,X1001,X1111,rD);
2829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *p++ = instr;
2830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // b .+8
2831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr = 0xEA000000;
2832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *p++ = instr;
2833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // .word imm32
2834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *p++ = imm32;
2835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
2837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VEX_ARM_ARCHLEVEL(arm_hwcaps) > 6) {
2838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Generate movw rD, #low16.  Then, if the high 16 are
2839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         nonzero, generate movt rD, #high16. */
2840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt lo16 = imm32 & 0xFFFF;
2841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt hi16 = (imm32 >> 16) & 0xFFFF;
2842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instr = XXXXXXXX(0xE, 0x3, 0x0, (lo16 >> 12) & 0xF, rD,
2843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       (lo16 >> 8) & 0xF, (lo16 >> 4) & 0xF,
2844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       lo16 & 0xF);
2845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *p++ = instr;
2846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (hi16 != 0) {
2847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr = XXXXXXXX(0xE, 0x3, 0x4, (hi16 >> 12) & 0xF, rD,
2848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          (hi16 >> 8) & 0xF, (hi16 >> 4) & 0xF,
2849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          hi16 & 0xF);
2850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = instr;
2851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
2853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt imm, rot;
2854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt op = X1010;
2855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt rN = 0;
2856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((imm32 & 0xFF) || (imm32 == 0)) {
2857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         imm = imm32 & 0xFF;
2858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         rot = 0;
2859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr = XXXXXXXX(0xE, 0x3, op, rN, rD, rot, imm >> 4, imm & 0xF);
2860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = instr;
2861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         op = X1000;
2862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         rN = rD;
2863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (imm32 & 0xFF000000) {
2865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         imm = (imm32 >> 24) & 0xFF;
2866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         rot = 4;
2867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr = XXXXXXXX(0xE, 0x3, op, rN, rD, rot, imm >> 4, imm & 0xF);
2868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = instr;
2869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         op = X1000;
2870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         rN = rD;
2871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (imm32 & 0xFF0000) {
2873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         imm = (imm32 >> 16) & 0xFF;
2874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         rot = 8;
2875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr = XXXXXXXX(0xE, 0x3, op, rN, rD, rot, imm >> 4, imm & 0xF);
2876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = instr;
2877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         op = X1000;
2878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         rN = rD;
2879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (imm32 & 0xFF00) {
2881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         imm = (imm32 >> 8) & 0xFF;
2882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         rot = 12;
2883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr = XXXXXXXX(0xE, 0x3, op, rN, rD, rot, imm >> 4, imm & 0xF);
2884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = instr;
2885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         op = X1000;
2886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         rN = rD;
2887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
2890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return p;
2891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Get an immediate into a register, using only that register, and
2894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   generating exactly 2 instructions, regardless of the value of the
2895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   immediate. This is used when generating sections of code that need
2896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   to be patched later, so as to guarantee a specific size. */
2897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UInt* imm32_to_iregNo_EXACTLY2 ( UInt* p, Int rD, UInt imm32 )
2898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
2899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (VEX_ARM_ARCHLEVEL(arm_hwcaps) > 6) {
2900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Generate movw rD, #low16 ;  movt rD, #high16. */
2901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      UInt lo16 = imm32 & 0xFFFF;
2902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      UInt hi16 = (imm32 >> 16) & 0xFFFF;
2903663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      UInt instr;
2904663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      instr = XXXXXXXX(0xE, 0x3, 0x0, (lo16 >> 12) & 0xF, rD,
2905663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                       (lo16 >> 8) & 0xF, (lo16 >> 4) & 0xF,
2906663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                       lo16 & 0xF);
2907663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      *p++ = instr;
2908663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      instr = XXXXXXXX(0xE, 0x3, 0x4, (hi16 >> 12) & 0xF, rD,
2909663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                       (hi16 >> 8) & 0xF, (hi16 >> 4) & 0xF,
2910663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                       hi16 & 0xF);
2911663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      *p++ = instr;
2912663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } else {
2913663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(0); /* lose */
2914663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
2915663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return p;
2916663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
2917663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Check whether p points at a 2-insn sequence cooked up by
2919663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   imm32_to_iregNo_EXACTLY2(). */
2920663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool is_imm32_to_iregNo_EXACTLY2 ( UInt* p, Int rD, UInt imm32 )
2921663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
2922663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (VEX_ARM_ARCHLEVEL(arm_hwcaps) > 6) {
2923663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Generate movw rD, #low16 ;  movt rD, #high16. */
2924663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      UInt lo16 = imm32 & 0xFFFF;
2925663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      UInt hi16 = (imm32 >> 16) & 0xFFFF;
2926663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      UInt i0, i1;
2927663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      i0 = XXXXXXXX(0xE, 0x3, 0x0, (lo16 >> 12) & 0xF, rD,
2928663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    (lo16 >> 8) & 0xF, (lo16 >> 4) & 0xF,
2929663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    lo16 & 0xF);
2930663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      i1 = XXXXXXXX(0xE, 0x3, 0x4, (hi16 >> 12) & 0xF, rD,
2931663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    (hi16 >> 8) & 0xF, (hi16 >> 4) & 0xF,
2932663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    hi16 & 0xF);
2933663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return p[0] == i0 && p[1] == i1;
2934663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } else {
2935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(0); /* lose */
2936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
2937663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
2938663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2939663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2940663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UInt* do_load_or_store32 ( UInt* p,
2941663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  Bool isLoad, UInt rD, ARMAMode1* am )
2942663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
2943663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(rD <= 12);
2944663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(am->tag == ARMam1_RI); // RR case is not handled
2945663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   UInt bB = 0;
2946663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   UInt bL = isLoad ? 1 : 0;
2947663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Int  simm12;
2948663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   UInt instr, bP;
2949663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (am->ARMam1.RI.simm13 < 0) {
2950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      bP = 0;
2951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      simm12 = -am->ARMam1.RI.simm13;
2952663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } else {
2953663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      bP = 1;
2954663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      simm12 = am->ARMam1.RI.simm13;
2955663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
2956663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(simm12 >= 0 && simm12 <= 4095);
2957663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   instr = XXXXX___(X1110,X0101,BITS4(bP,bB,0,bL),
2958663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    iregNo(am->ARMam1.RI.reg),
2959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    rD);
2960663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   instr |= simm12;
2961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   *p++ = instr;
2962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return p;
2963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
2964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2966663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Emit an instruction into buf and return the number of bytes used.
2967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Note that buf is not the insn's final place, and therefore it is
2968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   imperative to emit position-independent code.  If the emitted
2969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   instruction was a profiler inc, set *is_profInc to True, else
2970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   leave it unchanged. */
2971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2972663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengInt emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc,
2973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    UChar* buf, Int nbuf, ARMInstr* i,
2974b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    Bool mode64,
2975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    void* disp_cp_chain_me_to_slowEP,
2976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    void* disp_cp_chain_me_to_fastEP,
2977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    void* disp_cp_xindir,
2978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    void* disp_cp_xassisted )
2979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)buf;
2981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(nbuf >= 32);
2982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(mode64 == False);
2983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(0 == (((HWord)buf) & 3));
2984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (i->tag) {
2986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Alu: {
2987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt     instr, subopc;
2988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt     rD   = iregNo(i->ARMin.Alu.dst);
2989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt     rN   = iregNo(i->ARMin.Alu.argL);
2990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARMRI84* argR = i->ARMin.Alu.argR;
2991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.Alu.op) {
2992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMalu_ADDS: /* fallthru */
2993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMalu_ADD:  subopc = X0100; break;
2994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMalu_ADC:  subopc = X0101; break;
2995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMalu_SUBS: /* fallthru */
2996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMalu_SUB:  subopc = X0010; break;
2997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMalu_SBC:  subopc = X0110; break;
2998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMalu_AND:  subopc = X0000; break;
2999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMalu_BIC:  subopc = X1110; break;
3000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMalu_OR:   subopc = X1100; break;
3001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMalu_XOR:  subopc = X0001; break;
3002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default: goto bad;
3003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr = skeletal_RI84(argR);
3005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr |= XXXXX___(X1110, (1 & (subopc >> 3)),
3006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           (subopc << 1) & 0xF, rN, rD);
3007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.Alu.op == ARMalu_ADDS
3008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             || i->ARMin.Alu.op == ARMalu_SUBS) {
3009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            instr |= 1<<20;  /* set the S bit */
3010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = instr;
3012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Shift: {
3015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt    instr, subopc;
3016436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt    rD   = iregNo(i->ARMin.Shift.dst);
3017436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt    rM   = iregNo(i->ARMin.Shift.argL);
3018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARMRI5* argR = i->ARMin.Shift.argR;
3019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.Shift.op) {
3020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMsh_SHL: subopc = X0000; break;
3021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMsh_SHR: subopc = X0001; break;
3022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMsh_SAR: subopc = X0010; break;
3023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default: goto bad;
3024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr = skeletal_RI5(argR);
3026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr |= XXXXX__X(X1110,X0001,X1010,X0000,rD, /* _ _ */ rM);
3027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr |= (subopc & 3) << 5;
3028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = instr;
3029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Unary: {
3032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt instr;
3033436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt rDst = iregNo(i->ARMin.Unary.dst);
3034436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt rSrc = iregNo(i->ARMin.Unary.src);
3035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.Unary.op) {
3036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMun_CLZ:
3037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               instr = XXXXXXXX(X1110,X0001,X0110,X1111,
3038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                rDst,X1111,X0001,rSrc);
3039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               *p++ = instr;
3040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto done;
3041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMun_NEG: /* RSB rD,rS,#0 */
3042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               instr = XXXXX___(X1110,0x2,0x6,rSrc,rDst);
3043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               *p++ = instr;
3044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto done;
3045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMun_NOT: {
3046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               UInt subopc = X1111; /* MVN */
3047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               instr = rSrc;
3048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               instr |= XXXXX___(X1110, (1 & (subopc >> 3)),
3049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 (subopc << 1) & 0xF, 0, rDst);
3050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               *p++ = instr;
3051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto done;
3052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
3053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default:
3054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
3055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad;
3057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_CmpOrTst: {
3059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt instr  = skeletal_RI84(i->ARMin.CmpOrTst.argR);
3060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt subopc = i->ARMin.CmpOrTst.isCmp ? X1010 : X1000;
3061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt SBZ    = 0;
3062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr |= XXXXX___(X1110, (1 & (subopc >> 3)),
3063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           ((subopc << 1) & 0xF) | 1,
3064436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                           iregNo(i->ARMin.CmpOrTst.argL), SBZ );
3065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = instr;
3066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Mov: {
3069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt instr  = skeletal_RI84(i->ARMin.Mov.src);
3070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt subopc = X1101; /* MOV */
3071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt SBZ    = 0;
3072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr |= XXXXX___(X1110, (1 & (subopc >> 3)),
3073436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                           (subopc << 1) & 0xF, SBZ,
3074436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                           iregNo(i->ARMin.Mov.dst));
3075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = instr;
3076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Imm32: {
3079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         p = imm32_to_iregNo( (UInt*)p, iregNo(i->ARMin.Imm32.dst),
3080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                        i->ARMin.Imm32.imm32 );
3081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdSt32:
3084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdSt8U: {
3085436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt        bL, bB;
3086436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         HReg        rD;
3087436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ARMAMode1*  am;
3088436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ARMCondCode cc;
3089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->tag == ARMin_LdSt32) {
3090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            bB = 0;
3091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            bL = i->ARMin.LdSt32.isLoad ? 1 : 0;
3092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            am = i->ARMin.LdSt32.amode;
3093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            rD = i->ARMin.LdSt32.rD;
3094436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            cc = i->ARMin.LdSt32.cc;
3095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
3096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            bB = 1;
3097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            bL = i->ARMin.LdSt8U.isLoad ? 1 : 0;
3098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            am = i->ARMin.LdSt8U.amode;
3099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            rD = i->ARMin.LdSt8U.rD;
3100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            cc = i->ARMin.LdSt8U.cc;
3101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(cc != ARMcc_NV);
3103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (am->tag == ARMam1_RI) {
3104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int  simm12;
3105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt instr, bP;
3106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (am->ARMam1.RI.simm13 < 0) {
3107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               bP = 0;
3108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               simm12 = -am->ARMam1.RI.simm13;
3109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } else {
3110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               bP = 1;
3111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               simm12 = am->ARMam1.RI.simm13;
3112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
3113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vassert(simm12 >= 0 && simm12 <= 4095);
3114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            instr = XXXXX___(cc,X0101,BITS4(bP,bB,0,bL),
3115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             iregNo(am->ARMam1.RI.reg),
3116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             iregNo(rD));
3117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            instr |= simm12;
3118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *p++ = instr;
3119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto done;
3120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
3121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // RR case
3122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto bad;
3123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdSt16: {
3126436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         HReg        rD = i->ARMin.LdSt16.rD;
3127436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt        bS = i->ARMin.LdSt16.signedLoad ? 1 : 0;
3128436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt        bL = i->ARMin.LdSt16.isLoad ? 1 : 0;
3129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ARMAMode2*  am = i->ARMin.LdSt16.amode;
3130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ARMCondCode cc = i->ARMin.LdSt16.cc;
3131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(cc != ARMcc_NV);
3132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (am->tag == ARMam2_RI) {
3133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            HReg rN = am->ARMam2.RI.reg;
3134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int  simm8;
3135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt bP, imm8hi, imm8lo, instr;
3136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (am->ARMam2.RI.simm9 < 0) {
3137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               bP = 0;
3138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               simm8 = -am->ARMam2.RI.simm9;
3139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } else {
3140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               bP = 1;
3141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               simm8 = am->ARMam2.RI.simm9;
3142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
3143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vassert(simm8 >= 0 && simm8 <= 255);
3144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            imm8hi = (simm8 >> 4) & 0xF;
3145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            imm8lo = simm8 & 0xF;
3146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vassert(!(bL == 0 && bS == 1)); // "! signed store"
3147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /**/ if (bL == 0 && bS == 0) {
3148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               // strh
3149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               instr = XXXXXXXX(cc,X0001, BITS4(bP,1,0,0), iregNo(rN),
3150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                iregNo(rD), imm8hi, X1011, imm8lo);
3151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               *p++ = instr;
3152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto done;
3153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
3154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            else if (bL == 1 && bS == 0) {
3155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               // ldrh
3156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               instr = XXXXXXXX(cc,X0001, BITS4(bP,1,0,1), iregNo(rN),
3157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                iregNo(rD), imm8hi, X1011, imm8lo);
3158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               *p++ = instr;
3159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto done;
3160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
3161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            else if (bL == 1 && bS == 1) {
3162436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               // ldrsh
3163436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               instr = XXXXXXXX(cc,X0001, BITS4(bP,1,0,1), iregNo(rN),
3164436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                iregNo(rD), imm8hi, X1111, imm8lo);
3165436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               *p++ = instr;
3166436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               goto done;
3167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
3168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            else vassert(0); // ill-constructed insn
3169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
3170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // RR case
3171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto bad;
3172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case ARMin_Ld8S: {
3175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         HReg        rD = i->ARMin.Ld8S.rD;
3176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ARMAMode2*  am = i->ARMin.Ld8S.amode;
3177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         ARMCondCode cc = i->ARMin.Ld8S.cc;
3178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(cc != ARMcc_NV);
3179436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (am->tag == ARMam2_RI) {
3180436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            HReg rN = am->ARMam2.RI.reg;
3181436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            Int  simm8;
3182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            UInt bP, imm8hi, imm8lo, instr;
3183436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (am->ARMam2.RI.simm9 < 0) {
3184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               bP = 0;
3185436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               simm8 = -am->ARMam2.RI.simm9;
3186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } else {
3187436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               bP = 1;
3188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               simm8 = am->ARMam2.RI.simm9;
3189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
3190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            vassert(simm8 >= 0 && simm8 <= 255);
3191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            imm8hi = (simm8 >> 4) & 0xF;
3192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            imm8lo = simm8 & 0xF;
3193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            // ldrsb
3194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            instr = XXXXXXXX(cc,X0001, BITS4(bP,1,0,1), iregNo(rN),
3195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                             iregNo(rD), imm8hi, X1101, imm8lo);
3196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            *p++ = instr;
3197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            goto done;
3198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
3199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            // RR case
3200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            goto bad;
3201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
3202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
3203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_XDirect: {
3205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* NB: what goes on here has to be very closely coordinated
3206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            with the chainXDirect_ARM and unchainXDirect_ARM below. */
3207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* We're generating chain-me requests here, so we need to be
3208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            sure this is actually allowed -- no-redir translations
3209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            can't use chain-me's.  Hence: */
3210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(disp_cp_chain_me_to_slowEP != NULL);
3211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(disp_cp_chain_me_to_fastEP != NULL);
3212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* Use ptmp for backpatching conditional jumps. */
3214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         UInt* ptmp = NULL;
3215663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3216663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* First off, if this is conditional, create a conditional
3217663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            jump over the rest of it.  Or at least, leave a space for
3218663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            it that we will shortly fill in. */
3219663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (i->ARMin.XDirect.cond != ARMcc_AL) {
3220663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(i->ARMin.XDirect.cond != ARMcc_NV);
3221663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            ptmp = p;
3222663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            *p++ = 0;
3223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3225663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* Update the guest R15T. */
3226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* movw r12, lo16(dstGA) */
3227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* movt r12, hi16(dstGA) */
3228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* str r12, amR15T */
3229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         p = imm32_to_iregNo(p, /*r*/12, i->ARMin.XDirect.dstGA);
3230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         p = do_load_or_store32(p, False/*!isLoad*/,
3231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                /*r*/12, i->ARMin.XDirect.amR15T);
3232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* --- FIRST PATCHABLE BYTE follows --- */
3234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* VG_(disp_cp_chain_me_to_{slowEP,fastEP}) (where we're
3235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            calling to) backs up the return address, so as to find the
3236663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            address of the first patchable byte.  So: don't change the
3237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            number of instructions (3) below. */
3238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* movw r12, lo16(VG_(disp_cp_chain_me_to_{slowEP,fastEP})) */
3239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* movt r12, hi16(VG_(disp_cp_chain_me_to_{slowEP,fastEP})) */
3240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* blx  r12  (A1) */
3241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         void* disp_cp_chain_me
3242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                  = i->ARMin.XDirect.toFastEP ? disp_cp_chain_me_to_fastEP
3243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                              : disp_cp_chain_me_to_slowEP;
3244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         p = imm32_to_iregNo_EXACTLY2(p, /*r*/12,
3245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                      (UInt)Ptr_to_ULong(disp_cp_chain_me));
3246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xE12FFF3C;
3247663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* --- END of PATCHABLE BYTES --- */
3248663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3249663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* Fix up the conditional jump, if there was one. */
3250663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (i->ARMin.XDirect.cond != ARMcc_AL) {
3251663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            Int delta = (UChar*)p - (UChar*)ptmp; /* must be signed */
3252663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(delta > 0 && delta < 40);
3253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert((delta & 3) == 0);
3254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            UInt notCond = 1 ^ (UInt)i->ARMin.XDirect.cond;
3255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(notCond <= 13); /* Neither AL nor NV */
3256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            delta = (delta >> 2) - 2;
3257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            *ptmp = XX______(notCond, X1010) | (delta & 0xFFFFFF);
3258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         goto done;
3260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
3261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_XIndir: {
3263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* We're generating transfers that could lead indirectly to a
3264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            chain-me, so we need to be sure this is actually allowed
3265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            -- no-redir translations are not allowed to reach normal
3266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            translations without going through the scheduler.  That
3267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            means no XDirects or XIndirs out from no-redir
3268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            translations.  Hence: */
3269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(disp_cp_xindir != NULL);
3270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* Use ptmp for backpatching conditional jumps. */
3272663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         UInt* ptmp = NULL;
3273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* First off, if this is conditional, create a conditional
3275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            jump over the rest of it.  Or at least, leave a space for
3276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            it that we will shortly fill in. */
3277663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (i->ARMin.XIndir.cond != ARMcc_AL) {
3278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(i->ARMin.XIndir.cond != ARMcc_NV);
3279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            ptmp = p;
3280663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            *p++ = 0;
3281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         }
3282663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3283663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* Update the guest R15T. */
3284663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* str r-dstGA, amR15T */
3285663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         p = do_load_or_store32(p, False/*!isLoad*/,
3286663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                iregNo(i->ARMin.XIndir.dstGA),
3287663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                i->ARMin.XIndir.amR15T);
3288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3289663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* movw r12, lo16(VG_(disp_cp_xindir)) */
3290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* movt r12, hi16(VG_(disp_cp_xindir)) */
3291663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* bx   r12  (A1) */
3292663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         p = imm32_to_iregNo(p, /*r*/12,
3293663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                             (UInt)Ptr_to_ULong(disp_cp_xindir));
3294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xE12FFF1C;
3295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3296663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* Fix up the conditional jump, if there was one. */
3297663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (i->ARMin.XIndir.cond != ARMcc_AL) {
3298663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            Int delta = (UChar*)p - (UChar*)ptmp; /* must be signed */
3299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(delta > 0 && delta < 40);
3300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert((delta & 3) == 0);
3301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            UInt notCond = 1 ^ (UInt)i->ARMin.XIndir.cond;
3302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(notCond <= 13); /* Neither AL nor NV */
3303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            delta = (delta >> 2) - 2;
3304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            *ptmp = XX______(notCond, X1010) | (delta & 0xFFFFFF);
3305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_XAssisted: {
3310663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* Use ptmp for backpatching conditional jumps. */
3311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         UInt* ptmp = NULL;
3312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3313663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* First off, if this is conditional, create a conditional
3314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            jump over the rest of it.  Or at least, leave a space for
3315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            it that we will shortly fill in. */
3316663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (i->ARMin.XAssisted.cond != ARMcc_AL) {
3317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(i->ARMin.XAssisted.cond != ARMcc_NV);
3318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            ptmp = p;
3319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            *p++ = 0;
3320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         }
3321663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3322663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* Update the guest R15T. */
3323663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* str r-dstGA, amR15T */
3324663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         p = do_load_or_store32(p, False/*!isLoad*/,
3325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                iregNo(i->ARMin.XAssisted.dstGA),
3326663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                i->ARMin.XAssisted.amR15T);
3327663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3328663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* movw r8,  $magic_number */
3329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         UInt trcval = 0;
3330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         switch (i->ARMin.XAssisted.jk) {
3331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            case Ijk_ClientReq:   trcval = VEX_TRC_JMP_CLIENTREQ;   break;
3332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            case Ijk_Sys_syscall: trcval = VEX_TRC_JMP_SYS_SYSCALL; break;
3333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            //case Ijk_Sys_int128:  trcval = VEX_TRC_JMP_SYS_INT128;  break;
3334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            case Ijk_Yield:       trcval = VEX_TRC_JMP_YIELD;       break;
3335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            //case Ijk_EmWarn:      trcval = VEX_TRC_JMP_EMWARN;      break;
3336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            //case Ijk_MapFail:     trcval = VEX_TRC_JMP_MAPFAIL;     break;
3337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            case Ijk_NoDecode:    trcval = VEX_TRC_JMP_NODECODE;    break;
3338eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            case Ijk_InvalICache: trcval = VEX_TRC_JMP_INVALICACHE; break;
3339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            case Ijk_NoRedir:     trcval = VEX_TRC_JMP_NOREDIR;     break;
3340663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            //case Ijk_SigTRAP:     trcval = VEX_TRC_JMP_SIGTRAP;     break;
3341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            //case Ijk_SigSEGV:     trcval = VEX_TRC_JMP_SIGSEGV;     break;
3342663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            case Ijk_Boring:      trcval = VEX_TRC_JMP_BORING;      break;
3343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            /* We don't expect to see the following being assisted. */
3344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            //case Ijk_Ret:
3345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            //case Ijk_Call:
3346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            /* fallthrough */
3347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            default:
3348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               ppIRJumpKind(i->ARMin.XAssisted.jk);
3349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               vpanic("emit_ARMInstr.ARMin_XAssisted: unexpected jump kind");
3350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         }
3351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(trcval != 0);
3352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         p = imm32_to_iregNo(p, /*r*/8, trcval);
3353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* movw r12, lo16(VG_(disp_cp_xassisted)) */
3355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* movt r12, hi16(VG_(disp_cp_xassisted)) */
3356663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* bx   r12  (A1) */
3357663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         p = imm32_to_iregNo(p, /*r*/12,
3358663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                             (UInt)Ptr_to_ULong(disp_cp_xassisted));
3359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xE12FFF1C;
3360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* Fix up the conditional jump, if there was one. */
3362663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (i->ARMin.XAssisted.cond != ARMcc_AL) {
3363663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            Int delta = (UChar*)p - (UChar*)ptmp; /* must be signed */
3364663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(delta > 0 && delta < 40);
3365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert((delta & 3) == 0);
3366663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            UInt notCond = 1 ^ (UInt)i->ARMin.XAssisted.cond;
3367663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(notCond <= 13); /* Neither AL nor NV */
3368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            delta = (delta >> 2) - 2;
3369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            *ptmp = XX______(notCond, X1010) | (delta & 0xFFFFFF);
3370663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         }
3371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         goto done;
3372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
3373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_CMov: {
3375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt instr  = skeletal_RI84(i->ARMin.CMov.src);
3376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt subopc = X1101; /* MOV */
3377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt SBZ    = 0;
3378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         instr |= XXXXX___(i->ARMin.CMov.cond, (1 & (subopc >> 3)),
3379436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                           (subopc << 1) & 0xF, SBZ,
3380436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                           iregNo(i->ARMin.CMov.dst));
3381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = instr;
3382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3384436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Call: {
3386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt instr;
3387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Decide on a scratch reg used to hold to the call address.
3388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            This has to be done as per the comments in getRegUsage. */
3389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Int scratchNo;
3390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.Call.nArgRegs) {
3391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 0:  scratchNo = 0;  break;
3392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 1:  scratchNo = 1;  break;
3393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 2:  scratchNo = 2;  break;
3394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 3:  scratchNo = 3;  break;
3395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 4:  scratchNo = 11; break;
3396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default: vassert(0);
3397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3398436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         /* If we don't need to do any fixup actions in the case that
3399436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            the call doesn't happen, just do the simple thing and emit
3400436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            straight-line code.  We hope this is the common case. */
3401436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (i->ARMin.Call.cond == ARMcc_AL/*call always happens*/
3402436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             || i->ARMin.Call.rloc.pri == RLPri_None/*no fixup action*/) {
3403436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            // r"scratchNo" = &target
3404436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            p = imm32_to_iregNo( (UInt*)p,
3405436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                 scratchNo, (UInt)i->ARMin.Call.target );
3406436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            // blx{cond} r"scratchNo"
3407436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            instr = XXX___XX(i->ARMin.Call.cond, X0001, X0010, /*___*/
3408436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                             X0011, scratchNo);
3409436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            instr |= 0xFFF << 8; // stick in the SBOnes
3410436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            *p++ = instr;
3411436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
3412436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            Int delta;
3413436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            /* Complex case.  We have to generate an if-then-else
3414436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               diamond. */
3415436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            // before:
3416436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            //   b{!cond} else:
3417436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            //   r"scratchNo" = &target
3418436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            //   blx{AL} r"scratchNo"
3419436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            // preElse:
3420436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            //   b after:
3421436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            // else:
3422436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            //   mov r0, #0x55555555  // possibly
3423436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            //   mov r1, r0           // possibly
3424436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            // after:
3425436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3426436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            // before:
3427436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            UInt* pBefore = p;
3428436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3429436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            //   b{!cond} else:  // ptmp1 points here
3430436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            *p++ = 0; // filled in later
3431436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3432436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            //   r"scratchNo" = &target
3433436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            p = imm32_to_iregNo( (UInt*)p,
3434436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                                 scratchNo, (UInt)i->ARMin.Call.target );
3435436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3436436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            //   blx{AL} r"scratchNo"
3437436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            instr = XXX___XX(ARMcc_AL, X0001, X0010, /*___*/
3438436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                             X0011, scratchNo);
3439436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            instr |= 0xFFF << 8; // stick in the SBOnes
3440436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            *p++ = instr;
3441436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3442436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            // preElse:
3443436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            UInt* pPreElse = p;
3444436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            //   b after:
3446436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            *p++ = 0; // filled in later
3447436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3448436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            // else:
3449436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            delta = (UChar*)p - (UChar*)pBefore;
3450436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            delta = (delta >> 2) - 2;
3451436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            *pBefore
3452436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               = XX______(1 ^ i->ARMin.Call.cond, X1010) | (delta & 0xFFFFFF);
3453436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3454436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            /* Do the 'else' actions */
3455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            switch (i->ARMin.Call.rloc.pri) {
3456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               case RLPri_Int:
3457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                  p = imm32_to_iregNo_EXACTLY2(p, /*r*/0, 0x55555555);
3458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                  break;
3459436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               case RLPri_2Int:
3460436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                  vassert(0); //ATC
3461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                  p = imm32_to_iregNo_EXACTLY2(p, /*r*/0, 0x55555555);
3462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                  /* mov r1, r0 */
3463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                  *p++ = 0xE1A01000;
3464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                  break;
3465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               case RLPri_None: case RLPri_INVALID: default:
3466436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                  vassert(0);
3467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
3468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3469436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            // after:
3470436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            delta = (UChar*)p - (UChar*)pPreElse;
3471436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            delta = (delta >> 2) - 2;
3472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            *pPreElse = XX______(ARMcc_AL, X1010) | (delta & 0xFFFFFF);
3473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
3474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Mul: {
3479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* E0000392   mul     r0, r2, r3
3480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            E0810392   umull   r0(LO), r1(HI), r2, r3
3481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            E0C10392   smull   r0(LO), r1(HI), r2, r3
3482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
3483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.Mul.op) {
3484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMmul_PLAIN: *p++ = 0xE0000392; goto done;
3485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMmul_ZX:    *p++ = 0xE0810392; goto done;
3486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMmul_SX:    *p++ = 0xE0C10392; goto done;
3487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default: vassert(0);
3488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad;
3490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_LdrEX: {
3492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* E1D42F9F   ldrexb r2, [r4]
3493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            E1F42F9F   ldrexh r2, [r4]
3494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            E1942F9F   ldrex  r2, [r4]
3495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            E1B42F9F   ldrexd r2, r3, [r4]
3496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
3497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.LdrEX.szB) {
3498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            case 1: *p++ = 0xE1D42F9F; goto done;
3499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            case 2: *p++ = 0xE1F42F9F; goto done;
3500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            case 4: *p++ = 0xE1942F9F; goto done;
3501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            case 8: *p++ = 0xE1B42F9F; goto done;
3502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default: break;
3503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad;
3505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_StrEX: {
3507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* E1C40F92   strexb r0, r2, [r4]
3508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            E1E40F92   strexh r0, r2, [r4]
3509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            E1840F92   strex  r0, r2, [r4]
3510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            E1A40F92   strexd r0, r2, r3, [r4]
3511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
3512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.StrEX.szB) {
3513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            case 1: *p++ = 0xE1C40F92; goto done;
3514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            case 2: *p++ = 0xE1E40F92; goto done;
3515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            case 4: *p++ = 0xE1840F92; goto done;
3516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            case 8: *p++ = 0xE1A40F92; goto done;
3517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default: break;
3518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad;
3520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VLdStD: {
3522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dD     = dregNo(i->ARMin.VLdStD.dD);
3523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt rN     = iregNo(i->ARMin.VLdStD.amode->reg);
3524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Int  simm11 = i->ARMin.VLdStD.amode->simm11;
3525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt off8   = simm11 >= 0 ? simm11 : ((UInt)(-simm11));
3526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bU     = simm11 >= 0 ? 1 : 0;
3527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bL     = i->ARMin.VLdStD.isLoad ? 1 : 0;
3528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn;
3529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0 == (off8 & 3));
3530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         off8 >>= 2;
3531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0 == (off8 & 0xFFFFFF00));
3532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         insn = XXXXXX__(0xE,X1101,BITS4(bU,0,0,bL),rN,dD,X1011);
3533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         insn |= off8;
3534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
3535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VLdStS: {
3538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt fD     = fregNo(i->ARMin.VLdStS.fD);
3539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt rN     = iregNo(i->ARMin.VLdStS.amode->reg);
3540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Int  simm11 = i->ARMin.VLdStS.amode->simm11;
3541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt off8   = simm11 >= 0 ? simm11 : ((UInt)(-simm11));
3542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bU     = simm11 >= 0 ? 1 : 0;
3543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bL     = i->ARMin.VLdStS.isLoad ? 1 : 0;
3544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bD     = fD & 1;
3545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn;
3546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0 == (off8 & 3));
3547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         off8 >>= 2;
3548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0 == (off8 & 0xFFFFFF00));
3549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         insn = XXXXXX__(0xE,X1101,BITS4(bU,bD,0,bL),rN, (fD >> 1), X1010);
3550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         insn |= off8;
3551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
3552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VAluD: {
3555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dN = dregNo(i->ARMin.VAluD.argL);
3556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dD = dregNo(i->ARMin.VAluD.dst);
3557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dM = dregNo(i->ARMin.VAluD.argR);
3558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt pqrs = X1111; /* undefined */
3559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.VAluD.op) {
3560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfp_ADD: pqrs = X0110; break;
3561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfp_SUB: pqrs = X0111; break;
3562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfp_MUL: pqrs = X0100; break;
3563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfp_DIV: pqrs = X1000; break;
3564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default: goto bad;
3565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(pqrs != X1111);
3567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bP  = (pqrs >> 3) & 1;
3568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bQ  = (pqrs >> 2) & 1;
3569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bR  = (pqrs >> 1) & 1;
3570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bS  = (pqrs >> 0) & 1;
3571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn = XXXXXXXX(0xE, X1110, BITS4(bP,0,bQ,bR), dN, dD,
3572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              X1011, BITS4(0,bS,0,0), dM);
3573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
3574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VAluS: {
3577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dN = fregNo(i->ARMin.VAluS.argL);
3578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dD = fregNo(i->ARMin.VAluS.dst);
3579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dM = fregNo(i->ARMin.VAluS.argR);
3580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bN = dN & 1;
3581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bD = dD & 1;
3582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bM = dM & 1;
3583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt pqrs = X1111; /* undefined */
3584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.VAluS.op) {
3585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfp_ADD: pqrs = X0110; break;
3586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfp_SUB: pqrs = X0111; break;
3587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfp_MUL: pqrs = X0100; break;
3588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfp_DIV: pqrs = X1000; break;
3589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default: goto bad;
3590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(pqrs != X1111);
3592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bP  = (pqrs >> 3) & 1;
3593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bQ  = (pqrs >> 2) & 1;
3594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bR  = (pqrs >> 1) & 1;
3595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bS  = (pqrs >> 0) & 1;
3596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn = XXXXXXXX(0xE, X1110, BITS4(bP,bD,bQ,bR),
3597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              (dN >> 1), (dD >> 1),
3598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              X1010, BITS4(bN,bS,bM,0), (dM >> 1));
3599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
3600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VUnaryD: {
3603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dD   = dregNo(i->ARMin.VUnaryD.dst);
3604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dM   = dregNo(i->ARMin.VUnaryD.src);
3605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn = 0;
3606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.VUnaryD.op) {
3607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfpu_COPY:
3608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xE, X1110,X1011,X0000,dD,X1011,X0100,dM);
3609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
3610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfpu_ABS:
3611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xE, X1110,X1011,X0000,dD,X1011,X1100,dM);
3612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
3613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfpu_NEG:
3614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xE, X1110,X1011,X0001,dD,X1011,X0100,dM);
3615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
3616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfpu_SQRT:
3617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xE, X1110,X1011,X0001,dD,X1011,X1100,dM);
3618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
3619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default:
3620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto bad;
3621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
3623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VUnaryS: {
3626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt fD   = fregNo(i->ARMin.VUnaryS.dst);
3627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt fM   = fregNo(i->ARMin.VUnaryS.src);
3628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn = 0;
3629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.VUnaryS.op) {
3630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfpu_COPY:
3631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xE, X1110, BITS4(1,(fD & 1),1,1), X0000,
3632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (fD >> 1), X1010, BITS4(0,1,(fM & 1),0),
3633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (fM >> 1));
3634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
3635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfpu_ABS:
3636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xE, X1110, BITS4(1,(fD & 1),1,1), X0000,
3637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (fD >> 1), X1010, BITS4(1,1,(fM & 1),0),
3638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (fM >> 1));
3639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
3640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfpu_NEG:
3641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xE, X1110, BITS4(1,(fD & 1),1,1), X0001,
3642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (fD >> 1), X1010, BITS4(0,1,(fM & 1),0),
3643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (fM >> 1));
3644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
3645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMvfpu_SQRT:
3646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xE, X1110, BITS4(1,(fD & 1),1,1), X0001,
3647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (fD >> 1), X1010, BITS4(1,1,(fM & 1),0),
3648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (fM >> 1));
3649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
3650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default:
3651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto bad;
3652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
3654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCmpD: {
3657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dD   = dregNo(i->ARMin.VCmpD.argL);
3658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dM   = dregNo(i->ARMin.VCmpD.argR);
3659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn = XXXXXXXX(0xE, X1110, X1011, X0100, dD, X1011, X0100, dM);
3660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;       /* FCMPD dD, dM */
3661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = 0xEEF1FA10; /* FMSTAT */
3662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCMovD: {
3665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt cc = (UInt)i->ARMin.VCMovD.cond;
3666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dD = dregNo(i->ARMin.VCMovD.dst);
3667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dM = dregNo(i->ARMin.VCMovD.src);
3668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(cc < 16 && cc != ARMcc_AL);
3669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn = XXXXXXXX(cc, X1110,X1011,X0000,dD,X1011,X0100,dM);
3670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
3671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCMovS: {
3674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt cc = (UInt)i->ARMin.VCMovS.cond;
3675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt fD = fregNo(i->ARMin.VCMovS.dst);
3676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt fM = fregNo(i->ARMin.VCMovS.src);
3677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(cc < 16 && cc != ARMcc_AL);
3678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn = XXXXXXXX(cc, X1110, BITS4(1,(fD & 1),1,1),
3679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              X0000,(fD >> 1),X1010,
3680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              BITS4(0,1,(fM & 1),0), (fM >> 1));
3681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
3682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCvtSD: {
3685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.VCvtSD.sToD) {
3686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt dD = dregNo(i->ARMin.VCvtSD.dst);
3687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt fM = fregNo(i->ARMin.VCvtSD.src);
3688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt insn = XXXXXXXX(0xE, X1110, X1011, X0111, dD, X1010,
3689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 BITS4(1,1, (fM & 1), 0),
3690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 (fM >> 1));
3691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *p++ = insn;
3692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto done;
3693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
3694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt fD = fregNo(i->ARMin.VCvtSD.dst);
3695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt dM = dregNo(i->ARMin.VCvtSD.src);
3696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt insn = XXXXXXXX(0xE, X1110, BITS4(1,(fD & 1),1,1),
3697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 X0111, (fD >> 1),
3698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 X1011, X1100, dM);
3699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *p++ = insn;
3700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto done;
3701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VXferD: {
3704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dD  = dregNo(i->ARMin.VXferD.dD);
3705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt rHi = iregNo(i->ARMin.VXferD.rHi);
3706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt rLo = iregNo(i->ARMin.VXferD.rLo);
3707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* vmov dD, rLo, rHi is
3708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            E C 4 rHi rLo B (0,0,dD[4],1) dD[3:0]
3709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vmov rLo, rHi, dD is
3710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            E C 5 rHi rLo B (0,0,dD[4],1) dD[3:0]
3711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
3712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn
3713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = XXXXXXXX(0xE, 0xC, i->ARMin.VXferD.toD ? 4 : 5,
3714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       rHi, rLo, 0xB,
3715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       BITS4(0,0, ((dD >> 4) & 1), 1), (dD & 0xF));
3716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
3717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VXferS: {
3720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt fD  = fregNo(i->ARMin.VXferS.fD);
3721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt rLo = iregNo(i->ARMin.VXferS.rLo);
3722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* vmov fD, rLo is
3723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            E E 0 fD[4:1] rLo A (fD[0],0,0,1) 0
3724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vmov rLo, fD is
3725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            E E 1 fD[4:1] rLo A (fD[0],0,0,1) 0
3726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
3727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn
3728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = XXXXXXXX(0xE, 0xE, i->ARMin.VXferS.toS ? 0 : 1,
3729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       (fD >> 1) & 0xF, rLo, 0xA,
3730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       BITS4((fD & 1),0,0,1), 0);
3731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
3732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_VCvtID: {
3735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Bool iToD = i->ARMin.VCvtID.iToD;
3736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Bool syned = i->ARMin.VCvtID.syned;
3737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (iToD && syned) {
3738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // FSITOD: I32S-in-freg to F64-in-dreg
3739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt regF = fregNo(i->ARMin.VCvtID.src);
3740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt regD = dregNo(i->ARMin.VCvtID.dst);
3741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt insn = XXXXXXXX(0xE, X1110, X1011, X1000, regD,
3742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 X1011, BITS4(1,1,(regF & 1),0),
3743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 (regF >> 1) & 0xF);
3744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *p++ = insn;
3745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto done;
3746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (iToD && (!syned)) {
3748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // FUITOD: I32U-in-freg to F64-in-dreg
3749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt regF = fregNo(i->ARMin.VCvtID.src);
3750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt regD = dregNo(i->ARMin.VCvtID.dst);
3751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt insn = XXXXXXXX(0xE, X1110, X1011, X1000, regD,
3752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 X1011, BITS4(0,1,(regF & 1),0),
3753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 (regF >> 1) & 0xF);
3754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *p++ = insn;
3755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto done;
3756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if ((!iToD) && syned) {
3758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // FTOSID: F64-in-dreg to I32S-in-freg
3759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt regD = dregNo(i->ARMin.VCvtID.src);
3760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt regF = fregNo(i->ARMin.VCvtID.dst);
3761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt insn = XXXXXXXX(0xE, X1110, BITS4(1,(regF & 1),1,1),
3762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 X1101, (regF >> 1) & 0xF,
3763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 X1011, X0100, regD);
3764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *p++ = insn;
3765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto done;
3766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if ((!iToD) && (!syned)) {
3768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // FTOUID: F64-in-dreg to I32U-in-freg
3769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt regD = dregNo(i->ARMin.VCvtID.src);
3770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt regF = fregNo(i->ARMin.VCvtID.dst);
3771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UInt insn = XXXXXXXX(0xE, X1110, BITS4(1,(regF & 1),1,1),
3772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 X1100, (regF >> 1) & 0xF,
3773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 X1011, X0100, regD);
3774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *p++ = insn;
3775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto done;
3776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /*UNREACHED*/
3778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(0);
3779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_FPSCR: {
3781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Bool toFPSCR = i->ARMin.FPSCR.toFPSCR;
3782436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt iReg    = iregNo(i->ARMin.FPSCR.iReg);
3783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (toFPSCR) {
3784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* fmxr fpscr, iReg is EEE1 iReg A10 */
3785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            *p++ = 0xEEE10A10 | ((iReg & 0xF) << 12);
3786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto done;
3787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad; // FPSCR -> iReg case currently ATC
3789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_MFence: {
3791663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         // It's not clear (to me) how these relate to the ARMv7
3792663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         // versions, so let's just use the v7 versions as they
3793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         // are at least well documented.
3794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         //*p++ = 0xEE070F9A; /* mcr 15,0,r0,c7,c10,4 (DSB) */
3795663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         //*p++ = 0xEE070FBA; /* mcr 15,0,r0,c7,c10,5 (DMB) */
3796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         //*p++ = 0xEE070F95; /* mcr 15,0,r0,c7,c5,4  (ISB) */
3797663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xF57FF04F; /* DSB sy */
3798663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xF57FF05F; /* DMB sy */
3799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xF57FF06F; /* ISB */
3800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3802b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      case ARMin_CLREX: {
3803b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *p++ = 0xF57FF01F; /* clrex */
3804b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         goto done;
3805b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
3806b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NLdStQ: {
3808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regD = qregNo(i->ARMin.NLdStQ.dQ) << 1;
3809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regN, regM;
3810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt D = regD >> 4;
3811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bL = i->ARMin.NLdStQ.isLoad ? 1 : 0;
3812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn;
3813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(hregClass(i->ARMin.NLdStQ.dQ) == HRcVec128);
3814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regD &= 0xF;
3815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NLdStQ.amode->tag == ARMamN_RR) {
3816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            regN = iregNo(i->ARMin.NLdStQ.amode->ARMamN.RR.rN);
3817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            regM = iregNo(i->ARMin.NLdStQ.amode->ARMamN.RR.rM);
3818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
3819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            regN = iregNo(i->ARMin.NLdStQ.amode->ARMamN.R.rN);
3820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            regM = 15;
3821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         insn = XXXXXXXX(0xF, X0100, BITS4(0, D, bL, 0),
3823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              regN, regD, X1010, X1000, regM);
3824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
3825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NLdStD: {
3828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regD = dregNo(i->ARMin.NLdStD.dD);
3829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regN, regM;
3830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt D = regD >> 4;
3831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt bL = i->ARMin.NLdStD.isLoad ? 1 : 0;
3832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn;
3833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(hregClass(i->ARMin.NLdStD.dD) == HRcFlt64);
3834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regD &= 0xF;
3835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NLdStD.amode->tag == ARMamN_RR) {
3836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            regN = iregNo(i->ARMin.NLdStD.amode->ARMamN.RR.rN);
3837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            regM = iregNo(i->ARMin.NLdStD.amode->ARMamN.RR.rM);
3838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
3839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            regN = iregNo(i->ARMin.NLdStD.amode->ARMamN.R.rN);
3840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            regM = 15;
3841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         insn = XXXXXXXX(0xF, X0100, BITS4(0, D, bL, 0),
3843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              regN, regD, X0111, X1000, regM);
3844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
3845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
3846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NUnaryS: {
3848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt Q = i->ARMin.NUnaryS.Q ? 1 : 0;
3849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regD, D;
3850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regM, M;
3851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt size = i->ARMin.NUnaryS.size;
3852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn;
3853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt opc, opc1, opc2;
3854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.NUnaryS.op) {
3855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    case ARMneon_VDUP:
3856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (i->ARMin.NUnaryS.size >= 16)
3857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  goto bad;
3858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (i->ARMin.NUnaryS.dst->tag != ARMNRS_Reg)
3859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  goto bad;
3860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (i->ARMin.NUnaryS.src->tag != ARMNRS_Scalar)
3861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  goto bad;
3862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regD = (hregClass(i->ARMin.NUnaryS.dst->reg) == HRcVec128)
3863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        ? (qregNo(i->ARMin.NUnaryS.dst->reg) << 1)
3864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        : dregNo(i->ARMin.NUnaryS.dst->reg);
3865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regM = (hregClass(i->ARMin.NUnaryS.src->reg) == HRcVec128)
3866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        ? (qregNo(i->ARMin.NUnaryS.src->reg) << 1)
3867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        : dregNo(i->ARMin.NUnaryS.src->reg);
3868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               D = regD >> 4;
3869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               M = regM >> 4;
3870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regD &= 0xf;
3871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regM &= 0xf;
3872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1),
3873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (i->ARMin.NUnaryS.size & 0xf), regD,
3874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1100, BITS4(0,Q,M,0), regM);
3875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               *p++ = insn;
3876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto done;
3877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_SETELEM:
3878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regD = Q ? (qregNo(i->ARMin.NUnaryS.dst->reg) << 1) :
3879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                dregNo(i->ARMin.NUnaryS.dst->reg);
3880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regM = iregNo(i->ARMin.NUnaryS.src->reg);
3881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               M = regM >> 4;
3882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               D = regD >> 4;
3883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regM &= 0xF;
3884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regD &= 0xF;
3885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (i->ARMin.NUnaryS.dst->tag != ARMNRS_Scalar)
3886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  goto bad;
3887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               switch (size) {
3888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  case 0:
3889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (i->ARMin.NUnaryS.dst->index > 7)
3890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        goto bad;
3891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     opc = X1000 | i->ARMin.NUnaryS.dst->index;
3892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     break;
3893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  case 1:
3894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (i->ARMin.NUnaryS.dst->index > 3)
3895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        goto bad;
3896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     opc = X0001 | (i->ARMin.NUnaryS.dst->index << 1);
3897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     break;
3898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  case 2:
3899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (i->ARMin.NUnaryS.dst->index > 1)
3900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        goto bad;
3901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     opc = X0000 | (i->ARMin.NUnaryS.dst->index << 2);
3902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     break;
3903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  default:
3904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     goto bad;
3905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               }
3906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               opc1 = (opc >> 2) & 3;
3907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               opc2 = opc & 3;
3908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xE, X1110, BITS4(0,(opc1 >> 1),(opc1 & 1),0),
3909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, regM, X1011,
3910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(D,(opc2 >> 1),(opc2 & 1),1), X0000);
3911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               *p++ = insn;
3912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto done;
3913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_GETELEMU:
3914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regM = Q ? (qregNo(i->ARMin.NUnaryS.src->reg) << 1) :
3915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                dregNo(i->ARMin.NUnaryS.src->reg);
3916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regD = iregNo(i->ARMin.NUnaryS.dst->reg);
3917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               M = regM >> 4;
3918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               D = regD >> 4;
3919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regM &= 0xF;
3920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regD &= 0xF;
3921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (i->ARMin.NUnaryS.src->tag != ARMNRS_Scalar)
3922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  goto bad;
3923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               switch (size) {
3924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  case 0:
3925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (Q && i->ARMin.NUnaryS.src->index > 7) {
3926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        regM++;
3927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        i->ARMin.NUnaryS.src->index -= 8;
3928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     }
3929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (i->ARMin.NUnaryS.src->index > 7)
3930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        goto bad;
3931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     opc = X1000 | i->ARMin.NUnaryS.src->index;
3932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     break;
3933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  case 1:
3934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (Q && i->ARMin.NUnaryS.src->index > 3) {
3935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        regM++;
3936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        i->ARMin.NUnaryS.src->index -= 4;
3937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     }
3938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (i->ARMin.NUnaryS.src->index > 3)
3939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        goto bad;
3940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     opc = X0001 | (i->ARMin.NUnaryS.src->index << 1);
3941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     break;
3942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  case 2:
3943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     goto bad;
3944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  default:
3945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     goto bad;
3946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               }
3947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               opc1 = (opc >> 2) & 3;
3948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               opc2 = opc & 3;
3949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xE, X1110, BITS4(1,(opc1 >> 1),(opc1 & 1),1),
3950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regM, regD, X1011,
3951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(M,(opc2 >> 1),(opc2 & 1),1), X0000);
3952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               *p++ = insn;
3953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto done;
3954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_GETELEMS:
3955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regM = Q ? (qregNo(i->ARMin.NUnaryS.src->reg) << 1) :
3956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                dregNo(i->ARMin.NUnaryS.src->reg);
3957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regD = iregNo(i->ARMin.NUnaryS.dst->reg);
3958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               M = regM >> 4;
3959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               D = regD >> 4;
3960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regM &= 0xF;
3961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               regD &= 0xF;
3962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (i->ARMin.NUnaryS.src->tag != ARMNRS_Scalar)
3963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  goto bad;
3964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               switch (size) {
3965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  case 0:
3966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (Q && i->ARMin.NUnaryS.src->index > 7) {
3967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        regM++;
3968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        i->ARMin.NUnaryS.src->index -= 8;
3969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     }
3970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (i->ARMin.NUnaryS.src->index > 7)
3971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        goto bad;
3972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     opc = X1000 | i->ARMin.NUnaryS.src->index;
3973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     break;
3974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  case 1:
3975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (Q && i->ARMin.NUnaryS.src->index > 3) {
3976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        regM++;
3977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        i->ARMin.NUnaryS.src->index -= 4;
3978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     }
3979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (i->ARMin.NUnaryS.src->index > 3)
3980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        goto bad;
3981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     opc = X0001 | (i->ARMin.NUnaryS.src->index << 1);
3982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     break;
3983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  case 2:
3984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (Q && i->ARMin.NUnaryS.src->index > 1) {
3985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        regM++;
3986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        i->ARMin.NUnaryS.src->index -= 2;
3987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     }
3988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     if (i->ARMin.NUnaryS.src->index > 1)
3989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        goto bad;
3990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     opc = X0000 | (i->ARMin.NUnaryS.src->index << 2);
3991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     break;
3992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  default:
3993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     goto bad;
3994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               }
3995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               opc1 = (opc >> 2) & 3;
3996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               opc2 = opc & 3;
3997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xE, X1110, BITS4(0,(opc1 >> 1),(opc1 & 1),1),
3998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regM, regD, X1011,
3999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(M,(opc2 >> 1),(opc2 & 1),1), X0000);
4000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               *p++ = insn;
4001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto done;
4002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default:
4003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto bad;
4004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
4005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NUnary: {
4007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt Q = i->ARMin.NUnary.Q ? 1 : 0;
4008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regD = (hregClass(i->ARMin.NUnary.dst) == HRcVec128)
4009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ? (qregNo(i->ARMin.NUnary.dst) << 1)
4010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       : dregNo(i->ARMin.NUnary.dst);
4011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regM, M;
4012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt D = regD >> 4;
4013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt sz1 = i->ARMin.NUnary.size >> 1;
4014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt sz2 = i->ARMin.NUnary.size & 1;
4015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt sz = i->ARMin.NUnary.size;
4016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn;
4017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt F = 0; /* TODO: floating point EQZ ??? */
4018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->ARMin.NUnary.op != ARMneon_DUP) {
4019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            regM = (hregClass(i->ARMin.NUnary.src) == HRcVec128)
4020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     ? (qregNo(i->ARMin.NUnary.src) << 1)
4021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     : dregNo(i->ARMin.NUnary.src);
4022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            M = regM >> 4;
4023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
4024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            regM = iregNo(i->ARMin.NUnary.src);
4025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            M = regM >> 4;
4026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
4027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regD &= 0xF;
4028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regM &= 0xF;
4029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.NUnary.op) {
4030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_COPY: /* VMOV reg, reg */
4031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,1,0), regM, regD, X0001,
4032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(M,Q,M,1), regM);
4033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_COPYN: /* VMOVN regD, regQ */
4035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,1,0),
4036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X0010, BITS4(0,0,M,0), regM);
4037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_COPYQNSS: /* VQMOVN regD, regQ */
4039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,1,0),
4040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X0010, BITS4(1,0,M,0), regM);
4041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_COPYQNUS: /* VQMOVUN regD, regQ */
4043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,1,0),
4044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X0010, BITS4(0,1,M,0), regM);
4045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_COPYQNUU: /* VQMOVN regD, regQ */
4047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,1,0),
4048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X0010, BITS4(1,1,M,0), regM);
4049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_COPYLS: /* VMOVL regQ, regD */
4051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (sz >= 3)
4052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  goto bad;
4053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010,
4054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(1,D,(sz == 2) ? 1 : 0,(sz == 1) ? 1 : 0),
4055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4((sz == 0) ? 1 : 0,0,0,0),
4056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X1010, BITS4(0,0,M,1), regM);
4057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_COPYLU: /* VMOVL regQ, regD */
4059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (sz >= 3)
4060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  goto bad;
4061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011,
4062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(1,D,(sz == 2) ? 1 : 0,(sz == 1) ? 1 : 0),
4063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4((sz == 0) ? 1 : 0,0,0,0),
4064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X1010, BITS4(0,0,M,1), regM);
4065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_NOT: /* VMVN reg, reg*/
4067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X0000, regD, X0101,
4068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(1,Q,M,0), regM);
4069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_EQZ:
4071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,0,1),
4072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, BITS4(0,F,0,1), BITS4(0,Q,M,0), regM);
4073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_CNT:
4075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X0000, regD, X0101,
4076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(0,Q,M,0), regM);
4077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_CLZ:
4079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,0,0),
4080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X0100, BITS4(1,Q,M,0), regM);
4081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_CLS:
4083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,0,0),
4084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X0100, BITS4(0,Q,M,0), regM);
4085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_ABS:
4087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,0,1),
4088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X0011, BITS4(0,Q,M,0), regM);
4089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_DUP:
4091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz1 = i->ARMin.NUnary.size == 0 ? 1 : 0;
4092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz2 = i->ARMin.NUnary.size == 1 ? 1 : 0;
4093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               vassert(sz1 + sz2 < 2);
4094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xE, X1110, BITS4(1, sz1, Q, 0), regD, regM,
4095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1011, BITS4(D,0,sz2,1), X0000);
4096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_REV16:
4098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,0,0),
4099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, BITS4(0,0,0,1), BITS4(0,Q,M,0), regM);
4100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_REV32:
4102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,0,0),
4103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, BITS4(0,0,0,0), BITS4(1,Q,M,0), regM);
4104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_REV64:
4106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,0,0),
4107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, BITS4(0,0,0,0), BITS4(0,Q,M,0), regM);
4108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_PADDLU:
4110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,0,0),
4111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X0010, BITS4(1,Q,M,0), regM);
4112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_PADDLS:
4114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,0,0),
4115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X0010, BITS4(0,Q,M,0), regM);
4116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VQSHLNUU:
4118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011,
4119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (1 << 3) | (D << 2) | ((sz >> 4) & 3),
4120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               sz & 0xf, regD, X0111,
4121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(sz >> 6,Q,M,1), regM);
4122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VQSHLNSS:
4124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010,
4125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (1 << 3) | (D << 2) | ((sz >> 4) & 3),
4126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               sz & 0xf, regD, X0111,
4127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(sz >> 6,Q,M,1), regM);
4128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VQSHLNUS:
4130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011,
4131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (1 << 3) | (D << 2) | ((sz >> 4) & 3),
4132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               sz & 0xf, regD, X0110,
4133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(sz >> 6,Q,M,1), regM);
4134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCVTFtoS:
4136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X1011, regD, X0111,
4137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(0,Q,M,0), regM);
4138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCVTFtoU:
4140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X1011, regD, X0111,
4141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(1,Q,M,0), regM);
4142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCVTStoF:
4144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X1011, regD, X0110,
4145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(0,Q,M,0), regM);
4146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCVTUtoF:
4148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X1011, regD, X0110,
4149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(1,Q,M,0), regM);
4150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCVTFtoFixedU:
4152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz1 = (sz >> 5) & 1;
4153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz2 = (sz >> 4) & 1;
4154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz &= 0xf;
4155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011,
4156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(1,D,sz1,sz2), sz, regD, X1111,
4157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(0,Q,M,1), regM);
4158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCVTFtoFixedS:
4160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz1 = (sz >> 5) & 1;
4161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz2 = (sz >> 4) & 1;
4162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz &= 0xf;
4163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010,
4164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(1,D,sz1,sz2), sz, regD, X1111,
4165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(0,Q,M,1), regM);
4166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCVTFixedUtoF:
4168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz1 = (sz >> 5) & 1;
4169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz2 = (sz >> 4) & 1;
4170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz &= 0xf;
4171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011,
4172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(1,D,sz1,sz2), sz, regD, X1110,
4173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(0,Q,M,1), regM);
4174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCVTFixedStoF:
4176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz1 = (sz >> 5) & 1;
4177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz2 = (sz >> 4) & 1;
4178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sz &= 0xf;
4179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010,
4180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(1,D,sz1,sz2), sz, regD, X1110,
4181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(0,Q,M,1), regM);
4182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCVTF32toF16:
4184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X0110, regD, X0110,
4185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(0,0,M,0), regM);
4186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCVTF16toF32:
4188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X0110, regD, X0111,
4189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(0,0,M,0), regM);
4190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VRECIP:
4192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X1011, regD, X0100,
4193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(0,Q,M,0), regM);
4194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VRECIPF:
4196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X1011, regD, X0101,
4197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(0,Q,M,0), regM);
4198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VABSFP:
4200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X1001, regD, X0111,
4201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(0,Q,M,0), regM);
4202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VRSQRTEFP:
4204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X1011, regD, X0101,
4205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(1,Q,M,0), regM);
4206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VRSQRTE:
4208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X1011, regD, X0100,
4209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(1,Q,M,0), regM);
4210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VNEGF:
4212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), X1001, regD, X0111,
4213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(1,Q,M,0), regM);
4214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default:
4217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto bad;
4218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
4219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
4220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
4221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NDual: {
4223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt Q = i->ARMin.NDual.Q ? 1 : 0;
4224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regD = (hregClass(i->ARMin.NDual.arg1) == HRcVec128)
4225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ? (qregNo(i->ARMin.NDual.arg1) << 1)
4226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       : dregNo(i->ARMin.NDual.arg1);
4227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regM = (hregClass(i->ARMin.NDual.arg2) == HRcVec128)
4228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ? (qregNo(i->ARMin.NDual.arg2) << 1)
4229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       : dregNo(i->ARMin.NDual.arg2);
4230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt D = regD >> 4;
4231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt M = regM >> 4;
4232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt sz1 = i->ARMin.NDual.size >> 1;
4233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt sz2 = i->ARMin.NDual.size & 1;
4234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn;
4235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regD &= 0xF;
4236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regM &= 0xF;
4237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.NDual.op) {
4238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_TRN: /* VTRN reg, reg */
4239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,1,0),
4240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X0000, BITS4(1,Q,M,0), regM);
4241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_ZIP: /* VZIP reg, reg */
4243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,1,0),
4244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X0001, BITS4(1,Q,M,0), regM);
4245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_UZP: /* VUZP reg, reg */
4247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), BITS4(sz1,sz2,1,0),
4248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regD, X0001, BITS4(0,Q,M,0), regM);
4249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default:
4251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto bad;
4252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
4253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
4254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
4255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NBinary: {
4257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt Q = i->ARMin.NBinary.Q ? 1 : 0;
4258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regD = (hregClass(i->ARMin.NBinary.dst) == HRcVec128)
4259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ? (qregNo(i->ARMin.NBinary.dst) << 1)
4260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       : dregNo(i->ARMin.NBinary.dst);
4261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regN = (hregClass(i->ARMin.NBinary.argL) == HRcVec128)
4262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ? (qregNo(i->ARMin.NBinary.argL) << 1)
4263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       : dregNo(i->ARMin.NBinary.argL);
4264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regM = (hregClass(i->ARMin.NBinary.argR) == HRcVec128)
4265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ? (qregNo(i->ARMin.NBinary.argR) << 1)
4266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       : dregNo(i->ARMin.NBinary.argR);
4267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt sz1 = i->ARMin.NBinary.size >> 1;
4268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt sz2 = i->ARMin.NBinary.size & 1;
4269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt D = regD >> 4;
4270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt N = regN >> 4;
4271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt M = regM >> 4;
4272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn;
4273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regD &= 0xF;
4274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regM &= 0xF;
4275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regN &= 0xF;
4276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.NBinary.op) {
4277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VAND: /* VAND reg, reg, reg */
4278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,0,0), regN, regD, X0001,
4279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(N,Q,M,1), regM);
4280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VORR: /* VORR reg, reg, reg*/
4282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,1,0), regN, regD, X0001,
4283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(N,Q,M,1), regM);
4284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VXOR: /* VEOR reg, reg, reg */
4286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,0,0), regN, regD, X0001,
4287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(N,Q,M,1), regM);
4288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VADD: /* VADD reg, reg, reg */
4290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1000, BITS4(N,Q,M,0), regM);
4292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VSUB: /* VSUB reg, reg, reg */
4294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1000, BITS4(N,Q,M,0), regM);
4296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VMINU: /* VMIN.Uxx reg, reg, reg */
4298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0110, BITS4(N,Q,M,1), regM);
4300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VMINS: /* VMIN.Sxx reg, reg, reg */
4302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0110, BITS4(N,Q,M,1), regM);
4304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VMAXU: /* VMAX.Uxx reg, reg, reg */
4306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0110, BITS4(N,Q,M,0), regM);
4308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VMAXS: /* VMAX.Sxx reg, reg, reg */
4310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0110, BITS4(N,Q,M,0), regM);
4312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VRHADDS: /* VRHADD.Sxx reg, reg, reg */
4314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0001, BITS4(N,Q,M,0), regM);
4316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VRHADDU: /* VRHADD.Uxx reg, reg, reg */
4318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0001, BITS4(N,Q,M,0), regM);
4320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VQADDU: /* VQADD unsigned reg, reg, reg */
4322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0000, BITS4(N,Q,M,1), regM);
4324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VQADDS: /* VQADD signed reg, reg, reg */
4326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0000, BITS4(N,Q,M,1), regM);
4328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VQSUBU: /* VQSUB unsigned reg, reg, reg */
4330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0010, BITS4(N,Q,M,1), regM);
4332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VQSUBS: /* VQSUB signed reg, reg, reg */
4334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0010, BITS4(N,Q,M,1), regM);
4336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCGTU: /* VCGT unsigned reg, reg, reg */
4338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0011, BITS4(N,Q,M,0), regM);
4340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCGTS: /* VCGT signed reg, reg, reg */
4342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0011, BITS4(N,Q,M,0), regM);
4344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCGEU: /* VCGE unsigned reg, reg, reg */
4346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0011, BITS4(N,Q,M,1), regM);
4348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCGES: /* VCGE signed reg, reg, reg */
4350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0011, BITS4(N,Q,M,1), regM);
4352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCEQ: /* VCEQ reg, reg, reg */
4354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1000, BITS4(N,Q,M,1), regM);
4356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VEXT: /* VEXT.8 reg, reg, #imm4*/
4358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (i->ARMin.NBinary.size >= 16)
4359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  goto bad;
4360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(1,D,1,1), regN, regD,
4361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               i->ARMin.NBinary.size & 0xf, BITS4(N,Q,M,0),
4362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               regM);
4363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VMUL:
4365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1001, BITS4(N,Q,M,1), regM);
4367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VMULLU:
4369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,sz1,sz2), regN, regD,
4370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1100, BITS4(N,0,M,0), regM);
4371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VMULLS:
4373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(1,D,sz1,sz2), regN, regD,
4374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1100, BITS4(N,0,M,0), regM);
4375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VMULP:
4377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1001, BITS4(N,Q,M,1), regM);
4379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VMULFP:
4381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,0,0), regN, regD,
4382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1101, BITS4(N,Q,M,1), regM);
4383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VMULLP:
4385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(1,D,sz1,sz2), regN, regD,
4386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1110, BITS4(N,0,M,0), regM);
4387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VQDMULH:
4389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1011, BITS4(N,Q,M,0), regM);
4391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VQRDMULH:
4393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1011, BITS4(N,Q,M,0), regM);
4395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VQDMULL:
4397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(1,D,sz1,sz2), regN, regD,
4398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1101, BITS4(N,0,M,0), regM);
4399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VTBL:
4401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(1,D,1,1), regN, regD,
4402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1000, BITS4(N,0,M,0), regM);
4403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VPADD:
4405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1011, BITS4(N,Q,M,1), regM);
4407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VPADDFP:
4409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,0,0), regN, regD,
4410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1101, BITS4(N,Q,M,0), regM);
4411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VPMINU:
4413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1010, BITS4(N,Q,M,1), regM);
4415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VPMINS:
4417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1010, BITS4(N,Q,M,1), regM);
4419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VPMAXU:
4421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1010, BITS4(N,Q,M,0), regM);
4423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VPMAXS:
4425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1010, BITS4(N,Q,M,0), regM);
4427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VADDFP: /* VADD reg, reg, reg */
4429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,0,0), regN, regD,
4430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1101, BITS4(N,Q,M,0), regM);
4431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VSUBFP: /* VADD reg, reg, reg */
4433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,1,0), regN, regD,
4434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1101, BITS4(N,Q,M,0), regM);
4435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VABDFP: /* VABD reg, reg, reg */
4437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,1,0), regN, regD,
4438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1101, BITS4(N,Q,M,0), regM);
4439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VMINF:
4441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,1,0), regN, regD,
4442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1111, BITS4(N,Q,M,0), regM);
4443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VMAXF:
4445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,0,0), regN, regD,
4446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1111, BITS4(N,Q,M,0), regM);
4447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VPMINF:
4449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,1,0), regN, regD,
4450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1111, BITS4(N,Q,M,0), regM);
4451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VPMAXF:
4453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,0,0), regN, regD,
4454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X1111, BITS4(N,Q,M,0), regM);
4455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VRECPS:
4457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,0,0), regN, regD, X1111,
4458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(N,Q,M,1), regM);
4459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCGTF:
4461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,1,0), regN, regD, X1110,
4462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(N,Q,M,0), regM);
4463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCGEF:
4465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,0,0), regN, regD, X1110,
4466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(N,Q,M,0), regM);
4467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VCEQF:
4469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,0,0), regN, regD, X1110,
4470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(N,Q,M,0), regM);
4471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VRSQRTS:
4473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,1,0), regN, regD, X1111,
4474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               BITS4(N,Q,M,1), regM);
4475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default:
4477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto bad;
4478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
4479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
4480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
4481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NShift: {
4483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt Q = i->ARMin.NShift.Q ? 1 : 0;
4484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regD = (hregClass(i->ARMin.NShift.dst) == HRcVec128)
4485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ? (qregNo(i->ARMin.NShift.dst) << 1)
4486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       : dregNo(i->ARMin.NShift.dst);
4487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regM = (hregClass(i->ARMin.NShift.argL) == HRcVec128)
4488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ? (qregNo(i->ARMin.NShift.argL) << 1)
4489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       : dregNo(i->ARMin.NShift.argL);
4490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regN = (hregClass(i->ARMin.NShift.argR) == HRcVec128)
4491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ? (qregNo(i->ARMin.NShift.argR) << 1)
4492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       : dregNo(i->ARMin.NShift.argR);
4493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt sz1 = i->ARMin.NShift.size >> 1;
4494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt sz2 = i->ARMin.NShift.size & 1;
4495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt D = regD >> 4;
4496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt N = regN >> 4;
4497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt M = regM >> 4;
4498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn;
4499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regD &= 0xF;
4500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regM &= 0xF;
4501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regN &= 0xF;
4502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (i->ARMin.NShift.op) {
4503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VSHL:
4504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0100, BITS4(N,Q,M,0), regM);
4506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VSAL:
4508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0100, BITS4(N,Q,M,0), regM);
4510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VQSHL:
4512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0011, BITS4(0,D,sz1,sz2), regN, regD,
4513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0100, BITS4(N,Q,M,1), regM);
4514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case ARMneon_VQSAL:
4516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               insn = XXXXXXXX(0xF, X0010, BITS4(0,D,sz1,sz2), regN, regD,
4517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               X0100, BITS4(N,Q,M,1), regM);
4518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default:
4520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto bad;
4521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
4522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
4523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
4524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4525436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case ARMin_NShl64: {
4526436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         HReg regDreg = i->ARMin.NShl64.dst;
4527436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         HReg regMreg = i->ARMin.NShl64.src;
4528436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt amt     = i->ARMin.NShl64.amt;
4529436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(amt >= 1 && amt <= 63);
4530436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(hregClass(regDreg) == HRcFlt64);
4531436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         vassert(hregClass(regMreg) == HRcFlt64);
4532436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt regD = dregNo(regDreg);
4533436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt regM = dregNo(regMreg);
4534436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt D    = (regD >> 4) & 1;
4535436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt Vd   = regD & 0xF;
4536436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt L    = 1;
4537436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt Q    = 0; /* always 64-bit */
4538436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt M    = (regM >> 4) & 1;
4539436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt Vm   = regM & 0xF;
4540436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         UInt insn = XXXXXXXX(X1111,X0010, BITS4(1,D,(amt>>5)&1,(amt>>4)&1),
4541436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                              amt & 0xF, Vd, X0101, BITS4(L,Q,M,1), Vm);
4542436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         *p++ = insn;
4543436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         goto done;
4544436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
4545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NeonImm: {
4546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt Q = (hregClass(i->ARMin.NeonImm.dst) == HRcVec128) ? 1 : 0;
4547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regD = Q ? (qregNo(i->ARMin.NeonImm.dst) << 1) :
4548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          dregNo(i->ARMin.NeonImm.dst);
4549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt D = regD >> 4;
4550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt imm = i->ARMin.NeonImm.imm->imm8;
4551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt tp = i->ARMin.NeonImm.imm->type;
4552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt j = imm >> 7;
4553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt imm3 = (imm >> 4) & 0x7;
4554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt imm4 = imm & 0xF;
4555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt cmode, op;
4556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn;
4557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         regD &= 0xF;
4558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (tp == 9)
4559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            op = 1;
4560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else
4561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            op = 0;
4562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (tp) {
4563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 0:
4564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 1:
4565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 2:
4566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 3:
4567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 4:
4568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 5:
4569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               cmode = tp << 1;
4570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 9:
4572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 6:
4573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               cmode = 14;
4574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 7:
4576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               cmode = 12;
4577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 8:
4579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               cmode = 13;
4580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case 10:
4582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               cmode = 15;
4583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               break;
4584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default:
4585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               vpanic("ARMin_NeonImm");
4586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
4588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         insn = XXXXXXXX(0xF, BITS4(0,0,1,j), BITS4(1,D,0,0), imm3, regD,
4589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         cmode, BITS4(0,Q,op,1), imm4);
4590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
4591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
4592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_NCMovQ: {
4594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt cc = (UInt)i->ARMin.NCMovQ.cond;
4595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt qM = qregNo(i->ARMin.NCMovQ.src) << 1;
4596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt qD = qregNo(i->ARMin.NCMovQ.dst) << 1;
4597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt vM = qM & 0xF;
4598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt vD = qD & 0xF;
4599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt M  = (qM >> 4) & 1;
4600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt D  = (qD >> 4) & 1;
4601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(cc < 16 && cc != ARMcc_AL && cc != ARMcc_NV);
4602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* b!cc here+8: !cc A00 0000 */
4603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn = XXXXXXXX(cc ^ 1, 0xA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
4604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
4605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* vmov qD, qM */
4606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         insn = XXXXXXXX(0xF, 0x2, BITS4(0,D,1,0),
4607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         vM, vD, BITS4(0,0,0,1), BITS4(M,1,M,1), vM);
4608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
4609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
4610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case ARMin_Add32: {
4612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regD = iregNo(i->ARMin.Add32.rD);
4613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt regN = iregNo(i->ARMin.Add32.rN);
4614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt imm32 = i->ARMin.Add32.imm32;
4615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(regD != regN);
4616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* MOV regD, imm32 */
4617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         p = imm32_to_iregNo((UInt *)p, regD, imm32);
4618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* ADD regD, regN, regD */
4619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt insn = XXXXXXXX(0xE, 0, X1000, regN, regD, 0, 0, regD);
4620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *p++ = insn;
4621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto done;
4622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4623663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4624663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_EvCheck: {
4625663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* We generate:
4626663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               ldr  r12, [r8 + #4]   4 == offsetof(host_EvC_COUNTER)
4627663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               subs r12, r12, #1  (A1)
4628663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               str  r12, [r8 + #4]   4 == offsetof(host_EvC_COUNTER)
4629663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               bpl  nofail
4630663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               ldr  r12, [r8 + #0]   0 == offsetof(host_EvC_FAILADDR)
4631663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               bx   r12
4632663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng              nofail:
4633663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         */
4634663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         UInt* p0 = p;
4635663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         p = do_load_or_store32(p, True/*isLoad*/, /*r*/12,
4636663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                i->ARMin.EvCheck.amCounter);
4637663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xE25CC001; /* subs r12, r12, #1 */
4638663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         p = do_load_or_store32(p, False/*!isLoad*/, /*r*/12,
4639663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                i->ARMin.EvCheck.amCounter);
4640663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0x5A000001; /* bpl nofail */
4641663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         p = do_load_or_store32(p, True/*isLoad*/, /*r*/12,
4642663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                i->ARMin.EvCheck.amFailAddr);
4643663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xE12FFF1C; /* bx r12 */
4644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* nofail: */
4645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* Crosscheck */
4647663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(evCheckSzB_ARM() == (UChar*)p - (UChar*)p0);
4648663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         goto done;
4649663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
4650663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4651663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case ARMin_ProfInc: {
4652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* We generate:
4653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng              (ctrP is unknown now, so use 0x65556555 in the
4654663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng              expectation that a later call to LibVEX_patchProfCtr
4655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng              will be used to fill in the immediate fields once the
4656663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng              right value is known.)
4657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            movw r12, lo16(0x65556555)
4658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            movt r12, lo16(0x65556555)
4659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            ldr  r11, [r12]
4660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            adds r11, r11, #1
4661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            str  r11, [r12]
4662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            ldr  r11, [r12+4]
4663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            adc  r11, r11, #0
4664663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            str  r11, [r12+4]
4665663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         */
4666663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         p = imm32_to_iregNo_EXACTLY2(p, /*r*/12, 0x65556555);
4667663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xE59CB000;
4668663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xE29BB001;
4669663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xE58CB000;
4670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xE59CB004;
4671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xE2ABB000;
4672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *p++ = 0xE58CB004;
4673663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /* Tell the caller .. */
4674663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vassert(!(*is_profInc));
4675663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *is_profInc = True;
4676663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         goto done;
4677663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
4678663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... */
4680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
4681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad;
4682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  bad:
4685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ppARMInstr(i);
4686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vpanic("emit_ARMInstr");
4687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
4688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  done:
4690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(((UChar*)p) - &buf[0] <= 32);
4691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return ((UChar*)p) - &buf[0];
4692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* How big is an event check?  See case for ARMin_EvCheck in
4696663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   emit_ARMInstr just above.  That crosschecks what this returns, so
4697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   we can tell if we're inconsistent. */
4698663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengInt evCheckSzB_ARM ( void )
4699663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
4700663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return 24;
4701663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
4702663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4703663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4704663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* NB: what goes on here has to be very closely coordinated with the
4705663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   emitInstr case for XDirect, above. */
4706663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengVexInvalRange chainXDirect_ARM ( void* place_to_chain,
4707663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 void* disp_cp_chain_me_EXPECTED,
4708663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 void* place_to_jump_to )
4709663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
4710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* What we're expecting to see is:
4711663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        movw r12, lo16(disp_cp_chain_me_to_EXPECTED)
4712663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        movt r12, hi16(disp_cp_chain_me_to_EXPECTED)
4713663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        blx  r12
4714663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      viz
4715663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        <8 bytes generated by imm32_to_iregNo_EXACTLY2>
4716663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        E1 2F FF 3C
4717663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   */
4718663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   UInt* p = (UInt*)place_to_chain;
4719663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(0 == (3 & (HWord)p));
4720663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(is_imm32_to_iregNo_EXACTLY2(
4721663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng              p, /*r*/12, (UInt)Ptr_to_ULong(disp_cp_chain_me_EXPECTED)));
4722663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(p[2] == 0xE12FFF3C);
4723663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* And what we want to change it to is either:
4724663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        (general case)
4725663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          movw r12, lo16(place_to_jump_to)
4726663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          movt r12, hi16(place_to_jump_to)
4727663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          bx   r12
4728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        viz
4729663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          <8 bytes generated by imm32_to_iregNo_EXACTLY2>
4730663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          E1 2F FF 1C
4731663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      ---OR---
4732663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        in the case where the displacement falls within 26 bits
4733663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          b disp24; undef; undef
4734663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        viz
4735663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          EA <3 bytes == disp24>
4736663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          FF 00 00 00
4737663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          FF 00 00 00
4738663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4739663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      In both cases the replacement has the same length as the original.
4740663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      To remain sane & verifiable,
4741663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      (1) limit the displacement for the short form to
4742663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          (say) +/- 30 million, so as to avoid wraparound
4743663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          off-by-ones
4744663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      (2) even if the short form is applicable, once every (say)
4745663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          1024 times use the long form anyway, so as to maintain
4746663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          verifiability
4747663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   */
4748663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4749663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* This is the delta we need to put into a B insn.  It's relative
4750663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      to the start of the next-but-one insn, hence the -8.  */
4751663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Long delta   = (Long)((UChar*)place_to_jump_to - (UChar*)p) - (Long)8;
4752663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Bool shortOK = delta >= -30*1000*1000 && delta < 30*1000*1000;
4753663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(0 == (delta & (Long)3));
4754663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4755663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   static UInt shortCTR = 0; /* DO NOT MAKE NON-STATIC */
4756663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (shortOK) {
4757663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      shortCTR++; // thread safety bleh
4758663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (0 == (shortCTR & 0x3FF)) {
4759663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         shortOK = False;
4760663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (0)
4761663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vex_printf("QQQ chainXDirect_ARM: shortCTR = %u, "
4762663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                       "using long form\n", shortCTR);
4763663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
4764663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
4765663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4766663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* And make the modifications. */
4767663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (shortOK) {
4768663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int simm24 = (Int)(delta >> 2);
4769663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(simm24 == ((simm24 << 8) >> 8));
4770663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      p[0] = 0xEA000000 | (simm24 & 0x00FFFFFF);
4771663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      p[1] = 0xFF000000;
4772663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      p[2] = 0xFF000000;
4773663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } else {
4774663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      (void)imm32_to_iregNo_EXACTLY2(
4775663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               p, /*r*/12, (UInt)Ptr_to_ULong(place_to_jump_to));
4776663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      p[2] = 0xE12FFF1C;
4777663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
4778663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4779663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VexInvalRange vir = {(HWord)p, 12};
4780663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return vir;
4781663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
4782663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4783663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4784663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* NB: what goes on here has to be very closely coordinated with the
4785663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   emitInstr case for XDirect, above. */
4786663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengVexInvalRange unchainXDirect_ARM ( void* place_to_unchain,
4787663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                   void* place_to_jump_to_EXPECTED,
4788663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                   void* disp_cp_chain_me )
4789663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
4790663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* What we're expecting to see is:
4791663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        (general case)
4792663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          movw r12, lo16(place_to_jump_to_EXPECTED)
4793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          movt r12, lo16(place_to_jump_to_EXPECTED)
4794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          bx   r12
4795663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        viz
4796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          <8 bytes generated by imm32_to_iregNo_EXACTLY2>
4797663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          E1 2F FF 1C
4798663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      ---OR---
4799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        in the case where the displacement falls within 26 bits
4800663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          b disp24; undef; undef
4801663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        viz
4802663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          EA <3 bytes == disp24>
4803663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          FF 00 00 00
4804663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          FF 00 00 00
4805663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   */
4806663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   UInt* p = (UInt*)place_to_unchain;
4807663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(0 == (3 & (HWord)p));
4808663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4809663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Bool valid = False;
4810663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (is_imm32_to_iregNo_EXACTLY2(
4811663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          p, /*r*/12, (UInt)Ptr_to_ULong(place_to_jump_to_EXPECTED))
4812663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng       && p[2] == 0xE12FFF1C) {
4813663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      valid = True; /* it's the long form */
4814663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (0)
4815663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("QQQ unchainXDirect_ARM: found long form\n");
4816663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } else
4817663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if ((p[0] >> 24) == 0xEA && p[1] == 0xFF000000 && p[2] == 0xFF000000) {
4818663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* It's the short form.  Check the displacement is right. */
4819663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int simm24 = p[0] & 0x00FFFFFF;
4820663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      simm24 <<= 8; simm24 >>= 8;
4821663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if ((UChar*)p + (simm24 << 2) + 8 == (UChar*)place_to_jump_to_EXPECTED) {
4822663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         valid = True;
4823663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (0)
4824663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vex_printf("QQQ unchainXDirect_ARM: found short form\n");
4825663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
4826663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
4827663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(valid);
4828663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* And what we want to change it to is:
4830663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        movw r12, lo16(disp_cp_chain_me)
4831663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        movt r12, hi16(disp_cp_chain_me)
4832663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        blx  r12
4833663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      viz
4834663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        <8 bytes generated by imm32_to_iregNo_EXACTLY2>
4835663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        E1 2F FF 3C
4836663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   */
4837663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   (void)imm32_to_iregNo_EXACTLY2(
4838663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            p, /*r*/12, (UInt)Ptr_to_ULong(disp_cp_chain_me));
4839663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   p[2] = 0xE12FFF3C;
4840663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VexInvalRange vir = {(HWord)p, 12};
4841663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return vir;
4842663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
4843663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4844663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4845663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Patch the counter address into a profile inc point, as previously
4846663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   created by the ARMin_ProfInc case for emit_ARMInstr. */
4847663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengVexInvalRange patchProfInc_ARM ( void*  place_to_patch,
4848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 ULong* location_of_counter )
4849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
4850663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(sizeof(ULong*) == 4);
4851663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   UInt* p = (UInt*)place_to_patch;
4852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(0 == (3 & (HWord)p));
4853663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(is_imm32_to_iregNo_EXACTLY2(p, /*r*/12, 0x65556555));
4854663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(p[2] == 0xE59CB000);
4855663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(p[3] == 0xE29BB001);
4856663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(p[4] == 0xE58CB000);
4857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(p[5] == 0xE59CB004);
4858663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(p[6] == 0xE2ABB000);
4859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(p[7] == 0xE58CB004);
4860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   imm32_to_iregNo_EXACTLY2(p, /*r*/12,
4861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                            (UInt)Ptr_to_ULong(location_of_counter));
4862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   VexInvalRange vir = {(HWord)p, 8};
4863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return vir;
4864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
4865663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef BITS4
4868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X0000
4869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X0001
4870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X0010
4871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X0011
4872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X0100
4873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X0101
4874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X0110
4875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X0111
4876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X1000
4877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X1001
4878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X1010
4879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X1011
4880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X1100
4881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X1101
4882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X1110
4883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef X1111
4884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef XXXXX___
4885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef XXXXXX__
4886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef XXX___XX
4887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef XXXXX__X
4888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef XXXXXXXX
4889663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef XX______
4890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
4892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end                                     host_arm_defs.c ---*/
4893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/
4894