blob: cd2051256aa7bc44a85ac57e348ceeb7bf6482ef [file] [log] [blame]
cerion05782872004-12-16 11:50:19 +00001/*---------------------------------------------------------------*/
sewardj752f9062010-05-03 21:38:49 +00002/*--- begin host_arm_defs.h ---*/
cerion05782872004-12-16 11:50:19 +00003/*---------------------------------------------------------------*/
4
5/*
sewardj752f9062010-05-03 21:38:49 +00006 This file is part of Valgrind, a dynamic binary instrumentation
7 framework.
cerion05782872004-12-16 11:50:19 +00008
sewardj785952d2015-08-21 11:29:16 +00009 Copyright (C) 2004-2015 OpenWorks LLP
sewardj752f9062010-05-03 21:38:49 +000010 info@open-works.net
cerion05782872004-12-16 11:50:19 +000011
sewardj752f9062010-05-03 21:38:49 +000012 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
cerion05782872004-12-16 11:50:19 +000016
sewardj752f9062010-05-03 21:38:49 +000017 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
sewardj7bd6ffe2005-08-03 16:07:36 +000025 02110-1301, USA.
26
sewardj752f9062010-05-03 21:38:49 +000027 The GNU General Public License is contained in the file COPYING.
cerion05782872004-12-16 11:50:19 +000028*/
29
sewardjcef7d3e2009-07-02 12:21:59 +000030#ifndef __VEX_HOST_ARM_DEFS_H
31#define __VEX_HOST_ARM_DEFS_H
cerion05782872004-12-16 11:50:19 +000032
florian58a637b2012-09-30 20:30:17 +000033#include "libvex_basictypes.h"
34#include "libvex.h" // VexArch
35#include "host_generic_regs.h" // HReg
36
sewardj6c60b322010-08-22 12:48:28 +000037extern UInt arm_hwcaps;
38
cerion05782872004-12-16 11:50:19 +000039
40/* --------- Registers. --------- */
41
sewardja5b50222015-03-26 07:18:32 +000042#define ST_IN static inline
43ST_IN HReg hregARM_R4 ( void ) { return mkHReg(False, HRcInt32, 4, 0); }
44ST_IN HReg hregARM_R5 ( void ) { return mkHReg(False, HRcInt32, 5, 1); }
45ST_IN HReg hregARM_R6 ( void ) { return mkHReg(False, HRcInt32, 6, 2); }
46ST_IN HReg hregARM_R7 ( void ) { return mkHReg(False, HRcInt32, 7, 3); }
47ST_IN HReg hregARM_R10 ( void ) { return mkHReg(False, HRcInt32, 10, 4); }
48ST_IN HReg hregARM_R11 ( void ) { return mkHReg(False, HRcInt32, 11, 5); }
49
50ST_IN HReg hregARM_R0 ( void ) { return mkHReg(False, HRcInt32, 0, 6); }
51ST_IN HReg hregARM_R1 ( void ) { return mkHReg(False, HRcInt32, 1, 7); }
52ST_IN HReg hregARM_R2 ( void ) { return mkHReg(False, HRcInt32, 2, 8); }
53ST_IN HReg hregARM_R3 ( void ) { return mkHReg(False, HRcInt32, 3, 9); }
54ST_IN HReg hregARM_R9 ( void ) { return mkHReg(False, HRcInt32, 9, 10); }
55
56ST_IN HReg hregARM_D8 ( void ) { return mkHReg(False, HRcFlt64, 8, 11); }
57ST_IN HReg hregARM_D9 ( void ) { return mkHReg(False, HRcFlt64, 9, 12); }
58ST_IN HReg hregARM_D10 ( void ) { return mkHReg(False, HRcFlt64, 10, 13); }
59ST_IN HReg hregARM_D11 ( void ) { return mkHReg(False, HRcFlt64, 11, 14); }
60ST_IN HReg hregARM_D12 ( void ) { return mkHReg(False, HRcFlt64, 12, 15); }
61
62ST_IN HReg hregARM_S26 ( void ) { return mkHReg(False, HRcFlt32, 26, 16); }
63ST_IN HReg hregARM_S27 ( void ) { return mkHReg(False, HRcFlt32, 27, 17); }
64ST_IN HReg hregARM_S28 ( void ) { return mkHReg(False, HRcFlt32, 28, 18); }
65ST_IN HReg hregARM_S29 ( void ) { return mkHReg(False, HRcFlt32, 29, 19); }
66ST_IN HReg hregARM_S30 ( void ) { return mkHReg(False, HRcFlt32, 30, 20); }
67
68ST_IN HReg hregARM_Q8 ( void ) { return mkHReg(False, HRcVec128, 8, 21); }
69ST_IN HReg hregARM_Q9 ( void ) { return mkHReg(False, HRcVec128, 9, 22); }
70ST_IN HReg hregARM_Q10 ( void ) { return mkHReg(False, HRcVec128, 10, 23); }
71ST_IN HReg hregARM_Q11 ( void ) { return mkHReg(False, HRcVec128, 11, 24); }
72ST_IN HReg hregARM_Q12 ( void ) { return mkHReg(False, HRcVec128, 12, 25); }
73
74ST_IN HReg hregARM_R8 ( void ) { return mkHReg(False, HRcInt32, 8, 26); }
75ST_IN HReg hregARM_R12 ( void ) { return mkHReg(False, HRcInt32, 12, 27); }
76ST_IN HReg hregARM_R13 ( void ) { return mkHReg(False, HRcInt32, 13, 28); }
77ST_IN HReg hregARM_R14 ( void ) { return mkHReg(False, HRcInt32, 14, 29); }
78ST_IN HReg hregARM_R15 ( void ) { return mkHReg(False, HRcInt32, 15, 30); }
79ST_IN HReg hregARM_Q13 ( void ) { return mkHReg(False, HRcVec128, 13, 31); }
80ST_IN HReg hregARM_Q14 ( void ) { return mkHReg(False, HRcVec128, 14, 32); }
81ST_IN HReg hregARM_Q15 ( void ) { return mkHReg(False, HRcVec128, 15, 33); }
82#undef ST_IN
cerion05782872004-12-16 11:50:19 +000083
84extern void ppHRegARM ( HReg );
85
sewardj6c299f32009-12-31 18:00:12 +000086/* Number of registers used arg passing in function calls */
87#define ARM_N_ARGREGS 4 /* r0, r1, r2, r3 */
cerion05782872004-12-16 11:50:19 +000088
89
sewardj6c299f32009-12-31 18:00:12 +000090/* --------- Condition codes. --------- */
cerion05782872004-12-16 11:50:19 +000091
92typedef
93 enum {
sewardj6c299f32009-12-31 18:00:12 +000094 ARMcc_EQ = 0, /* equal : Z=1 */
95 ARMcc_NE = 1, /* not equal : Z=0 */
cerion05782872004-12-16 11:50:19 +000096
sewardj6c299f32009-12-31 18:00:12 +000097 ARMcc_HS = 2, /* >=u (higher or same) : C=1 */
98 ARMcc_LO = 3, /* <u (lower) : C=0 */
cerion05782872004-12-16 11:50:19 +000099
sewardj6c299f32009-12-31 18:00:12 +0000100 ARMcc_MI = 4, /* minus (negative) : N=1 */
101 ARMcc_PL = 5, /* plus (zero or +ve) : N=0 */
cerion05782872004-12-16 11:50:19 +0000102
sewardj6c299f32009-12-31 18:00:12 +0000103 ARMcc_VS = 6, /* overflow : V=1 */
104 ARMcc_VC = 7, /* no overflow : V=0 */
cerion05782872004-12-16 11:50:19 +0000105
sewardj6c299f32009-12-31 18:00:12 +0000106 ARMcc_HI = 8, /* >u (higher) : C=1 && Z=0 */
107 ARMcc_LS = 9, /* <=u (lower or same) : C=0 || Z=1 */
cerion05782872004-12-16 11:50:19 +0000108
sewardj6c299f32009-12-31 18:00:12 +0000109 ARMcc_GE = 10, /* >=s (signed greater or equal) : N=V */
110 ARMcc_LT = 11, /* <s (signed less than) : N!=V */
cerion05782872004-12-16 11:50:19 +0000111
sewardj6c299f32009-12-31 18:00:12 +0000112 ARMcc_GT = 12, /* >s (signed greater) : Z=0 && N=V */
113 ARMcc_LE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
cerion05782872004-12-16 11:50:19 +0000114
sewardj6c299f32009-12-31 18:00:12 +0000115 ARMcc_AL = 14, /* always (unconditional) */
116 ARMcc_NV = 15 /* never (basically undefined meaning), deprecated */
cerion05782872004-12-16 11:50:19 +0000117 }
118 ARMCondCode;
119
florian55085f82012-11-21 00:36:55 +0000120extern const HChar* showARMCondCode ( ARMCondCode );
cerion05782872004-12-16 11:50:19 +0000121
122
123
cerion05782872004-12-16 11:50:19 +0000124/* --------- Memory address expressions (amodes). --------- */
125
126/* --- Addressing Mode 1 --- */
127typedef
128 enum {
sewardj6c299f32009-12-31 18:00:12 +0000129 ARMam1_RI=1, /* reg +/- imm12 */
130 ARMam1_RRS /* reg1 + (reg2 << 0, 1 2 or 3) */
cerion05782872004-12-16 11:50:19 +0000131 }
132 ARMAMode1Tag;
133
134typedef
135 struct {
sewardj6c299f32009-12-31 18:00:12 +0000136 ARMAMode1Tag tag;
137 union {
138 struct {
139 HReg reg;
140 Int simm13; /* -4095 .. +4095 */
141 } RI;
142 struct {
143 HReg base;
144 HReg index;
145 UInt shift; /* 0, 1 2 or 3 */
146 } RRS;
147 } ARMam1;
cerion05782872004-12-16 11:50:19 +0000148 }
149 ARMAMode1;
150
sewardj6c299f32009-12-31 18:00:12 +0000151extern ARMAMode1* ARMAMode1_RI ( HReg reg, Int simm13 );
152extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
cerion05782872004-12-16 11:50:19 +0000153
154extern void ppARMAMode1 ( ARMAMode1* );
155
156
cerion05782872004-12-16 11:50:19 +0000157/* --- Addressing Mode 2 --- */
158typedef
159 enum {
sewardj6c299f32009-12-31 18:00:12 +0000160 ARMam2_RI=3, /* reg +/- imm8 */
161 ARMam2_RR /* reg1 + reg2 */
cerion05782872004-12-16 11:50:19 +0000162 }
163 ARMAMode2Tag;
164
165typedef
166 struct {
167 ARMAMode2Tag tag;
168 union {
169 struct {
sewardj6c299f32009-12-31 18:00:12 +0000170 HReg reg;
171 Int simm9; /* -255 .. 255 */
cerion05782872004-12-16 11:50:19 +0000172 } RI;
173 struct {
sewardj6c299f32009-12-31 18:00:12 +0000174 HReg base;
175 HReg index;
176 } RR;
cerion82edbb32004-12-16 14:06:34 +0000177 } ARMam2;
cerion05782872004-12-16 11:50:19 +0000178 }
179 ARMAMode2;
180
sewardj6c299f32009-12-31 18:00:12 +0000181extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
182extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
cerion05782872004-12-16 11:50:19 +0000183
184extern void ppARMAMode2 ( ARMAMode2* );
185
186
sewardj6c299f32009-12-31 18:00:12 +0000187/* --- Addressing Mode suitable for VFP --- */
188/* The simm11 is encoded as 8 bits + 1 sign bit,
189 so can only be 0 % 4. */
190typedef
191 struct {
192 HReg reg;
193 Int simm11; /* -1020, -1016 .. 1016, 1020 */
194 }
195 ARMAModeV;
196
197extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
198
199extern void ppARMAModeV ( ARMAModeV* );
200
sewardj6c60b322010-08-22 12:48:28 +0000201/* --- Addressing Mode suitable for Neon --- */
202typedef
203 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000204 ARMamN_R=5,
sewardj6c60b322010-08-22 12:48:28 +0000205 ARMamN_RR
206 /* ... */
207 }
208 ARMAModeNTag;
209
210typedef
211 struct {
212 ARMAModeNTag tag;
213 union {
214 struct {
215 HReg rN;
216 HReg rM;
217 } RR;
218 struct {
219 HReg rN;
220 } R;
221 /* ... */
222 } ARMamN;
223 }
224 ARMAModeN;
225
226extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg );
227extern ARMAModeN* mkARMAModeN_R ( HReg );
228extern void ppARMAModeN ( ARMAModeN* );
sewardj6c299f32009-12-31 18:00:12 +0000229
230/* --------- Reg or imm-8x4 operands --------- */
231/* a.k.a (a very restricted form of) Shifter Operand,
232 in the ARM parlance. */
233
cerion05782872004-12-16 11:50:19 +0000234typedef
235 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000236 ARMri84_I84=7, /* imm8 `ror` (2 * imm4) */
sewardj6c299f32009-12-31 18:00:12 +0000237 ARMri84_R /* reg */
cerion05782872004-12-16 11:50:19 +0000238 }
sewardj6c299f32009-12-31 18:00:12 +0000239 ARMRI84Tag;
cerion05782872004-12-16 11:50:19 +0000240
241typedef
242 struct {
sewardj6c299f32009-12-31 18:00:12 +0000243 ARMRI84Tag tag;
cerion05782872004-12-16 11:50:19 +0000244 union {
245 struct {
sewardj6c299f32009-12-31 18:00:12 +0000246 UShort imm8;
247 UShort imm4;
248 } I84;
cerion05782872004-12-16 11:50:19 +0000249 struct {
sewardj6c299f32009-12-31 18:00:12 +0000250 HReg reg;
251 } R;
252 } ARMri84;
cerion05782872004-12-16 11:50:19 +0000253 }
sewardj6c299f32009-12-31 18:00:12 +0000254 ARMRI84;
255
256extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
257extern ARMRI84* ARMRI84_R ( HReg );
258
259extern void ppARMRI84 ( ARMRI84* );
cerion05782872004-12-16 11:50:19 +0000260
261
sewardj6c299f32009-12-31 18:00:12 +0000262/* --------- Reg or imm5 operands --------- */
cerion05782872004-12-16 11:50:19 +0000263typedef
264 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000265 ARMri5_I5=9, /* imm5, 1 .. 31 only (no zero!) */
sewardj6c299f32009-12-31 18:00:12 +0000266 ARMri5_R /* reg */
cerion05782872004-12-16 11:50:19 +0000267 }
sewardj6c299f32009-12-31 18:00:12 +0000268 ARMRI5Tag;
cerion05782872004-12-16 11:50:19 +0000269
270typedef
sewardj6c299f32009-12-31 18:00:12 +0000271 struct {
272 ARMRI5Tag tag;
cerion05782872004-12-16 11:50:19 +0000273 union {
sewardj6c299f32009-12-31 18:00:12 +0000274 struct {
275 UInt imm5;
276 } I5;
277 struct {
278 HReg reg;
279 } R;
280 } ARMri5;
281 }
282 ARMRI5;
cerion05782872004-12-16 11:50:19 +0000283
sewardj6c299f32009-12-31 18:00:12 +0000284extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
285extern ARMRI5* ARMRI5_R ( HReg );
cerion82edbb32004-12-16 14:06:34 +0000286
sewardj6c299f32009-12-31 18:00:12 +0000287extern void ppARMRI5 ( ARMRI5* );
cerion05782872004-12-16 11:50:19 +0000288
sewardj6c60b322010-08-22 12:48:28 +0000289/* -------- Neon Immediate operand -------- */
290
291/* imm8 = abcdefgh, B = NOT(b);
292
293type | value (64bit binary)
294-----+-------------------------------------------------------------------------
295 0 | 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh
296 1 | 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000
297 2 | 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000
298 3 | abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000
299 4 | 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh
300 5 | abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000
301 6 | abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh
302 7 | 00000000 00000000 abcdefgh 11111111 00000000 00000000 abcdefgh 11111111
303 8 | 00000000 abcdefgh 11111111 11111111 00000000 abcdefgh 11111111 11111111
304 9 | aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
305 10 | aBbbbbbc defgh000 00000000 00000000 aBbbbbbc defgh000 00000000 00000000
306-----+-------------------------------------------------------------------------
307
308Type 10 is:
309 (-1)^S * 2^exp * mantissa
310where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16
311*/
312
313typedef
314 struct {
315 UInt type;
316 UInt imm8;
317 }
318 ARMNImm;
319
320extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 );
321extern ULong ARMNImm_to_Imm64 ( ARMNImm* );
322extern ARMNImm* Imm64_to_ARMNImm ( ULong );
323
324extern void ppARMNImm ( ARMNImm* );
325
326/* ------ Neon Register or Scalar Operand ------ */
327
328typedef
329 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000330 ARMNRS_Reg=11,
sewardj6c60b322010-08-22 12:48:28 +0000331 ARMNRS_Scalar
332 }
333 ARMNRS_tag;
334
335typedef
336 struct {
337 ARMNRS_tag tag;
338 HReg reg;
339 UInt index;
340 }
341 ARMNRS;
342
343extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index);
344extern void ppARMNRS ( ARMNRS* );
cerion05782872004-12-16 11:50:19 +0000345
346/* --------- Instructions. --------- */
347
cerion05782872004-12-16 11:50:19 +0000348/* --------- */
349typedef
350 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000351 ARMalu_ADD=20, /* plain 32-bit add */
sewardj6c299f32009-12-31 18:00:12 +0000352 ARMalu_ADDS, /* 32-bit add, and set the flags */
353 ARMalu_ADC, /* 32-bit add with carry */
354 ARMalu_SUB, /* plain 32-bit subtract */
355 ARMalu_SUBS, /* 32-bit subtract, and set the flags */
356 ARMalu_SBC, /* 32-bit subtract with carry */
357 ARMalu_AND,
358 ARMalu_BIC,
359 ARMalu_OR,
360 ARMalu_XOR
361 }
362 ARMAluOp;
cerion05782872004-12-16 11:50:19 +0000363
florian55085f82012-11-21 00:36:55 +0000364extern const HChar* showARMAluOp ( ARMAluOp op );
cerion05782872004-12-16 11:50:19 +0000365
sewardj6c299f32009-12-31 18:00:12 +0000366
367typedef
368 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000369 ARMsh_SHL=40,
sewardj6c299f32009-12-31 18:00:12 +0000370 ARMsh_SHR,
371 ARMsh_SAR
372 }
373 ARMShiftOp;
374
florian55085f82012-11-21 00:36:55 +0000375extern const HChar* showARMShiftOp ( ARMShiftOp op );
sewardj6c299f32009-12-31 18:00:12 +0000376
377
378typedef
379 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000380 ARMun_NEG=50,
sewardj6c299f32009-12-31 18:00:12 +0000381 ARMun_NOT,
382 ARMun_CLZ
383 }
384 ARMUnaryOp;
385
florian55085f82012-11-21 00:36:55 +0000386extern const HChar* showARMUnaryOp ( ARMUnaryOp op );
sewardj6c299f32009-12-31 18:00:12 +0000387
388
389typedef
390 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000391 ARMmul_PLAIN=60,
sewardj6c299f32009-12-31 18:00:12 +0000392 ARMmul_ZX,
393 ARMmul_SX
394 }
395 ARMMulOp;
396
florian55085f82012-11-21 00:36:55 +0000397extern const HChar* showARMMulOp ( ARMMulOp op );
sewardj6c299f32009-12-31 18:00:12 +0000398
399
400typedef
401 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000402 ARMvfp_ADD=70,
sewardj6c299f32009-12-31 18:00:12 +0000403 ARMvfp_SUB,
404 ARMvfp_MUL,
405 ARMvfp_DIV
406 }
407 ARMVfpOp;
408
florian55085f82012-11-21 00:36:55 +0000409extern const HChar* showARMVfpOp ( ARMVfpOp op );
sewardj6c299f32009-12-31 18:00:12 +0000410
411
412typedef
413 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000414 ARMvfpu_COPY=80,
sewardj6c299f32009-12-31 18:00:12 +0000415 ARMvfpu_NEG,
416 ARMvfpu_ABS,
417 ARMvfpu_SQRT
418 }
419 ARMVfpUnaryOp;
420
florian55085f82012-11-21 00:36:55 +0000421extern const HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
sewardj6c299f32009-12-31 18:00:12 +0000422
sewardj6c60b322010-08-22 12:48:28 +0000423typedef
424 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000425 ARMneon_VAND=90,
sewardj6c60b322010-08-22 12:48:28 +0000426 ARMneon_VORR,
427 ARMneon_VXOR,
428 ARMneon_VADD,
429 ARMneon_VADDFP,
430 ARMneon_VRHADDS,
431 ARMneon_VRHADDU,
432 ARMneon_VPADDFP,
433 ARMneon_VABDFP,
434 ARMneon_VSUB,
435 ARMneon_VSUBFP,
436 ARMneon_VMAXU,
437 ARMneon_VMAXS,
438 ARMneon_VMAXF,
439 ARMneon_VMINU,
440 ARMneon_VMINS,
441 ARMneon_VMINF,
442 ARMneon_VQADDU,
443 ARMneon_VQADDS,
444 ARMneon_VQSUBU,
445 ARMneon_VQSUBS,
446 ARMneon_VCGTU,
447 ARMneon_VCGTS,
448 ARMneon_VCGEU,
449 ARMneon_VCGES,
450 ARMneon_VCGTF,
451 ARMneon_VCGEF,
452 ARMneon_VCEQ,
453 ARMneon_VCEQF,
454 ARMneon_VEXT,
455 ARMneon_VMUL,
456 ARMneon_VMULFP,
457 ARMneon_VMULLU,
458 ARMneon_VMULLS,
459 ARMneon_VMULP,
460 ARMneon_VMULLP,
461 ARMneon_VQDMULH,
462 ARMneon_VQRDMULH,
463 ARMneon_VPADD,
464 ARMneon_VPMINU,
465 ARMneon_VPMINS,
466 ARMneon_VPMINF,
467 ARMneon_VPMAXU,
468 ARMneon_VPMAXS,
469 ARMneon_VPMAXF,
470 ARMneon_VTBL,
471 ARMneon_VQDMULL,
sewardj6c60b322010-08-22 12:48:28 +0000472 ARMneon_VRECPS,
sewardj6c60b322010-08-22 12:48:28 +0000473 ARMneon_VRSQRTS,
sewardje84eeb42014-03-15 11:41:39 +0000474 ARMneon_INVALID
sewardj6c60b322010-08-22 12:48:28 +0000475 /* ... */
476 }
477 ARMNeonBinOp;
478
479typedef
480 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000481 ARMneon_VSHL=150,
sewardj6c60b322010-08-22 12:48:28 +0000482 ARMneon_VSAL, /* Yah, not SAR but SAL */
483 ARMneon_VQSHL,
484 ARMneon_VQSAL
485 }
486 ARMNeonShiftOp;
487
488typedef
489 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000490 ARMneon_COPY=160,
sewardj6c60b322010-08-22 12:48:28 +0000491 ARMneon_COPYLU,
492 ARMneon_COPYLS,
493 ARMneon_COPYN,
494 ARMneon_COPYQNSS,
495 ARMneon_COPYQNUS,
496 ARMneon_COPYQNUU,
497 ARMneon_NOT,
498 ARMneon_EQZ,
499 ARMneon_DUP,
500 ARMneon_PADDLS,
501 ARMneon_PADDLU,
502 ARMneon_CNT,
503 ARMneon_CLZ,
504 ARMneon_CLS,
505 ARMneon_VCVTxFPxINT,
506 ARMneon_VQSHLNSS,
507 ARMneon_VQSHLNUU,
508 ARMneon_VQSHLNUS,
509 ARMneon_VCVTFtoU,
510 ARMneon_VCVTFtoS,
511 ARMneon_VCVTUtoF,
512 ARMneon_VCVTStoF,
513 ARMneon_VCVTFtoFixedU,
514 ARMneon_VCVTFtoFixedS,
515 ARMneon_VCVTFixedUtoF,
516 ARMneon_VCVTFixedStoF,
517 ARMneon_VCVTF16toF32,
518 ARMneon_VCVTF32toF16,
519 ARMneon_REV16,
520 ARMneon_REV32,
521 ARMneon_REV64,
522 ARMneon_ABS,
523 ARMneon_VNEGF,
sewardj6aa87a62010-10-06 20:34:53 +0000524 ARMneon_VRECIP,
525 ARMneon_VRECIPF,
526 ARMneon_VABSFP,
527 ARMneon_VRSQRTEFP,
528 ARMneon_VRSQRTE
sewardj6c60b322010-08-22 12:48:28 +0000529 /* ... */
530 }
531 ARMNeonUnOp;
532
533typedef
534 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000535 ARMneon_SETELEM=200,
sewardj6c60b322010-08-22 12:48:28 +0000536 ARMneon_GETELEMU,
sewardj6aa87a62010-10-06 20:34:53 +0000537 ARMneon_GETELEMS,
538 ARMneon_VDUP,
sewardj6c60b322010-08-22 12:48:28 +0000539 }
540 ARMNeonUnOpS;
541
542typedef
543 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000544 ARMneon_TRN=210,
sewardj6c60b322010-08-22 12:48:28 +0000545 ARMneon_ZIP,
546 ARMneon_UZP
547 /* ... */
548 }
549 ARMNeonDualOp;
550
florian55085f82012-11-21 00:36:55 +0000551extern const HChar* showARMNeonBinOp ( ARMNeonBinOp op );
552extern const HChar* showARMNeonUnOp ( ARMNeonUnOp op );
553extern const HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
554extern const HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
555extern const HChar* showARMNeonDualOp ( ARMNeonDualOp op );
556extern const HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
557extern const HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
558extern const HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
559extern const HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
560extern const HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
sewardj6c299f32009-12-31 18:00:12 +0000561
562typedef
563 enum {
564 /* baseline */
sewardjb48eddb2010-10-04 09:34:46 +0000565 ARMin_Alu=220,
sewardj6c299f32009-12-31 18:00:12 +0000566 ARMin_Shift,
567 ARMin_Unary,
568 ARMin_CmpOrTst,
569 ARMin_Mov,
570 ARMin_Imm32,
571 ARMin_LdSt32,
572 ARMin_LdSt16,
573 ARMin_LdSt8U,
574 ARMin_Ld8S,
sewardjc6f970f2012-04-02 21:54:49 +0000575 ARMin_XDirect, /* direct transfer to GA */
576 ARMin_XIndir, /* indirect transfer to GA */
577 ARMin_XAssisted, /* assisted transfer to GA */
sewardj6c299f32009-12-31 18:00:12 +0000578 ARMin_CMov,
579 ARMin_Call,
580 ARMin_Mul,
581 ARMin_LdrEX,
582 ARMin_StrEX,
583 /* vfp */
584 ARMin_VLdStD,
585 ARMin_VLdStS,
586 ARMin_VAluD,
587 ARMin_VAluS,
588 ARMin_VUnaryD,
589 ARMin_VUnaryS,
590 ARMin_VCmpD,
591 ARMin_VCMovD,
592 ARMin_VCMovS,
593 ARMin_VCvtSD,
Elliott Hughesa0664b92017-04-18 17:46:52 -0700594 ARMin_VXferQ,
sewardj6c299f32009-12-31 18:00:12 +0000595 ARMin_VXferD,
596 ARMin_VXferS,
597 ARMin_VCvtID,
sewardj412098c2010-05-04 08:48:43 +0000598 ARMin_FPSCR,
sewardj6c60b322010-08-22 12:48:28 +0000599 ARMin_MFence,
sewardj6d615ba2011-09-26 16:19:43 +0000600 ARMin_CLREX,
sewardj6c60b322010-08-22 12:48:28 +0000601 /* Neon */
602 ARMin_NLdStQ,
603 ARMin_NLdStD,
604 ARMin_NUnary,
605 ARMin_NUnaryS,
606 ARMin_NDual,
607 ARMin_NBinary,
608 ARMin_NBinaryS,
609 ARMin_NShift,
sewardjf78a81c2013-04-21 00:45:18 +0000610 ARMin_NShl64, // special case 64-bit shift of Dreg by immediate
sewardj6c60b322010-08-22 12:48:28 +0000611 ARMin_NeonImm,
612 ARMin_NCMovQ,
613 /* This is not a NEON instruction. Actually there is no corresponding
614 instruction in ARM instruction set at all. We need this one to
615 generate spill/reload of 128-bit registers since current register
616 allocator demands them to consist of no more than two instructions.
617 We will split this instruction into 2 or 3 ARM instructions on the
618 emiting phase.
sewardj6c60b322010-08-22 12:48:28 +0000619 NOTE: source and destination registers should be different! */
sewardjc6f970f2012-04-02 21:54:49 +0000620 ARMin_Add32,
621 ARMin_EvCheck, /* Event check */
622 ARMin_ProfInc /* 64-bit profile counter increment */
cerion05782872004-12-16 11:50:19 +0000623 }
624 ARMInstrTag;
625
sewardj6c299f32009-12-31 18:00:12 +0000626/* Destinations are on the LEFT (first operand) */
cerion05782872004-12-16 11:50:19 +0000627
628typedef
629 struct {
630 ARMInstrTag tag;
631 union {
sewardj6c299f32009-12-31 18:00:12 +0000632 /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
633 struct {
634 ARMAluOp op;
635 HReg dst;
636 HReg argL;
637 ARMRI84* argR;
638 } Alu;
639 /* SHL/SHR/SAR, 2nd arg is reg or imm */
640 struct {
641 ARMShiftOp op;
642 HReg dst;
643 HReg argL;
644 ARMRI5* argR;
645 } Shift;
646 /* NOT/NEG/CLZ */
647 struct {
648 ARMUnaryOp op;
649 HReg dst;
650 HReg src;
651 } Unary;
652 /* CMP/TST; subtract/and, discard result, set NZCV */
653 struct {
654 Bool isCmp;
655 HReg argL;
656 ARMRI84* argR;
657 } CmpOrTst;
658 /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
659 struct {
660 HReg dst;
661 ARMRI84* src;
662 } Mov;
663 /* Pseudo-insn; make a 32-bit immediate */
664 struct {
665 HReg dst;
666 UInt imm32;
667 } Imm32;
sewardjcfe046e2013-01-17 14:23:53 +0000668 /* 32-bit load or store, may be conditional */
sewardj6c299f32009-12-31 18:00:12 +0000669 struct {
sewardjcfe046e2013-01-17 14:23:53 +0000670 ARMCondCode cc; /* ARMcc_NV is not allowed */
671 Bool isLoad;
672 HReg rD;
673 ARMAMode1* amode;
sewardj6c299f32009-12-31 18:00:12 +0000674 } LdSt32;
sewardjcfe046e2013-01-17 14:23:53 +0000675 /* 16-bit load or store, may be conditional */
sewardj6c299f32009-12-31 18:00:12 +0000676 struct {
sewardjcfe046e2013-01-17 14:23:53 +0000677 ARMCondCode cc; /* ARMcc_NV is not allowed */
678 Bool isLoad;
679 Bool signedLoad;
680 HReg rD;
681 ARMAMode2* amode;
sewardj6c299f32009-12-31 18:00:12 +0000682 } LdSt16;
sewardjcfe046e2013-01-17 14:23:53 +0000683 /* 8-bit (unsigned) load or store, may be conditional */
sewardj6c299f32009-12-31 18:00:12 +0000684 struct {
sewardjcfe046e2013-01-17 14:23:53 +0000685 ARMCondCode cc; /* ARMcc_NV is not allowed */
686 Bool isLoad;
687 HReg rD;
688 ARMAMode1* amode;
sewardj6c299f32009-12-31 18:00:12 +0000689 } LdSt8U;
sewardjcfe046e2013-01-17 14:23:53 +0000690 /* 8-bit signed load, may be conditional */
sewardj6c299f32009-12-31 18:00:12 +0000691 struct {
sewardjcfe046e2013-01-17 14:23:53 +0000692 ARMCondCode cc; /* ARMcc_NV is not allowed */
693 HReg rD;
694 ARMAMode2* amode;
sewardj6c299f32009-12-31 18:00:12 +0000695 } Ld8S;
sewardjc6f970f2012-04-02 21:54:49 +0000696 /* Update the guest R15T value, then exit requesting to chain
697 to it. May be conditional. Urr, use of Addr32 implicitly
698 assumes that wordsize(guest) == wordsize(host). */
sewardj6c299f32009-12-31 18:00:12 +0000699 struct {
sewardjc6f970f2012-04-02 21:54:49 +0000700 Addr32 dstGA; /* next guest address */
701 ARMAMode1* amR15T; /* amode in guest state for R15T */
702 ARMCondCode cond; /* can be ARMcc_AL */
703 Bool toFastEP; /* chain to the slow or fast point? */
704 } XDirect;
705 /* Boring transfer to a guest address not known at JIT time.
706 Not chainable. May be conditional. */
707 struct {
708 HReg dstGA;
709 ARMAMode1* amR15T;
710 ARMCondCode cond; /* can be ARMcc_AL */
711 } XIndir;
712 /* Assisted transfer to a guest address, most general case.
713 Not chainable. May be conditional. */
714 struct {
715 HReg dstGA;
716 ARMAMode1* amR15T;
717 ARMCondCode cond; /* can be ARMcc_AL */
sewardj6c299f32009-12-31 18:00:12 +0000718 IRJumpKind jk;
sewardjc6f970f2012-04-02 21:54:49 +0000719 } XAssisted;
sewardj6c299f32009-12-31 18:00:12 +0000720 /* Mov src to dst on the given condition, which may not
721 be ARMcc_AL. */
722 struct {
723 ARMCondCode cond;
724 HReg dst;
725 ARMRI84* src;
726 } CMov;
727 /* Pseudo-insn. Call target (an absolute address), on given
728 condition (which could be ARMcc_AL). */
729 struct {
730 ARMCondCode cond;
florian93a09742015-01-07 20:14:48 +0000731 Addr32 target;
sewardj6c299f32009-12-31 18:00:12 +0000732 Int nArgRegs; /* # regs carrying args: 0 .. 4 */
sewardjcfe046e2013-01-17 14:23:53 +0000733 RetLoc rloc; /* where the return value will be */
sewardj6c299f32009-12-31 18:00:12 +0000734 } Call;
735 /* (PLAIN) 32 * 32 -> 32: r0 = r2 * r3
736 (ZX) 32 *u 32 -> 64: r1:r0 = r2 *u r3
737 (SX) 32 *s 32 -> 64: r1:r0 = r2 *s r3
738 Why hardwired registers? Because the ARM ARM specifies
739 (eg for straight MUL) the result (Rd) and the left arg (Rm)
740 may not be the same register. That's not a constraint we
741 can enforce in the register allocator (without mucho extra
742 complexity). Hence hardwire it. At least using caller-saves
743 registers, which are less likely to be in use. */
744 struct {
745 ARMMulOp op;
746 } Mul;
sewardjff7f5b72011-07-11 11:43:38 +0000747 /* LDREX{,H,B} r2, [r4] and
748 LDREXD r2, r3, [r4] (on LE hosts, transferred value is r3:r2)
sewardj6c299f32009-12-31 18:00:12 +0000749 Again, hardwired registers since this is not performance
750 critical, and there are possibly constraints on the
751 registers that we can't express in the register allocator.*/
752 struct {
sewardjff7f5b72011-07-11 11:43:38 +0000753 Int szB; /* 1, 2, 4 or 8 */
sewardj6c299f32009-12-31 18:00:12 +0000754 } LdrEX;
sewardjff7f5b72011-07-11 11:43:38 +0000755 /* STREX{,H,B} r0, r2, [r4] and
756 STREXD r0, r2, r3, [r4] (on LE hosts, transferred value is r3:r2)
757 r0 = SC( [r4] = r2 ) (8, 16, 32 bit transfers)
758 r0 = SC( [r4] = r3:r2) (64 bit transfers)
sewardj6c299f32009-12-31 18:00:12 +0000759 Ditto comment re fixed registers. */
760 struct {
sewardjff7f5b72011-07-11 11:43:38 +0000761 Int szB; /* 1, 2, 4 or 8 */
sewardj6c299f32009-12-31 18:00:12 +0000762 } StrEX;
763 /* VFP INSTRUCTIONS */
764 /* 64-bit Fp load/store */
765 struct {
766 Bool isLoad;
767 HReg dD;
768 ARMAModeV* amode;
769 } VLdStD;
770 /* 32-bit Fp load/store */
771 struct {
772 Bool isLoad;
773 HReg fD;
774 ARMAModeV* amode;
775 } VLdStS;
776 /* 64-bit FP binary arithmetic */
777 struct {
778 ARMVfpOp op;
779 HReg dst;
780 HReg argL;
781 HReg argR;
782 } VAluD;
783 /* 32-bit FP binary arithmetic */
784 struct {
785 ARMVfpOp op;
786 HReg dst;
787 HReg argL;
788 HReg argR;
789 } VAluS;
790 /* 64-bit FP unary, also reg-reg move */
791 struct {
792 ARMVfpUnaryOp op;
793 HReg dst;
794 HReg src;
795 } VUnaryD;
796 /* 32-bit FP unary, also reg-reg move */
797 struct {
798 ARMVfpUnaryOp op;
799 HReg dst;
800 HReg src;
801 } VUnaryS;
802 /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
803 struct {
804 HReg argL;
805 HReg argR;
806 } VCmpD;
807 /* 64-bit FP mov src to dst on the given condition, which may
808 not be ARMcc_AL. */
809 struct {
810 ARMCondCode cond;
811 HReg dst;
812 HReg src;
813 } VCMovD;
814 /* 32-bit FP mov src to dst on the given condition, which may
815 not be ARMcc_AL. */
816 struct {
817 ARMCondCode cond;
818 HReg dst;
819 HReg src;
820 } VCMovS;
821 /* Convert between 32-bit and 64-bit FP values (both ways).
822 (FCVTSD, FCVTDS) */
823 struct {
824 Bool sToD; /* True: F32->F64. False: F64->F32 */
825 HReg dst;
826 HReg src;
827 } VCvtSD;
Elliott Hughesa0664b92017-04-18 17:46:52 -0700828 /* Transfer a NEON Q reg to/from two D registers (VMOV x 2) */
829 struct {
830 Bool toQ;
831 HReg qD;
832 HReg dHi;
833 HReg dLo;
834 } VXferQ;
sewardj6c299f32009-12-31 18:00:12 +0000835 /* Transfer a VFP D reg to/from two integer registers (VMOV) */
836 struct {
837 Bool toD;
838 HReg dD;
839 HReg rHi;
840 HReg rLo;
841 } VXferD;
842 /* Transfer a VFP S reg to/from an integer register (VMOV) */
843 struct {
844 Bool toS;
845 HReg fD;
846 HReg rLo;
847 } VXferS;
848 /* Convert between 32-bit ints and 64-bit FP values (both ways
849 and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
850 struct {
851 Bool iToD; /* True: I32->F64. False: F64->I32 */
852 Bool syned; /* True: I32 is signed. False: I32 is unsigned */
853 HReg dst;
854 HReg src;
855 } VCvtID;
856 /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
857 struct {
858 Bool toFPSCR;
859 HReg iReg;
860 } FPSCR;
sewardj412098c2010-05-04 08:48:43 +0000861 /* Mem fence. An insn which fences all loads and stores as
862 much as possible before continuing. On ARM we emit the
863 sequence
864 mcr 15,0,r0,c7,c10,4 (DSB)
865 mcr 15,0,r0,c7,c10,5 (DMB)
866 mcr 15,0,r0,c7,c5,4 (ISB)
867 which is probably total overkill, but better safe than
868 sorry.
869 */
870 struct {
871 } MFence;
sewardj6d615ba2011-09-26 16:19:43 +0000872 /* A CLREX instruction. */
873 struct {
874 } CLREX;
sewardj6c60b322010-08-22 12:48:28 +0000875 /* Neon data processing instruction: 3 registers of the same
876 length */
877 struct {
878 ARMNeonBinOp op;
879 HReg dst;
880 HReg argL;
881 HReg argR;
882 UInt size;
883 Bool Q;
884 } NBinary;
885 struct {
886 ARMNeonBinOp op;
887 ARMNRS* dst;
888 ARMNRS* argL;
889 ARMNRS* argR;
890 UInt size;
891 Bool Q;
892 } NBinaryS;
893 struct {
894 ARMNeonShiftOp op;
895 HReg dst;
896 HReg argL;
897 HReg argR;
898 UInt size;
899 Bool Q;
900 } NShift;
901 struct {
sewardjf78a81c2013-04-21 00:45:18 +0000902 HReg dst;
903 HReg src;
904 UInt amt; /* 1..63 only */
905 } NShl64;
906 struct {
sewardj6c60b322010-08-22 12:48:28 +0000907 Bool isLoad;
908 HReg dQ;
909 ARMAModeN *amode;
910 } NLdStQ;
911 struct {
912 Bool isLoad;
913 HReg dD;
914 ARMAModeN *amode;
915 } NLdStD;
916 struct {
sewardj6aa87a62010-10-06 20:34:53 +0000917 ARMNeonUnOpS op;
sewardj6c60b322010-08-22 12:48:28 +0000918 ARMNRS* dst;
919 ARMNRS* src;
920 UInt size;
921 Bool Q;
922 } NUnaryS;
923 struct {
924 ARMNeonUnOp op;
925 HReg dst;
926 HReg src;
927 UInt size;
928 Bool Q;
929 } NUnary;
930 /* Takes two arguments and modifies them both. */
931 struct {
932 ARMNeonDualOp op;
933 HReg arg1;
934 HReg arg2;
935 UInt size;
936 Bool Q;
937 } NDual;
938 struct {
939 HReg dst;
940 ARMNImm* imm;
941 } NeonImm;
942 /* 128-bit Neon move src to dst on the given condition, which
943 may not be ARMcc_AL. */
944 struct {
945 ARMCondCode cond;
946 HReg dst;
947 HReg src;
948 } NCMovQ;
949 struct {
950 /* Note: rD != rN */
951 HReg rD;
952 HReg rN;
953 UInt imm32;
954 } Add32;
sewardjc6f970f2012-04-02 21:54:49 +0000955 struct {
956 ARMAMode1* amCounter;
957 ARMAMode1* amFailAddr;
958 } EvCheck;
959 struct {
960 /* No fields. The address of the counter to inc is
961 installed later, post-translation, by patching it in,
962 as it is not known at translation time. */
963 } ProfInc;
cerion05782872004-12-16 11:50:19 +0000964 } ARMin;
965 }
966 ARMInstr;
967
cerion05782872004-12-16 11:50:19 +0000968
sewardj6c299f32009-12-31 18:00:12 +0000969extern ARMInstr* ARMInstr_Alu ( ARMAluOp, HReg, HReg, ARMRI84* );
970extern ARMInstr* ARMInstr_Shift ( ARMShiftOp, HReg, HReg, ARMRI5* );
971extern ARMInstr* ARMInstr_Unary ( ARMUnaryOp, HReg, HReg );
972extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
973extern ARMInstr* ARMInstr_Mov ( HReg, ARMRI84* );
974extern ARMInstr* ARMInstr_Imm32 ( HReg, UInt );
sewardjcfe046e2013-01-17 14:23:53 +0000975extern ARMInstr* ARMInstr_LdSt32 ( ARMCondCode,
976 Bool isLoad, HReg, ARMAMode1* );
977extern ARMInstr* ARMInstr_LdSt16 ( ARMCondCode,
978 Bool isLoad, Bool signedLoad,
sewardj6c299f32009-12-31 18:00:12 +0000979 HReg, ARMAMode2* );
sewardjcfe046e2013-01-17 14:23:53 +0000980extern ARMInstr* ARMInstr_LdSt8U ( ARMCondCode,
981 Bool isLoad, HReg, ARMAMode1* );
982extern ARMInstr* ARMInstr_Ld8S ( ARMCondCode, HReg, ARMAMode2* );
sewardjc6f970f2012-04-02 21:54:49 +0000983extern ARMInstr* ARMInstr_XDirect ( Addr32 dstGA, ARMAMode1* amR15T,
984 ARMCondCode cond, Bool toFastEP );
985extern ARMInstr* ARMInstr_XIndir ( HReg dstGA, ARMAMode1* amR15T,
986 ARMCondCode cond );
987extern ARMInstr* ARMInstr_XAssisted ( HReg dstGA, ARMAMode1* amR15T,
988 ARMCondCode cond, IRJumpKind jk );
sewardj6c299f32009-12-31 18:00:12 +0000989extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src );
florian93a09742015-01-07 20:14:48 +0000990extern ARMInstr* ARMInstr_Call ( ARMCondCode, Addr32, Int nArgRegs,
sewardjcfe046e2013-01-17 14:23:53 +0000991 RetLoc rloc );
sewardj6c299f32009-12-31 18:00:12 +0000992extern ARMInstr* ARMInstr_Mul ( ARMMulOp op );
993extern ARMInstr* ARMInstr_LdrEX ( Int szB );
994extern ARMInstr* ARMInstr_StrEX ( Int szB );
995extern ARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg, ARMAModeV* );
996extern ARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg, ARMAModeV* );
997extern ARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg, HReg, HReg );
998extern ARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg, HReg, HReg );
999extern ARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp, HReg dst, HReg src );
1000extern ARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp, HReg dst, HReg src );
1001extern ARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR );
1002extern ARMInstr* ARMInstr_VCMovD ( ARMCondCode, HReg dst, HReg src );
1003extern ARMInstr* ARMInstr_VCMovS ( ARMCondCode, HReg dst, HReg src );
1004extern ARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src );
Elliott Hughesa0664b92017-04-18 17:46:52 -07001005extern ARMInstr* ARMInstr_VXferQ ( Bool toQ, HReg qD, HReg dHi, HReg dLo );
sewardj6c299f32009-12-31 18:00:12 +00001006extern ARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo );
1007extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo );
1008extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned,
1009 HReg dst, HReg src );
1010extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg );
sewardj412098c2010-05-04 08:48:43 +00001011extern ARMInstr* ARMInstr_MFence ( void );
sewardj6d615ba2011-09-26 16:19:43 +00001012extern ARMInstr* ARMInstr_CLREX ( void );
sewardj6c60b322010-08-22 12:48:28 +00001013extern ARMInstr* ARMInstr_NLdStQ ( Bool isLoad, HReg, ARMAModeN* );
1014extern ARMInstr* ARMInstr_NLdStD ( Bool isLoad, HReg, ARMAModeN* );
1015extern ARMInstr* ARMInstr_NUnary ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
sewardjcb9ad0d2011-04-27 07:02:44 +00001016extern ARMInstr* ARMInstr_NUnaryS ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
sewardj6c60b322010-08-22 12:48:28 +00001017 UInt, Bool );
1018extern ARMInstr* ARMInstr_NDual ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
1019extern ARMInstr* ARMInstr_NBinary ( ARMNeonBinOp, HReg, HReg, HReg,
1020 UInt, Bool );
1021extern ARMInstr* ARMInstr_NShift ( ARMNeonShiftOp, HReg, HReg, HReg,
1022 UInt, Bool );
sewardjf78a81c2013-04-21 00:45:18 +00001023extern ARMInstr* ARMInstr_NShl64 ( HReg, HReg, UInt );
sewardj6c60b322010-08-22 12:48:28 +00001024extern ARMInstr* ARMInstr_NeonImm ( HReg, ARMNImm* );
1025extern ARMInstr* ARMInstr_NCMovQ ( ARMCondCode, HReg, HReg );
1026extern ARMInstr* ARMInstr_Add32 ( HReg rD, HReg rN, UInt imm32 );
sewardjc6f970f2012-04-02 21:54:49 +00001027extern ARMInstr* ARMInstr_EvCheck ( ARMAMode1* amCounter,
1028 ARMAMode1* amFailAddr );
1029extern ARMInstr* ARMInstr_ProfInc ( void );
cerion05782872004-12-16 11:50:19 +00001030
floriand8c64e02014-10-08 08:54:44 +00001031extern void ppARMInstr ( const ARMInstr* );
cerion05782872004-12-16 11:50:19 +00001032
1033
cerion05782872004-12-16 11:50:19 +00001034/* Some functions that insulate the register allocator from details
1035 of the underlying instruction set. */
floriand8c64e02014-10-08 08:54:44 +00001036extern void getRegUsage_ARMInstr ( HRegUsage*, const ARMInstr*, Bool );
sewardj6c299f32009-12-31 18:00:12 +00001037extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool );
floriand8c64e02014-10-08 08:54:44 +00001038extern Bool isMove_ARMInstr ( const ARMInstr*, HReg*, HReg* );
sewardjc6f970f2012-04-02 21:54:49 +00001039extern Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc,
floriand8c64e02014-10-08 08:54:44 +00001040 UChar* buf, Int nbuf, const ARMInstr* i,
sewardjc6f970f2012-04-02 21:54:49 +00001041 Bool mode64,
sewardj9b769162014-07-24 12:42:03 +00001042 VexEndness endness_host,
florian8462d112014-09-24 15:18:09 +00001043 const void* disp_cp_chain_me_to_slowEP,
1044 const void* disp_cp_chain_me_to_fastEP,
1045 const void* disp_cp_xindir,
1046 const void* disp_cp_xassisted );
sewardj6c299f32009-12-31 18:00:12 +00001047
1048extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1049 HReg rreg, Int offset, Bool );
1050extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1051 HReg rreg, Int offset, Bool );
1052
sewardja5b50222015-03-26 07:18:32 +00001053extern const RRegUniverse* getRRegUniverse_ARM ( void );
1054
floriancacba8e2014-12-15 18:58:07 +00001055extern HInstrArray* iselSB_ARM ( const IRSB*,
sewardjc6f970f2012-04-02 21:54:49 +00001056 VexArch,
floriand8c64e02014-10-08 08:54:44 +00001057 const VexArchInfo*,
1058 const VexAbiInfo*,
sewardjc6f970f2012-04-02 21:54:49 +00001059 Int offs_Host_EvC_Counter,
1060 Int offs_Host_EvC_FailAddr,
1061 Bool chainingAllowed,
1062 Bool addProfInc,
floriandcd6d232015-01-02 17:32:21 +00001063 Addr max_ga );
sewardjc6f970f2012-04-02 21:54:49 +00001064
1065/* How big is an event check? This is kind of a kludge because it
1066 depends on the offsets of host_EvC_FAILADDR and
1067 host_EvC_COUNTER. */
florian7ce2cc82015-01-10 16:10:58 +00001068extern Int evCheckSzB_ARM (void);
sewardjc6f970f2012-04-02 21:54:49 +00001069
1070/* Perform a chaining and unchaining of an XDirect jump. */
sewardj9b769162014-07-24 12:42:03 +00001071extern VexInvalRange chainXDirect_ARM ( VexEndness endness_host,
1072 void* place_to_chain,
florian7d6f81d2014-09-22 21:43:37 +00001073 const void* disp_cp_chain_me_EXPECTED,
1074 const void* place_to_jump_to );
sewardjc6f970f2012-04-02 21:54:49 +00001075
sewardj9b769162014-07-24 12:42:03 +00001076extern VexInvalRange unchainXDirect_ARM ( VexEndness endness_host,
1077 void* place_to_unchain,
florian7d6f81d2014-09-22 21:43:37 +00001078 const void* place_to_jump_to_EXPECTED,
1079 const void* disp_cp_chain_me );
sewardjc6f970f2012-04-02 21:54:49 +00001080
1081/* Patch the counter location into an existing ProfInc point. */
sewardj9b769162014-07-24 12:42:03 +00001082extern VexInvalRange patchProfInc_ARM ( VexEndness endness_host,
1083 void* place_to_patch,
florian7d6f81d2014-09-22 21:43:37 +00001084 const ULong* location_of_counter );
sewardjc6f970f2012-04-02 21:54:49 +00001085
cerion05782872004-12-16 11:50:19 +00001086
sewardjcef7d3e2009-07-02 12:21:59 +00001087#endif /* ndef __VEX_HOST_ARM_DEFS_H */
cerion05782872004-12-16 11:50:19 +00001088
1089/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +00001090/*--- end host_arm_defs.h ---*/
cerion05782872004-12-16 11:50:19 +00001091/*---------------------------------------------------------------*/