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