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-2011 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    }
    388    ARMMulOp;
    389 
    390 extern HChar* showARMMulOp ( ARMMulOp op );
    391 
    392 
    393 typedef
    394    enum {
    395       ARMvfp_ADD=70,
    396       ARMvfp_SUB,
    397       ARMvfp_MUL,
    398       ARMvfp_DIV
    399    }
    400    ARMVfpOp;
    401 
    402 extern HChar* showARMVfpOp ( ARMVfpOp op );
    403 
    404 
    405 typedef
    406    enum {
    407       ARMvfpu_COPY=80,
    408       ARMvfpu_NEG,
    409       ARMvfpu_ABS,
    410       ARMvfpu_SQRT
    411    }
    412    ARMVfpUnaryOp;
    413 
    414 extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
    415 
    416 typedef
    417    enum {
    418       ARMneon_VAND=90,
    419       ARMneon_VORR,
    420       ARMneon_VXOR,
    421       ARMneon_VADD,
    422       ARMneon_VADDFP,
    423       ARMneon_VRHADDS,
    424       ARMneon_VRHADDU,
    425       ARMneon_VPADDFP,
    426       ARMneon_VABDFP,
    427       ARMneon_VSUB,
    428       ARMneon_VSUBFP,
    429       ARMneon_VMAXU,
    430       ARMneon_VMAXS,
    431       ARMneon_VMAXF,
    432       ARMneon_VMINU,
    433       ARMneon_VMINS,
    434       ARMneon_VMINF,
    435       ARMneon_VQADDU,
    436       ARMneon_VQADDS,
    437       ARMneon_VQSUBU,
    438       ARMneon_VQSUBS,
    439       ARMneon_VCGTU,
    440       ARMneon_VCGTS,
    441       ARMneon_VCGEU,
    442       ARMneon_VCGES,
    443       ARMneon_VCGTF,
    444       ARMneon_VCGEF,
    445       ARMneon_VCEQ,
    446       ARMneon_VCEQF,
    447       ARMneon_VEXT,
    448       ARMneon_VMUL,
    449       ARMneon_VMULFP,
    450       ARMneon_VMULLU,
    451       ARMneon_VMULLS,
    452       ARMneon_VMULP,
    453       ARMneon_VMULLP,
    454       ARMneon_VQDMULH,
    455       ARMneon_VQRDMULH,
    456       ARMneon_VPADD,
    457       ARMneon_VPMINU,
    458       ARMneon_VPMINS,
    459       ARMneon_VPMINF,
    460       ARMneon_VPMAXU,
    461       ARMneon_VPMAXS,
    462       ARMneon_VPMAXF,
    463       ARMneon_VTBL,
    464       ARMneon_VQDMULL,
    465       ARMneon_VRECPS,
    466       ARMneon_VRSQRTS,
    467       /* ... */
    468    }
    469    ARMNeonBinOp;
    470 
    471 typedef
    472    enum {
    473       ARMneon_VSHL=150,
    474       ARMneon_VSAL, /* Yah, not SAR but SAL */
    475       ARMneon_VQSHL,
    476       ARMneon_VQSAL
    477    }
    478    ARMNeonShiftOp;
    479 
    480 typedef
    481    enum {
    482       ARMneon_COPY=160,
    483       ARMneon_COPYLU,
    484       ARMneon_COPYLS,
    485       ARMneon_COPYN,
    486       ARMneon_COPYQNSS,
    487       ARMneon_COPYQNUS,
    488       ARMneon_COPYQNUU,
    489       ARMneon_NOT,
    490       ARMneon_EQZ,
    491       ARMneon_DUP,
    492       ARMneon_PADDLS,
    493       ARMneon_PADDLU,
    494       ARMneon_CNT,
    495       ARMneon_CLZ,
    496       ARMneon_CLS,
    497       ARMneon_VCVTxFPxINT,
    498       ARMneon_VQSHLNSS,
    499       ARMneon_VQSHLNUU,
    500       ARMneon_VQSHLNUS,
    501       ARMneon_VCVTFtoU,
    502       ARMneon_VCVTFtoS,
    503       ARMneon_VCVTUtoF,
    504       ARMneon_VCVTStoF,
    505       ARMneon_VCVTFtoFixedU,
    506       ARMneon_VCVTFtoFixedS,
    507       ARMneon_VCVTFixedUtoF,
    508       ARMneon_VCVTFixedStoF,
    509       ARMneon_VCVTF16toF32,
    510       ARMneon_VCVTF32toF16,
    511       ARMneon_REV16,
    512       ARMneon_REV32,
    513       ARMneon_REV64,
    514       ARMneon_ABS,
    515       ARMneon_VNEGF,
    516       ARMneon_VRECIP,
    517       ARMneon_VRECIPF,
    518       ARMneon_VABSFP,
    519       ARMneon_VRSQRTEFP,
    520       ARMneon_VRSQRTE
    521       /* ... */
    522    }
    523    ARMNeonUnOp;
    524 
    525 typedef
    526    enum {
    527       ARMneon_SETELEM=200,
    528       ARMneon_GETELEMU,
    529       ARMneon_GETELEMS,
    530       ARMneon_VDUP,
    531    }
    532    ARMNeonUnOpS;
    533 
    534 typedef
    535    enum {
    536       ARMneon_TRN=210,
    537       ARMneon_ZIP,
    538       ARMneon_UZP
    539       /* ... */
    540    }
    541    ARMNeonDualOp;
    542 
    543 extern HChar* showARMNeonBinOp ( ARMNeonBinOp op );
    544 extern HChar* showARMNeonUnOp ( ARMNeonUnOp op );
    545 extern HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
    546 extern HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
    547 extern HChar* showARMNeonDualOp ( ARMNeonDualOp op );
    548 extern HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
    549 extern HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
    550 extern HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
    551 extern HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
    552 extern HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
    553 
    554 typedef
    555    enum {
    556       /* baseline */
    557       ARMin_Alu=220,
    558       ARMin_Shift,
    559       ARMin_Unary,
    560       ARMin_CmpOrTst,
    561       ARMin_Mov,
    562       ARMin_Imm32,
    563       ARMin_LdSt32,
    564       ARMin_LdSt16,
    565       ARMin_LdSt8U,
    566       ARMin_Ld8S,
    567       ARMin_Goto,
    568       ARMin_CMov,
    569       ARMin_Call,
    570       ARMin_Mul,
    571       ARMin_LdrEX,
    572       ARMin_StrEX,
    573       /* vfp */
    574       ARMin_VLdStD,
    575       ARMin_VLdStS,
    576       ARMin_VAluD,
    577       ARMin_VAluS,
    578       ARMin_VUnaryD,
    579       ARMin_VUnaryS,
    580       ARMin_VCmpD,
    581       ARMin_VCMovD,
    582       ARMin_VCMovS,
    583       ARMin_VCvtSD,
    584       ARMin_VXferD,
    585       ARMin_VXferS,
    586       ARMin_VCvtID,
    587       ARMin_FPSCR,
    588       ARMin_MFence,
    589       ARMin_CLREX,
    590       /* Neon */
    591       ARMin_NLdStQ,
    592       ARMin_NLdStD,
    593       ARMin_NUnary,
    594       ARMin_NUnaryS,
    595       ARMin_NDual,
    596       ARMin_NBinary,
    597       ARMin_NBinaryS,
    598       ARMin_NShift,
    599       ARMin_NeonImm,
    600       ARMin_NCMovQ,
    601       /* This is not a NEON instruction. Actually there is no corresponding
    602          instruction in ARM instruction set at all. We need this one to
    603          generate spill/reload of 128-bit registers since current register
    604          allocator demands them to consist of no more than two instructions.
    605          We will split this instruction into 2 or 3 ARM instructions on the
    606          emiting phase.
    607 
    608          NOTE: source and destination registers should be different! */
    609       ARMin_Add32
    610    }
    611    ARMInstrTag;
    612 
    613 /* Destinations are on the LEFT (first operand) */
    614 
    615 typedef
    616    struct {
    617       ARMInstrTag tag;
    618       union {
    619          /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
    620          struct {
    621             ARMAluOp op;
    622             HReg     dst;
    623             HReg     argL;
    624             ARMRI84* argR;
    625          } Alu;
    626          /* SHL/SHR/SAR, 2nd arg is reg or imm */
    627          struct {
    628             ARMShiftOp op;
    629             HReg       dst;
    630             HReg       argL;
    631             ARMRI5*    argR;
    632          } Shift;
    633          /* NOT/NEG/CLZ */
    634          struct {
    635             ARMUnaryOp op;
    636             HReg       dst;
    637             HReg       src;
    638          } Unary;
    639          /* CMP/TST; subtract/and, discard result, set NZCV */
    640          struct {
    641             Bool     isCmp;
    642             HReg     argL;
    643             ARMRI84* argR;
    644          } CmpOrTst;
    645          /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
    646          struct {
    647             HReg     dst;
    648             ARMRI84* src;
    649          } Mov;
    650          /* Pseudo-insn; make a 32-bit immediate */
    651          struct {
    652             HReg dst;
    653             UInt imm32;
    654          } Imm32;
    655          /* 32-bit load or store */
    656          struct {
    657             Bool       isLoad;
    658             HReg       rD;
    659             ARMAMode1* amode;
    660          } LdSt32;
    661          /* 16-bit load or store */
    662          struct {
    663             Bool       isLoad;
    664             Bool       signedLoad;
    665             HReg       rD;
    666             ARMAMode2* amode;
    667          } LdSt16;
    668          /* 8-bit (unsigned) load or store */
    669          struct {
    670             Bool       isLoad;
    671             HReg       rD;
    672             ARMAMode1* amode;
    673          } LdSt8U;
    674          /* 8-bit signed load */
    675          struct {
    676             HReg       rD;
    677             ARMAMode2* amode;
    678          } Ld8S;
    679          /* Pseudo-insn.  Go to guest address gnext, on given
    680             condition, which could be ARMcc_AL. */
    681          struct {
    682             IRJumpKind  jk;
    683             ARMCondCode cond;
    684             HReg        gnext;
    685          } Goto;
    686          /* Mov src to dst on the given condition, which may not
    687             be ARMcc_AL. */
    688          struct {
    689             ARMCondCode cond;
    690             HReg        dst;
    691             ARMRI84*    src;
    692          } CMov;
    693          /* Pseudo-insn.  Call target (an absolute address), on given
    694             condition (which could be ARMcc_AL). */
    695          struct {
    696             ARMCondCode cond;
    697             HWord       target;
    698             Int         nArgRegs; /* # regs carrying args: 0 .. 4 */
    699          } Call;
    700          /* (PLAIN) 32 *  32 -> 32:  r0    = r2 * r3
    701             (ZX)    32 *u 32 -> 64:  r1:r0 = r2 *u r3
    702             (SX)    32 *s 32 -> 64:  r1:r0 = r2 *s r3
    703             Why hardwired registers?  Because the ARM ARM specifies
    704             (eg for straight MUL) the result (Rd) and the left arg (Rm)
    705             may not be the same register.  That's not a constraint we
    706             can enforce in the register allocator (without mucho extra
    707             complexity).  Hence hardwire it.  At least using caller-saves
    708             registers, which are less likely to be in use. */
    709          struct {
    710             ARMMulOp op;
    711          } Mul;
    712          /* LDREX{,H,B} r2, [r4]  and
    713             LDREXD r2, r3, [r4]   (on LE hosts, transferred value is r3:r2)
    714             Again, hardwired registers since this is not performance
    715             critical, and there are possibly constraints on the
    716             registers that we can't express in the register allocator.*/
    717          struct {
    718             Int  szB; /* 1, 2, 4 or 8 */
    719          } LdrEX;
    720          /* STREX{,H,B} r0, r2, [r4]  and
    721             STREXD r0, r2, r3, [r4]   (on LE hosts, transferred value is r3:r2)
    722             r0 = SC( [r4] = r2 )      (8, 16, 32 bit transfers)
    723             r0 = SC( [r4] = r3:r2)    (64 bit transfers)
    724             Ditto comment re fixed registers. */
    725          struct {
    726             Int  szB; /* 1, 2, 4 or 8 */
    727          } StrEX;
    728          /* VFP INSTRUCTIONS */
    729          /* 64-bit Fp load/store */
    730          struct {
    731             Bool       isLoad;
    732             HReg       dD;
    733             ARMAModeV* amode;
    734          } VLdStD;
    735          /* 32-bit Fp load/store */
    736          struct {
    737             Bool       isLoad;
    738             HReg       fD;
    739             ARMAModeV* amode;
    740          } VLdStS;
    741          /* 64-bit FP binary arithmetic */
    742          struct {
    743             ARMVfpOp op;
    744             HReg     dst;
    745             HReg     argL;
    746             HReg     argR;
    747          } VAluD;
    748          /* 32-bit FP binary arithmetic */
    749          struct {
    750             ARMVfpOp op;
    751             HReg     dst;
    752             HReg     argL;
    753             HReg     argR;
    754          } VAluS;
    755          /* 64-bit FP unary, also reg-reg move */
    756          struct {
    757             ARMVfpUnaryOp op;
    758             HReg          dst;
    759             HReg          src;
    760          } VUnaryD;
    761          /* 32-bit FP unary, also reg-reg move */
    762          struct {
    763             ARMVfpUnaryOp op;
    764             HReg          dst;
    765             HReg          src;
    766          } VUnaryS;
    767          /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
    768          struct {
    769             HReg argL;
    770             HReg argR;
    771          } VCmpD;
    772          /* 64-bit FP mov src to dst on the given condition, which may
    773             not be ARMcc_AL. */
    774          struct {
    775             ARMCondCode cond;
    776             HReg        dst;
    777             HReg        src;
    778          } VCMovD;
    779          /* 32-bit FP mov src to dst on the given condition, which may
    780             not be ARMcc_AL. */
    781          struct {
    782             ARMCondCode cond;
    783             HReg        dst;
    784             HReg        src;
    785          } VCMovS;
    786          /* Convert between 32-bit and 64-bit FP values (both ways).
    787             (FCVTSD, FCVTDS) */
    788          struct {
    789             Bool sToD; /* True: F32->F64.  False: F64->F32 */
    790             HReg dst;
    791             HReg src;
    792          } VCvtSD;
    793          /* Transfer a VFP D reg to/from two integer registers (VMOV) */
    794          struct {
    795             Bool toD;
    796             HReg dD;
    797             HReg rHi;
    798             HReg rLo;
    799          } VXferD;
    800          /* Transfer a VFP S reg to/from an integer register (VMOV) */
    801          struct {
    802             Bool toS;
    803             HReg fD;
    804             HReg rLo;
    805          } VXferS;
    806          /* Convert between 32-bit ints and 64-bit FP values (both ways
    807             and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
    808          struct {
    809             Bool iToD; /* True: I32->F64.  False: F64->I32 */
    810             Bool syned; /* True: I32 is signed.  False: I32 is unsigned */
    811             HReg dst;
    812             HReg src;
    813          } VCvtID;
    814          /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
    815          struct {
    816             Bool toFPSCR;
    817             HReg iReg;
    818          } FPSCR;
    819          /* Mem fence.  An insn which fences all loads and stores as
    820             much as possible before continuing.  On ARM we emit the
    821             sequence
    822                mcr 15,0,r0,c7,c10,4 (DSB)
    823                mcr 15,0,r0,c7,c10,5 (DMB)
    824                mcr 15,0,r0,c7,c5,4 (ISB)
    825             which is probably total overkill, but better safe than
    826             sorry.
    827          */
    828          struct {
    829          } MFence;
    830          /* A CLREX instruction. */
    831          struct {
    832          } CLREX;
    833          /* Neon data processing instruction: 3 registers of the same
    834             length */
    835          struct {
    836             ARMNeonBinOp op;
    837             HReg dst;
    838             HReg argL;
    839             HReg argR;
    840             UInt size;
    841             Bool Q;
    842          } NBinary;
    843          struct {
    844             ARMNeonBinOp op;
    845             ARMNRS* dst;
    846             ARMNRS* argL;
    847             ARMNRS* argR;
    848             UInt size;
    849             Bool Q;
    850          } NBinaryS;
    851          struct {
    852             ARMNeonShiftOp op;
    853             HReg dst;
    854             HReg argL;
    855             HReg argR;
    856             UInt size;
    857             Bool Q;
    858          } NShift;
    859          struct {
    860             Bool isLoad;
    861             HReg dQ;
    862             ARMAModeN *amode;
    863          } NLdStQ;
    864          struct {
    865             Bool isLoad;
    866             HReg dD;
    867             ARMAModeN *amode;
    868          } NLdStD;
    869          struct {
    870             ARMNeonUnOpS op;
    871             ARMNRS*  dst;
    872             ARMNRS*  src;
    873             UInt size;
    874             Bool Q;
    875          } NUnaryS;
    876          struct {
    877             ARMNeonUnOp op;
    878             HReg  dst;
    879             HReg  src;
    880             UInt size;
    881             Bool Q;
    882          } NUnary;
    883          /* Takes two arguments and modifies them both. */
    884          struct {
    885             ARMNeonDualOp op;
    886             HReg  arg1;
    887             HReg  arg2;
    888             UInt size;
    889             Bool Q;
    890          } NDual;
    891          struct {
    892             HReg dst;
    893             ARMNImm* imm;
    894          } NeonImm;
    895          /* 128-bit Neon move src to dst on the given condition, which
    896             may not be ARMcc_AL. */
    897          struct {
    898             ARMCondCode cond;
    899             HReg        dst;
    900             HReg        src;
    901          } NCMovQ;
    902          struct {
    903             /* Note: rD != rN */
    904             HReg rD;
    905             HReg rN;
    906             UInt imm32;
    907          } Add32;
    908       } ARMin;
    909    }
    910    ARMInstr;
    911 
    912 
    913 extern ARMInstr* ARMInstr_Alu      ( ARMAluOp, HReg, HReg, ARMRI84* );
    914 extern ARMInstr* ARMInstr_Shift    ( ARMShiftOp, HReg, HReg, ARMRI5* );
    915 extern ARMInstr* ARMInstr_Unary    ( ARMUnaryOp, HReg, HReg );
    916 extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
    917 extern ARMInstr* ARMInstr_Mov      ( HReg, ARMRI84* );
    918 extern ARMInstr* ARMInstr_Imm32    ( HReg, UInt );
    919 extern ARMInstr* ARMInstr_LdSt32   ( Bool isLoad, HReg, ARMAMode1* );
    920 extern ARMInstr* ARMInstr_LdSt16   ( Bool isLoad, Bool signedLoad,
    921                                      HReg, ARMAMode2* );
    922 extern ARMInstr* ARMInstr_LdSt8U   ( Bool isLoad, HReg, ARMAMode1* );
    923 extern ARMInstr* ARMInstr_Ld8S     ( HReg, ARMAMode2* );
    924 extern ARMInstr* ARMInstr_Goto     ( IRJumpKind, ARMCondCode, HReg gnext );
    925 extern ARMInstr* ARMInstr_CMov     ( ARMCondCode, HReg dst, ARMRI84* src );
    926 extern ARMInstr* ARMInstr_Call     ( ARMCondCode, HWord, Int nArgRegs );
    927 extern ARMInstr* ARMInstr_Mul      ( ARMMulOp op );
    928 extern ARMInstr* ARMInstr_LdrEX    ( Int szB );
    929 extern ARMInstr* ARMInstr_StrEX    ( Int szB );
    930 extern ARMInstr* ARMInstr_VLdStD   ( Bool isLoad, HReg, ARMAModeV* );
    931 extern ARMInstr* ARMInstr_VLdStS   ( Bool isLoad, HReg, ARMAModeV* );
    932 extern ARMInstr* ARMInstr_VAluD    ( ARMVfpOp op, HReg, HReg, HReg );
    933 extern ARMInstr* ARMInstr_VAluS    ( ARMVfpOp op, HReg, HReg, HReg );
    934 extern ARMInstr* ARMInstr_VUnaryD  ( ARMVfpUnaryOp, HReg dst, HReg src );
    935 extern ARMInstr* ARMInstr_VUnaryS  ( ARMVfpUnaryOp, HReg dst, HReg src );
    936 extern ARMInstr* ARMInstr_VCmpD    ( HReg argL, HReg argR );
    937 extern ARMInstr* ARMInstr_VCMovD   ( ARMCondCode, HReg dst, HReg src );
    938 extern ARMInstr* ARMInstr_VCMovS   ( ARMCondCode, HReg dst, HReg src );
    939 extern ARMInstr* ARMInstr_VCvtSD   ( Bool sToD, HReg dst, HReg src );
    940 extern ARMInstr* ARMInstr_VXferD   ( Bool toD, HReg dD, HReg rHi, HReg rLo );
    941 extern ARMInstr* ARMInstr_VXferS   ( Bool toS, HReg fD, HReg rLo );
    942 extern ARMInstr* ARMInstr_VCvtID   ( Bool iToD, Bool syned,
    943                                      HReg dst, HReg src );
    944 extern ARMInstr* ARMInstr_FPSCR    ( Bool toFPSCR, HReg iReg );
    945 extern ARMInstr* ARMInstr_MFence   ( void );
    946 extern ARMInstr* ARMInstr_CLREX    ( void );
    947 extern ARMInstr* ARMInstr_NLdStQ   ( Bool isLoad, HReg, ARMAModeN* );
    948 extern ARMInstr* ARMInstr_NLdStD   ( Bool isLoad, HReg, ARMAModeN* );
    949 extern ARMInstr* ARMInstr_NUnary   ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
    950 extern ARMInstr* ARMInstr_NUnaryS  ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
    951                                      UInt, Bool );
    952 extern ARMInstr* ARMInstr_NDual    ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
    953 extern ARMInstr* ARMInstr_NBinary  ( ARMNeonBinOp, HReg, HReg, HReg,
    954                                      UInt, Bool );
    955 extern ARMInstr* ARMInstr_NShift   ( ARMNeonShiftOp, HReg, HReg, HReg,
    956                                      UInt, Bool );
    957 extern ARMInstr* ARMInstr_NeonImm  ( HReg, ARMNImm* );
    958 extern ARMInstr* ARMInstr_NCMovQ   ( ARMCondCode, HReg, HReg );
    959 extern ARMInstr* ARMInstr_Add32    ( HReg rD, HReg rN, UInt imm32 );
    960 
    961 extern void ppARMInstr ( ARMInstr* );
    962 
    963 
    964 /* Some functions that insulate the register allocator from details
    965    of the underlying instruction set. */
    966 extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool );
    967 extern void mapRegs_ARMInstr     ( HRegRemap*, ARMInstr*, Bool );
    968 extern Bool isMove_ARMInstr      ( ARMInstr*, HReg*, HReg* );
    969 extern Int  emit_ARMInstr        ( UChar* buf, Int nbuf, ARMInstr*,
    970                                    Bool,
    971                                    void* dispatch_unassisted,
    972                                    void* dispatch_assisted );
    973 
    974 extern void genSpill_ARM  ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
    975                             HReg rreg, Int offset, Bool );
    976 extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
    977                             HReg rreg, Int offset, Bool );
    978 
    979 extern void getAllocableRegs_ARM ( Int*, HReg** );
    980 extern HInstrArray* iselSB_ARM   ( IRSB*, VexArch,
    981                                    VexArchInfo*, VexAbiInfo* );
    982 
    983 #endif /* ndef __VEX_HOST_ARM_DEFS_H */
    984 
    985 /*---------------------------------------------------------------*/
    986 /*--- end                                     host_arm_defs.h ---*/
    987 /*---------------------------------------------------------------*/
    988