Bug 497723 - forgot to restore callgrind output cleanup
[valgrind.git] / VEX / priv / host_arm_defs.h
blob0f4b5195155bf403018f11e85df8653ee29ba4fb
1 /*---------------------------------------------------------------*/
2 /*--- begin host_arm_defs.h ---*/
3 /*---------------------------------------------------------------*/
5 /*
6 This file is part of Valgrind, a dynamic binary instrumentation
7 framework.
9 Copyright (C) 2004-2017 OpenWorks LLP
10 info@open-works.net
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.
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.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, see <http://www.gnu.org/licenses/>.
25 The GNU General Public License is contained in the file COPYING.
28 #ifndef __VEX_HOST_ARM_DEFS_H
29 #define __VEX_HOST_ARM_DEFS_H
31 #include "libvex_basictypes.h"
32 #include "libvex.h" // VexArch
33 #include "host_generic_regs.h" // HReg
35 extern UInt arm_hwcaps;
38 /* --------- Registers. --------- */
40 #define ST_IN static inline
41 ST_IN HReg hregARM_R4 ( void ) { return mkHReg(False, HRcInt32, 4, 0); }
42 ST_IN HReg hregARM_R5 ( void ) { return mkHReg(False, HRcInt32, 5, 1); }
43 ST_IN HReg hregARM_R6 ( void ) { return mkHReg(False, HRcInt32, 6, 2); }
44 ST_IN HReg hregARM_R7 ( void ) { return mkHReg(False, HRcInt32, 7, 3); }
45 ST_IN HReg hregARM_R10 ( void ) { return mkHReg(False, HRcInt32, 10, 4); }
46 ST_IN HReg hregARM_R11 ( void ) { return mkHReg(False, HRcInt32, 11, 5); }
48 ST_IN HReg hregARM_R0 ( void ) { return mkHReg(False, HRcInt32, 0, 6); }
49 ST_IN HReg hregARM_R1 ( void ) { return mkHReg(False, HRcInt32, 1, 7); }
50 ST_IN HReg hregARM_R2 ( void ) { return mkHReg(False, HRcInt32, 2, 8); }
51 ST_IN HReg hregARM_R3 ( void ) { return mkHReg(False, HRcInt32, 3, 9); }
52 ST_IN HReg hregARM_R9 ( void ) { return mkHReg(False, HRcInt32, 9, 10); }
54 ST_IN HReg hregARM_D8 ( void ) { return mkHReg(False, HRcFlt64, 8, 11); }
55 ST_IN HReg hregARM_D9 ( void ) { return mkHReg(False, HRcFlt64, 9, 12); }
56 ST_IN HReg hregARM_D10 ( void ) { return mkHReg(False, HRcFlt64, 10, 13); }
57 ST_IN HReg hregARM_D11 ( void ) { return mkHReg(False, HRcFlt64, 11, 14); }
58 ST_IN HReg hregARM_D12 ( void ) { return mkHReg(False, HRcFlt64, 12, 15); }
60 ST_IN HReg hregARM_S26 ( void ) { return mkHReg(False, HRcFlt32, 26, 16); }
61 ST_IN HReg hregARM_S27 ( void ) { return mkHReg(False, HRcFlt32, 27, 17); }
62 ST_IN HReg hregARM_S28 ( void ) { return mkHReg(False, HRcFlt32, 28, 18); }
63 ST_IN HReg hregARM_S29 ( void ) { return mkHReg(False, HRcFlt32, 29, 19); }
64 ST_IN HReg hregARM_S30 ( void ) { return mkHReg(False, HRcFlt32, 30, 20); }
66 ST_IN HReg hregARM_Q8 ( void ) { return mkHReg(False, HRcVec128, 8, 21); }
67 ST_IN HReg hregARM_Q9 ( void ) { return mkHReg(False, HRcVec128, 9, 22); }
68 ST_IN HReg hregARM_Q10 ( void ) { return mkHReg(False, HRcVec128, 10, 23); }
69 ST_IN HReg hregARM_Q11 ( void ) { return mkHReg(False, HRcVec128, 11, 24); }
70 ST_IN HReg hregARM_Q12 ( void ) { return mkHReg(False, HRcVec128, 12, 25); }
72 ST_IN HReg hregARM_R8 ( void ) { return mkHReg(False, HRcInt32, 8, 26); }
73 ST_IN HReg hregARM_R12 ( void ) { return mkHReg(False, HRcInt32, 12, 27); }
74 ST_IN HReg hregARM_R13 ( void ) { return mkHReg(False, HRcInt32, 13, 28); }
75 ST_IN HReg hregARM_R14 ( void ) { return mkHReg(False, HRcInt32, 14, 29); }
76 ST_IN HReg hregARM_R15 ( void ) { return mkHReg(False, HRcInt32, 15, 30); }
77 ST_IN HReg hregARM_Q13 ( void ) { return mkHReg(False, HRcVec128, 13, 31); }
78 ST_IN HReg hregARM_Q14 ( void ) { return mkHReg(False, HRcVec128, 14, 32); }
79 ST_IN HReg hregARM_Q15 ( void ) { return mkHReg(False, HRcVec128, 15, 33); }
80 #undef ST_IN
82 extern UInt ppHRegARM ( HReg );
84 /* Number of registers used arg passing in function calls */
85 #define ARM_N_ARGREGS 4 /* r0, r1, r2, r3 */
88 /* --------- Condition codes. --------- */
90 typedef
91 enum {
92 ARMcc_EQ = 0, /* equal : Z=1 */
93 ARMcc_NE = 1, /* not equal : Z=0 */
95 ARMcc_HS = 2, /* >=u (higher or same) : C=1 */
96 ARMcc_LO = 3, /* <u (lower) : C=0 */
98 ARMcc_MI = 4, /* minus (negative) : N=1 */
99 ARMcc_PL = 5, /* plus (zero or +ve) : N=0 */
101 ARMcc_VS = 6, /* overflow : V=1 */
102 ARMcc_VC = 7, /* no overflow : V=0 */
104 ARMcc_HI = 8, /* >u (higher) : C=1 && Z=0 */
105 ARMcc_LS = 9, /* <=u (lower or same) : C=0 || Z=1 */
107 ARMcc_GE = 10, /* >=s (signed greater or equal) : N=V */
108 ARMcc_LT = 11, /* <s (signed less than) : N!=V */
110 ARMcc_GT = 12, /* >s (signed greater) : Z=0 && N=V */
111 ARMcc_LE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
113 ARMcc_AL = 14, /* always (unconditional) */
114 ARMcc_NV = 15 /* never (basically undefined meaning), deprecated */
116 ARMCondCode;
118 extern const HChar* showARMCondCode ( ARMCondCode );
122 /* --------- Memory address expressions (amodes). --------- */
124 /* --- Addressing Mode 1 --- */
125 typedef
126 enum {
127 ARMam1_RI=1, /* reg +/- imm12 */
128 ARMam1_RRS /* reg1 + (reg2 << 0, 1 2 or 3) */
130 ARMAMode1Tag;
132 typedef
133 struct {
134 ARMAMode1Tag tag;
135 union {
136 struct {
137 HReg reg;
138 Int simm13; /* -4095 .. +4095 */
139 } RI;
140 struct {
141 HReg base;
142 HReg index;
143 UInt shift; /* 0, 1 2 or 3 */
144 } RRS;
145 } ARMam1;
147 ARMAMode1;
149 extern ARMAMode1* ARMAMode1_RI ( HReg reg, Int simm13 );
150 extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
152 extern void ppARMAMode1 ( ARMAMode1* );
155 /* --- Addressing Mode 2 --- */
156 typedef
157 enum {
158 ARMam2_RI=3, /* reg +/- imm8 */
159 ARMam2_RR /* reg1 + reg2 */
161 ARMAMode2Tag;
163 typedef
164 struct {
165 ARMAMode2Tag tag;
166 union {
167 struct {
168 HReg reg;
169 Int simm9; /* -255 .. 255 */
170 } RI;
171 struct {
172 HReg base;
173 HReg index;
174 } RR;
175 } ARMam2;
177 ARMAMode2;
179 extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
180 extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
182 extern void ppARMAMode2 ( ARMAMode2* );
185 /* --- Addressing Mode suitable for VFP --- */
186 /* The simm11 is encoded as 8 bits + 1 sign bit,
187 so can only be 0 % 4. */
188 typedef
189 struct {
190 HReg reg;
191 Int simm11; /* -1020, -1016 .. 1016, 1020 */
193 ARMAModeV;
195 extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
197 extern void ppARMAModeV ( ARMAModeV* );
199 /* --- Addressing Mode suitable for Neon --- */
200 typedef
201 enum {
202 ARMamN_R=5,
203 ARMamN_RR
204 /* ... */
206 ARMAModeNTag;
208 typedef
209 struct {
210 ARMAModeNTag tag;
211 union {
212 struct {
213 HReg rN;
214 HReg rM;
215 } RR;
216 struct {
217 HReg rN;
218 } R;
219 /* ... */
220 } ARMamN;
222 ARMAModeN;
224 extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg );
225 extern ARMAModeN* mkARMAModeN_R ( HReg );
226 extern void ppARMAModeN ( ARMAModeN* );
228 /* --------- Reg or imm-8x4 operands --------- */
229 /* a.k.a (a very restricted form of) Shifter Operand,
230 in the ARM parlance. */
232 typedef
233 enum {
234 ARMri84_I84=7, /* imm8 `ror` (2 * imm4) */
235 ARMri84_R /* reg */
237 ARMRI84Tag;
239 typedef
240 struct {
241 ARMRI84Tag tag;
242 union {
243 struct {
244 UShort imm8;
245 UShort imm4;
246 } I84;
247 struct {
248 HReg reg;
249 } R;
250 } ARMri84;
252 ARMRI84;
254 extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
255 extern ARMRI84* ARMRI84_R ( HReg );
257 extern void ppARMRI84 ( ARMRI84* );
260 /* --------- Reg or imm5 operands --------- */
261 typedef
262 enum {
263 ARMri5_I5=9, /* imm5, 1 .. 31 only (no zero!) */
264 ARMri5_R /* reg */
266 ARMRI5Tag;
268 typedef
269 struct {
270 ARMRI5Tag tag;
271 union {
272 struct {
273 UInt imm5;
274 } I5;
275 struct {
276 HReg reg;
277 } R;
278 } ARMri5;
280 ARMRI5;
282 extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
283 extern ARMRI5* ARMRI5_R ( HReg );
285 extern void ppARMRI5 ( ARMRI5* );
287 /* -------- Neon Immediate operand -------- */
289 /* imm8 = abcdefgh, B = NOT(b);
291 type | value (64bit binary)
292 -----+-------------------------------------------------------------------------
293 0 | 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh
294 1 | 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000
295 2 | 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000
296 3 | abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000
297 4 | 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh
298 5 | abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000
299 6 | abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh
300 7 | 00000000 00000000 abcdefgh 11111111 00000000 00000000 abcdefgh 11111111
301 8 | 00000000 abcdefgh 11111111 11111111 00000000 abcdefgh 11111111 11111111
302 9 | aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
303 10 | aBbbbbbc defgh000 00000000 00000000 aBbbbbbc defgh000 00000000 00000000
304 -----+-------------------------------------------------------------------------
306 Type 10 is:
307 (-1)^S * 2^exp * mantissa
308 where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16
311 typedef
312 struct {
313 UInt type;
314 UInt imm8;
316 ARMNImm;
318 extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 );
319 extern ULong ARMNImm_to_Imm64 ( ARMNImm* );
320 extern ARMNImm* Imm64_to_ARMNImm ( ULong );
322 extern void ppARMNImm ( ARMNImm* );
324 /* ------ Neon Register or Scalar Operand ------ */
326 typedef
327 enum {
328 ARMNRS_Reg=11,
329 ARMNRS_Scalar
331 ARMNRS_tag;
333 typedef
334 struct {
335 ARMNRS_tag tag;
336 HReg reg;
337 UInt index;
339 ARMNRS;
341 extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index);
342 extern void ppARMNRS ( ARMNRS* );
344 /* --------- Instructions. --------- */
346 /* --------- */
347 typedef
348 enum {
349 ARMalu_ADD=20, /* plain 32-bit add */
350 ARMalu_ADDS, /* 32-bit add, and set the flags */
351 ARMalu_ADC, /* 32-bit add with carry */
352 ARMalu_SUB, /* plain 32-bit subtract */
353 ARMalu_SUBS, /* 32-bit subtract, and set the flags */
354 ARMalu_SBC, /* 32-bit subtract with carry */
355 ARMalu_AND,
356 ARMalu_BIC,
357 ARMalu_OR,
358 ARMalu_XOR
360 ARMAluOp;
362 extern const HChar* showARMAluOp ( ARMAluOp op );
365 typedef
366 enum {
367 ARMsh_SHL=40,
368 ARMsh_SHR,
369 ARMsh_SAR
371 ARMShiftOp;
373 extern const HChar* showARMShiftOp ( ARMShiftOp op );
376 typedef
377 enum {
378 ARMun_NEG=50,
379 ARMun_NOT,
380 ARMun_CLZ
382 ARMUnaryOp;
384 extern const HChar* showARMUnaryOp ( ARMUnaryOp op );
387 typedef
388 enum {
389 ARMmul_PLAIN=60,
390 ARMmul_ZX,
391 ARMmul_SX
393 ARMMulOp;
395 extern const HChar* showARMMulOp ( ARMMulOp op );
398 typedef
399 enum {
400 ARMvfp_ADD=70,
401 ARMvfp_SUB,
402 ARMvfp_MUL,
403 ARMvfp_DIV
405 ARMVfpOp;
407 extern const HChar* showARMVfpOp ( ARMVfpOp op );
410 typedef
411 enum {
412 ARMvfpu_COPY=80,
413 ARMvfpu_NEG,
414 ARMvfpu_ABS,
415 ARMvfpu_SQRT
417 ARMVfpUnaryOp;
419 extern const HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
421 typedef
422 enum {
423 ARMneon_VAND=90,
424 ARMneon_VORR,
425 ARMneon_VXOR,
426 ARMneon_VADD,
427 ARMneon_VADDFP,
428 ARMneon_VRHADDS,
429 ARMneon_VRHADDU,
430 ARMneon_VPADDFP,
431 ARMneon_VABDFP,
432 ARMneon_VSUB,
433 ARMneon_VSUBFP,
434 ARMneon_VMAXU,
435 ARMneon_VMAXS,
436 ARMneon_VMAXF,
437 ARMneon_VMINU,
438 ARMneon_VMINS,
439 ARMneon_VMINF,
440 ARMneon_VQADDU,
441 ARMneon_VQADDS,
442 ARMneon_VQSUBU,
443 ARMneon_VQSUBS,
444 ARMneon_VCGTU,
445 ARMneon_VCGTS,
446 ARMneon_VCGEU,
447 ARMneon_VCGES,
448 ARMneon_VCGTF,
449 ARMneon_VCGEF,
450 ARMneon_VCEQ,
451 ARMneon_VCEQF,
452 ARMneon_VEXT,
453 ARMneon_VMUL,
454 ARMneon_VMULFP,
455 ARMneon_VMULLU,
456 ARMneon_VMULLS,
457 ARMneon_VMULP,
458 ARMneon_VMULLP,
459 ARMneon_VQDMULH,
460 ARMneon_VQRDMULH,
461 ARMneon_VPADD,
462 ARMneon_VPMINU,
463 ARMneon_VPMINS,
464 ARMneon_VPMINF,
465 ARMneon_VPMAXU,
466 ARMneon_VPMAXS,
467 ARMneon_VPMAXF,
468 ARMneon_VTBL,
469 ARMneon_VQDMULL,
470 ARMneon_VRECPS,
471 ARMneon_VRSQRTS,
472 ARMneon_INVALID
473 /* ... */
475 ARMNeonBinOp;
477 typedef
478 enum {
479 ARMneon_VSHL=150,
480 ARMneon_VSAL, /* Yah, not SAR but SAL */
481 ARMneon_VQSHL,
482 ARMneon_VQSAL
484 ARMNeonShiftOp;
486 typedef
487 enum {
488 ARMneon_COPY=160,
489 ARMneon_COPYLU,
490 ARMneon_COPYLS,
491 ARMneon_COPYN,
492 ARMneon_COPYQNSS,
493 ARMneon_COPYQNUS,
494 ARMneon_COPYQNUU,
495 ARMneon_NOT,
496 ARMneon_EQZ,
497 ARMneon_DUP,
498 ARMneon_PADDLS,
499 ARMneon_PADDLU,
500 ARMneon_CNT,
501 ARMneon_CLZ,
502 ARMneon_CLS,
503 ARMneon_VCVTxFPxINT,
504 ARMneon_VQSHLNSS,
505 ARMneon_VQSHLNUU,
506 ARMneon_VQSHLNUS,
507 ARMneon_VCVTFtoU,
508 ARMneon_VCVTFtoS,
509 ARMneon_VCVTUtoF,
510 ARMneon_VCVTStoF,
511 ARMneon_VCVTFtoFixedU,
512 ARMneon_VCVTFtoFixedS,
513 ARMneon_VCVTFixedUtoF,
514 ARMneon_VCVTFixedStoF,
515 ARMneon_VCVTF16toF32,
516 ARMneon_VCVTF32toF16,
517 ARMneon_REV16,
518 ARMneon_REV32,
519 ARMneon_REV64,
520 ARMneon_ABS,
521 ARMneon_VNEGF,
522 ARMneon_VRECIP,
523 ARMneon_VRECIPF,
524 ARMneon_VABSFP,
525 ARMneon_VRSQRTEFP,
526 ARMneon_VRSQRTE
527 /* ... */
529 ARMNeonUnOp;
531 typedef
532 enum {
533 ARMneon_SETELEM=200,
534 ARMneon_GETELEMU,
535 ARMneon_GETELEMS,
536 ARMneon_VDUP,
538 ARMNeonUnOpS;
540 typedef
541 enum {
542 ARMneon_TRN=210,
543 ARMneon_ZIP,
544 ARMneon_UZP
545 /* ... */
547 ARMNeonDualOp;
549 extern const HChar* showARMNeonBinOp ( ARMNeonBinOp op );
550 extern const HChar* showARMNeonUnOp ( ARMNeonUnOp op );
551 extern const HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
552 extern const HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
553 extern const HChar* showARMNeonDualOp ( ARMNeonDualOp op );
554 extern const HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
555 extern const HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
556 extern const HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
557 extern const HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
558 extern const HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
560 typedef
561 enum {
562 /* baseline */
563 ARMin_Alu=220,
564 ARMin_Shift,
565 ARMin_Unary,
566 ARMin_CmpOrTst,
567 ARMin_Mov,
568 ARMin_Imm32,
569 ARMin_LdSt32,
570 ARMin_LdSt16,
571 ARMin_LdSt8U,
572 ARMin_Ld8S,
573 ARMin_XDirect, /* direct transfer to GA */
574 ARMin_XIndir, /* indirect transfer to GA */
575 ARMin_XAssisted, /* assisted transfer to GA */
576 ARMin_CMov,
577 ARMin_Call,
578 ARMin_Mul,
579 ARMin_LdrEX,
580 ARMin_StrEX,
581 /* vfp */
582 ARMin_VLdStD,
583 ARMin_VLdStS,
584 ARMin_VAluD,
585 ARMin_VAluS,
586 ARMin_VUnaryD,
587 ARMin_VUnaryS,
588 ARMin_VCmpD,
589 ARMin_VCMovD,
590 ARMin_VCMovS,
591 ARMin_VCvtSD,
592 ARMin_VXferQ,
593 ARMin_VXferD,
594 ARMin_VXferS,
595 ARMin_VCvtID,
596 ARMin_VRIntR,
597 ARMin_VMinMaxNum,
598 ARMin_FPSCR,
599 ARMin_MFence,
600 ARMin_CLREX,
601 /* 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,
610 ARMin_NShl64, // special case 64-bit shift of Dreg by immediate
611 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.
619 NOTE: source and destination registers should be different! */
620 ARMin_Add32,
621 ARMin_EvCheck, /* Event check */
622 ARMin_ProfInc /* 64-bit profile counter increment */
624 ARMInstrTag;
626 /* Destinations are on the LEFT (first operand) */
628 typedef
629 struct {
630 ARMInstrTag tag;
631 union {
632 /* 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;
668 /* 32-bit load or store, may be conditional */
669 struct {
670 ARMCondCode cc; /* ARMcc_NV is not allowed */
671 Bool isLoad;
672 HReg rD;
673 ARMAMode1* amode;
674 } LdSt32;
675 /* 16-bit load or store, may be conditional */
676 struct {
677 ARMCondCode cc; /* ARMcc_NV is not allowed */
678 Bool isLoad;
679 Bool signedLoad;
680 HReg rD;
681 ARMAMode2* amode;
682 } LdSt16;
683 /* 8-bit (unsigned) load or store, may be conditional */
684 struct {
685 ARMCondCode cc; /* ARMcc_NV is not allowed */
686 Bool isLoad;
687 HReg rD;
688 ARMAMode1* amode;
689 } LdSt8U;
690 /* 8-bit signed load, may be conditional */
691 struct {
692 ARMCondCode cc; /* ARMcc_NV is not allowed */
693 HReg rD;
694 ARMAMode2* amode;
695 } Ld8S;
696 /* 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). */
699 struct {
700 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 */
718 IRJumpKind jk;
719 } XAssisted;
720 /* 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;
731 Addr32 target;
732 Int nArgRegs; /* # regs carrying args: 0 .. 4 */
733 RetLoc rloc; /* where the return value will be */
734 } 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;
747 /* LDREX{,H,B} r2, [r4] and
748 LDREXD r2, r3, [r4] (on LE hosts, transferred value is r3:r2)
749 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 {
753 Int szB; /* 1, 2, 4 or 8 */
754 } LdrEX;
755 /* 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)
759 Ditto comment re fixed registers. */
760 struct {
761 Int szB; /* 1, 2, 4 or 8 */
762 } 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;
828 /* 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;
835 /* 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 /* Round a F32 or F64 value to the nearest integral value,
857 according to the FPSCR.RM. For ARM >= V8 hosts only. */
858 struct {
859 Bool isF64;
860 HReg dst;
861 HReg src;
862 } VRIntR;
863 /* Do Min/Max of F32 or F64 values, propagating the numerical arg
864 if the other is a qNaN. For ARM >= V8 hosts only. */
865 struct {
866 Bool isF64;
867 Bool isMax;
868 HReg dst;
869 HReg srcL;
870 HReg srcR;
871 } VMinMaxNum;
872 /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
873 struct {
874 Bool toFPSCR;
875 HReg iReg;
876 } FPSCR;
877 /* Mem fence. An insn which fences all loads and stores as
878 much as possible before continuing. On ARM we emit the
879 sequence
880 mcr 15,0,r0,c7,c10,4 (DSB)
881 mcr 15,0,r0,c7,c10,5 (DMB)
882 mcr 15,0,r0,c7,c5,4 (ISB)
883 which is probably total overkill, but better safe than
884 sorry.
886 struct {
887 } MFence;
888 /* A CLREX instruction. */
889 struct {
890 } CLREX;
891 /* Neon data processing instruction: 3 registers of the same
892 length */
893 struct {
894 ARMNeonBinOp op;
895 HReg dst;
896 HReg argL;
897 HReg argR;
898 UInt size;
899 Bool Q;
900 } NBinary;
901 struct {
902 ARMNeonBinOp op;
903 ARMNRS* dst;
904 ARMNRS* argL;
905 ARMNRS* argR;
906 UInt size;
907 Bool Q;
908 } NBinaryS;
909 struct {
910 ARMNeonShiftOp op;
911 HReg dst;
912 HReg argL;
913 HReg argR;
914 UInt size;
915 Bool Q;
916 } NShift;
917 struct {
918 HReg dst;
919 HReg src;
920 UInt amt; /* 1..63 only */
921 } NShl64;
922 struct {
923 Bool isLoad;
924 HReg dQ;
925 ARMAModeN *amode;
926 } NLdStQ;
927 struct {
928 Bool isLoad;
929 HReg dD;
930 ARMAModeN *amode;
931 } NLdStD;
932 struct {
933 ARMNeonUnOpS op;
934 ARMNRS* dst;
935 ARMNRS* src;
936 UInt size;
937 Bool Q;
938 } NUnaryS;
939 struct {
940 ARMNeonUnOp op;
941 HReg dst;
942 HReg src;
943 UInt size;
944 Bool Q;
945 } NUnary;
946 /* Takes two arguments and modifies them both. */
947 struct {
948 ARMNeonDualOp op;
949 HReg arg1;
950 HReg arg2;
951 UInt size;
952 Bool Q;
953 } NDual;
954 struct {
955 HReg dst;
956 ARMNImm* imm;
957 } NeonImm;
958 /* 128-bit Neon move src to dst on the given condition, which
959 may not be ARMcc_AL. */
960 struct {
961 ARMCondCode cond;
962 HReg dst;
963 HReg src;
964 } NCMovQ;
965 struct {
966 /* Note: rD != rN */
967 HReg rD;
968 HReg rN;
969 UInt imm32;
970 } Add32;
971 struct {
972 ARMAMode1* amCounter;
973 ARMAMode1* amFailAddr;
974 } EvCheck;
975 struct {
976 /* No fields. The address of the counter to inc is
977 installed later, post-translation, by patching it in,
978 as it is not known at translation time. */
979 } ProfInc;
980 } ARMin;
982 ARMInstr;
985 extern ARMInstr* ARMInstr_Alu ( ARMAluOp, HReg, HReg, ARMRI84* );
986 extern ARMInstr* ARMInstr_Shift ( ARMShiftOp, HReg, HReg, ARMRI5* );
987 extern ARMInstr* ARMInstr_Unary ( ARMUnaryOp, HReg, HReg );
988 extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
989 extern ARMInstr* ARMInstr_Mov ( HReg, ARMRI84* );
990 extern ARMInstr* ARMInstr_Imm32 ( HReg, UInt );
991 extern ARMInstr* ARMInstr_LdSt32 ( ARMCondCode,
992 Bool isLoad, HReg, ARMAMode1* );
993 extern ARMInstr* ARMInstr_LdSt16 ( ARMCondCode,
994 Bool isLoad, Bool signedLoad,
995 HReg, ARMAMode2* );
996 extern ARMInstr* ARMInstr_LdSt8U ( ARMCondCode,
997 Bool isLoad, HReg, ARMAMode1* );
998 extern ARMInstr* ARMInstr_Ld8S ( ARMCondCode, HReg, ARMAMode2* );
999 extern ARMInstr* ARMInstr_XDirect ( Addr32 dstGA, ARMAMode1* amR15T,
1000 ARMCondCode cond, Bool toFastEP );
1001 extern ARMInstr* ARMInstr_XIndir ( HReg dstGA, ARMAMode1* amR15T,
1002 ARMCondCode cond );
1003 extern ARMInstr* ARMInstr_XAssisted ( HReg dstGA, ARMAMode1* amR15T,
1004 ARMCondCode cond, IRJumpKind jk );
1005 extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src );
1006 extern ARMInstr* ARMInstr_Call ( ARMCondCode, Addr32, Int nArgRegs,
1007 RetLoc rloc );
1008 extern ARMInstr* ARMInstr_Mul ( ARMMulOp op );
1009 extern ARMInstr* ARMInstr_LdrEX ( Int szB );
1010 extern ARMInstr* ARMInstr_StrEX ( Int szB );
1011 extern ARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg, ARMAModeV* );
1012 extern ARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg, ARMAModeV* );
1013 extern ARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg, HReg, HReg );
1014 extern ARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg, HReg, HReg );
1015 extern ARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp, HReg dst, HReg src );
1016 extern ARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp, HReg dst, HReg src );
1017 extern ARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR );
1018 extern ARMInstr* ARMInstr_VCMovD ( ARMCondCode, HReg dst, HReg src );
1019 extern ARMInstr* ARMInstr_VCMovS ( ARMCondCode, HReg dst, HReg src );
1020 extern ARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src );
1021 extern ARMInstr* ARMInstr_VXferQ ( Bool toQ, HReg qD, HReg dHi, HReg dLo );
1022 extern ARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo );
1023 extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo );
1024 extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned,
1025 HReg dst, HReg src );
1026 extern ARMInstr* ARMInstr_VRIntR ( Bool isF64, HReg dst, HReg src );
1027 extern ARMInstr* ARMInstr_VMinMaxNum ( Bool isF64, Bool isMax,
1028 HReg dst, HReg srcL, HReg srcR );
1029 extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg );
1030 extern ARMInstr* ARMInstr_MFence ( void );
1031 extern ARMInstr* ARMInstr_CLREX ( void );
1032 extern ARMInstr* ARMInstr_NLdStQ ( Bool isLoad, HReg, ARMAModeN* );
1033 extern ARMInstr* ARMInstr_NLdStD ( Bool isLoad, HReg, ARMAModeN* );
1034 extern ARMInstr* ARMInstr_NUnary ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
1035 extern ARMInstr* ARMInstr_NUnaryS ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
1036 UInt, Bool );
1037 extern ARMInstr* ARMInstr_NDual ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
1038 extern ARMInstr* ARMInstr_NBinary ( ARMNeonBinOp, HReg, HReg, HReg,
1039 UInt, Bool );
1040 extern ARMInstr* ARMInstr_NShift ( ARMNeonShiftOp, HReg, HReg, HReg,
1041 UInt, Bool );
1042 extern ARMInstr* ARMInstr_NShl64 ( HReg, HReg, UInt );
1043 extern ARMInstr* ARMInstr_NeonImm ( HReg, ARMNImm* );
1044 extern ARMInstr* ARMInstr_NCMovQ ( ARMCondCode, HReg, HReg );
1045 extern ARMInstr* ARMInstr_Add32 ( HReg rD, HReg rN, UInt imm32 );
1046 extern ARMInstr* ARMInstr_EvCheck ( ARMAMode1* amCounter,
1047 ARMAMode1* amFailAddr );
1048 extern ARMInstr* ARMInstr_ProfInc ( void );
1050 extern void ppARMInstr ( const ARMInstr* );
1053 /* Some functions that insulate the register allocator from details
1054 of the underlying instruction set. */
1055 extern void getRegUsage_ARMInstr ( HRegUsage*, const ARMInstr*, Bool );
1056 extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool );
1057 extern Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc,
1058 UChar* buf, Int nbuf, const ARMInstr* i,
1059 Bool mode64,
1060 VexEndness endness_host,
1061 const void* disp_cp_chain_me_to_slowEP,
1062 const void* disp_cp_chain_me_to_fastEP,
1063 const void* disp_cp_xindir,
1064 const void* disp_cp_xassisted );
1066 extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1067 HReg rreg, Int offset, Bool );
1068 extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1069 HReg rreg, Int offset, Bool );
1070 extern ARMInstr* genMove_ARM(HReg from, HReg to, Bool);
1072 extern const RRegUniverse* getRRegUniverse_ARM ( void );
1074 extern HInstrArray* iselSB_ARM ( const IRSB*,
1075 VexArch,
1076 const VexArchInfo*,
1077 const VexAbiInfo*,
1078 Int offs_Host_EvC_Counter,
1079 Int offs_Host_EvC_FailAddr,
1080 Bool chainingAllowed,
1081 Bool addProfInc,
1082 Addr max_ga );
1084 /* How big is an event check? This is kind of a kludge because it
1085 depends on the offsets of host_EvC_FAILADDR and
1086 host_EvC_COUNTER. */
1087 extern Int evCheckSzB_ARM (void);
1089 /* Perform a chaining and unchaining of an XDirect jump. */
1090 extern VexInvalRange chainXDirect_ARM ( VexEndness endness_host,
1091 void* place_to_chain,
1092 const void* disp_cp_chain_me_EXPECTED,
1093 const void* place_to_jump_to );
1095 extern VexInvalRange unchainXDirect_ARM ( VexEndness endness_host,
1096 void* place_to_unchain,
1097 const void* place_to_jump_to_EXPECTED,
1098 const void* disp_cp_chain_me );
1100 /* Patch the counter location into an existing ProfInc point. */
1101 extern VexInvalRange patchProfInc_ARM ( VexEndness endness_host,
1102 void* place_to_patch,
1103 const ULong* location_of_counter );
1106 #endif /* ndef __VEX_HOST_ARM_DEFS_H */
1108 /*---------------------------------------------------------------*/
1109 /*--- end host_arm_defs.h ---*/
1110 /*---------------------------------------------------------------*/