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