2 /*---------------------------------------------------------------*/
3 /*--- begin host_arm_defs.h ---*/
4 /*---------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2004-2010 OpenWorks LLP
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
31 #ifndef __VEX_HOST_ARM_DEFS_H
32 #define __VEX_HOST_ARM_DEFS_H
35 /* --------- Registers. --------- */
37 /* The usual HReg abstraction.
38 There are 16 general purpose regs.
41 extern void ppHRegARM ( HReg );
43 extern HReg hregARM_R0 ( void );
44 extern HReg hregARM_R1 ( void );
45 extern HReg hregARM_R2 ( void );
46 extern HReg hregARM_R3 ( void );
47 extern HReg hregARM_R4 ( void );
48 extern HReg hregARM_R5 ( void );
49 extern HReg hregARM_R6 ( void );
50 extern HReg hregARM_R7 ( void );
51 extern HReg hregARM_R8 ( void );
52 extern HReg hregARM_R9 ( void );
53 extern HReg hregARM_R10 ( void );
54 extern HReg hregARM_R11 ( void );
55 extern HReg hregARM_R12 ( void );
56 extern HReg hregARM_R13 ( void );
57 extern HReg hregARM_R14 ( void );
58 extern HReg hregARM_R15 ( void );
59 extern HReg hregARM_D8 ( void );
60 extern HReg hregARM_D9 ( void );
61 extern HReg hregARM_D10 ( void );
62 extern HReg hregARM_D11 ( void );
63 extern HReg hregARM_D12 ( void );
64 extern HReg hregARM_S26 ( void );
65 extern HReg hregARM_S27 ( void );
66 extern HReg hregARM_S28 ( void );
67 extern HReg hregARM_S29 ( void );
68 extern HReg hregARM_S30 ( void );
70 /* Number of registers used arg passing in function calls */
71 #define ARM_N_ARGREGS 4 /* r0, r1, r2, r3 */
74 /* --------- Condition codes. --------- */
78 ARMcc_EQ = 0, /* equal : Z=1 */
79 ARMcc_NE = 1, /* not equal : Z=0 */
81 ARMcc_HS = 2, /* >=u (higher or same) : C=1 */
82 ARMcc_LO = 3, /* <u (lower) : C=0 */
84 ARMcc_MI = 4, /* minus (negative) : N=1 */
85 ARMcc_PL = 5, /* plus (zero or +ve) : N=0 */
87 ARMcc_VS = 6, /* overflow : V=1 */
88 ARMcc_VC = 7, /* no overflow : V=0 */
90 ARMcc_HI = 8, /* >u (higher) : C=1 && Z=0 */
91 ARMcc_LS = 9, /* <=u (lower or same) : C=0 || Z=1 */
93 ARMcc_GE = 10, /* >=s (signed greater or equal) : N=V */
94 ARMcc_LT = 11, /* <s (signed less than) : N!=V */
96 ARMcc_GT = 12, /* >s (signed greater) : Z=0 && N=V */
97 ARMcc_LE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
99 ARMcc_AL = 14, /* always (unconditional) */
100 ARMcc_NV = 15 /* never (basically undefined meaning), deprecated */
104 extern HChar* showARMCondCode ( ARMCondCode );
108 /* --------- Memory address expressions (amodes). --------- */
110 /* --- Addressing Mode 1 --- */
113 ARMam1_RI=1, /* reg +/- imm12 */
114 ARMam1_RRS /* reg1 + (reg2 << 0, 1 2 or 3) */
124 Int simm13; /* -4095 .. +4095 */
129 UInt shift; /* 0, 1 2 or 3 */
135 extern ARMAMode1* ARMAMode1_RI ( HReg reg, Int simm13 );
136 extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
138 extern void ppARMAMode1 ( ARMAMode1* );
141 /* --- Addressing Mode 2 --- */
144 ARMam2_RI=3, /* reg +/- imm8 */
145 ARMam2_RR /* reg1 + reg2 */
155 Int simm9; /* -255 .. 255 */
165 extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
166 extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
168 extern void ppARMAMode2 ( ARMAMode2* );
171 /* --- Addressing Mode suitable for VFP --- */
172 /* The simm11 is encoded as 8 bits + 1 sign bit,
173 so can only be 0 % 4. */
177 Int simm11; /* -1020, -1016 .. 1016, 1020 */
181 extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
183 extern void ppARMAModeV ( ARMAModeV* );
186 /* --------- Reg or imm-8x4 operands --------- */
187 /* a.k.a (a very restricted form of) Shifter Operand,
188 in the ARM parlance. */
192 ARMri84_I84=5, /* imm8 `ror` (2 * imm4) */
212 extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
213 extern ARMRI84* ARMRI84_R ( HReg );
215 extern void ppARMRI84 ( ARMRI84* );
218 /* --------- Reg or imm5 operands --------- */
221 ARMri5_I5=7, /* imm5, 1 .. 31 only (no zero!) */
240 extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
241 extern ARMRI5* ARMRI5_R ( HReg );
243 extern void ppARMRI5 ( ARMRI5* );
246 /* --------- Instructions. --------- */
251 ARMalu_ADD=10, /* plain 32-bit add */
252 ARMalu_ADDS, /* 32-bit add, and set the flags */
253 ARMalu_ADC, /* 32-bit add with carry */
254 ARMalu_SUB, /* plain 32-bit subtract */
255 ARMalu_SUBS, /* 32-bit subtract, and set the flags */
256 ARMalu_SBC, /* 32-bit subtract with carry */
264 extern HChar* showARMAluOp ( ARMAluOp op );
275 extern HChar* showARMShiftOp ( ARMShiftOp op );
286 extern HChar* showARMUnaryOp ( ARMUnaryOp op );
297 extern HChar* showARMMulOp ( ARMMulOp op );
309 extern HChar* showARMVfpOp ( ARMVfpOp op );
321 extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
362 /* Destinations are on the LEFT (first operand) */
368 /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
375 /* SHL/SHR/SAR, 2nd arg is reg or imm */
388 /* CMP/TST; subtract/and, discard result, set NZCV */
394 /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
399 /* Pseudo-insn; make a 32-bit immediate */
404 /* 32-bit load or store */
410 /* 16-bit load or store */
417 /* 8-bit (unsigned) load or store */
423 /* 8-bit signed load */
428 /* Pseudo-insn. Go to guest address gnext, on given
429 condition, which could be ARMcc_AL. */
435 /* Mov src to dst on the given condition, which may not
442 /* Pseudo-insn. Call target (an absolute address), on given
443 condition (which could be ARMcc_AL). */
447 Int nArgRegs; /* # regs carrying args: 0 .. 4 */
449 /* (PLAIN) 32 * 32 -> 32: r0 = r2 * r3
450 (ZX) 32 *u 32 -> 64: r1:r0 = r2 *u r3
451 (SX) 32 *s 32 -> 64: r1:r0 = r2 *s r3
452 Why hardwired registers? Because the ARM ARM specifies
453 (eg for straight MUL) the result (Rd) and the left arg (Rm)
454 may not be the same register. That's not a constraint we
455 can enforce in the register allocator (without mucho extra
456 complexity). Hence hardwire it. At least using caller-saves
457 registers, which are less likely to be in use. */
461 /* LDREX{,H,B} r0, [r1]
462 Again, hardwired registers since this is not performance
463 critical, and there are possibly constraints on the
464 registers that we can't express in the register allocator.*/
466 Int szB; /* currently only 4 is allowed */
468 /* STREX{,H,B} r0, r1, [r2]
470 Ditto comment re fixed registers. */
472 Int szB; /* currently only 4 is allowed */
474 /* VFP INSTRUCTIONS */
475 /* 64-bit Fp load/store */
481 /* 32-bit Fp load/store */
487 /* 64-bit FP binary arithmetic */
494 /* 32-bit FP binary arithmetic */
501 /* 64-bit FP unary, also reg-reg move */
507 /* 32-bit FP unary, also reg-reg move */
513 /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
518 /* 64-bit FP mov src to dst on the given condition, which may
525 /* 32-bit FP mov src to dst on the given condition, which may
532 /* Convert between 32-bit and 64-bit FP values (both ways).
535 Bool sToD; /* True: F32->F64. False: F64->F32 */
539 /* Transfer a VFP D reg to/from two integer registers (VMOV) */
546 /* Transfer a VFP S reg to/from an integer register (VMOV) */
552 /* Convert between 32-bit ints and 64-bit FP values (both ways
553 and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
555 Bool iToD; /* True: I32->F64. False: F64->I32 */
556 Bool syned; /* True: I32 is signed. False: I32 is unsigned */
560 /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
565 /* Mem fence. An insn which fences all loads and stores as
566 much as possible before continuing. On ARM we emit the
568 mcr 15,0,r0,c7,c10,4 (DSB)
569 mcr 15,0,r0,c7,c10,5 (DMB)
570 mcr 15,0,r0,c7,c5,4 (ISB)
571 which is probably total overkill, but better safe than
582 extern ARMInstr* ARMInstr_Alu ( ARMAluOp, HReg, HReg, ARMRI84* );
583 extern ARMInstr* ARMInstr_Shift ( ARMShiftOp, HReg, HReg, ARMRI5* );
584 extern ARMInstr* ARMInstr_Unary ( ARMUnaryOp, HReg, HReg );
585 extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
586 extern ARMInstr* ARMInstr_Mov ( HReg, ARMRI84* );
587 extern ARMInstr* ARMInstr_Imm32 ( HReg, UInt );
588 extern ARMInstr* ARMInstr_LdSt32 ( Bool isLoad, HReg, ARMAMode1* );
589 extern ARMInstr* ARMInstr_LdSt16 ( Bool isLoad, Bool signedLoad,
591 extern ARMInstr* ARMInstr_LdSt8U ( Bool isLoad, HReg, ARMAMode1* );
592 extern ARMInstr* ARMInstr_Ld8S ( HReg, ARMAMode2* );
593 extern ARMInstr* ARMInstr_Goto ( IRJumpKind, ARMCondCode, HReg gnext );
594 extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src );
595 extern ARMInstr* ARMInstr_Call ( ARMCondCode, HWord, Int nArgRegs );
596 extern ARMInstr* ARMInstr_Mul ( ARMMulOp op );
597 extern ARMInstr* ARMInstr_LdrEX ( Int szB );
598 extern ARMInstr* ARMInstr_StrEX ( Int szB );
599 extern ARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg, ARMAModeV* );
600 extern ARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg, ARMAModeV* );
601 extern ARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg, HReg, HReg );
602 extern ARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg, HReg, HReg );
603 extern ARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp, HReg dst, HReg src );
604 extern ARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp, HReg dst, HReg src );
605 extern ARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR );
606 extern ARMInstr* ARMInstr_VCMovD ( ARMCondCode, HReg dst, HReg src );
607 extern ARMInstr* ARMInstr_VCMovS ( ARMCondCode, HReg dst, HReg src );
608 extern ARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src );
609 extern ARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo );
610 extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo );
611 extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned,
612 HReg dst, HReg src );
613 extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg );
614 extern ARMInstr* ARMInstr_MFence ( void );
616 extern void ppARMInstr ( ARMInstr* );
619 /* Some functions that insulate the register allocator from details
620 of the underlying instruction set. */
621 extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool );
622 extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool );
623 extern Bool isMove_ARMInstr ( ARMInstr*, HReg*, HReg* );
624 extern Int emit_ARMInstr ( UChar* buf, Int nbuf, ARMInstr*,
625 Bool, void* dispatch );
627 extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
628 HReg rreg, Int offset, Bool );
629 extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
630 HReg rreg, Int offset, Bool );
632 extern void getAllocableRegs_ARM ( Int*, HReg** );
633 extern HInstrArray* iselSB_ARM ( IRSB*, VexArch,
634 VexArchInfo*, VexAbiInfo* );
636 #endif /* ndef __VEX_HOST_ARM_DEFS_H */
638 /*---------------------------------------------------------------*/
639 /*--- end host_arm_defs.h ---*/
640 /*---------------------------------------------------------------*/