Home | History | Annotate | Download | only in priv
      1 
      2 /*---------------------------------------------------------------*/
      3 /*--- begin                                   host_arm_defs.h ---*/
      4 /*---------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2004-2010 OpenWorks LLP
     11       info (at) open-works.net
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     26    02110-1301, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 */
     30 
     31 #ifndef __VEX_HOST_ARM_DEFS_H
     32 #define __VEX_HOST_ARM_DEFS_H
     33 
     34 extern UInt arm_hwcaps;
     35 
     36 
     37 /* --------- Registers. --------- */
     38 
     39 /* The usual HReg abstraction.
     40    There are 16 general purpose regs.
     41 */
     42 
     43 extern void ppHRegARM ( HReg );
     44 
     45 extern HReg hregARM_R0  ( void );
     46 extern HReg hregARM_R1  ( void );
     47 extern HReg hregARM_R2  ( void );
     48 extern HReg hregARM_R3  ( void );
     49 extern HReg hregARM_R4  ( void );
     50 extern HReg hregARM_R5  ( void );
     51 extern HReg hregARM_R6  ( void );
     52 extern HReg hregARM_R7  ( void );
     53 extern HReg hregARM_R8  ( void );
     54 extern HReg hregARM_R9  ( void );
     55 extern HReg hregARM_R10 ( void );
     56 extern HReg hregARM_R11 ( void );
     57 extern HReg hregARM_R12 ( void );
     58 extern HReg hregARM_R13 ( void );
     59 extern HReg hregARM_R14 ( void );
     60 extern HReg hregARM_R15 ( void );
     61 extern HReg hregARM_D8  ( void );
     62 extern HReg hregARM_D9  ( void );
     63 extern HReg hregARM_D10 ( void );
     64 extern HReg hregARM_D11 ( void );
     65 extern HReg hregARM_D12 ( void );
     66 extern HReg hregARM_S26 ( void );
     67 extern HReg hregARM_S27 ( void );
     68 extern HReg hregARM_S28 ( void );
     69 extern HReg hregARM_S29 ( void );
     70 extern HReg hregARM_S30 ( void );
     71 extern HReg hregARM_Q8  ( void );
     72 extern HReg hregARM_Q9  ( void );
     73 extern HReg hregARM_Q10 ( void );
     74 extern HReg hregARM_Q11 ( void );
     75 extern HReg hregARM_Q12 ( void );
     76 extern HReg hregARM_Q13 ( void );
     77 extern HReg hregARM_Q14 ( void );
     78 extern HReg hregARM_Q15 ( void );
     79 
     80 /* Number of registers used arg passing in function calls */
     81 #define ARM_N_ARGREGS 4   /* r0, r1, r2, r3 */
     82 
     83 
     84 /* --------- Condition codes. --------- */
     85 
     86 typedef
     87    enum {
     88       ARMcc_EQ  = 0,  /* equal                          : Z=1 */
     89       ARMcc_NE  = 1,  /* not equal                      : Z=0 */
     90 
     91       ARMcc_HS  = 2,  /* >=u (higher or same)           : C=1 */
     92       ARMcc_LO  = 3,  /* <u  (lower)                    : C=0 */
     93 
     94       ARMcc_MI  = 4,  /* minus (negative)               : N=1 */
     95       ARMcc_PL  = 5,  /* plus (zero or +ve)             : N=0 */
     96 
     97       ARMcc_VS  = 6,  /* overflow                       : V=1 */
     98       ARMcc_VC  = 7,  /* no overflow                    : V=0 */
     99 
    100       ARMcc_HI  = 8,  /* >u   (higher)                  : C=1 && Z=0 */
    101       ARMcc_LS  = 9,  /* <=u  (lower or same)           : C=0 || Z=1 */
    102 
    103       ARMcc_GE  = 10, /* >=s (signed greater or equal)  : N=V */
    104       ARMcc_LT  = 11, /* <s  (signed less than)         : N!=V */
    105 
    106       ARMcc_GT  = 12, /* >s  (signed greater)           : Z=0 && N=V */
    107       ARMcc_LE  = 13, /* <=s (signed less or equal)     : Z=1 || N!=V */
    108 
    109       ARMcc_AL  = 14, /* always (unconditional) */
    110       ARMcc_NV  = 15  /* never (basically undefined meaning), deprecated */
    111    }
    112    ARMCondCode;
    113 
    114 extern HChar* showARMCondCode ( ARMCondCode );
    115 
    116 
    117 
    118 /* --------- Memory address expressions (amodes). --------- */
    119 
    120 /* --- Addressing Mode 1 --- */
    121 typedef
    122    enum {
    123       ARMam1_RI=1,   /* reg +/- imm12 */
    124       ARMam1_RRS     /* reg1 + (reg2 << 0, 1 2 or 3) */
    125    }
    126    ARMAMode1Tag;
    127 
    128 typedef
    129    struct {
    130       ARMAMode1Tag tag;
    131       union {
    132          struct {
    133             HReg reg;
    134             Int  simm13; /* -4095 .. +4095 */
    135          } RI;
    136          struct {
    137             HReg base;
    138             HReg index;
    139             UInt shift; /* 0, 1 2 or 3 */
    140          } RRS;
    141       } ARMam1;
    142    }
    143    ARMAMode1;
    144 
    145 extern ARMAMode1* ARMAMode1_RI  ( HReg reg, Int simm13 );
    146 extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
    147 
    148 extern void ppARMAMode1 ( ARMAMode1* );
    149 
    150 
    151 /* --- Addressing Mode 2 --- */
    152 typedef
    153    enum {
    154       ARMam2_RI=3,   /* reg +/- imm8 */
    155       ARMam2_RR      /* reg1 + reg2 */
    156    }
    157    ARMAMode2Tag;
    158 
    159 typedef
    160    struct {
    161       ARMAMode2Tag tag;
    162       union {
    163          struct {
    164             HReg reg;
    165             Int  simm9; /* -255 .. 255 */
    166          } RI;
    167          struct {
    168             HReg base;
    169             HReg index;
    170          } RR;
    171       } ARMam2;
    172    }
    173    ARMAMode2;
    174 
    175 extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
    176 extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
    177 
    178 extern void ppARMAMode2 ( ARMAMode2* );
    179 
    180 
    181 /* --- Addressing Mode suitable for VFP --- */
    182 /* The simm11 is encoded as 8 bits + 1 sign bit,
    183    so can only be 0 % 4. */
    184 typedef
    185    struct {
    186       HReg reg;
    187       Int  simm11; /* -1020, -1016 .. 1016, 1020 */
    188    }
    189    ARMAModeV;
    190 
    191 extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
    192 
    193 extern void ppARMAModeV ( ARMAModeV* );
    194 
    195 /* --- Addressing Mode suitable for Neon --- */
    196 typedef
    197    enum {
    198       ARMamN_R=5,
    199       ARMamN_RR
    200       /* ... */
    201    }
    202    ARMAModeNTag;
    203 
    204 typedef
    205    struct {
    206       ARMAModeNTag tag;
    207       union {
    208          struct {
    209             HReg rN;
    210             HReg rM;
    211          } RR;
    212          struct {
    213             HReg rN;
    214          } R;
    215          /* ... */
    216       } ARMamN;
    217    }
    218    ARMAModeN;
    219 
    220 extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg );
    221 extern ARMAModeN* mkARMAModeN_R ( HReg );
    222 extern void ppARMAModeN ( ARMAModeN* );
    223 
    224 /* --------- Reg or imm-8x4 operands --------- */
    225 /* a.k.a (a very restricted form of) Shifter Operand,
    226    in the ARM parlance. */
    227 
    228 typedef
    229    enum {
    230       ARMri84_I84=7,   /* imm8 `ror` (2 * imm4) */
    231       ARMri84_R        /* reg */
    232    }
    233    ARMRI84Tag;
    234 
    235 typedef
    236    struct {
    237       ARMRI84Tag tag;
    238       union {
    239          struct {
    240             UShort imm8;
    241             UShort imm4;
    242          } I84;
    243          struct {
    244             HReg reg;
    245          } R;
    246       } ARMri84;
    247    }
    248    ARMRI84;
    249 
    250 extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
    251 extern ARMRI84* ARMRI84_R   ( HReg );
    252 
    253 extern void ppARMRI84 ( ARMRI84* );
    254 
    255 
    256 /* --------- Reg or imm5 operands --------- */
    257 typedef
    258    enum {
    259       ARMri5_I5=9,   /* imm5, 1 .. 31 only (no zero!) */
    260       ARMri5_R       /* reg */
    261    }
    262    ARMRI5Tag;
    263 
    264 typedef
    265    struct {
    266       ARMRI5Tag tag;
    267       union {
    268          struct {
    269             UInt imm5;
    270          } I5;
    271          struct {
    272             HReg reg;
    273          } R;
    274       } ARMri5;
    275    }
    276    ARMRI5;
    277 
    278 extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
    279 extern ARMRI5* ARMRI5_R  ( HReg );
    280 
    281 extern void ppARMRI5 ( ARMRI5* );
    282 
    283 /* -------- Neon Immediate operand -------- */
    284 
    285 /* imm8 = abcdefgh, B = NOT(b);
    286 
    287 type | value (64bit binary)
    288 -----+-------------------------------------------------------------------------
    289    0 | 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh
    290    1 | 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000
    291    2 | 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000
    292    3 | abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000
    293    4 | 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh
    294    5 | abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000
    295    6 | abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh
    296    7 | 00000000 00000000 abcdefgh 11111111 00000000 00000000 abcdefgh 11111111
    297    8 | 00000000 abcdefgh 11111111 11111111 00000000 abcdefgh 11111111 11111111
    298    9 | aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
    299   10 | aBbbbbbc defgh000 00000000 00000000 aBbbbbbc defgh000 00000000 00000000
    300 -----+-------------------------------------------------------------------------
    301 
    302 Type 10 is:
    303    (-1)^S * 2^exp * mantissa
    304 where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16
    305 */
    306 
    307 typedef
    308    struct {
    309       UInt type;
    310       UInt imm8;
    311    }
    312    ARMNImm;
    313 
    314 extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 );
    315 extern ULong ARMNImm_to_Imm64 ( ARMNImm* );
    316 extern ARMNImm* Imm64_to_ARMNImm ( ULong );
    317 
    318 extern void ppARMNImm ( ARMNImm* );
    319 
    320 /* ------ Neon Register or Scalar Operand ------ */
    321 
    322 typedef
    323    enum {
    324       ARMNRS_Reg=11,
    325       ARMNRS_Scalar
    326    }
    327    ARMNRS_tag;
    328 
    329 typedef
    330    struct {
    331       ARMNRS_tag tag;
    332       HReg reg;
    333       UInt index;
    334    }
    335    ARMNRS;
    336 
    337 extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index);
    338 extern void ppARMNRS ( ARMNRS* );
    339 
    340 /* --------- Instructions. --------- */
    341 
    342 /* --------- */
    343 typedef
    344    enum {
    345       ARMalu_ADD=20,   /* plain 32-bit add */
    346       ARMalu_ADDS,     /* 32-bit add, and set the flags */
    347       ARMalu_ADC,      /* 32-bit add with carry */
    348       ARMalu_SUB,      /* plain 32-bit subtract */
    349       ARMalu_SUBS,     /* 32-bit subtract, and set the flags */
    350       ARMalu_SBC,      /* 32-bit subtract with carry */
    351       ARMalu_AND,
    352       ARMalu_BIC,
    353       ARMalu_OR,
    354       ARMalu_XOR
    355    }
    356    ARMAluOp;
    357 
    358 extern HChar* showARMAluOp ( ARMAluOp op );
    359 
    360 
    361 typedef
    362    enum {
    363       ARMsh_SHL=40,
    364       ARMsh_SHR,
    365       ARMsh_SAR
    366    }
    367    ARMShiftOp;
    368 
    369 extern HChar* showARMShiftOp ( ARMShiftOp op );
    370 
    371 
    372 typedef
    373    enum {
    374       ARMun_NEG=50,
    375       ARMun_NOT,
    376       ARMun_CLZ
    377    }
    378    ARMUnaryOp;
    379 
    380 extern HChar* showARMUnaryOp ( ARMUnaryOp op );
    381 
    382 
    383 typedef
    384    enum {
    385       ARMmul_PLAIN=60,
    386       ARMmul_ZX,
    387       ARMmul_SX
    388    }
    389    ARMMulOp;
    390 
    391 extern HChar* showARMMulOp ( ARMMulOp op );
    392 
    393 
    394 typedef
    395    enum {
    396       ARMvfp_ADD=70,
    397       ARMvfp_SUB,
    398       ARMvfp_MUL,
    399       ARMvfp_DIV
    400    }
    401    ARMVfpOp;
    402 
    403 extern HChar* showARMVfpOp ( ARMVfpOp op );
    404 
    405 
    406 typedef
    407    enum {
    408       ARMvfpu_COPY=80,
    409       ARMvfpu_NEG,
    410       ARMvfpu_ABS,
    411       ARMvfpu_SQRT
    412    }
    413    ARMVfpUnaryOp;
    414 
    415 extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
    416 
    417 typedef
    418    enum {
    419       ARMneon_VAND=90,
    420       ARMneon_VORR,
    421       ARMneon_VXOR,
    422       ARMneon_VADD,
    423       ARMneon_VADDFP,
    424       ARMneon_VRHADDS,
    425       ARMneon_VRHADDU,
    426       ARMneon_VPADDFP,
    427       ARMneon_VABDFP,
    428       ARMneon_VSUB,
    429       ARMneon_VSUBFP,
    430       ARMneon_VMAXU,
    431       ARMneon_VMAXS,
    432       ARMneon_VMAXF,
    433       ARMneon_VMINU,
    434       ARMneon_VMINS,
    435       ARMneon_VMINF,
    436       ARMneon_VQADDU,
    437       ARMneon_VQADDS,
    438       ARMneon_VQSUBU,
    439       ARMneon_VQSUBS,
    440       ARMneon_VCGTU,
    441       ARMneon_VCGTS,
    442       ARMneon_VCGEU,
    443       ARMneon_VCGES,
    444       ARMneon_VCGTF,
    445       ARMneon_VCGEF,
    446       ARMneon_VCEQ,
    447       ARMneon_VCEQF,
    448       ARMneon_VEXT,
    449       ARMneon_VMUL,
    450       ARMneon_VMULFP,
    451       ARMneon_VMULLU,
    452       ARMneon_VMULLS,
    453       ARMneon_VMULP,
    454       ARMneon_VMULLP,
    455       ARMneon_VQDMULH,
    456       ARMneon_VQRDMULH,
    457       ARMneon_VPADD,
    458       ARMneon_VPMINU,
    459       ARMneon_VPMINS,
    460       ARMneon_VPMINF,
    461       ARMneon_VPMAXU,
    462       ARMneon_VPMAXS,
    463       ARMneon_VPMAXF,
    464       ARMneon_VTBL,
    465       ARMneon_VQDMULL,
    466       ARMneon_VRECPS,
    467       ARMneon_VRSQRTS,
    468       /* ... */
    469    }
    470    ARMNeonBinOp;
    471 
    472 typedef
    473    enum {
    474       ARMneon_VSHL=150,
    475       ARMneon_VSAL, /* Yah, not SAR but SAL */
    476       ARMneon_VQSHL,
    477       ARMneon_VQSAL
    478    }
    479    ARMNeonShiftOp;
    480 
    481 typedef
    482    enum {
    483       ARMneon_COPY=160,
    484       ARMneon_COPYLU,
    485       ARMneon_COPYLS,
    486       ARMneon_COPYN,
    487       ARMneon_COPYQNSS,
    488       ARMneon_COPYQNUS,
    489       ARMneon_COPYQNUU,
    490       ARMneon_NOT,
    491       ARMneon_EQZ,
    492       ARMneon_DUP,
    493       ARMneon_PADDLS,
    494       ARMneon_PADDLU,
    495       ARMneon_CNT,
    496       ARMneon_CLZ,
    497       ARMneon_CLS,
    498       ARMneon_VCVTxFPxINT,
    499       ARMneon_VQSHLNSS,
    500       ARMneon_VQSHLNUU,
    501       ARMneon_VQSHLNUS,
    502       ARMneon_VCVTFtoU,
    503       ARMneon_VCVTFtoS,
    504       ARMneon_VCVTUtoF,
    505       ARMneon_VCVTStoF,
    506       ARMneon_VCVTFtoFixedU,
    507       ARMneon_VCVTFtoFixedS,
    508       ARMneon_VCVTFixedUtoF,
    509       ARMneon_VCVTFixedStoF,
    510       ARMneon_VCVTF16toF32,
    511       ARMneon_VCVTF32toF16,
    512       ARMneon_REV16,
    513       ARMneon_REV32,
    514       ARMneon_REV64,
    515       ARMneon_ABS,
    516       ARMneon_VNEGF,
    517       ARMneon_VRECIP,
    518       ARMneon_VRECIPF,
    519       ARMneon_VABSFP,
    520       ARMneon_VRSQRTEFP,
    521       ARMneon_VRSQRTE
    522       /* ... */
    523    }
    524    ARMNeonUnOp;
    525 
    526 typedef
    527    enum {
    528       ARMneon_SETELEM=200,
    529       ARMneon_GETELEMU,
    530       ARMneon_GETELEMS,
    531       ARMneon_VDUP,
    532    }
    533    ARMNeonUnOpS;
    534 
    535 typedef
    536    enum {
    537       ARMneon_TRN=210,
    538       ARMneon_ZIP,
    539       ARMneon_UZP
    540       /* ... */
    541    }
    542    ARMNeonDualOp;
    543 
    544 extern HChar* showARMNeonBinOp ( ARMNeonBinOp op );
    545 extern HChar* showARMNeonUnOp ( ARMNeonUnOp op );
    546 extern HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
    547 extern HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
    548 extern HChar* showARMNeonDualOp ( ARMNeonDualOp op );
    549 extern HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
    550 extern HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
    551 extern HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
    552 extern HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
    553 extern HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
    554 
    555 typedef
    556    enum {
    557       /* baseline */
    558       ARMin_Alu=220,
    559       ARMin_Shift,
    560       ARMin_Unary,
    561       ARMin_CmpOrTst,
    562       ARMin_Mov,
    563       ARMin_Imm32,
    564       ARMin_LdSt32,
    565       ARMin_LdSt16,
    566       ARMin_LdSt8U,
    567       ARMin_Ld8S,
    568       ARMin_Goto,
    569       ARMin_CMov,
    570       ARMin_Call,
    571       ARMin_Mul,
    572       ARMin_LdrEX,
    573       ARMin_StrEX,
    574       /* vfp */
    575       ARMin_VLdStD,
    576       ARMin_VLdStS,
    577       ARMin_VAluD,
    578       ARMin_VAluS,
    579       ARMin_VUnaryD,
    580       ARMin_VUnaryS,
    581       ARMin_VCmpD,
    582       ARMin_VCMovD,
    583       ARMin_VCMovS,
    584       ARMin_VCvtSD,
    585       ARMin_VXferD,
    586       ARMin_VXferS,
    587       ARMin_VCvtID,
    588       ARMin_FPSCR,
    589       ARMin_MFence,
    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} r0, [r1]
    713             Again, hardwired registers since this is not performance
    714             critical, and there are possibly constraints on the
    715             registers that we can't express in the register allocator.*/
    716          struct {
    717             Int  szB; /* currently only 4 is allowed */
    718          } LdrEX;
    719          /* STREX{,H,B} r0, r1, [r2]
    720             r0 = SC( [r2] = r1 )
    721             Ditto comment re fixed registers. */
    722          struct {
    723             Int  szB; /* currently only 4 is allowed */
    724          } StrEX;
    725          /* VFP INSTRUCTIONS */
    726          /* 64-bit Fp load/store */
    727          struct {
    728             Bool       isLoad;
    729             HReg       dD;
    730             ARMAModeV* amode;
    731          } VLdStD;
    732          /* 32-bit Fp load/store */
    733          struct {
    734             Bool       isLoad;
    735             HReg       fD;
    736             ARMAModeV* amode;
    737          } VLdStS;
    738          /* 64-bit FP binary arithmetic */
    739          struct {
    740             ARMVfpOp op;
    741             HReg     dst;
    742             HReg     argL;
    743             HReg     argR;
    744          } VAluD;
    745          /* 32-bit FP binary arithmetic */
    746          struct {
    747             ARMVfpOp op;
    748             HReg     dst;
    749             HReg     argL;
    750             HReg     argR;
    751          } VAluS;
    752          /* 64-bit FP unary, also reg-reg move */
    753          struct {
    754             ARMVfpUnaryOp op;
    755             HReg          dst;
    756             HReg          src;
    757          } VUnaryD;
    758          /* 32-bit FP unary, also reg-reg move */
    759          struct {
    760             ARMVfpUnaryOp op;
    761             HReg          dst;
    762             HReg          src;
    763          } VUnaryS;
    764          /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
    765          struct {
    766             HReg argL;
    767             HReg argR;
    768          } VCmpD;
    769          /* 64-bit FP mov src to dst on the given condition, which may
    770             not be ARMcc_AL. */
    771          struct {
    772             ARMCondCode cond;
    773             HReg        dst;
    774             HReg        src;
    775          } VCMovD;
    776          /* 32-bit FP mov src to dst on the given condition, which may
    777             not be ARMcc_AL. */
    778          struct {
    779             ARMCondCode cond;
    780             HReg        dst;
    781             HReg        src;
    782          } VCMovS;
    783          /* Convert between 32-bit and 64-bit FP values (both ways).
    784             (FCVTSD, FCVTDS) */
    785          struct {
    786             Bool sToD; /* True: F32->F64.  False: F64->F32 */
    787             HReg dst;
    788             HReg src;
    789          } VCvtSD;
    790          /* Transfer a VFP D reg to/from two integer registers (VMOV) */
    791          struct {
    792             Bool toD;
    793             HReg dD;
    794             HReg rHi;
    795             HReg rLo;
    796          } VXferD;
    797          /* Transfer a VFP S reg to/from an integer register (VMOV) */
    798          struct {
    799             Bool toS;
    800             HReg fD;
    801             HReg rLo;
    802          } VXferS;
    803          /* Convert between 32-bit ints and 64-bit FP values (both ways
    804             and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
    805          struct {
    806             Bool iToD; /* True: I32->F64.  False: F64->I32 */
    807             Bool syned; /* True: I32 is signed.  False: I32 is unsigned */
    808             HReg dst;
    809             HReg src;
    810          } VCvtID;
    811          /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
    812          struct {
    813             Bool toFPSCR;
    814             HReg iReg;
    815          } FPSCR;
    816          /* Mem fence.  An insn which fences all loads and stores as
    817             much as possible before continuing.  On ARM we emit the
    818             sequence
    819                mcr 15,0,r0,c7,c10,4 (DSB)
    820                mcr 15,0,r0,c7,c10,5 (DMB)
    821                mcr 15,0,r0,c7,c5,4 (ISB)
    822             which is probably total overkill, but better safe than
    823             sorry.
    824          */
    825          struct {
    826          } MFence;
    827          /* Neon data processing instruction: 3 registers of the same
    828             length */
    829          struct {
    830             ARMNeonBinOp op;
    831             HReg dst;
    832             HReg argL;
    833             HReg argR;
    834             UInt size;
    835             Bool Q;
    836          } NBinary;
    837          struct {
    838             ARMNeonBinOp op;
    839             ARMNRS* dst;
    840             ARMNRS* argL;
    841             ARMNRS* argR;
    842             UInt size;
    843             Bool Q;
    844          } NBinaryS;
    845          struct {
    846             ARMNeonShiftOp op;
    847             HReg dst;
    848             HReg argL;
    849             HReg argR;
    850             UInt size;
    851             Bool Q;
    852          } NShift;
    853          struct {
    854             Bool isLoad;
    855             HReg dQ;
    856             ARMAModeN *amode;
    857          } NLdStQ;
    858          struct {
    859             Bool isLoad;
    860             HReg dD;
    861             ARMAModeN *amode;
    862          } NLdStD;
    863          struct {
    864             ARMNeonUnOpS op;
    865             ARMNRS*  dst;
    866             ARMNRS*  src;
    867             UInt size;
    868             Bool Q;
    869          } NUnaryS;
    870          struct {
    871             ARMNeonUnOp op;
    872             HReg  dst;
    873             HReg  src;
    874             UInt size;
    875             Bool Q;
    876          } NUnary;
    877          /* Takes two arguments and modifies them both. */
    878          struct {
    879             ARMNeonDualOp op;
    880             HReg  arg1;
    881             HReg  arg2;
    882             UInt size;
    883             Bool Q;
    884          } NDual;
    885          struct {
    886             HReg dst;
    887             ARMNImm* imm;
    888          } NeonImm;
    889          /* 128-bit Neon move src to dst on the given condition, which
    890             may not be ARMcc_AL. */
    891          struct {
    892             ARMCondCode cond;
    893             HReg        dst;
    894             HReg        src;
    895          } NCMovQ;
    896          struct {
    897             /* Note: rD != rN */
    898             HReg rD;
    899             HReg rN;
    900             UInt imm32;
    901          } Add32;
    902       } ARMin;
    903    }
    904    ARMInstr;
    905 
    906 
    907 extern ARMInstr* ARMInstr_Alu      ( ARMAluOp, HReg, HReg, ARMRI84* );
    908 extern ARMInstr* ARMInstr_Shift    ( ARMShiftOp, HReg, HReg, ARMRI5* );
    909 extern ARMInstr* ARMInstr_Unary    ( ARMUnaryOp, HReg, HReg );
    910 extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
    911 extern ARMInstr* ARMInstr_Mov      ( HReg, ARMRI84* );
    912 extern ARMInstr* ARMInstr_Imm32    ( HReg, UInt );
    913 extern ARMInstr* ARMInstr_LdSt32   ( Bool isLoad, HReg, ARMAMode1* );
    914 extern ARMInstr* ARMInstr_LdSt16   ( Bool isLoad, Bool signedLoad,
    915                                      HReg, ARMAMode2* );
    916 extern ARMInstr* ARMInstr_LdSt8U   ( Bool isLoad, HReg, ARMAMode1* );
    917 extern ARMInstr* ARMInstr_Ld8S     ( HReg, ARMAMode2* );
    918 extern ARMInstr* ARMInstr_Goto     ( IRJumpKind, ARMCondCode, HReg gnext );
    919 extern ARMInstr* ARMInstr_CMov     ( ARMCondCode, HReg dst, ARMRI84* src );
    920 extern ARMInstr* ARMInstr_Call     ( ARMCondCode, HWord, Int nArgRegs );
    921 extern ARMInstr* ARMInstr_Mul      ( ARMMulOp op );
    922 extern ARMInstr* ARMInstr_LdrEX    ( Int szB );
    923 extern ARMInstr* ARMInstr_StrEX    ( Int szB );
    924 extern ARMInstr* ARMInstr_VLdStD   ( Bool isLoad, HReg, ARMAModeV* );
    925 extern ARMInstr* ARMInstr_VLdStS   ( Bool isLoad, HReg, ARMAModeV* );
    926 extern ARMInstr* ARMInstr_VAluD    ( ARMVfpOp op, HReg, HReg, HReg );
    927 extern ARMInstr* ARMInstr_VAluS    ( ARMVfpOp op, HReg, HReg, HReg );
    928 extern ARMInstr* ARMInstr_VUnaryD  ( ARMVfpUnaryOp, HReg dst, HReg src );
    929 extern ARMInstr* ARMInstr_VUnaryS  ( ARMVfpUnaryOp, HReg dst, HReg src );
    930 extern ARMInstr* ARMInstr_VCmpD    ( HReg argL, HReg argR );
    931 extern ARMInstr* ARMInstr_VCMovD   ( ARMCondCode, HReg dst, HReg src );
    932 extern ARMInstr* ARMInstr_VCMovS   ( ARMCondCode, HReg dst, HReg src );
    933 extern ARMInstr* ARMInstr_VCvtSD   ( Bool sToD, HReg dst, HReg src );
    934 extern ARMInstr* ARMInstr_VXferD   ( Bool toD, HReg dD, HReg rHi, HReg rLo );
    935 extern ARMInstr* ARMInstr_VXferS   ( Bool toS, HReg fD, HReg rLo );
    936 extern ARMInstr* ARMInstr_VCvtID   ( Bool iToD, Bool syned,
    937                                      HReg dst, HReg src );
    938 extern ARMInstr* ARMInstr_FPSCR    ( Bool toFPSCR, HReg iReg );
    939 extern ARMInstr* ARMInstr_MFence   ( void );
    940 extern ARMInstr* ARMInstr_NLdStQ   ( Bool isLoad, HReg, ARMAModeN* );
    941 extern ARMInstr* ARMInstr_NLdStD   ( Bool isLoad, HReg, ARMAModeN* );
    942 extern ARMInstr* ARMInstr_NUnary   ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
    943 extern ARMInstr* ARMInstr_NUnaryS  ( ARMNeonUnOp, ARMNRS*, ARMNRS*,
    944                                      UInt, Bool );
    945 extern ARMInstr* ARMInstr_NDual    ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
    946 extern ARMInstr* ARMInstr_NBinary  ( ARMNeonBinOp, HReg, HReg, HReg,
    947                                      UInt, Bool );
    948 extern ARMInstr* ARMInstr_NShift   ( ARMNeonShiftOp, HReg, HReg, HReg,
    949                                      UInt, Bool );
    950 extern ARMInstr* ARMInstr_NeonImm  ( HReg, ARMNImm* );
    951 extern ARMInstr* ARMInstr_NCMovQ   ( ARMCondCode, HReg, HReg );
    952 extern ARMInstr* ARMInstr_Add32    ( HReg rD, HReg rN, UInt imm32 );
    953 
    954 extern void ppARMInstr ( ARMInstr* );
    955 
    956 
    957 /* Some functions that insulate the register allocator from details
    958    of the underlying instruction set. */
    959 extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool );
    960 extern void mapRegs_ARMInstr     ( HRegRemap*, ARMInstr*, Bool );
    961 extern Bool isMove_ARMInstr      ( ARMInstr*, HReg*, HReg* );
    962 extern Int  emit_ARMInstr        ( UChar* buf, Int nbuf, ARMInstr*,
    963                                    Bool, void* dispatch );
    964 
    965 extern void genSpill_ARM  ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
    966                             HReg rreg, Int offset, Bool );
    967 extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
    968                             HReg rreg, Int offset, Bool );
    969 
    970 extern void getAllocableRegs_ARM ( Int*, HReg** );
    971 extern HInstrArray* iselSB_ARM   ( IRSB*, VexArch,
    972                                    VexArchInfo*, VexAbiInfo* );
    973 
    974 #endif /* ndef __VEX_HOST_ARM_DEFS_H */
    975 
    976 /*---------------------------------------------------------------*/
    977 /*--- end                                     host_arm_defs.h ---*/
    978 /*---------------------------------------------------------------*/
    979