blob: 384e4f5e3640dfd2b7f13ce6238ad0455b152c23 [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
sewardj89ae8472013-10-18 14:12:58 +00009 Copyright (C) 2004-2013 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
cerion1df83112004-12-16 12:10:59 +000042/* The usual HReg abstraction.
43 There are 16 general purpose regs.
cerion05782872004-12-16 11:50:19 +000044*/
45
46extern void ppHRegARM ( HReg );
47
sewardj6c299f32009-12-31 18:00:12 +000048extern HReg hregARM_R0 ( void );
49extern HReg hregARM_R1 ( void );
50extern HReg hregARM_R2 ( void );
51extern HReg hregARM_R3 ( void );
52extern HReg hregARM_R4 ( void );
53extern HReg hregARM_R5 ( void );
54extern HReg hregARM_R6 ( void );
55extern HReg hregARM_R7 ( void );
56extern HReg hregARM_R8 ( void );
57extern HReg hregARM_R9 ( void );
cerion05782872004-12-16 11:50:19 +000058extern HReg hregARM_R10 ( void );
59extern HReg hregARM_R11 ( void );
60extern HReg hregARM_R12 ( void );
61extern HReg hregARM_R13 ( void );
62extern HReg hregARM_R14 ( void );
63extern HReg hregARM_R15 ( void );
sewardj6c299f32009-12-31 18:00:12 +000064extern HReg hregARM_D8 ( void );
65extern HReg hregARM_D9 ( void );
66extern HReg hregARM_D10 ( void );
67extern HReg hregARM_D11 ( void );
68extern HReg hregARM_D12 ( void );
69extern HReg hregARM_S26 ( void );
70extern HReg hregARM_S27 ( void );
71extern HReg hregARM_S28 ( void );
72extern HReg hregARM_S29 ( void );
73extern HReg hregARM_S30 ( void );
sewardj6c60b322010-08-22 12:48:28 +000074extern HReg hregARM_Q8 ( void );
75extern HReg hregARM_Q9 ( void );
76extern HReg hregARM_Q10 ( void );
77extern HReg hregARM_Q11 ( void );
78extern HReg hregARM_Q12 ( void );
79extern HReg hregARM_Q13 ( void );
80extern HReg hregARM_Q14 ( void );
81extern HReg hregARM_Q15 ( void );
sewardj6c299f32009-12-31 18:00:12 +000082
83/* Number of registers used arg passing in function calls */
84#define ARM_N_ARGREGS 4 /* r0, r1, r2, r3 */
cerion05782872004-12-16 11:50:19 +000085
86
sewardj6c299f32009-12-31 18:00:12 +000087/* --------- Condition codes. --------- */
cerion05782872004-12-16 11:50:19 +000088
89typedef
90 enum {
sewardj6c299f32009-12-31 18:00:12 +000091 ARMcc_EQ = 0, /* equal : Z=1 */
92 ARMcc_NE = 1, /* not equal : Z=0 */
cerion05782872004-12-16 11:50:19 +000093
sewardj6c299f32009-12-31 18:00:12 +000094 ARMcc_HS = 2, /* >=u (higher or same) : C=1 */
95 ARMcc_LO = 3, /* <u (lower) : C=0 */
cerion05782872004-12-16 11:50:19 +000096
sewardj6c299f32009-12-31 18:00:12 +000097 ARMcc_MI = 4, /* minus (negative) : N=1 */
98 ARMcc_PL = 5, /* plus (zero or +ve) : N=0 */
cerion05782872004-12-16 11:50:19 +000099
sewardj6c299f32009-12-31 18:00:12 +0000100 ARMcc_VS = 6, /* overflow : V=1 */
101 ARMcc_VC = 7, /* no overflow : V=0 */
cerion05782872004-12-16 11:50:19 +0000102
sewardj6c299f32009-12-31 18:00:12 +0000103 ARMcc_HI = 8, /* >u (higher) : C=1 && Z=0 */
104 ARMcc_LS = 9, /* <=u (lower or same) : C=0 || Z=1 */
cerion05782872004-12-16 11:50:19 +0000105
sewardj6c299f32009-12-31 18:00:12 +0000106 ARMcc_GE = 10, /* >=s (signed greater or equal) : N=V */
107 ARMcc_LT = 11, /* <s (signed less than) : N!=V */
cerion05782872004-12-16 11:50:19 +0000108
sewardj6c299f32009-12-31 18:00:12 +0000109 ARMcc_GT = 12, /* >s (signed greater) : Z=0 && N=V */
110 ARMcc_LE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
cerion05782872004-12-16 11:50:19 +0000111
sewardj6c299f32009-12-31 18:00:12 +0000112 ARMcc_AL = 14, /* always (unconditional) */
113 ARMcc_NV = 15 /* never (basically undefined meaning), deprecated */
cerion05782872004-12-16 11:50:19 +0000114 }
115 ARMCondCode;
116
florian55085f82012-11-21 00:36:55 +0000117extern const HChar* showARMCondCode ( ARMCondCode );
cerion05782872004-12-16 11:50:19 +0000118
119
120
cerion05782872004-12-16 11:50:19 +0000121/* --------- Memory address expressions (amodes). --------- */
122
123/* --- Addressing Mode 1 --- */
124typedef
125 enum {
sewardj6c299f32009-12-31 18:00:12 +0000126 ARMam1_RI=1, /* reg +/- imm12 */
127 ARMam1_RRS /* reg1 + (reg2 << 0, 1 2 or 3) */
cerion05782872004-12-16 11:50:19 +0000128 }
129 ARMAMode1Tag;
130
131typedef
132 struct {
sewardj6c299f32009-12-31 18:00:12 +0000133 ARMAMode1Tag tag;
134 union {
135 struct {
136 HReg reg;
137 Int simm13; /* -4095 .. +4095 */
138 } RI;
139 struct {
140 HReg base;
141 HReg index;
142 UInt shift; /* 0, 1 2 or 3 */
143 } RRS;
144 } ARMam1;
cerion05782872004-12-16 11:50:19 +0000145 }
146 ARMAMode1;
147
sewardj6c299f32009-12-31 18:00:12 +0000148extern ARMAMode1* ARMAMode1_RI ( HReg reg, Int simm13 );
149extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
cerion05782872004-12-16 11:50:19 +0000150
151extern void ppARMAMode1 ( ARMAMode1* );
152
153
cerion05782872004-12-16 11:50:19 +0000154/* --- Addressing Mode 2 --- */
155typedef
156 enum {
sewardj6c299f32009-12-31 18:00:12 +0000157 ARMam2_RI=3, /* reg +/- imm8 */
158 ARMam2_RR /* reg1 + reg2 */
cerion05782872004-12-16 11:50:19 +0000159 }
160 ARMAMode2Tag;
161
162typedef
163 struct {
164 ARMAMode2Tag tag;
165 union {
166 struct {
sewardj6c299f32009-12-31 18:00:12 +0000167 HReg reg;
168 Int simm9; /* -255 .. 255 */
cerion05782872004-12-16 11:50:19 +0000169 } RI;
170 struct {
sewardj6c299f32009-12-31 18:00:12 +0000171 HReg base;
172 HReg index;
173 } RR;
cerion82edbb32004-12-16 14:06:34 +0000174 } ARMam2;
cerion05782872004-12-16 11:50:19 +0000175 }
176 ARMAMode2;
177
sewardj6c299f32009-12-31 18:00:12 +0000178extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
179extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
cerion05782872004-12-16 11:50:19 +0000180
181extern void ppARMAMode2 ( ARMAMode2* );
182
183
sewardj6c299f32009-12-31 18:00:12 +0000184/* --- Addressing Mode suitable for VFP --- */
185/* The simm11 is encoded as 8 bits + 1 sign bit,
186 so can only be 0 % 4. */
187typedef
188 struct {
189 HReg reg;
190 Int simm11; /* -1020, -1016 .. 1016, 1020 */
191 }
192 ARMAModeV;
193
194extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
195
196extern void ppARMAModeV ( ARMAModeV* );
197
sewardj6c60b322010-08-22 12:48:28 +0000198/* --- Addressing Mode suitable for Neon --- */
199typedef
200 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000201 ARMamN_R=5,
sewardj6c60b322010-08-22 12:48:28 +0000202 ARMamN_RR
203 /* ... */
204 }
205 ARMAModeNTag;
206
207typedef
208 struct {
209 ARMAModeNTag tag;
210 union {
211 struct {
212 HReg rN;
213 HReg rM;
214 } RR;
215 struct {
216 HReg rN;
217 } R;
218 /* ... */
219 } ARMamN;
220 }
221 ARMAModeN;
222
223extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg );
224extern ARMAModeN* mkARMAModeN_R ( HReg );
225extern void ppARMAModeN ( ARMAModeN* );
sewardj6c299f32009-12-31 18:00:12 +0000226
227/* --------- Reg or imm-8x4 operands --------- */
228/* a.k.a (a very restricted form of) Shifter Operand,
229 in the ARM parlance. */
230
cerion05782872004-12-16 11:50:19 +0000231typedef
232 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000233 ARMri84_I84=7, /* imm8 `ror` (2 * imm4) */
sewardj6c299f32009-12-31 18:00:12 +0000234 ARMri84_R /* reg */
cerion05782872004-12-16 11:50:19 +0000235 }
sewardj6c299f32009-12-31 18:00:12 +0000236 ARMRI84Tag;
cerion05782872004-12-16 11:50:19 +0000237
238typedef
239 struct {
sewardj6c299f32009-12-31 18:00:12 +0000240 ARMRI84Tag tag;
cerion05782872004-12-16 11:50:19 +0000241 union {
242 struct {
sewardj6c299f32009-12-31 18:00:12 +0000243 UShort imm8;
244 UShort imm4;
245 } I84;
cerion05782872004-12-16 11:50:19 +0000246 struct {
sewardj6c299f32009-12-31 18:00:12 +0000247 HReg reg;
248 } R;
249 } ARMri84;
cerion05782872004-12-16 11:50:19 +0000250 }
sewardj6c299f32009-12-31 18:00:12 +0000251 ARMRI84;
252
253extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
254extern ARMRI84* ARMRI84_R ( HReg );
255
256extern void ppARMRI84 ( ARMRI84* );
cerion05782872004-12-16 11:50:19 +0000257
258
sewardj6c299f32009-12-31 18:00:12 +0000259/* --------- Reg or imm5 operands --------- */
cerion05782872004-12-16 11:50:19 +0000260typedef
261 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000262 ARMri5_I5=9, /* imm5, 1 .. 31 only (no zero!) */
sewardj6c299f32009-12-31 18:00:12 +0000263 ARMri5_R /* reg */
cerion05782872004-12-16 11:50:19 +0000264 }
sewardj6c299f32009-12-31 18:00:12 +0000265 ARMRI5Tag;
cerion05782872004-12-16 11:50:19 +0000266
267typedef
sewardj6c299f32009-12-31 18:00:12 +0000268 struct {
269 ARMRI5Tag tag;
cerion05782872004-12-16 11:50:19 +0000270 union {
sewardj6c299f32009-12-31 18:00:12 +0000271 struct {
272 UInt imm5;
273 } I5;
274 struct {
275 HReg reg;
276 } R;
277 } ARMri5;
278 }
279 ARMRI5;
cerion05782872004-12-16 11:50:19 +0000280
sewardj6c299f32009-12-31 18:00:12 +0000281extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
282extern ARMRI5* ARMRI5_R ( HReg );
cerion82edbb32004-12-16 14:06:34 +0000283
sewardj6c299f32009-12-31 18:00:12 +0000284extern void ppARMRI5 ( ARMRI5* );
cerion05782872004-12-16 11:50:19 +0000285
sewardj6c60b322010-08-22 12:48:28 +0000286/* -------- Neon Immediate operand -------- */
287
288/* imm8 = abcdefgh, B = NOT(b);
289
290type | value (64bit binary)
291-----+-------------------------------------------------------------------------
292 0 | 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh
293 1 | 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000
294 2 | 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000
295 3 | abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000
296 4 | 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh
297 5 | abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000
298 6 | abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh
299 7 | 00000000 00000000 abcdefgh 11111111 00000000 00000000 abcdefgh 11111111
300 8 | 00000000 abcdefgh 11111111 11111111 00000000 abcdefgh 11111111 11111111
301 9 | aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
302 10 | aBbbbbbc defgh000 00000000 00000000 aBbbbbbc defgh000 00000000 00000000
303-----+-------------------------------------------------------------------------
304
305Type 10 is:
306 (-1)^S * 2^exp * mantissa
307where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16
308*/
309
310typedef
311 struct {
312 UInt type;
313 UInt imm8;
314 }
315 ARMNImm;
316
317extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 );
318extern ULong ARMNImm_to_Imm64 ( ARMNImm* );
319extern ARMNImm* Imm64_to_ARMNImm ( ULong );
320
321extern void ppARMNImm ( ARMNImm* );
322
323/* ------ Neon Register or Scalar Operand ------ */
324
325typedef
326 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000327 ARMNRS_Reg=11,
sewardj6c60b322010-08-22 12:48:28 +0000328 ARMNRS_Scalar
329 }
330 ARMNRS_tag;
331
332typedef
333 struct {
334 ARMNRS_tag tag;
335 HReg reg;
336 UInt index;
337 }
338 ARMNRS;
339
340extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index);
341extern void ppARMNRS ( ARMNRS* );
cerion05782872004-12-16 11:50:19 +0000342
343/* --------- Instructions. --------- */
344
cerion05782872004-12-16 11:50:19 +0000345/* --------- */
346typedef
347 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000348 ARMalu_ADD=20, /* plain 32-bit add */
sewardj6c299f32009-12-31 18:00:12 +0000349 ARMalu_ADDS, /* 32-bit add, and set the flags */
350 ARMalu_ADC, /* 32-bit add with carry */
351 ARMalu_SUB, /* plain 32-bit subtract */
352 ARMalu_SUBS, /* 32-bit subtract, and set the flags */
353 ARMalu_SBC, /* 32-bit subtract with carry */
354 ARMalu_AND,
355 ARMalu_BIC,
356 ARMalu_OR,
357 ARMalu_XOR
358 }
359 ARMAluOp;
cerion05782872004-12-16 11:50:19 +0000360
florian55085f82012-11-21 00:36:55 +0000361extern const HChar* showARMAluOp ( ARMAluOp op );
cerion05782872004-12-16 11:50:19 +0000362
sewardj6c299f32009-12-31 18:00:12 +0000363
364typedef
365 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000366 ARMsh_SHL=40,
sewardj6c299f32009-12-31 18:00:12 +0000367 ARMsh_SHR,
368 ARMsh_SAR
369 }
370 ARMShiftOp;
371
florian55085f82012-11-21 00:36:55 +0000372extern const HChar* showARMShiftOp ( ARMShiftOp op );
sewardj6c299f32009-12-31 18:00:12 +0000373
374
375typedef
376 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000377 ARMun_NEG=50,
sewardj6c299f32009-12-31 18:00:12 +0000378 ARMun_NOT,
379 ARMun_CLZ
380 }
381 ARMUnaryOp;
382
florian55085f82012-11-21 00:36:55 +0000383extern const HChar* showARMUnaryOp ( ARMUnaryOp op );
sewardj6c299f32009-12-31 18:00:12 +0000384
385
386typedef
387 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000388 ARMmul_PLAIN=60,
sewardj6c299f32009-12-31 18:00:12 +0000389 ARMmul_ZX,
390 ARMmul_SX
391 }
392 ARMMulOp;
393
florian55085f82012-11-21 00:36:55 +0000394extern const HChar* showARMMulOp ( ARMMulOp op );
sewardj6c299f32009-12-31 18:00:12 +0000395
396
397typedef
398 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000399 ARMvfp_ADD=70,
sewardj6c299f32009-12-31 18:00:12 +0000400 ARMvfp_SUB,
401 ARMvfp_MUL,
402 ARMvfp_DIV
403 }
404 ARMVfpOp;
405
florian55085f82012-11-21 00:36:55 +0000406extern const HChar* showARMVfpOp ( ARMVfpOp op );
sewardj6c299f32009-12-31 18:00:12 +0000407
408
409typedef
410 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000411 ARMvfpu_COPY=80,
sewardj6c299f32009-12-31 18:00:12 +0000412 ARMvfpu_NEG,
413 ARMvfpu_ABS,
414 ARMvfpu_SQRT
415 }
416 ARMVfpUnaryOp;
417
florian55085f82012-11-21 00:36:55 +0000418extern const HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
sewardj6c299f32009-12-31 18:00:12 +0000419
sewardj6c60b322010-08-22 12:48:28 +0000420typedef
421 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000422 ARMneon_VAND=90,
sewardj6c60b322010-08-22 12:48:28 +0000423 ARMneon_VORR,
424 ARMneon_VXOR,
425 ARMneon_VADD,
426 ARMneon_VADDFP,
427 ARMneon_VRHADDS,
428 ARMneon_VRHADDU,
429 ARMneon_VPADDFP,
430 ARMneon_VABDFP,
431 ARMneon_VSUB,
432 ARMneon_VSUBFP,
433 ARMneon_VMAXU,
434 ARMneon_VMAXS,
435 ARMneon_VMAXF,
436 ARMneon_VMINU,
437 ARMneon_VMINS,
438 ARMneon_VMINF,
439 ARMneon_VQADDU,
440 ARMneon_VQADDS,
441 ARMneon_VQSUBU,
442 ARMneon_VQSUBS,
443 ARMneon_VCGTU,
444 ARMneon_VCGTS,
445 ARMneon_VCGEU,
446 ARMneon_VCGES,
447 ARMneon_VCGTF,
448 ARMneon_VCGEF,
449 ARMneon_VCEQ,
450 ARMneon_VCEQF,
451 ARMneon_VEXT,
452 ARMneon_VMUL,
453 ARMneon_VMULFP,
454 ARMneon_VMULLU,
455 ARMneon_VMULLS,
456 ARMneon_VMULP,
457 ARMneon_VMULLP,
458 ARMneon_VQDMULH,
459 ARMneon_VQRDMULH,
460 ARMneon_VPADD,
461 ARMneon_VPMINU,
462 ARMneon_VPMINS,
463 ARMneon_VPMINF,
464 ARMneon_VPMAXU,
465 ARMneon_VPMAXS,
466 ARMneon_VPMAXF,
467 ARMneon_VTBL,
468 ARMneon_VQDMULL,
sewardj6c60b322010-08-22 12:48:28 +0000469 ARMneon_VRECPS,
sewardj6c60b322010-08-22 12:48:28 +0000470 ARMneon_VRSQRTS,
sewardje84eeb42014-03-15 11:41:39 +0000471 ARMneon_INVALID
sewardj6c60b322010-08-22 12:48:28 +0000472 /* ... */
473 }
474 ARMNeonBinOp;
475
476typedef
477 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000478 ARMneon_VSHL=150,
sewardj6c60b322010-08-22 12:48:28 +0000479 ARMneon_VSAL, /* Yah, not SAR but SAL */
480 ARMneon_VQSHL,
481 ARMneon_VQSAL
482 }
483 ARMNeonShiftOp;
484
485typedef
486 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000487 ARMneon_COPY=160,
sewardj6c60b322010-08-22 12:48:28 +0000488 ARMneon_COPYLU,
489 ARMneon_COPYLS,
490 ARMneon_COPYN,
491 ARMneon_COPYQNSS,
492 ARMneon_COPYQNUS,
493 ARMneon_COPYQNUU,
494 ARMneon_NOT,
495 ARMneon_EQZ,
496 ARMneon_DUP,
497 ARMneon_PADDLS,
498 ARMneon_PADDLU,
499 ARMneon_CNT,
500 ARMneon_CLZ,
501 ARMneon_CLS,
502 ARMneon_VCVTxFPxINT,
503 ARMneon_VQSHLNSS,
504 ARMneon_VQSHLNUU,
505 ARMneon_VQSHLNUS,
506 ARMneon_VCVTFtoU,
507 ARMneon_VCVTFtoS,
508 ARMneon_VCVTUtoF,
509 ARMneon_VCVTStoF,
510 ARMneon_VCVTFtoFixedU,
511 ARMneon_VCVTFtoFixedS,
512 ARMneon_VCVTFixedUtoF,
513 ARMneon_VCVTFixedStoF,
514 ARMneon_VCVTF16toF32,
515 ARMneon_VCVTF32toF16,
516 ARMneon_REV16,
517 ARMneon_REV32,
518 ARMneon_REV64,
519 ARMneon_ABS,
520 ARMneon_VNEGF,
sewardj6aa87a62010-10-06 20:34:53 +0000521 ARMneon_VRECIP,
522 ARMneon_VRECIPF,
523 ARMneon_VABSFP,
524 ARMneon_VRSQRTEFP,
525 ARMneon_VRSQRTE
sewardj6c60b322010-08-22 12:48:28 +0000526 /* ... */
527 }
528 ARMNeonUnOp;
529
530typedef
531 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000532 ARMneon_SETELEM=200,
sewardj6c60b322010-08-22 12:48:28 +0000533 ARMneon_GETELEMU,
sewardj6aa87a62010-10-06 20:34:53 +0000534 ARMneon_GETELEMS,
535 ARMneon_VDUP,
sewardj6c60b322010-08-22 12:48:28 +0000536 }
537 ARMNeonUnOpS;
538
539typedef
540 enum {
sewardjb48eddb2010-10-04 09:34:46 +0000541 ARMneon_TRN=210,
sewardj6c60b322010-08-22 12:48:28 +0000542 ARMneon_ZIP,
543 ARMneon_UZP
544 /* ... */
545 }
546 ARMNeonDualOp;
547
florian55085f82012-11-21 00:36:55 +0000548extern const HChar* showARMNeonBinOp ( ARMNeonBinOp op );
549extern const HChar* showARMNeonUnOp ( ARMNeonUnOp op );
550extern const HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
551extern const HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
552extern const HChar* showARMNeonDualOp ( ARMNeonDualOp op );
553extern const HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
554extern const HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
555extern const HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
556extern const HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
557extern const HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
sewardj6c299f32009-12-31 18:00:12 +0000558
559typedef
560 enum {
561 /* baseline */
sewardjb48eddb2010-10-04 09:34:46 +0000562 ARMin_Alu=220,
sewardj6c299f32009-12-31 18:00:12 +0000563 ARMin_Shift,
564 ARMin_Unary,
565 ARMin_CmpOrTst,
566 ARMin_Mov,
567 ARMin_Imm32,
568 ARMin_LdSt32,
569 ARMin_LdSt16,
570 ARMin_LdSt8U,
571 ARMin_Ld8S,
sewardjc6f970f2012-04-02 21:54:49 +0000572 ARMin_XDirect, /* direct transfer to GA */
573 ARMin_XIndir, /* indirect transfer to GA */
574 ARMin_XAssisted, /* assisted transfer to GA */
sewardj6c299f32009-12-31 18:00:12 +0000575 ARMin_CMov,
576 ARMin_Call,
577 ARMin_Mul,
578 ARMin_LdrEX,
579 ARMin_StrEX,
580 /* vfp */
581 ARMin_VLdStD,
582 ARMin_VLdStS,
583 ARMin_VAluD,
584 ARMin_VAluS,
585 ARMin_VUnaryD,
586 ARMin_VUnaryS,
587 ARMin_VCmpD,
588 ARMin_VCMovD,
589 ARMin_VCMovS,
590 ARMin_VCvtSD,
591 ARMin_VXferD,
592 ARMin_VXferS,
593 ARMin_VCvtID,
sewardj412098c2010-05-04 08:48:43 +0000594 ARMin_FPSCR,
sewardj6c60b322010-08-22 12:48:28 +0000595 ARMin_MFence,
sewardj6d615ba2011-09-26 16:19:43 +0000596 ARMin_CLREX,
sewardj6c60b322010-08-22 12:48:28 +0000597 /* Neon */
598 ARMin_NLdStQ,
599 ARMin_NLdStD,
600 ARMin_NUnary,
601 ARMin_NUnaryS,
602 ARMin_NDual,
603 ARMin_NBinary,
604 ARMin_NBinaryS,
605 ARMin_NShift,
sewardjf78a81c2013-04-21 00:45:18 +0000606 ARMin_NShl64, // special case 64-bit shift of Dreg by immediate
sewardj6c60b322010-08-22 12:48:28 +0000607 ARMin_NeonImm,
608 ARMin_NCMovQ,
609 /* This is not a NEON instruction. Actually there is no corresponding
610 instruction in ARM instruction set at all. We need this one to
611 generate spill/reload of 128-bit registers since current register
612 allocator demands them to consist of no more than two instructions.
613 We will split this instruction into 2 or 3 ARM instructions on the
614 emiting phase.
sewardj6c60b322010-08-22 12:48:28 +0000615 NOTE: source and destination registers should be different! */
sewardjc6f970f2012-04-02 21:54:49 +0000616 ARMin_Add32,
617 ARMin_EvCheck, /* Event check */
618 ARMin_ProfInc /* 64-bit profile counter increment */
cerion05782872004-12-16 11:50:19 +0000619 }
620 ARMInstrTag;
621
sewardj6c299f32009-12-31 18:00:12 +0000622/* Destinations are on the LEFT (first operand) */
cerion05782872004-12-16 11:50:19 +0000623
624typedef
625 struct {
626 ARMInstrTag tag;
627 union {
sewardj6c299f32009-12-31 18:00:12 +0000628 /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
629 struct {
630 ARMAluOp op;
631 HReg dst;
632 HReg argL;
633 ARMRI84* argR;
634 } Alu;
635 /* SHL/SHR/SAR, 2nd arg is reg or imm */
636 struct {
637 ARMShiftOp op;
638 HReg dst;
639 HReg argL;
640 ARMRI5* argR;
641 } Shift;
642 /* NOT/NEG/CLZ */
643 struct {
644 ARMUnaryOp op;
645 HReg dst;
646 HReg src;
647 } Unary;
648 /* CMP/TST; subtract/and, discard result, set NZCV */
649 struct {
650 Bool isCmp;
651 HReg argL;
652 ARMRI84* argR;
653 } CmpOrTst;
654 /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
655 struct {
656 HReg dst;
657 ARMRI84* src;
658 } Mov;
659 /* Pseudo-insn; make a 32-bit immediate */
660 struct {
661 HReg dst;
662 UInt imm32;
663 } Imm32;
sewardjcfe046e2013-01-17 14:23:53 +0000664 /* 32-bit load or store, may be conditional */
sewardj6c299f32009-12-31 18:00:12 +0000665 struct {
sewardjcfe046e2013-01-17 14:23:53 +0000666 ARMCondCode cc; /* ARMcc_NV is not allowed */
667 Bool isLoad;
668 HReg rD;
669 ARMAMode1* amode;
sewardj6c299f32009-12-31 18:00:12 +0000670 } LdSt32;
sewardjcfe046e2013-01-17 14:23:53 +0000671 /* 16-bit load or store, may be conditional */
sewardj6c299f32009-12-31 18:00:12 +0000672 struct {
sewardjcfe046e2013-01-17 14:23:53 +0000673 ARMCondCode cc; /* ARMcc_NV is not allowed */
674 Bool isLoad;
675 Bool signedLoad;
676 HReg rD;
677 ARMAMode2* amode;
sewardj6c299f32009-12-31 18:00:12 +0000678 } LdSt16;
sewardjcfe046e2013-01-17 14:23:53 +0000679 /* 8-bit (unsigned) load or store, may be conditional */
sewardj6c299f32009-12-31 18:00:12 +0000680 struct {
sewardjcfe046e2013-01-17 14:23:53 +0000681 ARMCondCode cc; /* ARMcc_NV is not allowed */
682 Bool isLoad;
683 HReg rD;
684 ARMAMode1* amode;
sewardj6c299f32009-12-31 18:00:12 +0000685 } LdSt8U;
sewardjcfe046e2013-01-17 14:23:53 +0000686 /* 8-bit signed load, may be conditional */
sewardj6c299f32009-12-31 18:00:12 +0000687 struct {
sewardjcfe046e2013-01-17 14:23:53 +0000688 ARMCondCode cc; /* ARMcc_NV is not allowed */
689 HReg rD;
690 ARMAMode2* amode;
sewardj6c299f32009-12-31 18:00:12 +0000691 } Ld8S;
sewardjc6f970f2012-04-02 21:54:49 +0000692 /* Update the guest R15T value, then exit requesting to chain
693 to it. May be conditional. Urr, use of Addr32 implicitly
694 assumes that wordsize(guest) == wordsize(host). */
sewardj6c299f32009-12-31 18:00:12 +0000695 struct {
sewardjc6f970f2012-04-02 21:54:49 +0000696 Addr32 dstGA; /* next guest address */
697 ARMAMode1* amR15T; /* amode in guest state for R15T */
698 ARMCondCode cond; /* can be ARMcc_AL */
699 Bool toFastEP; /* chain to the slow or fast point? */
700 } XDirect;
701 /* Boring transfer to a guest address not known at JIT time.
702 Not chainable. May be conditional. */
703 struct {
704 HReg dstGA;
705 ARMAMode1* amR15T;
706 ARMCondCode cond; /* can be ARMcc_AL */
707 } XIndir;
708 /* Assisted transfer to a guest address, most general case.
709 Not chainable. May be conditional. */
710 struct {
711 HReg dstGA;
712 ARMAMode1* amR15T;
713 ARMCondCode cond; /* can be ARMcc_AL */
sewardj6c299f32009-12-31 18:00:12 +0000714 IRJumpKind jk;
sewardjc6f970f2012-04-02 21:54:49 +0000715 } XAssisted;
sewardj6c299f32009-12-31 18:00:12 +0000716 /* Mov src to dst on the given condition, which may not
717 be ARMcc_AL. */
718 struct {
719 ARMCondCode cond;
720 HReg dst;
721 ARMRI84* src;
722 } CMov;
723 /* Pseudo-insn. Call target (an absolute address), on given
724 condition (which could be ARMcc_AL). */
725 struct {
726 ARMCondCode cond;
727 HWord target;
728 Int nArgRegs; /* # regs carrying args: 0 .. 4 */
sewardjcfe046e2013-01-17 14:23:53 +0000729 RetLoc rloc; /* where the return value will be */
sewardj6c299f32009-12-31 18:00:12 +0000730 } Call;
731 /* (PLAIN) 32 * 32 -> 32: r0 = r2 * r3
732 (ZX) 32 *u 32 -> 64: r1:r0 = r2 *u r3
733 (SX) 32 *s 32 -> 64: r1:r0 = r2 *s r3
734 Why hardwired registers? Because the ARM ARM specifies
735 (eg for straight MUL) the result (Rd) and the left arg (Rm)
736 may not be the same register. That's not a constraint we
737 can enforce in the register allocator (without mucho extra
738 complexity). Hence hardwire it. At least using caller-saves
739 registers, which are less likely to be in use. */
740 struct {
741 ARMMulOp op;
742 } Mul;
sewardjff7f5b72011-07-11 11:43:38 +0000743 /* LDREX{,H,B} r2, [r4] and
744 LDREXD r2, r3, [r4] (on LE hosts, transferred value is r3:r2)
sewardj6c299f32009-12-31 18:00:12 +0000745 Again, hardwired registers since this is not performance
746 critical, and there are possibly constraints on the
747 registers that we can't express in the register allocator.*/
748 struct {
sewardjff7f5b72011-07-11 11:43:38 +0000749 Int szB; /* 1, 2, 4 or 8 */
sewardj6c299f32009-12-31 18:00:12 +0000750 } LdrEX;
sewardjff7f5b72011-07-11 11:43:38 +0000751 /* STREX{,H,B} r0, r2, [r4] and
752 STREXD r0, r2, r3, [r4] (on LE hosts, transferred value is r3:r2)
753 r0 = SC( [r4] = r2 ) (8, 16, 32 bit transfers)
754 r0 = SC( [r4] = r3:r2) (64 bit transfers)
sewardj6c299f32009-12-31 18:00:12 +0000755 Ditto comment re fixed registers. */
756 struct {
sewardjff7f5b72011-07-11 11:43:38 +0000757 Int szB; /* 1, 2, 4 or 8 */
sewardj6c299f32009-12-31 18:00:12 +0000758 } StrEX;
759 /* VFP INSTRUCTIONS */
760 /* 64-bit Fp load/store */
761 struct {
762 Bool isLoad;
763 HReg dD;
764 ARMAModeV* amode;
765 } VLdStD;
766 /* 32-bit Fp load/store */
767 struct {
768 Bool isLoad;
769 HReg fD;
770 ARMAModeV* amode;
771 } VLdStS;
772 /* 64-bit FP binary arithmetic */
773 struct {
774 ARMVfpOp op;
775 HReg dst;
776 HReg argL;
777 HReg argR;
778 } VAluD;
779 /* 32-bit FP binary arithmetic */
780 struct {
781 ARMVfpOp op;
782 HReg dst;
783 HReg argL;
784 HReg argR;
785 } VAluS;
786 /* 64-bit FP unary, also reg-reg move */
787 struct {
788 ARMVfpUnaryOp op;
789 HReg dst;
790 HReg src;
791 } VUnaryD;
792 /* 32-bit FP unary, also reg-reg move */
793 struct {
794 ARMVfpUnaryOp op;
795 HReg dst;
796 HReg src;
797 } VUnaryS;
798 /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
799 struct {
800 HReg argL;
801 HReg argR;
802 } VCmpD;
803 /* 64-bit FP mov src to dst on the given condition, which may
804 not be ARMcc_AL. */
805 struct {
806 ARMCondCode cond;
807 HReg dst;
808 HReg src;
809 } VCMovD;
810 /* 32-bit FP mov src to dst on the given condition, which may
811 not be ARMcc_AL. */
812 struct {
813 ARMCondCode cond;
814 HReg dst;
815 HReg src;
816 } VCMovS;
817 /* Convert between 32-bit and 64-bit FP values (both ways).
818 (FCVTSD, FCVTDS) */
819 struct {
820 Bool sToD; /* True: F32->F64. False: F64->F32 */
821 HReg dst;
822 HReg src;
823 } VCvtSD;
824 /* Transfer a VFP D reg to/from two integer registers (VMOV) */
825 struct {
826 Bool toD;
827 HReg dD;
828 HReg rHi;
829 HReg rLo;
830 } VXferD;
831 /* Transfer a VFP S reg to/from an integer register (VMOV) */
832 struct {
833 Bool toS;
834 HReg fD;
835 HReg rLo;
836 } VXferS;
837 /* Convert between 32-bit ints and 64-bit FP values (both ways
838 and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
839 struct {
840 Bool iToD; /* True: I32->F64. False: F64->I32 */
841 Bool syned; /* True: I32 is signed. False: I32 is unsigned */
842 HReg dst;
843 HReg src;
844 } VCvtID;
845 /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
846 struct {
847 Bool toFPSCR;
848 HReg iReg;
849 } FPSCR;
sewardj412098c2010-05-04 08:48:43 +0000850 /* Mem fence. An insn which fences all loads and stores as
851 much as possible before continuing. On ARM we emit the
852 sequence
853 mcr 15,0,r0,c7,c10,4 (DSB)
854 mcr 15,0,r0,c7,c10,5 (DMB)
855 mcr 15,0,r0,c7,c5,4 (ISB)
856 which is probably total overkill, but better safe than
857 sorry.
858 */
859 struct {
860 } MFence;
sewardj6d615ba2011-09-26 16:19:43 +0000861 /* A CLREX instruction. */
862 struct {
863 } CLREX;
sewardj6c60b322010-08-22 12:48:28 +0000864 /* Neon data processing instruction: 3 registers of the same
865 length */
866 struct {
867 ARMNeonBinOp op;
868 HReg dst;
869 HReg argL;
870 HReg argR;
871 UInt size;
872 Bool Q;
873 } NBinary;
874 struct {
875 ARMNeonBinOp op;
876 ARMNRS* dst;
877 ARMNRS* argL;
878 ARMNRS* argR;
879 UInt size;
880 Bool Q;
881 } NBinaryS;
882 struct {
883 ARMNeonShiftOp op;
884 HReg dst;
885 HReg argL;
886 HReg argR;
887 UInt size;
888 Bool Q;
889 } NShift;
890 struct {
sewardjf78a81c2013-04-21 00:45:18 +0000891 HReg dst;
892 HReg src;
893 UInt amt; /* 1..63 only */
894 } NShl64;
895 struct {
sewardj6c60b322010-08-22 12:48:28 +0000896 Bool isLoad;
897 HReg dQ;
898 ARMAModeN *amode;
899 } NLdStQ;
900 struct {
901 Bool isLoad;
902 HReg dD;
903 ARMAModeN *amode;
904 } NLdStD;
905 struct {
sewardj6aa87a62010-10-06 20:34:53 +0000906 ARMNeonUnOpS op;
sewardj6c60b322010-08-22 12:48:28 +0000907 ARMNRS* dst;
908 ARMNRS* src;
909 UInt size;
910 Bool Q;
911 } NUnaryS;
912 struct {
913 ARMNeonUnOp op;
914 HReg dst;
915 HReg src;
916 UInt size;
917 Bool Q;
918 } NUnary;
919 /* Takes two arguments and modifies them both. */
920 struct {
921 ARMNeonDualOp op;
922 HReg arg1;
923 HReg arg2;
924 UInt size;
925 Bool Q;
926 } NDual;
927 struct {
928 HReg dst;
929 ARMNImm* imm;
930 } NeonImm;
931 /* 128-bit Neon move src to dst on the given condition, which
932 may not be ARMcc_AL. */
933 struct {
934 ARMCondCode cond;
935 HReg dst;
936 HReg src;
937 } NCMovQ;
938 struct {
939 /* Note: rD != rN */
940 HReg rD;
941 HReg rN;
942 UInt imm32;
943 } Add32;
sewardjc6f970f2012-04-02 21:54:49 +0000944 struct {
945 ARMAMode1* amCounter;
946 ARMAMode1* amFailAddr;
947 } EvCheck;
948 struct {
949 /* No fields. The address of the counter to inc is
950 installed later, post-translation, by patching it in,
951 as it is not known at translation time. */
952 } ProfInc;
cerion05782872004-12-16 11:50:19 +0000953 } ARMin;
954 }
955 ARMInstr;
956
cerion05782872004-12-16 11:50:19 +0000957
sewardj6c299f32009-12-31 18:00:12 +0000958extern ARMInstr* ARMInstr_Alu ( ARMAluOp, HReg, HReg, ARMRI84* );
959extern ARMInstr* ARMInstr_Shift ( ARMShiftOp, HReg, HReg, ARMRI5* );
960extern ARMInstr* ARMInstr_Unary ( ARMUnaryOp, HReg, HReg );
961extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
962extern ARMInstr* ARMInstr_Mov ( HReg, ARMRI84* );
963extern ARMInstr* ARMInstr_Imm32 ( HReg, UInt );
sewardjcfe046e2013-01-17 14:23:53 +0000964extern ARMInstr* ARMInstr_LdSt32 ( ARMCondCode,
965 Bool isLoad, HReg, ARMAMode1* );
966extern ARMInstr* ARMInstr_LdSt16 ( ARMCondCode,
967 Bool isLoad, Bool signedLoad,
sewardj6c299f32009-12-31 18:00:12 +0000968 HReg, ARMAMode2* );
sewardjcfe046e2013-01-17 14:23:53 +0000969extern ARMInstr* ARMInstr_LdSt8U ( ARMCondCode,
970 Bool isLoad, HReg, ARMAMode1* );
971extern ARMInstr* ARMInstr_Ld8S ( ARMCondCode, HReg, ARMAMode2* );
sewardjc6f970f2012-04-02 21:54:49 +0000972extern ARMInstr* ARMInstr_XDirect ( Addr32 dstGA, ARMAMode1* amR15T,
973 ARMCondCode cond, Bool toFastEP );
974extern ARMInstr* ARMInstr_XIndir ( HReg dstGA, ARMAMode1* amR15T,
975 ARMCondCode cond );
976extern ARMInstr* ARMInstr_XAssisted ( HReg dstGA, ARMAMode1* amR15T,
977 ARMCondCode cond, IRJumpKind jk );
sewardj6c299f32009-12-31 18:00:12 +0000978extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src );
sewardjcfe046e2013-01-17 14:23:53 +0000979extern ARMInstr* ARMInstr_Call ( ARMCondCode, HWord, Int nArgRegs,
980 RetLoc rloc );
sewardj6c299f32009-12-31 18:00:12 +0000981extern ARMInstr* ARMInstr_Mul ( ARMMulOp op );
982extern ARMInstr* ARMInstr_LdrEX ( Int szB );
983extern ARMInstr* ARMInstr_StrEX ( Int szB );
984extern ARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg, ARMAModeV* );
985extern ARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg, ARMAModeV* );
986extern ARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg, HReg, HReg );
987extern ARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg, HReg, HReg );
988extern ARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp, HReg dst, HReg src );
989extern ARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp, HReg dst, HReg src );
990extern ARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR );
991extern ARMInstr* ARMInstr_VCMovD ( ARMCondCode, HReg dst, HReg src );
992extern ARMInstr* ARMInstr_VCMovS ( ARMCondCode, HReg dst, HReg src );
993extern ARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src );
994extern ARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo );
995extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo );
996extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned,
997 HReg dst, HReg src );
998extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg );
sewardj412098c2010-05-04 08:48:43 +0000999extern ARMInstr* ARMInstr_MFence ( void );
sewardj6d615ba2011-09-26 16:19:43 +00001000extern ARMInstr* ARMInstr_CLREX ( void );
sewardj6c60b322010-08-22 12:48:28 +00001001extern ARMInstr* ARMInstr_NLdStQ ( Bool isLoad, HReg, ARMAModeN* );
1002extern ARMInstr* ARMInstr_NLdStD ( Bool isLoad, HReg, ARMAModeN* );
1003extern ARMInstr* ARMInstr_NUnary ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
sewardjcb9ad0d2011-04-27 07:02:44 +00001004extern ARMInstr* ARMInstr_NUnaryS ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
sewardj6c60b322010-08-22 12:48:28 +00001005 UInt, Bool );
1006extern ARMInstr* ARMInstr_NDual ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
1007extern ARMInstr* ARMInstr_NBinary ( ARMNeonBinOp, HReg, HReg, HReg,
1008 UInt, Bool );
1009extern ARMInstr* ARMInstr_NShift ( ARMNeonShiftOp, HReg, HReg, HReg,
1010 UInt, Bool );
sewardjf78a81c2013-04-21 00:45:18 +00001011extern ARMInstr* ARMInstr_NShl64 ( HReg, HReg, UInt );
sewardj6c60b322010-08-22 12:48:28 +00001012extern ARMInstr* ARMInstr_NeonImm ( HReg, ARMNImm* );
1013extern ARMInstr* ARMInstr_NCMovQ ( ARMCondCode, HReg, HReg );
1014extern ARMInstr* ARMInstr_Add32 ( HReg rD, HReg rN, UInt imm32 );
sewardjc6f970f2012-04-02 21:54:49 +00001015extern ARMInstr* ARMInstr_EvCheck ( ARMAMode1* amCounter,
1016 ARMAMode1* amFailAddr );
1017extern ARMInstr* ARMInstr_ProfInc ( void );
cerion05782872004-12-16 11:50:19 +00001018
floriand8c64e02014-10-08 08:54:44 +00001019extern void ppARMInstr ( const ARMInstr* );
cerion05782872004-12-16 11:50:19 +00001020
1021
cerion05782872004-12-16 11:50:19 +00001022/* Some functions that insulate the register allocator from details
1023 of the underlying instruction set. */
floriand8c64e02014-10-08 08:54:44 +00001024extern void getRegUsage_ARMInstr ( HRegUsage*, const ARMInstr*, Bool );
sewardj6c299f32009-12-31 18:00:12 +00001025extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool );
floriand8c64e02014-10-08 08:54:44 +00001026extern Bool isMove_ARMInstr ( const ARMInstr*, HReg*, HReg* );
sewardjc6f970f2012-04-02 21:54:49 +00001027extern Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc,
floriand8c64e02014-10-08 08:54:44 +00001028 UChar* buf, Int nbuf, const ARMInstr* i,
sewardjc6f970f2012-04-02 21:54:49 +00001029 Bool mode64,
sewardj9b769162014-07-24 12:42:03 +00001030 VexEndness endness_host,
florian8462d112014-09-24 15:18:09 +00001031 const void* disp_cp_chain_me_to_slowEP,
1032 const void* disp_cp_chain_me_to_fastEP,
1033 const void* disp_cp_xindir,
1034 const void* disp_cp_xassisted );
sewardj6c299f32009-12-31 18:00:12 +00001035
1036extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1037 HReg rreg, Int offset, Bool );
1038extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1039 HReg rreg, Int offset, Bool );
1040
1041extern void getAllocableRegs_ARM ( Int*, HReg** );
floriancacba8e2014-12-15 18:58:07 +00001042extern HInstrArray* iselSB_ARM ( const IRSB*,
sewardjc6f970f2012-04-02 21:54:49 +00001043 VexArch,
floriand8c64e02014-10-08 08:54:44 +00001044 const VexArchInfo*,
1045 const VexAbiInfo*,
sewardjc6f970f2012-04-02 21:54:49 +00001046 Int offs_Host_EvC_Counter,
1047 Int offs_Host_EvC_FailAddr,
1048 Bool chainingAllowed,
1049 Bool addProfInc,
floriandcd6d232015-01-02 17:32:21 +00001050 Addr max_ga );
sewardjc6f970f2012-04-02 21:54:49 +00001051
1052/* How big is an event check? This is kind of a kludge because it
1053 depends on the offsets of host_EvC_FAILADDR and
1054 host_EvC_COUNTER. */
sewardj9b769162014-07-24 12:42:03 +00001055extern Int evCheckSzB_ARM ( VexEndness endness_host );
sewardjc6f970f2012-04-02 21:54:49 +00001056
1057/* Perform a chaining and unchaining of an XDirect jump. */
sewardj9b769162014-07-24 12:42:03 +00001058extern VexInvalRange chainXDirect_ARM ( VexEndness endness_host,
1059 void* place_to_chain,
florian7d6f81d2014-09-22 21:43:37 +00001060 const void* disp_cp_chain_me_EXPECTED,
1061 const void* place_to_jump_to );
sewardjc6f970f2012-04-02 21:54:49 +00001062
sewardj9b769162014-07-24 12:42:03 +00001063extern VexInvalRange unchainXDirect_ARM ( VexEndness endness_host,
1064 void* place_to_unchain,
florian7d6f81d2014-09-22 21:43:37 +00001065 const void* place_to_jump_to_EXPECTED,
1066 const void* disp_cp_chain_me );
sewardjc6f970f2012-04-02 21:54:49 +00001067
1068/* Patch the counter location into an existing ProfInc point. */
sewardj9b769162014-07-24 12:42:03 +00001069extern VexInvalRange patchProfInc_ARM ( VexEndness endness_host,
1070 void* place_to_patch,
florian7d6f81d2014-09-22 21:43:37 +00001071 const ULong* location_of_counter );
sewardjc6f970f2012-04-02 21:54:49 +00001072
cerion05782872004-12-16 11:50:19 +00001073
sewardjcef7d3e2009-07-02 12:21:59 +00001074#endif /* ndef __VEX_HOST_ARM_DEFS_H */
cerion05782872004-12-16 11:50:19 +00001075
1076/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +00001077/*--- end host_arm_defs.h ---*/
cerion05782872004-12-16 11:50:19 +00001078/*---------------------------------------------------------------*/