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
34 extern UInt arm_hwcaps;
37 /* --------- Registers. --------- */
39 /* The usual HReg abstraction.
40 There are 16 general purpose regs.
43 extern void ppHRegARM ( HReg );
45 extern HReg hregARM_R0 ( void );
46 extern HReg hregARM_R1 ( void );
47 extern HReg hregARM_R2 ( void );
48 extern HReg hregARM_R3 ( void );
49 extern HReg hregARM_R4 ( void );
50 extern HReg hregARM_R5 ( void );
51 extern HReg hregARM_R6 ( void );
52 extern HReg hregARM_R7 ( void );
53 extern HReg hregARM_R8 ( void );
54 extern HReg hregARM_R9 ( void );
55 extern HReg hregARM_R10 ( void );
56 extern HReg hregARM_R11 ( void );
57 extern HReg hregARM_R12 ( void );
58 extern HReg hregARM_R13 ( void );
59 extern HReg hregARM_R14 ( void );
60 extern HReg hregARM_R15 ( void );
61 extern HReg hregARM_D8 ( void );
62 extern HReg hregARM_D9 ( void );
63 extern HReg hregARM_D10 ( void );
64 extern HReg hregARM_D11 ( void );
65 extern HReg hregARM_D12 ( void );
66 extern HReg hregARM_S26 ( void );
67 extern HReg hregARM_S27 ( void );
68 extern HReg hregARM_S28 ( void );
69 extern HReg hregARM_S29 ( void );
70 extern HReg hregARM_S30 ( void );
71 extern HReg hregARM_Q8 ( void );
72 extern HReg hregARM_Q9 ( void );
73 extern HReg hregARM_Q10 ( void );
74 extern HReg hregARM_Q11 ( void );
75 extern HReg hregARM_Q12 ( void );
76 extern HReg hregARM_Q13 ( void );
77 extern HReg hregARM_Q14 ( void );
78 extern HReg hregARM_Q15 ( void );
80 /* Number of registers used arg passing in function calls */
81 #define ARM_N_ARGREGS 4 /* r0, r1, r2, r3 */
84 /* --------- Condition codes. --------- */
88 ARMcc_EQ = 0, /* equal : Z=1 */
89 ARMcc_NE = 1, /* not equal : Z=0 */
91 ARMcc_HS = 2, /* >=u (higher or same) : C=1 */
92 ARMcc_LO = 3, /* <u (lower) : C=0 */
94 ARMcc_MI = 4, /* minus (negative) : N=1 */
95 ARMcc_PL = 5, /* plus (zero or +ve) : N=0 */
97 ARMcc_VS = 6, /* overflow : V=1 */
98 ARMcc_VC = 7, /* no overflow : V=0 */
100 ARMcc_HI = 8, /* >u (higher) : C=1 && Z=0 */
101 ARMcc_LS = 9, /* <=u (lower or same) : C=0 || Z=1 */
103 ARMcc_GE = 10, /* >=s (signed greater or equal) : N=V */
104 ARMcc_LT = 11, /* <s (signed less than) : N!=V */
106 ARMcc_GT = 12, /* >s (signed greater) : Z=0 && N=V */
107 ARMcc_LE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
109 ARMcc_AL = 14, /* always (unconditional) */
110 ARMcc_NV = 15 /* never (basically undefined meaning), deprecated */
114 extern HChar* showARMCondCode ( ARMCondCode );
118 /* --------- Memory address expressions (amodes). --------- */
120 /* --- Addressing Mode 1 --- */
123 ARMam1_RI=1, /* reg +/- imm12 */
124 ARMam1_RRS /* reg1 + (reg2 << 0, 1 2 or 3) */
134 Int simm13; /* -4095 .. +4095 */
139 UInt shift; /* 0, 1 2 or 3 */
145 extern ARMAMode1* ARMAMode1_RI ( HReg reg, Int simm13 );
146 extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
148 extern void ppARMAMode1 ( ARMAMode1* );
151 /* --- Addressing Mode 2 --- */
154 ARMam2_RI=3, /* reg +/- imm8 */
155 ARMam2_RR /* reg1 + reg2 */
165 Int simm9; /* -255 .. 255 */
175 extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
176 extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
178 extern void ppARMAMode2 ( ARMAMode2* );
181 /* --- Addressing Mode suitable for VFP --- */
182 /* The simm11 is encoded as 8 bits + 1 sign bit,
183 so can only be 0 % 4. */
187 Int simm11; /* -1020, -1016 .. 1016, 1020 */
191 extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
193 extern void ppARMAModeV ( ARMAModeV* );
195 /* --- Addressing Mode suitable for Neon --- */
220 extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg );
221 extern ARMAModeN* mkARMAModeN_R ( HReg );
222 extern void ppARMAModeN ( ARMAModeN* );
224 /* --------- Reg or imm-8x4 operands --------- */
225 /* a.k.a (a very restricted form of) Shifter Operand,
226 in the ARM parlance. */
230 ARMri84_I84=7, /* imm8 `ror` (2 * imm4) */
250 extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
251 extern ARMRI84* ARMRI84_R ( HReg );
253 extern void ppARMRI84 ( ARMRI84* );
256 /* --------- Reg or imm5 operands --------- */
259 ARMri5_I5=9, /* imm5, 1 .. 31 only (no zero!) */
278 extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
279 extern ARMRI5* ARMRI5_R ( HReg );
281 extern void ppARMRI5 ( ARMRI5* );
283 /* -------- Neon Immediate operand -------- */
285 /* imm8 = abcdefgh, B = NOT(b);
287 type | value (64bit binary)
288 -----+-------------------------------------------------------------------------
289 0 | 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh
290 1 | 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000
291 2 | 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000
292 3 | abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000
293 4 | 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh
294 5 | abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000
295 6 | abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh
296 7 | 00000000 00000000 abcdefgh 11111111 00000000 00000000 abcdefgh 11111111
297 8 | 00000000 abcdefgh 11111111 11111111 00000000 abcdefgh 11111111 11111111
298 9 | aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
299 10 | aBbbbbbc defgh000 00000000 00000000 aBbbbbbc defgh000 00000000 00000000
300 -----+-------------------------------------------------------------------------
303 (-1)^S * 2^exp * mantissa
304 where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16
314 extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 );
315 extern ULong ARMNImm_to_Imm64 ( ARMNImm* );
316 extern ARMNImm* Imm64_to_ARMNImm ( ULong );
318 extern void ppARMNImm ( ARMNImm* );
320 /* ------ Neon Register or Scalar Operand ------ */
337 extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index);
338 extern void ppARMNRS ( ARMNRS* );
340 /* --------- Instructions. --------- */
345 ARMalu_ADD=20, /* plain 32-bit add */
346 ARMalu_ADDS, /* 32-bit add, and set the flags */
347 ARMalu_ADC, /* 32-bit add with carry */
348 ARMalu_SUB, /* plain 32-bit subtract */
349 ARMalu_SUBS, /* 32-bit subtract, and set the flags */
350 ARMalu_SBC, /* 32-bit subtract with carry */
358 extern HChar* showARMAluOp ( ARMAluOp op );
369 extern HChar* showARMShiftOp ( ARMShiftOp op );
380 extern HChar* showARMUnaryOp ( ARMUnaryOp op );
391 extern HChar* showARMMulOp ( ARMMulOp op );
403 extern HChar* showARMVfpOp ( ARMVfpOp op );
415 extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
475 ARMneon_VSAL, /* Yah, not SAR but SAL */
506 ARMneon_VCVTFtoFixedU,
507 ARMneon_VCVTFtoFixedS,
508 ARMneon_VCVTFixedUtoF,
509 ARMneon_VCVTFixedStoF,
510 ARMneon_VCVTF16toF32,
511 ARMneon_VCVTF32toF16,
544 extern HChar* showARMNeonBinOp ( ARMNeonBinOp op );
545 extern HChar* showARMNeonUnOp ( ARMNeonUnOp op );
546 extern HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
547 extern HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
548 extern HChar* showARMNeonDualOp ( ARMNeonDualOp op );
549 extern HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
550 extern HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
551 extern HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
552 extern HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
553 extern HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
601 /* This is not a NEON instruction. Actually there is no corresponding
602 instruction in ARM instruction set at all. We need this one to
603 generate spill/reload of 128-bit registers since current register
604 allocator demands them to consist of no more than two instructions.
605 We will split this instruction into 2 or 3 ARM instructions on the
608 NOTE: source and destination registers should be different! */
613 /* Destinations are on the LEFT (first operand) */
619 /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
626 /* SHL/SHR/SAR, 2nd arg is reg or imm */
639 /* CMP/TST; subtract/and, discard result, set NZCV */
645 /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
650 /* Pseudo-insn; make a 32-bit immediate */
655 /* 32-bit load or store */
661 /* 16-bit load or store */
668 /* 8-bit (unsigned) load or store */
674 /* 8-bit signed load */
679 /* Pseudo-insn. Go to guest address gnext, on given
680 condition, which could be ARMcc_AL. */
686 /* Mov src to dst on the given condition, which may not
693 /* Pseudo-insn. Call target (an absolute address), on given
694 condition (which could be ARMcc_AL). */
698 Int nArgRegs; /* # regs carrying args: 0 .. 4 */
700 /* (PLAIN) 32 * 32 -> 32: r0 = r2 * r3
701 (ZX) 32 *u 32 -> 64: r1:r0 = r2 *u r3
702 (SX) 32 *s 32 -> 64: r1:r0 = r2 *s r3
703 Why hardwired registers? Because the ARM ARM specifies
704 (eg for straight MUL) the result (Rd) and the left arg (Rm)
705 may not be the same register. That's not a constraint we
706 can enforce in the register allocator (without mucho extra
707 complexity). Hence hardwire it. At least using caller-saves
708 registers, which are less likely to be in use. */
712 /* LDREX{,H,B} r0, [r1]
713 Again, hardwired registers since this is not performance
714 critical, and there are possibly constraints on the
715 registers that we can't express in the register allocator.*/
717 Int szB; /* currently only 4 is allowed */
719 /* STREX{,H,B} r0, r1, [r2]
721 Ditto comment re fixed registers. */
723 Int szB; /* currently only 4 is allowed */
725 /* VFP INSTRUCTIONS */
726 /* 64-bit Fp load/store */
732 /* 32-bit Fp load/store */
738 /* 64-bit FP binary arithmetic */
745 /* 32-bit FP binary arithmetic */
752 /* 64-bit FP unary, also reg-reg move */
758 /* 32-bit FP unary, also reg-reg move */
764 /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
769 /* 64-bit FP mov src to dst on the given condition, which may
776 /* 32-bit FP mov src to dst on the given condition, which may
783 /* Convert between 32-bit and 64-bit FP values (both ways).
786 Bool sToD; /* True: F32->F64. False: F64->F32 */
790 /* Transfer a VFP D reg to/from two integer registers (VMOV) */
797 /* Transfer a VFP S reg to/from an integer register (VMOV) */
803 /* Convert between 32-bit ints and 64-bit FP values (both ways
804 and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
806 Bool iToD; /* True: I32->F64. False: F64->I32 */
807 Bool syned; /* True: I32 is signed. False: I32 is unsigned */
811 /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
816 /* Mem fence. An insn which fences all loads and stores as
817 much as possible before continuing. On ARM we emit the
819 mcr 15,0,r0,c7,c10,4 (DSB)
820 mcr 15,0,r0,c7,c10,5 (DMB)
821 mcr 15,0,r0,c7,c5,4 (ISB)
822 which is probably total overkill, but better safe than
827 /* Neon data processing instruction: 3 registers of the same
877 /* Takes two arguments and modifies them both. */
889 /* 128-bit Neon move src to dst on the given condition, which
890 may not be ARMcc_AL. */
907 extern ARMInstr* ARMInstr_Alu ( ARMAluOp, HReg, HReg, ARMRI84* );
908 extern ARMInstr* ARMInstr_Shift ( ARMShiftOp, HReg, HReg, ARMRI5* );
909 extern ARMInstr* ARMInstr_Unary ( ARMUnaryOp, HReg, HReg );
910 extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
911 extern ARMInstr* ARMInstr_Mov ( HReg, ARMRI84* );
912 extern ARMInstr* ARMInstr_Imm32 ( HReg, UInt );
913 extern ARMInstr* ARMInstr_LdSt32 ( Bool isLoad, HReg, ARMAMode1* );
914 extern ARMInstr* ARMInstr_LdSt16 ( Bool isLoad, Bool signedLoad,
916 extern ARMInstr* ARMInstr_LdSt8U ( Bool isLoad, HReg, ARMAMode1* );
917 extern ARMInstr* ARMInstr_Ld8S ( HReg, ARMAMode2* );
918 extern ARMInstr* ARMInstr_Goto ( IRJumpKind, ARMCondCode, HReg gnext );
919 extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src );
920 extern ARMInstr* ARMInstr_Call ( ARMCondCode, HWord, Int nArgRegs );
921 extern ARMInstr* ARMInstr_Mul ( ARMMulOp op );
922 extern ARMInstr* ARMInstr_LdrEX ( Int szB );
923 extern ARMInstr* ARMInstr_StrEX ( Int szB );
924 extern ARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg, ARMAModeV* );
925 extern ARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg, ARMAModeV* );
926 extern ARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg, HReg, HReg );
927 extern ARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg, HReg, HReg );
928 extern ARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp, HReg dst, HReg src );
929 extern ARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp, HReg dst, HReg src );
930 extern ARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR );
931 extern ARMInstr* ARMInstr_VCMovD ( ARMCondCode, HReg dst, HReg src );
932 extern ARMInstr* ARMInstr_VCMovS ( ARMCondCode, HReg dst, HReg src );
933 extern ARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src );
934 extern ARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo );
935 extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo );
936 extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned,
937 HReg dst, HReg src );
938 extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg );
939 extern ARMInstr* ARMInstr_MFence ( void );
940 extern ARMInstr* ARMInstr_NLdStQ ( Bool isLoad, HReg, ARMAModeN* );
941 extern ARMInstr* ARMInstr_NLdStD ( Bool isLoad, HReg, ARMAModeN* );
942 extern ARMInstr* ARMInstr_NUnary ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
943 extern ARMInstr* ARMInstr_NUnaryS ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
945 extern ARMInstr* ARMInstr_NDual ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
946 extern ARMInstr* ARMInstr_NBinary ( ARMNeonBinOp, HReg, HReg, HReg,
948 extern ARMInstr* ARMInstr_NShift ( ARMNeonShiftOp, HReg, HReg, HReg,
950 extern ARMInstr* ARMInstr_NeonImm ( HReg, ARMNImm* );
951 extern ARMInstr* ARMInstr_NCMovQ ( ARMCondCode, HReg, HReg );
952 extern ARMInstr* ARMInstr_Add32 ( HReg rD, HReg rN, UInt imm32 );
954 extern void ppARMInstr ( ARMInstr* );
957 /* Some functions that insulate the register allocator from details
958 of the underlying instruction set. */
959 extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool );
960 extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool );
961 extern Bool isMove_ARMInstr ( ARMInstr*, HReg*, HReg* );
962 extern Int emit_ARMInstr ( UChar* buf, Int nbuf, ARMInstr*,
963 Bool, void* dispatch );
965 extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
966 HReg rreg, Int offset, Bool );
967 extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
968 HReg rreg, Int offset, Bool );
970 extern void getAllocableRegs_ARM ( Int*, HReg** );
971 extern HInstrArray* iselSB_ARM ( IRSB*, VexArch,
972 VexArchInfo*, VexAbiInfo* );
974 #endif /* ndef __VEX_HOST_ARM_DEFS_H */
976 /*---------------------------------------------------------------*/
977 /*--- end host_arm_defs.h ---*/
978 /*---------------------------------------------------------------*/