Initial import of valgrind 3.6.0.
diff --git a/VEX/priv/host_arm_defs.h b/VEX/priv/host_arm_defs.h
new file mode 100644
index 0000000..1901e80
--- /dev/null
+++ b/VEX/priv/host_arm_defs.h
@@ -0,0 +1,978 @@
+
+/*---------------------------------------------------------------*/
+/*--- begin host_arm_defs.h ---*/
+/*---------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2004-2010 OpenWorks LLP
+ info@open-works.net
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __VEX_HOST_ARM_DEFS_H
+#define __VEX_HOST_ARM_DEFS_H
+
+extern UInt arm_hwcaps;
+
+
+/* --------- Registers. --------- */
+
+/* The usual HReg abstraction.
+ There are 16 general purpose regs.
+*/
+
+extern void ppHRegARM ( HReg );
+
+extern HReg hregARM_R0 ( void );
+extern HReg hregARM_R1 ( void );
+extern HReg hregARM_R2 ( void );
+extern HReg hregARM_R3 ( void );
+extern HReg hregARM_R4 ( void );
+extern HReg hregARM_R5 ( void );
+extern HReg hregARM_R6 ( void );
+extern HReg hregARM_R7 ( void );
+extern HReg hregARM_R8 ( void );
+extern HReg hregARM_R9 ( void );
+extern HReg hregARM_R10 ( void );
+extern HReg hregARM_R11 ( void );
+extern HReg hregARM_R12 ( void );
+extern HReg hregARM_R13 ( void );
+extern HReg hregARM_R14 ( void );
+extern HReg hregARM_R15 ( void );
+extern HReg hregARM_D8 ( void );
+extern HReg hregARM_D9 ( void );
+extern HReg hregARM_D10 ( void );
+extern HReg hregARM_D11 ( void );
+extern HReg hregARM_D12 ( void );
+extern HReg hregARM_S26 ( void );
+extern HReg hregARM_S27 ( void );
+extern HReg hregARM_S28 ( void );
+extern HReg hregARM_S29 ( void );
+extern HReg hregARM_S30 ( void );
+extern HReg hregARM_Q8 ( void );
+extern HReg hregARM_Q9 ( void );
+extern HReg hregARM_Q10 ( void );
+extern HReg hregARM_Q11 ( void );
+extern HReg hregARM_Q12 ( void );
+extern HReg hregARM_Q13 ( void );
+extern HReg hregARM_Q14 ( void );
+extern HReg hregARM_Q15 ( void );
+
+/* Number of registers used arg passing in function calls */
+#define ARM_N_ARGREGS 4 /* r0, r1, r2, r3 */
+
+
+/* --------- Condition codes. --------- */
+
+typedef
+ enum {
+ ARMcc_EQ = 0, /* equal : Z=1 */
+ ARMcc_NE = 1, /* not equal : Z=0 */
+
+ ARMcc_HS = 2, /* >=u (higher or same) : C=1 */
+ ARMcc_LO = 3, /* <u (lower) : C=0 */
+
+ ARMcc_MI = 4, /* minus (negative) : N=1 */
+ ARMcc_PL = 5, /* plus (zero or +ve) : N=0 */
+
+ ARMcc_VS = 6, /* overflow : V=1 */
+ ARMcc_VC = 7, /* no overflow : V=0 */
+
+ ARMcc_HI = 8, /* >u (higher) : C=1 && Z=0 */
+ ARMcc_LS = 9, /* <=u (lower or same) : C=0 || Z=1 */
+
+ ARMcc_GE = 10, /* >=s (signed greater or equal) : N=V */
+ ARMcc_LT = 11, /* <s (signed less than) : N!=V */
+
+ ARMcc_GT = 12, /* >s (signed greater) : Z=0 && N=V */
+ ARMcc_LE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
+
+ ARMcc_AL = 14, /* always (unconditional) */
+ ARMcc_NV = 15 /* never (basically undefined meaning), deprecated */
+ }
+ ARMCondCode;
+
+extern HChar* showARMCondCode ( ARMCondCode );
+
+
+
+/* --------- Memory address expressions (amodes). --------- */
+
+/* --- Addressing Mode 1 --- */
+typedef
+ enum {
+ ARMam1_RI=1, /* reg +/- imm12 */
+ ARMam1_RRS /* reg1 + (reg2 << 0, 1 2 or 3) */
+ }
+ ARMAMode1Tag;
+
+typedef
+ struct {
+ ARMAMode1Tag tag;
+ union {
+ struct {
+ HReg reg;
+ Int simm13; /* -4095 .. +4095 */
+ } RI;
+ struct {
+ HReg base;
+ HReg index;
+ UInt shift; /* 0, 1 2 or 3 */
+ } RRS;
+ } ARMam1;
+ }
+ ARMAMode1;
+
+extern ARMAMode1* ARMAMode1_RI ( HReg reg, Int simm13 );
+extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
+
+extern void ppARMAMode1 ( ARMAMode1* );
+
+
+/* --- Addressing Mode 2 --- */
+typedef
+ enum {
+ ARMam2_RI=3, /* reg +/- imm8 */
+ ARMam2_RR /* reg1 + reg2 */
+ }
+ ARMAMode2Tag;
+
+typedef
+ struct {
+ ARMAMode2Tag tag;
+ union {
+ struct {
+ HReg reg;
+ Int simm9; /* -255 .. 255 */
+ } RI;
+ struct {
+ HReg base;
+ HReg index;
+ } RR;
+ } ARMam2;
+ }
+ ARMAMode2;
+
+extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
+extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
+
+extern void ppARMAMode2 ( ARMAMode2* );
+
+
+/* --- Addressing Mode suitable for VFP --- */
+/* The simm11 is encoded as 8 bits + 1 sign bit,
+ so can only be 0 % 4. */
+typedef
+ struct {
+ HReg reg;
+ Int simm11; /* -1020, -1016 .. 1016, 1020 */
+ }
+ ARMAModeV;
+
+extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
+
+extern void ppARMAModeV ( ARMAModeV* );
+
+/* --- Addressing Mode suitable for Neon --- */
+typedef
+ enum {
+ ARMamN_R=5,
+ ARMamN_RR
+ /* ... */
+ }
+ ARMAModeNTag;
+
+typedef
+ struct {
+ ARMAModeNTag tag;
+ union {
+ struct {
+ HReg rN;
+ HReg rM;
+ } RR;
+ struct {
+ HReg rN;
+ } R;
+ /* ... */
+ } ARMamN;
+ }
+ ARMAModeN;
+
+extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg );
+extern ARMAModeN* mkARMAModeN_R ( HReg );
+extern void ppARMAModeN ( ARMAModeN* );
+
+/* --------- Reg or imm-8x4 operands --------- */
+/* a.k.a (a very restricted form of) Shifter Operand,
+ in the ARM parlance. */
+
+typedef
+ enum {
+ ARMri84_I84=7, /* imm8 `ror` (2 * imm4) */
+ ARMri84_R /* reg */
+ }
+ ARMRI84Tag;
+
+typedef
+ struct {
+ ARMRI84Tag tag;
+ union {
+ struct {
+ UShort imm8;
+ UShort imm4;
+ } I84;
+ struct {
+ HReg reg;
+ } R;
+ } ARMri84;
+ }
+ ARMRI84;
+
+extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
+extern ARMRI84* ARMRI84_R ( HReg );
+
+extern void ppARMRI84 ( ARMRI84* );
+
+
+/* --------- Reg or imm5 operands --------- */
+typedef
+ enum {
+ ARMri5_I5=9, /* imm5, 1 .. 31 only (no zero!) */
+ ARMri5_R /* reg */
+ }
+ ARMRI5Tag;
+
+typedef
+ struct {
+ ARMRI5Tag tag;
+ union {
+ struct {
+ UInt imm5;
+ } I5;
+ struct {
+ HReg reg;
+ } R;
+ } ARMri5;
+ }
+ ARMRI5;
+
+extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
+extern ARMRI5* ARMRI5_R ( HReg );
+
+extern void ppARMRI5 ( ARMRI5* );
+
+/* -------- Neon Immediate operand -------- */
+
+/* imm8 = abcdefgh, B = NOT(b);
+
+type | value (64bit binary)
+-----+-------------------------------------------------------------------------
+ 0 | 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh
+ 1 | 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000
+ 2 | 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000
+ 3 | abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000
+ 4 | 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh
+ 5 | abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000
+ 6 | abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh
+ 7 | 00000000 00000000 abcdefgh 11111111 00000000 00000000 abcdefgh 11111111
+ 8 | 00000000 abcdefgh 11111111 11111111 00000000 abcdefgh 11111111 11111111
+ 9 | aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
+ 10 | aBbbbbbc defgh000 00000000 00000000 aBbbbbbc defgh000 00000000 00000000
+-----+-------------------------------------------------------------------------
+
+Type 10 is:
+ (-1)^S * 2^exp * mantissa
+where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16
+*/
+
+typedef
+ struct {
+ UInt type;
+ UInt imm8;
+ }
+ ARMNImm;
+
+extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 );
+extern ULong ARMNImm_to_Imm64 ( ARMNImm* );
+extern ARMNImm* Imm64_to_ARMNImm ( ULong );
+
+extern void ppARMNImm ( ARMNImm* );
+
+/* ------ Neon Register or Scalar Operand ------ */
+
+typedef
+ enum {
+ ARMNRS_Reg=11,
+ ARMNRS_Scalar
+ }
+ ARMNRS_tag;
+
+typedef
+ struct {
+ ARMNRS_tag tag;
+ HReg reg;
+ UInt index;
+ }
+ ARMNRS;
+
+extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index);
+extern void ppARMNRS ( ARMNRS* );
+
+/* --------- Instructions. --------- */
+
+/* --------- */
+typedef
+ enum {
+ ARMalu_ADD=20, /* plain 32-bit add */
+ ARMalu_ADDS, /* 32-bit add, and set the flags */
+ ARMalu_ADC, /* 32-bit add with carry */
+ ARMalu_SUB, /* plain 32-bit subtract */
+ ARMalu_SUBS, /* 32-bit subtract, and set the flags */
+ ARMalu_SBC, /* 32-bit subtract with carry */
+ ARMalu_AND,
+ ARMalu_BIC,
+ ARMalu_OR,
+ ARMalu_XOR
+ }
+ ARMAluOp;
+
+extern HChar* showARMAluOp ( ARMAluOp op );
+
+
+typedef
+ enum {
+ ARMsh_SHL=40,
+ ARMsh_SHR,
+ ARMsh_SAR
+ }
+ ARMShiftOp;
+
+extern HChar* showARMShiftOp ( ARMShiftOp op );
+
+
+typedef
+ enum {
+ ARMun_NEG=50,
+ ARMun_NOT,
+ ARMun_CLZ
+ }
+ ARMUnaryOp;
+
+extern HChar* showARMUnaryOp ( ARMUnaryOp op );
+
+
+typedef
+ enum {
+ ARMmul_PLAIN=60,
+ ARMmul_ZX,
+ ARMmul_SX
+ }
+ ARMMulOp;
+
+extern HChar* showARMMulOp ( ARMMulOp op );
+
+
+typedef
+ enum {
+ ARMvfp_ADD=70,
+ ARMvfp_SUB,
+ ARMvfp_MUL,
+ ARMvfp_DIV
+ }
+ ARMVfpOp;
+
+extern HChar* showARMVfpOp ( ARMVfpOp op );
+
+
+typedef
+ enum {
+ ARMvfpu_COPY=80,
+ ARMvfpu_NEG,
+ ARMvfpu_ABS,
+ ARMvfpu_SQRT
+ }
+ ARMVfpUnaryOp;
+
+extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
+
+typedef
+ enum {
+ ARMneon_VAND=90,
+ ARMneon_VORR,
+ ARMneon_VXOR,
+ ARMneon_VADD,
+ ARMneon_VADDFP,
+ ARMneon_VRHADDS,
+ ARMneon_VRHADDU,
+ ARMneon_VPADDFP,
+ ARMneon_VABDFP,
+ ARMneon_VSUB,
+ ARMneon_VSUBFP,
+ ARMneon_VMAXU,
+ ARMneon_VMAXS,
+ ARMneon_VMAXF,
+ ARMneon_VMINU,
+ ARMneon_VMINS,
+ ARMneon_VMINF,
+ ARMneon_VQADDU,
+ ARMneon_VQADDS,
+ ARMneon_VQSUBU,
+ ARMneon_VQSUBS,
+ ARMneon_VCGTU,
+ ARMneon_VCGTS,
+ ARMneon_VCGEU,
+ ARMneon_VCGES,
+ ARMneon_VCGTF,
+ ARMneon_VCGEF,
+ ARMneon_VCEQ,
+ ARMneon_VCEQF,
+ ARMneon_VEXT,
+ ARMneon_VMUL,
+ ARMneon_VMULFP,
+ ARMneon_VMULLU,
+ ARMneon_VMULLS,
+ ARMneon_VMULP,
+ ARMneon_VMULLP,
+ ARMneon_VQDMULH,
+ ARMneon_VQRDMULH,
+ ARMneon_VPADD,
+ ARMneon_VPMINU,
+ ARMneon_VPMINS,
+ ARMneon_VPMINF,
+ ARMneon_VPMAXU,
+ ARMneon_VPMAXS,
+ ARMneon_VPMAXF,
+ ARMneon_VTBL,
+ ARMneon_VQDMULL,
+ ARMneon_VRECPS,
+ ARMneon_VRSQRTS,
+ /* ... */
+ }
+ ARMNeonBinOp;
+
+typedef
+ enum {
+ ARMneon_VSHL=150,
+ ARMneon_VSAL, /* Yah, not SAR but SAL */
+ ARMneon_VQSHL,
+ ARMneon_VQSAL
+ }
+ ARMNeonShiftOp;
+
+typedef
+ enum {
+ ARMneon_COPY=160,
+ ARMneon_COPYLU,
+ ARMneon_COPYLS,
+ ARMneon_COPYN,
+ ARMneon_COPYQNSS,
+ ARMneon_COPYQNUS,
+ ARMneon_COPYQNUU,
+ ARMneon_NOT,
+ ARMneon_EQZ,
+ ARMneon_DUP,
+ ARMneon_PADDLS,
+ ARMneon_PADDLU,
+ ARMneon_CNT,
+ ARMneon_CLZ,
+ ARMneon_CLS,
+ ARMneon_VCVTxFPxINT,
+ ARMneon_VQSHLNSS,
+ ARMneon_VQSHLNUU,
+ ARMneon_VQSHLNUS,
+ ARMneon_VCVTFtoU,
+ ARMneon_VCVTFtoS,
+ ARMneon_VCVTUtoF,
+ ARMneon_VCVTStoF,
+ ARMneon_VCVTFtoFixedU,
+ ARMneon_VCVTFtoFixedS,
+ ARMneon_VCVTFixedUtoF,
+ ARMneon_VCVTFixedStoF,
+ ARMneon_VCVTF16toF32,
+ ARMneon_VCVTF32toF16,
+ ARMneon_REV16,
+ ARMneon_REV32,
+ ARMneon_REV64,
+ ARMneon_ABS,
+ ARMneon_VNEGF,
+ ARMneon_VRECIP,
+ ARMneon_VRECIPF,
+ ARMneon_VABSFP,
+ ARMneon_VRSQRTEFP,
+ ARMneon_VRSQRTE
+ /* ... */
+ }
+ ARMNeonUnOp;
+
+typedef
+ enum {
+ ARMneon_SETELEM=200,
+ ARMneon_GETELEMU,
+ ARMneon_GETELEMS,
+ ARMneon_VDUP,
+ }
+ ARMNeonUnOpS;
+
+typedef
+ enum {
+ ARMneon_TRN=210,
+ ARMneon_ZIP,
+ ARMneon_UZP
+ /* ... */
+ }
+ ARMNeonDualOp;
+
+extern HChar* showARMNeonBinOp ( ARMNeonBinOp op );
+extern HChar* showARMNeonUnOp ( ARMNeonUnOp op );
+extern HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
+extern HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
+extern HChar* showARMNeonDualOp ( ARMNeonDualOp op );
+extern HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
+extern HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
+extern HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
+extern HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
+extern HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
+
+typedef
+ enum {
+ /* baseline */
+ ARMin_Alu=220,
+ ARMin_Shift,
+ ARMin_Unary,
+ ARMin_CmpOrTst,
+ ARMin_Mov,
+ ARMin_Imm32,
+ ARMin_LdSt32,
+ ARMin_LdSt16,
+ ARMin_LdSt8U,
+ ARMin_Ld8S,
+ ARMin_Goto,
+ ARMin_CMov,
+ ARMin_Call,
+ ARMin_Mul,
+ ARMin_LdrEX,
+ ARMin_StrEX,
+ /* vfp */
+ ARMin_VLdStD,
+ ARMin_VLdStS,
+ ARMin_VAluD,
+ ARMin_VAluS,
+ ARMin_VUnaryD,
+ ARMin_VUnaryS,
+ ARMin_VCmpD,
+ ARMin_VCMovD,
+ ARMin_VCMovS,
+ ARMin_VCvtSD,
+ ARMin_VXferD,
+ ARMin_VXferS,
+ ARMin_VCvtID,
+ ARMin_FPSCR,
+ ARMin_MFence,
+ /* Neon */
+ ARMin_NLdStQ,
+ ARMin_NLdStD,
+ ARMin_NUnary,
+ ARMin_NUnaryS,
+ ARMin_NDual,
+ ARMin_NBinary,
+ ARMin_NBinaryS,
+ ARMin_NShift,
+ ARMin_NeonImm,
+ ARMin_NCMovQ,
+ /* This is not a NEON instruction. Actually there is no corresponding
+ instruction in ARM instruction set at all. We need this one to
+ generate spill/reload of 128-bit registers since current register
+ allocator demands them to consist of no more than two instructions.
+ We will split this instruction into 2 or 3 ARM instructions on the
+ emiting phase.
+
+ NOTE: source and destination registers should be different! */
+ ARMin_Add32
+ }
+ ARMInstrTag;
+
+/* Destinations are on the LEFT (first operand) */
+
+typedef
+ struct {
+ ARMInstrTag tag;
+ union {
+ /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
+ struct {
+ ARMAluOp op;
+ HReg dst;
+ HReg argL;
+ ARMRI84* argR;
+ } Alu;
+ /* SHL/SHR/SAR, 2nd arg is reg or imm */
+ struct {
+ ARMShiftOp op;
+ HReg dst;
+ HReg argL;
+ ARMRI5* argR;
+ } Shift;
+ /* NOT/NEG/CLZ */
+ struct {
+ ARMUnaryOp op;
+ HReg dst;
+ HReg src;
+ } Unary;
+ /* CMP/TST; subtract/and, discard result, set NZCV */
+ struct {
+ Bool isCmp;
+ HReg argL;
+ ARMRI84* argR;
+ } CmpOrTst;
+ /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
+ struct {
+ HReg dst;
+ ARMRI84* src;
+ } Mov;
+ /* Pseudo-insn; make a 32-bit immediate */
+ struct {
+ HReg dst;
+ UInt imm32;
+ } Imm32;
+ /* 32-bit load or store */
+ struct {
+ Bool isLoad;
+ HReg rD;
+ ARMAMode1* amode;
+ } LdSt32;
+ /* 16-bit load or store */
+ struct {
+ Bool isLoad;
+ Bool signedLoad;
+ HReg rD;
+ ARMAMode2* amode;
+ } LdSt16;
+ /* 8-bit (unsigned) load or store */
+ struct {
+ Bool isLoad;
+ HReg rD;
+ ARMAMode1* amode;
+ } LdSt8U;
+ /* 8-bit signed load */
+ struct {
+ HReg rD;
+ ARMAMode2* amode;
+ } Ld8S;
+ /* Pseudo-insn. Go to guest address gnext, on given
+ condition, which could be ARMcc_AL. */
+ struct {
+ IRJumpKind jk;
+ ARMCondCode cond;
+ HReg gnext;
+ } Goto;
+ /* Mov src to dst on the given condition, which may not
+ be ARMcc_AL. */
+ struct {
+ ARMCondCode cond;
+ HReg dst;
+ ARMRI84* src;
+ } CMov;
+ /* Pseudo-insn. Call target (an absolute address), on given
+ condition (which could be ARMcc_AL). */
+ struct {
+ ARMCondCode cond;
+ HWord target;
+ Int nArgRegs; /* # regs carrying args: 0 .. 4 */
+ } Call;
+ /* (PLAIN) 32 * 32 -> 32: r0 = r2 * r3
+ (ZX) 32 *u 32 -> 64: r1:r0 = r2 *u r3
+ (SX) 32 *s 32 -> 64: r1:r0 = r2 *s r3
+ Why hardwired registers? Because the ARM ARM specifies
+ (eg for straight MUL) the result (Rd) and the left arg (Rm)
+ may not be the same register. That's not a constraint we
+ can enforce in the register allocator (without mucho extra
+ complexity). Hence hardwire it. At least using caller-saves
+ registers, which are less likely to be in use. */
+ struct {
+ ARMMulOp op;
+ } Mul;
+ /* LDREX{,H,B} r0, [r1]
+ Again, hardwired registers since this is not performance
+ critical, and there are possibly constraints on the
+ registers that we can't express in the register allocator.*/
+ struct {
+ Int szB; /* currently only 4 is allowed */
+ } LdrEX;
+ /* STREX{,H,B} r0, r1, [r2]
+ r0 = SC( [r2] = r1 )
+ Ditto comment re fixed registers. */
+ struct {
+ Int szB; /* currently only 4 is allowed */
+ } StrEX;
+ /* VFP INSTRUCTIONS */
+ /* 64-bit Fp load/store */
+ struct {
+ Bool isLoad;
+ HReg dD;
+ ARMAModeV* amode;
+ } VLdStD;
+ /* 32-bit Fp load/store */
+ struct {
+ Bool isLoad;
+ HReg fD;
+ ARMAModeV* amode;
+ } VLdStS;
+ /* 64-bit FP binary arithmetic */
+ struct {
+ ARMVfpOp op;
+ HReg dst;
+ HReg argL;
+ HReg argR;
+ } VAluD;
+ /* 32-bit FP binary arithmetic */
+ struct {
+ ARMVfpOp op;
+ HReg dst;
+ HReg argL;
+ HReg argR;
+ } VAluS;
+ /* 64-bit FP unary, also reg-reg move */
+ struct {
+ ARMVfpUnaryOp op;
+ HReg dst;
+ HReg src;
+ } VUnaryD;
+ /* 32-bit FP unary, also reg-reg move */
+ struct {
+ ARMVfpUnaryOp op;
+ HReg dst;
+ HReg src;
+ } VUnaryS;
+ /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
+ struct {
+ HReg argL;
+ HReg argR;
+ } VCmpD;
+ /* 64-bit FP mov src to dst on the given condition, which may
+ not be ARMcc_AL. */
+ struct {
+ ARMCondCode cond;
+ HReg dst;
+ HReg src;
+ } VCMovD;
+ /* 32-bit FP mov src to dst on the given condition, which may
+ not be ARMcc_AL. */
+ struct {
+ ARMCondCode cond;
+ HReg dst;
+ HReg src;
+ } VCMovS;
+ /* Convert between 32-bit and 64-bit FP values (both ways).
+ (FCVTSD, FCVTDS) */
+ struct {
+ Bool sToD; /* True: F32->F64. False: F64->F32 */
+ HReg dst;
+ HReg src;
+ } VCvtSD;
+ /* Transfer a VFP D reg to/from two integer registers (VMOV) */
+ struct {
+ Bool toD;
+ HReg dD;
+ HReg rHi;
+ HReg rLo;
+ } VXferD;
+ /* Transfer a VFP S reg to/from an integer register (VMOV) */
+ struct {
+ Bool toS;
+ HReg fD;
+ HReg rLo;
+ } VXferS;
+ /* Convert between 32-bit ints and 64-bit FP values (both ways
+ and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
+ struct {
+ Bool iToD; /* True: I32->F64. False: F64->I32 */
+ Bool syned; /* True: I32 is signed. False: I32 is unsigned */
+ HReg dst;
+ HReg src;
+ } VCvtID;
+ /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
+ struct {
+ Bool toFPSCR;
+ HReg iReg;
+ } FPSCR;
+ /* Mem fence. An insn which fences all loads and stores as
+ much as possible before continuing. On ARM we emit the
+ sequence
+ mcr 15,0,r0,c7,c10,4 (DSB)
+ mcr 15,0,r0,c7,c10,5 (DMB)
+ mcr 15,0,r0,c7,c5,4 (ISB)
+ which is probably total overkill, but better safe than
+ sorry.
+ */
+ struct {
+ } MFence;
+ /* Neon data processing instruction: 3 registers of the same
+ length */
+ struct {
+ ARMNeonBinOp op;
+ HReg dst;
+ HReg argL;
+ HReg argR;
+ UInt size;
+ Bool Q;
+ } NBinary;
+ struct {
+ ARMNeonBinOp op;
+ ARMNRS* dst;
+ ARMNRS* argL;
+ ARMNRS* argR;
+ UInt size;
+ Bool Q;
+ } NBinaryS;
+ struct {
+ ARMNeonShiftOp op;
+ HReg dst;
+ HReg argL;
+ HReg argR;
+ UInt size;
+ Bool Q;
+ } NShift;
+ struct {
+ Bool isLoad;
+ HReg dQ;
+ ARMAModeN *amode;
+ } NLdStQ;
+ struct {
+ Bool isLoad;
+ HReg dD;
+ ARMAModeN *amode;
+ } NLdStD;
+ struct {
+ ARMNeonUnOpS op;
+ ARMNRS* dst;
+ ARMNRS* src;
+ UInt size;
+ Bool Q;
+ } NUnaryS;
+ struct {
+ ARMNeonUnOp op;
+ HReg dst;
+ HReg src;
+ UInt size;
+ Bool Q;
+ } NUnary;
+ /* Takes two arguments and modifies them both. */
+ struct {
+ ARMNeonDualOp op;
+ HReg arg1;
+ HReg arg2;
+ UInt size;
+ Bool Q;
+ } NDual;
+ struct {
+ HReg dst;
+ ARMNImm* imm;
+ } NeonImm;
+ /* 128-bit Neon move src to dst on the given condition, which
+ may not be ARMcc_AL. */
+ struct {
+ ARMCondCode cond;
+ HReg dst;
+ HReg src;
+ } NCMovQ;
+ struct {
+ /* Note: rD != rN */
+ HReg rD;
+ HReg rN;
+ UInt imm32;
+ } Add32;
+ } ARMin;
+ }
+ ARMInstr;
+
+
+extern ARMInstr* ARMInstr_Alu ( ARMAluOp, HReg, HReg, ARMRI84* );
+extern ARMInstr* ARMInstr_Shift ( ARMShiftOp, HReg, HReg, ARMRI5* );
+extern ARMInstr* ARMInstr_Unary ( ARMUnaryOp, HReg, HReg );
+extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
+extern ARMInstr* ARMInstr_Mov ( HReg, ARMRI84* );
+extern ARMInstr* ARMInstr_Imm32 ( HReg, UInt );
+extern ARMInstr* ARMInstr_LdSt32 ( Bool isLoad, HReg, ARMAMode1* );
+extern ARMInstr* ARMInstr_LdSt16 ( Bool isLoad, Bool signedLoad,
+ HReg, ARMAMode2* );
+extern ARMInstr* ARMInstr_LdSt8U ( Bool isLoad, HReg, ARMAMode1* );
+extern ARMInstr* ARMInstr_Ld8S ( HReg, ARMAMode2* );
+extern ARMInstr* ARMInstr_Goto ( IRJumpKind, ARMCondCode, HReg gnext );
+extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src );
+extern ARMInstr* ARMInstr_Call ( ARMCondCode, HWord, Int nArgRegs );
+extern ARMInstr* ARMInstr_Mul ( ARMMulOp op );
+extern ARMInstr* ARMInstr_LdrEX ( Int szB );
+extern ARMInstr* ARMInstr_StrEX ( Int szB );
+extern ARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg, ARMAModeV* );
+extern ARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg, ARMAModeV* );
+extern ARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg, HReg, HReg );
+extern ARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg, HReg, HReg );
+extern ARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp, HReg dst, HReg src );
+extern ARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp, HReg dst, HReg src );
+extern ARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR );
+extern ARMInstr* ARMInstr_VCMovD ( ARMCondCode, HReg dst, HReg src );
+extern ARMInstr* ARMInstr_VCMovS ( ARMCondCode, HReg dst, HReg src );
+extern ARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src );
+extern ARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo );
+extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo );
+extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned,
+ HReg dst, HReg src );
+extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg );
+extern ARMInstr* ARMInstr_MFence ( void );
+extern ARMInstr* ARMInstr_NLdStQ ( Bool isLoad, HReg, ARMAModeN* );
+extern ARMInstr* ARMInstr_NLdStD ( Bool isLoad, HReg, ARMAModeN* );
+extern ARMInstr* ARMInstr_NUnary ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
+extern ARMInstr* ARMInstr_NUnaryS ( ARMNeonUnOp, ARMNRS*, ARMNRS*,
+ UInt, Bool );
+extern ARMInstr* ARMInstr_NDual ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
+extern ARMInstr* ARMInstr_NBinary ( ARMNeonBinOp, HReg, HReg, HReg,
+ UInt, Bool );
+extern ARMInstr* ARMInstr_NShift ( ARMNeonShiftOp, HReg, HReg, HReg,
+ UInt, Bool );
+extern ARMInstr* ARMInstr_NeonImm ( HReg, ARMNImm* );
+extern ARMInstr* ARMInstr_NCMovQ ( ARMCondCode, HReg, HReg );
+extern ARMInstr* ARMInstr_Add32 ( HReg rD, HReg rN, UInt imm32 );
+
+extern void ppARMInstr ( ARMInstr* );
+
+
+/* Some functions that insulate the register allocator from details
+ of the underlying instruction set. */
+extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool );
+extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool );
+extern Bool isMove_ARMInstr ( ARMInstr*, HReg*, HReg* );
+extern Int emit_ARMInstr ( UChar* buf, Int nbuf, ARMInstr*,
+ Bool, void* dispatch );
+
+extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
+ HReg rreg, Int offset, Bool );
+extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
+ HReg rreg, Int offset, Bool );
+
+extern void getAllocableRegs_ARM ( Int*, HReg** );
+extern HInstrArray* iselSB_ARM ( IRSB*, VexArch,
+ VexArchInfo*, VexAbiInfo* );
+
+#endif /* ndef __VEX_HOST_ARM_DEFS_H */
+
+/*---------------------------------------------------------------*/
+/*--- end host_arm_defs.h ---*/
+/*---------------------------------------------------------------*/