1 /*---------------------------------------------------------------*/
2 /*--- begin host_arm_defs.h ---*/
3 /*---------------------------------------------------------------*/
4
5 /*
6 This file is part of Valgrind, a dynamic binary instrumentation
7 framework.
8
9 Copyright (C) 2004-2015 OpenWorks LLP
10 info@open-works.net
11
12 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.
16
17 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
25 02110-1301, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28 */
29
30 #ifndef __VEX_HOST_ARM_DEFS_H
31 #define __VEX_HOST_ARM_DEFS_H
32
33 #include "libvex_basictypes.h"
34 #include "libvex.h" // VexArch
35 #include "host_generic_regs.h" // HReg
36
37 extern UInt arm_hwcaps;
38
39
40 /* --------- Registers. --------- */
41
42 #define ST_IN static inline
hregARM_R4(void)43 ST_IN HReg hregARM_R4 ( void ) { return mkHReg(False, HRcInt32, 4, 0); }
hregARM_R5(void)44 ST_IN HReg hregARM_R5 ( void ) { return mkHReg(False, HRcInt32, 5, 1); }
hregARM_R6(void)45 ST_IN HReg hregARM_R6 ( void ) { return mkHReg(False, HRcInt32, 6, 2); }
hregARM_R7(void)46 ST_IN HReg hregARM_R7 ( void ) { return mkHReg(False, HRcInt32, 7, 3); }
hregARM_R10(void)47 ST_IN HReg hregARM_R10 ( void ) { return mkHReg(False, HRcInt32, 10, 4); }
hregARM_R11(void)48 ST_IN HReg hregARM_R11 ( void ) { return mkHReg(False, HRcInt32, 11, 5); }
49
hregARM_R0(void)50 ST_IN HReg hregARM_R0 ( void ) { return mkHReg(False, HRcInt32, 0, 6); }
hregARM_R1(void)51 ST_IN HReg hregARM_R1 ( void ) { return mkHReg(False, HRcInt32, 1, 7); }
hregARM_R2(void)52 ST_IN HReg hregARM_R2 ( void ) { return mkHReg(False, HRcInt32, 2, 8); }
hregARM_R3(void)53 ST_IN HReg hregARM_R3 ( void ) { return mkHReg(False, HRcInt32, 3, 9); }
hregARM_R9(void)54 ST_IN HReg hregARM_R9 ( void ) { return mkHReg(False, HRcInt32, 9, 10); }
55
hregARM_D8(void)56 ST_IN HReg hregARM_D8 ( void ) { return mkHReg(False, HRcFlt64, 8, 11); }
hregARM_D9(void)57 ST_IN HReg hregARM_D9 ( void ) { return mkHReg(False, HRcFlt64, 9, 12); }
hregARM_D10(void)58 ST_IN HReg hregARM_D10 ( void ) { return mkHReg(False, HRcFlt64, 10, 13); }
hregARM_D11(void)59 ST_IN HReg hregARM_D11 ( void ) { return mkHReg(False, HRcFlt64, 11, 14); }
hregARM_D12(void)60 ST_IN HReg hregARM_D12 ( void ) { return mkHReg(False, HRcFlt64, 12, 15); }
61
hregARM_S26(void)62 ST_IN HReg hregARM_S26 ( void ) { return mkHReg(False, HRcFlt32, 26, 16); }
hregARM_S27(void)63 ST_IN HReg hregARM_S27 ( void ) { return mkHReg(False, HRcFlt32, 27, 17); }
hregARM_S28(void)64 ST_IN HReg hregARM_S28 ( void ) { return mkHReg(False, HRcFlt32, 28, 18); }
hregARM_S29(void)65 ST_IN HReg hregARM_S29 ( void ) { return mkHReg(False, HRcFlt32, 29, 19); }
hregARM_S30(void)66 ST_IN HReg hregARM_S30 ( void ) { return mkHReg(False, HRcFlt32, 30, 20); }
67
hregARM_Q8(void)68 ST_IN HReg hregARM_Q8 ( void ) { return mkHReg(False, HRcVec128, 8, 21); }
hregARM_Q9(void)69 ST_IN HReg hregARM_Q9 ( void ) { return mkHReg(False, HRcVec128, 9, 22); }
hregARM_Q10(void)70 ST_IN HReg hregARM_Q10 ( void ) { return mkHReg(False, HRcVec128, 10, 23); }
hregARM_Q11(void)71 ST_IN HReg hregARM_Q11 ( void ) { return mkHReg(False, HRcVec128, 11, 24); }
hregARM_Q12(void)72 ST_IN HReg hregARM_Q12 ( void ) { return mkHReg(False, HRcVec128, 12, 25); }
73
hregARM_R8(void)74 ST_IN HReg hregARM_R8 ( void ) { return mkHReg(False, HRcInt32, 8, 26); }
hregARM_R12(void)75 ST_IN HReg hregARM_R12 ( void ) { return mkHReg(False, HRcInt32, 12, 27); }
hregARM_R13(void)76 ST_IN HReg hregARM_R13 ( void ) { return mkHReg(False, HRcInt32, 13, 28); }
hregARM_R14(void)77 ST_IN HReg hregARM_R14 ( void ) { return mkHReg(False, HRcInt32, 14, 29); }
hregARM_R15(void)78 ST_IN HReg hregARM_R15 ( void ) { return mkHReg(False, HRcInt32, 15, 30); }
hregARM_Q13(void)79 ST_IN HReg hregARM_Q13 ( void ) { return mkHReg(False, HRcVec128, 13, 31); }
hregARM_Q14(void)80 ST_IN HReg hregARM_Q14 ( void ) { return mkHReg(False, HRcVec128, 14, 32); }
hregARM_Q15(void)81 ST_IN HReg hregARM_Q15 ( void ) { return mkHReg(False, HRcVec128, 15, 33); }
82 #undef ST_IN
83
84 extern void ppHRegARM ( HReg );
85
86 /* Number of registers used arg passing in function calls */
87 #define ARM_N_ARGREGS 4 /* r0, r1, r2, r3 */
88
89
90 /* --------- Condition codes. --------- */
91
92 typedef
93 enum {
94 ARMcc_EQ = 0, /* equal : Z=1 */
95 ARMcc_NE = 1, /* not equal : Z=0 */
96
97 ARMcc_HS = 2, /* >=u (higher or same) : C=1 */
98 ARMcc_LO = 3, /* <u (lower) : C=0 */
99
100 ARMcc_MI = 4, /* minus (negative) : N=1 */
101 ARMcc_PL = 5, /* plus (zero or +ve) : N=0 */
102
103 ARMcc_VS = 6, /* overflow : V=1 */
104 ARMcc_VC = 7, /* no overflow : V=0 */
105
106 ARMcc_HI = 8, /* >u (higher) : C=1 && Z=0 */
107 ARMcc_LS = 9, /* <=u (lower or same) : C=0 || Z=1 */
108
109 ARMcc_GE = 10, /* >=s (signed greater or equal) : N=V */
110 ARMcc_LT = 11, /* <s (signed less than) : N!=V */
111
112 ARMcc_GT = 12, /* >s (signed greater) : Z=0 && N=V */
113 ARMcc_LE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
114
115 ARMcc_AL = 14, /* always (unconditional) */
116 ARMcc_NV = 15 /* never (basically undefined meaning), deprecated */
117 }
118 ARMCondCode;
119
120 extern const HChar* showARMCondCode ( ARMCondCode );
121
122
123
124 /* --------- Memory address expressions (amodes). --------- */
125
126 /* --- Addressing Mode 1 --- */
127 typedef
128 enum {
129 ARMam1_RI=1, /* reg +/- imm12 */
130 ARMam1_RRS /* reg1 + (reg2 << 0, 1 2 or 3) */
131 }
132 ARMAMode1Tag;
133
134 typedef
135 struct {
136 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;
148 }
149 ARMAMode1;
150
151 extern ARMAMode1* ARMAMode1_RI ( HReg reg, Int simm13 );
152 extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
153
154 extern void ppARMAMode1 ( ARMAMode1* );
155
156
157 /* --- Addressing Mode 2 --- */
158 typedef
159 enum {
160 ARMam2_RI=3, /* reg +/- imm8 */
161 ARMam2_RR /* reg1 + reg2 */
162 }
163 ARMAMode2Tag;
164
165 typedef
166 struct {
167 ARMAMode2Tag tag;
168 union {
169 struct {
170 HReg reg;
171 Int simm9; /* -255 .. 255 */
172 } RI;
173 struct {
174 HReg base;
175 HReg index;
176 } RR;
177 } ARMam2;
178 }
179 ARMAMode2;
180
181 extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
182 extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
183
184 extern void ppARMAMode2 ( ARMAMode2* );
185
186
187 /* --- Addressing Mode suitable for VFP --- */
188 /* The simm11 is encoded as 8 bits + 1 sign bit,
189 so can only be 0 % 4. */
190 typedef
191 struct {
192 HReg reg;
193 Int simm11; /* -1020, -1016 .. 1016, 1020 */
194 }
195 ARMAModeV;
196
197 extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
198
199 extern void ppARMAModeV ( ARMAModeV* );
200
201 /* --- Addressing Mode suitable for Neon --- */
202 typedef
203 enum {
204 ARMamN_R=5,
205 ARMamN_RR
206 /* ... */
207 }
208 ARMAModeNTag;
209
210 typedef
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
226 extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg );
227 extern ARMAModeN* mkARMAModeN_R ( HReg );
228 extern void ppARMAModeN ( ARMAModeN* );
229
230 /* --------- Reg or imm-8x4 operands --------- */
231 /* a.k.a (a very restricted form of) Shifter Operand,
232 in the ARM parlance. */
233
234 typedef
235 enum {
236 ARMri84_I84=7, /* imm8 `ror` (2 * imm4) */
237 ARMri84_R /* reg */
238 }
239 ARMRI84Tag;
240
241 typedef
242 struct {
243 ARMRI84Tag tag;
244 union {
245 struct {
246 UShort imm8;
247 UShort imm4;
248 } I84;
249 struct {
250 HReg reg;
251 } R;
252 } ARMri84;
253 }
254 ARMRI84;
255
256 extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
257 extern ARMRI84* ARMRI84_R ( HReg );
258
259 extern void ppARMRI84 ( ARMRI84* );
260
261
262 /* --------- Reg or imm5 operands --------- */
263 typedef
264 enum {
265 ARMri5_I5=9, /* imm5, 1 .. 31 only (no zero!) */
266 ARMri5_R /* reg */
267 }
268 ARMRI5Tag;
269
270 typedef
271 struct {
272 ARMRI5Tag tag;
273 union {
274 struct {
275 UInt imm5;
276 } I5;
277 struct {
278 HReg reg;
279 } R;
280 } ARMri5;
281 }
282 ARMRI5;
283
284 extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
285 extern ARMRI5* ARMRI5_R ( HReg );
286
287 extern void ppARMRI5 ( ARMRI5* );
288
289 /* -------- Neon Immediate operand -------- */
290
291 /* imm8 = abcdefgh, B = NOT(b);
292
293 type | 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
308 Type 10 is:
309 (-1)^S * 2^exp * mantissa
310 where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16
311 */
312
313 typedef
314 struct {
315 UInt type;
316 UInt imm8;
317 }
318 ARMNImm;
319
320 extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 );
321 extern ULong ARMNImm_to_Imm64 ( ARMNImm* );
322 extern ARMNImm* Imm64_to_ARMNImm ( ULong );
323
324 extern void ppARMNImm ( ARMNImm* );
325
326 /* ------ Neon Register or Scalar Operand ------ */
327
328 typedef
329 enum {
330 ARMNRS_Reg=11,
331 ARMNRS_Scalar
332 }
333 ARMNRS_tag;
334
335 typedef
336 struct {
337 ARMNRS_tag tag;
338 HReg reg;
339 UInt index;
340 }
341 ARMNRS;
342
343 extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index);
344 extern void ppARMNRS ( ARMNRS* );
345
346 /* --------- Instructions. --------- */
347
348 /* --------- */
349 typedef
350 enum {
351 ARMalu_ADD=20, /* plain 32-bit add */
352 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;
363
364 extern const HChar* showARMAluOp ( ARMAluOp op );
365
366
367 typedef
368 enum {
369 ARMsh_SHL=40,
370 ARMsh_SHR,
371 ARMsh_SAR
372 }
373 ARMShiftOp;
374
375 extern const HChar* showARMShiftOp ( ARMShiftOp op );
376
377
378 typedef
379 enum {
380 ARMun_NEG=50,
381 ARMun_NOT,
382 ARMun_CLZ
383 }
384 ARMUnaryOp;
385
386 extern const HChar* showARMUnaryOp ( ARMUnaryOp op );
387
388
389 typedef
390 enum {
391 ARMmul_PLAIN=60,
392 ARMmul_ZX,
393 ARMmul_SX
394 }
395 ARMMulOp;
396
397 extern const HChar* showARMMulOp ( ARMMulOp op );
398
399
400 typedef
401 enum {
402 ARMvfp_ADD=70,
403 ARMvfp_SUB,
404 ARMvfp_MUL,
405 ARMvfp_DIV
406 }
407 ARMVfpOp;
408
409 extern const HChar* showARMVfpOp ( ARMVfpOp op );
410
411
412 typedef
413 enum {
414 ARMvfpu_COPY=80,
415 ARMvfpu_NEG,
416 ARMvfpu_ABS,
417 ARMvfpu_SQRT
418 }
419 ARMVfpUnaryOp;
420
421 extern const HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
422
423 typedef
424 enum {
425 ARMneon_VAND=90,
426 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,
472 ARMneon_VRECPS,
473 ARMneon_VRSQRTS,
474 ARMneon_INVALID
475 /* ... */
476 }
477 ARMNeonBinOp;
478
479 typedef
480 enum {
481 ARMneon_VSHL=150,
482 ARMneon_VSAL, /* Yah, not SAR but SAL */
483 ARMneon_VQSHL,
484 ARMneon_VQSAL
485 }
486 ARMNeonShiftOp;
487
488 typedef
489 enum {
490 ARMneon_COPY=160,
491 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,
524 ARMneon_VRECIP,
525 ARMneon_VRECIPF,
526 ARMneon_VABSFP,
527 ARMneon_VRSQRTEFP,
528 ARMneon_VRSQRTE
529 /* ... */
530 }
531 ARMNeonUnOp;
532
533 typedef
534 enum {
535 ARMneon_SETELEM=200,
536 ARMneon_GETELEMU,
537 ARMneon_GETELEMS,
538 ARMneon_VDUP,
539 }
540 ARMNeonUnOpS;
541
542 typedef
543 enum {
544 ARMneon_TRN=210,
545 ARMneon_ZIP,
546 ARMneon_UZP
547 /* ... */
548 }
549 ARMNeonDualOp;
550
551 extern const HChar* showARMNeonBinOp ( ARMNeonBinOp op );
552 extern const HChar* showARMNeonUnOp ( ARMNeonUnOp op );
553 extern const HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
554 extern const HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
555 extern const HChar* showARMNeonDualOp ( ARMNeonDualOp op );
556 extern const HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
557 extern const HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
558 extern const HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
559 extern const HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
560 extern const HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
561
562 typedef
563 enum {
564 /* baseline */
565 ARMin_Alu=220,
566 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,
575 ARMin_XDirect, /* direct transfer to GA */
576 ARMin_XIndir, /* indirect transfer to GA */
577 ARMin_XAssisted, /* assisted transfer to GA */
578 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,
594 ARMin_VXferD,
595 ARMin_VXferS,
596 ARMin_VCvtID,
597 ARMin_FPSCR,
598 ARMin_MFence,
599 ARMin_CLREX,
600 /* Neon */
601 ARMin_NLdStQ,
602 ARMin_NLdStD,
603 ARMin_NUnary,
604 ARMin_NUnaryS,
605 ARMin_NDual,
606 ARMin_NBinary,
607 ARMin_NBinaryS,
608 ARMin_NShift,
609 ARMin_NShl64, // special case 64-bit shift of Dreg by immediate
610 ARMin_NeonImm,
611 ARMin_NCMovQ,
612 /* This is not a NEON instruction. Actually there is no corresponding
613 instruction in ARM instruction set at all. We need this one to
614 generate spill/reload of 128-bit registers since current register
615 allocator demands them to consist of no more than two instructions.
616 We will split this instruction into 2 or 3 ARM instructions on the
617 emiting phase.
618 NOTE: source and destination registers should be different! */
619 ARMin_Add32,
620 ARMin_EvCheck, /* Event check */
621 ARMin_ProfInc /* 64-bit profile counter increment */
622 }
623 ARMInstrTag;
624
625 /* Destinations are on the LEFT (first operand) */
626
627 typedef
628 struct {
629 ARMInstrTag tag;
630 union {
631 /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
632 struct {
633 ARMAluOp op;
634 HReg dst;
635 HReg argL;
636 ARMRI84* argR;
637 } Alu;
638 /* SHL/SHR/SAR, 2nd arg is reg or imm */
639 struct {
640 ARMShiftOp op;
641 HReg dst;
642 HReg argL;
643 ARMRI5* argR;
644 } Shift;
645 /* NOT/NEG/CLZ */
646 struct {
647 ARMUnaryOp op;
648 HReg dst;
649 HReg src;
650 } Unary;
651 /* CMP/TST; subtract/and, discard result, set NZCV */
652 struct {
653 Bool isCmp;
654 HReg argL;
655 ARMRI84* argR;
656 } CmpOrTst;
657 /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
658 struct {
659 HReg dst;
660 ARMRI84* src;
661 } Mov;
662 /* Pseudo-insn; make a 32-bit immediate */
663 struct {
664 HReg dst;
665 UInt imm32;
666 } Imm32;
667 /* 32-bit load or store, may be conditional */
668 struct {
669 ARMCondCode cc; /* ARMcc_NV is not allowed */
670 Bool isLoad;
671 HReg rD;
672 ARMAMode1* amode;
673 } LdSt32;
674 /* 16-bit load or store, may be conditional */
675 struct {
676 ARMCondCode cc; /* ARMcc_NV is not allowed */
677 Bool isLoad;
678 Bool signedLoad;
679 HReg rD;
680 ARMAMode2* amode;
681 } LdSt16;
682 /* 8-bit (unsigned) load or store, may be conditional */
683 struct {
684 ARMCondCode cc; /* ARMcc_NV is not allowed */
685 Bool isLoad;
686 HReg rD;
687 ARMAMode1* amode;
688 } LdSt8U;
689 /* 8-bit signed load, may be conditional */
690 struct {
691 ARMCondCode cc; /* ARMcc_NV is not allowed */
692 HReg rD;
693 ARMAMode2* amode;
694 } Ld8S;
695 /* Update the guest R15T value, then exit requesting to chain
696 to it. May be conditional. Urr, use of Addr32 implicitly
697 assumes that wordsize(guest) == wordsize(host). */
698 struct {
699 Addr32 dstGA; /* next guest address */
700 ARMAMode1* amR15T; /* amode in guest state for R15T */
701 ARMCondCode cond; /* can be ARMcc_AL */
702 Bool toFastEP; /* chain to the slow or fast point? */
703 } XDirect;
704 /* Boring transfer to a guest address not known at JIT time.
705 Not chainable. May be conditional. */
706 struct {
707 HReg dstGA;
708 ARMAMode1* amR15T;
709 ARMCondCode cond; /* can be ARMcc_AL */
710 } XIndir;
711 /* Assisted transfer to a guest address, most general case.
712 Not chainable. May be conditional. */
713 struct {
714 HReg dstGA;
715 ARMAMode1* amR15T;
716 ARMCondCode cond; /* can be ARMcc_AL */
717 IRJumpKind jk;
718 } XAssisted;
719 /* Mov src to dst on the given condition, which may not
720 be ARMcc_AL. */
721 struct {
722 ARMCondCode cond;
723 HReg dst;
724 ARMRI84* src;
725 } CMov;
726 /* Pseudo-insn. Call target (an absolute address), on given
727 condition (which could be ARMcc_AL). */
728 struct {
729 ARMCondCode cond;
730 Addr32 target;
731 Int nArgRegs; /* # regs carrying args: 0 .. 4 */
732 RetLoc rloc; /* where the return value will be */
733 } Call;
734 /* (PLAIN) 32 * 32 -> 32: r0 = r2 * r3
735 (ZX) 32 *u 32 -> 64: r1:r0 = r2 *u r3
736 (SX) 32 *s 32 -> 64: r1:r0 = r2 *s r3
737 Why hardwired registers? Because the ARM ARM specifies
738 (eg for straight MUL) the result (Rd) and the left arg (Rm)
739 may not be the same register. That's not a constraint we
740 can enforce in the register allocator (without mucho extra
741 complexity). Hence hardwire it. At least using caller-saves
742 registers, which are less likely to be in use. */
743 struct {
744 ARMMulOp op;
745 } Mul;
746 /* LDREX{,H,B} r2, [r4] and
747 LDREXD r2, r3, [r4] (on LE hosts, transferred value is r3:r2)
748 Again, hardwired registers since this is not performance
749 critical, and there are possibly constraints on the
750 registers that we can't express in the register allocator.*/
751 struct {
752 Int szB; /* 1, 2, 4 or 8 */
753 } LdrEX;
754 /* STREX{,H,B} r0, r2, [r4] and
755 STREXD r0, r2, r3, [r4] (on LE hosts, transferred value is r3:r2)
756 r0 = SC( [r4] = r2 ) (8, 16, 32 bit transfers)
757 r0 = SC( [r4] = r3:r2) (64 bit transfers)
758 Ditto comment re fixed registers. */
759 struct {
760 Int szB; /* 1, 2, 4 or 8 */
761 } StrEX;
762 /* VFP INSTRUCTIONS */
763 /* 64-bit Fp load/store */
764 struct {
765 Bool isLoad;
766 HReg dD;
767 ARMAModeV* amode;
768 } VLdStD;
769 /* 32-bit Fp load/store */
770 struct {
771 Bool isLoad;
772 HReg fD;
773 ARMAModeV* amode;
774 } VLdStS;
775 /* 64-bit FP binary arithmetic */
776 struct {
777 ARMVfpOp op;
778 HReg dst;
779 HReg argL;
780 HReg argR;
781 } VAluD;
782 /* 32-bit FP binary arithmetic */
783 struct {
784 ARMVfpOp op;
785 HReg dst;
786 HReg argL;
787 HReg argR;
788 } VAluS;
789 /* 64-bit FP unary, also reg-reg move */
790 struct {
791 ARMVfpUnaryOp op;
792 HReg dst;
793 HReg src;
794 } VUnaryD;
795 /* 32-bit FP unary, also reg-reg move */
796 struct {
797 ARMVfpUnaryOp op;
798 HReg dst;
799 HReg src;
800 } VUnaryS;
801 /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
802 struct {
803 HReg argL;
804 HReg argR;
805 } VCmpD;
806 /* 64-bit FP mov src to dst on the given condition, which may
807 not be ARMcc_AL. */
808 struct {
809 ARMCondCode cond;
810 HReg dst;
811 HReg src;
812 } VCMovD;
813 /* 32-bit FP mov src to dst on the given condition, which may
814 not be ARMcc_AL. */
815 struct {
816 ARMCondCode cond;
817 HReg dst;
818 HReg src;
819 } VCMovS;
820 /* Convert between 32-bit and 64-bit FP values (both ways).
821 (FCVTSD, FCVTDS) */
822 struct {
823 Bool sToD; /* True: F32->F64. False: F64->F32 */
824 HReg dst;
825 HReg src;
826 } VCvtSD;
827 /* Transfer a VFP D reg to/from two integer registers (VMOV) */
828 struct {
829 Bool toD;
830 HReg dD;
831 HReg rHi;
832 HReg rLo;
833 } VXferD;
834 /* Transfer a VFP S reg to/from an integer register (VMOV) */
835 struct {
836 Bool toS;
837 HReg fD;
838 HReg rLo;
839 } VXferS;
840 /* Convert between 32-bit ints and 64-bit FP values (both ways
841 and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
842 struct {
843 Bool iToD; /* True: I32->F64. False: F64->I32 */
844 Bool syned; /* True: I32 is signed. False: I32 is unsigned */
845 HReg dst;
846 HReg src;
847 } VCvtID;
848 /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
849 struct {
850 Bool toFPSCR;
851 HReg iReg;
852 } FPSCR;
853 /* Mem fence. An insn which fences all loads and stores as
854 much as possible before continuing. On ARM we emit the
855 sequence
856 mcr 15,0,r0,c7,c10,4 (DSB)
857 mcr 15,0,r0,c7,c10,5 (DMB)
858 mcr 15,0,r0,c7,c5,4 (ISB)
859 which is probably total overkill, but better safe than
860 sorry.
861 */
862 struct {
863 } MFence;
864 /* A CLREX instruction. */
865 struct {
866 } CLREX;
867 /* Neon data processing instruction: 3 registers of the same
868 length */
869 struct {
870 ARMNeonBinOp op;
871 HReg dst;
872 HReg argL;
873 HReg argR;
874 UInt size;
875 Bool Q;
876 } NBinary;
877 struct {
878 ARMNeonBinOp op;
879 ARMNRS* dst;
880 ARMNRS* argL;
881 ARMNRS* argR;
882 UInt size;
883 Bool Q;
884 } NBinaryS;
885 struct {
886 ARMNeonShiftOp op;
887 HReg dst;
888 HReg argL;
889 HReg argR;
890 UInt size;
891 Bool Q;
892 } NShift;
893 struct {
894 HReg dst;
895 HReg src;
896 UInt amt; /* 1..63 only */
897 } NShl64;
898 struct {
899 Bool isLoad;
900 HReg dQ;
901 ARMAModeN *amode;
902 } NLdStQ;
903 struct {
904 Bool isLoad;
905 HReg dD;
906 ARMAModeN *amode;
907 } NLdStD;
908 struct {
909 ARMNeonUnOpS op;
910 ARMNRS* dst;
911 ARMNRS* src;
912 UInt size;
913 Bool Q;
914 } NUnaryS;
915 struct {
916 ARMNeonUnOp op;
917 HReg dst;
918 HReg src;
919 UInt size;
920 Bool Q;
921 } NUnary;
922 /* Takes two arguments and modifies them both. */
923 struct {
924 ARMNeonDualOp op;
925 HReg arg1;
926 HReg arg2;
927 UInt size;
928 Bool Q;
929 } NDual;
930 struct {
931 HReg dst;
932 ARMNImm* imm;
933 } NeonImm;
934 /* 128-bit Neon move src to dst on the given condition, which
935 may not be ARMcc_AL. */
936 struct {
937 ARMCondCode cond;
938 HReg dst;
939 HReg src;
940 } NCMovQ;
941 struct {
942 /* Note: rD != rN */
943 HReg rD;
944 HReg rN;
945 UInt imm32;
946 } Add32;
947 struct {
948 ARMAMode1* amCounter;
949 ARMAMode1* amFailAddr;
950 } EvCheck;
951 struct {
952 /* No fields. The address of the counter to inc is
953 installed later, post-translation, by patching it in,
954 as it is not known at translation time. */
955 } ProfInc;
956 } ARMin;
957 }
958 ARMInstr;
959
960
961 extern ARMInstr* ARMInstr_Alu ( ARMAluOp, HReg, HReg, ARMRI84* );
962 extern ARMInstr* ARMInstr_Shift ( ARMShiftOp, HReg, HReg, ARMRI5* );
963 extern ARMInstr* ARMInstr_Unary ( ARMUnaryOp, HReg, HReg );
964 extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
965 extern ARMInstr* ARMInstr_Mov ( HReg, ARMRI84* );
966 extern ARMInstr* ARMInstr_Imm32 ( HReg, UInt );
967 extern ARMInstr* ARMInstr_LdSt32 ( ARMCondCode,
968 Bool isLoad, HReg, ARMAMode1* );
969 extern ARMInstr* ARMInstr_LdSt16 ( ARMCondCode,
970 Bool isLoad, Bool signedLoad,
971 HReg, ARMAMode2* );
972 extern ARMInstr* ARMInstr_LdSt8U ( ARMCondCode,
973 Bool isLoad, HReg, ARMAMode1* );
974 extern ARMInstr* ARMInstr_Ld8S ( ARMCondCode, HReg, ARMAMode2* );
975 extern ARMInstr* ARMInstr_XDirect ( Addr32 dstGA, ARMAMode1* amR15T,
976 ARMCondCode cond, Bool toFastEP );
977 extern ARMInstr* ARMInstr_XIndir ( HReg dstGA, ARMAMode1* amR15T,
978 ARMCondCode cond );
979 extern ARMInstr* ARMInstr_XAssisted ( HReg dstGA, ARMAMode1* amR15T,
980 ARMCondCode cond, IRJumpKind jk );
981 extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src );
982 extern ARMInstr* ARMInstr_Call ( ARMCondCode, Addr32, Int nArgRegs,
983 RetLoc rloc );
984 extern ARMInstr* ARMInstr_Mul ( ARMMulOp op );
985 extern ARMInstr* ARMInstr_LdrEX ( Int szB );
986 extern ARMInstr* ARMInstr_StrEX ( Int szB );
987 extern ARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg, ARMAModeV* );
988 extern ARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg, ARMAModeV* );
989 extern ARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg, HReg, HReg );
990 extern ARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg, HReg, HReg );
991 extern ARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp, HReg dst, HReg src );
992 extern ARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp, HReg dst, HReg src );
993 extern ARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR );
994 extern ARMInstr* ARMInstr_VCMovD ( ARMCondCode, HReg dst, HReg src );
995 extern ARMInstr* ARMInstr_VCMovS ( ARMCondCode, HReg dst, HReg src );
996 extern ARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src );
997 extern ARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo );
998 extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo );
999 extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned,
1000 HReg dst, HReg src );
1001 extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg );
1002 extern ARMInstr* ARMInstr_MFence ( void );
1003 extern ARMInstr* ARMInstr_CLREX ( void );
1004 extern ARMInstr* ARMInstr_NLdStQ ( Bool isLoad, HReg, ARMAModeN* );
1005 extern ARMInstr* ARMInstr_NLdStD ( Bool isLoad, HReg, ARMAModeN* );
1006 extern ARMInstr* ARMInstr_NUnary ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
1007 extern ARMInstr* ARMInstr_NUnaryS ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
1008 UInt, Bool );
1009 extern ARMInstr* ARMInstr_NDual ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
1010 extern ARMInstr* ARMInstr_NBinary ( ARMNeonBinOp, HReg, HReg, HReg,
1011 UInt, Bool );
1012 extern ARMInstr* ARMInstr_NShift ( ARMNeonShiftOp, HReg, HReg, HReg,
1013 UInt, Bool );
1014 extern ARMInstr* ARMInstr_NShl64 ( HReg, HReg, UInt );
1015 extern ARMInstr* ARMInstr_NeonImm ( HReg, ARMNImm* );
1016 extern ARMInstr* ARMInstr_NCMovQ ( ARMCondCode, HReg, HReg );
1017 extern ARMInstr* ARMInstr_Add32 ( HReg rD, HReg rN, UInt imm32 );
1018 extern ARMInstr* ARMInstr_EvCheck ( ARMAMode1* amCounter,
1019 ARMAMode1* amFailAddr );
1020 extern ARMInstr* ARMInstr_ProfInc ( void );
1021
1022 extern void ppARMInstr ( const ARMInstr* );
1023
1024
1025 /* Some functions that insulate the register allocator from details
1026 of the underlying instruction set. */
1027 extern void getRegUsage_ARMInstr ( HRegUsage*, const ARMInstr*, Bool );
1028 extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool );
1029 extern Bool isMove_ARMInstr ( const ARMInstr*, HReg*, HReg* );
1030 extern Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc,
1031 UChar* buf, Int nbuf, const ARMInstr* i,
1032 Bool mode64,
1033 VexEndness endness_host,
1034 const void* disp_cp_chain_me_to_slowEP,
1035 const void* disp_cp_chain_me_to_fastEP,
1036 const void* disp_cp_xindir,
1037 const void* disp_cp_xassisted );
1038
1039 extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1040 HReg rreg, Int offset, Bool );
1041 extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1042 HReg rreg, Int offset, Bool );
1043
1044 extern const RRegUniverse* getRRegUniverse_ARM ( void );
1045
1046 extern HInstrArray* iselSB_ARM ( const IRSB*,
1047 VexArch,
1048 const VexArchInfo*,
1049 const VexAbiInfo*,
1050 Int offs_Host_EvC_Counter,
1051 Int offs_Host_EvC_FailAddr,
1052 Bool chainingAllowed,
1053 Bool addProfInc,
1054 Addr max_ga );
1055
1056 /* How big is an event check? This is kind of a kludge because it
1057 depends on the offsets of host_EvC_FAILADDR and
1058 host_EvC_COUNTER. */
1059 extern Int evCheckSzB_ARM (void);
1060
1061 /* Perform a chaining and unchaining of an XDirect jump. */
1062 extern VexInvalRange chainXDirect_ARM ( VexEndness endness_host,
1063 void* place_to_chain,
1064 const void* disp_cp_chain_me_EXPECTED,
1065 const void* place_to_jump_to );
1066
1067 extern VexInvalRange unchainXDirect_ARM ( VexEndness endness_host,
1068 void* place_to_unchain,
1069 const void* place_to_jump_to_EXPECTED,
1070 const void* disp_cp_chain_me );
1071
1072 /* Patch the counter location into an existing ProfInc point. */
1073 extern VexInvalRange patchProfInc_ARM ( VexEndness endness_host,
1074 void* place_to_patch,
1075 const ULong* location_of_counter );
1076
1077
1078 #endif /* ndef __VEX_HOST_ARM_DEFS_H */
1079
1080 /*---------------------------------------------------------------*/
1081 /*--- end host_arm_defs.h ---*/
1082 /*---------------------------------------------------------------*/
1083