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