Home | History | Annotate | Download | only in priv
      1 
      2 /*---------------------------------------------------------------*/
      3 /*--- begin                                 host_arm64_defs.h ---*/
      4 /*---------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2013-2013 OpenWorks
     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_ARM64_DEFS_H
     32 #define __VEX_HOST_ARM64_DEFS_H
     33 
     34 #include "libvex_basictypes.h"
     35 #include "libvex.h"                      // VexArch
     36 #include "host_generic_regs.h"           // HReg
     37 
     38 //ZZ extern UInt arm_hwcaps;
     39 
     40 
     41 /* --------- Registers. --------- */
     42 
     43 //ZZ /* The usual HReg abstraction.
     44 //ZZ    There are 16 general purpose regs.
     45 //ZZ */
     46 
     47 extern void ppHRegARM64 ( HReg );
     48 
     49 extern HReg hregARM64_X0  ( void );
     50 extern HReg hregARM64_X1  ( void );
     51 extern HReg hregARM64_X2  ( void );
     52 extern HReg hregARM64_X3  ( void );
     53 extern HReg hregARM64_X4  ( void );
     54 extern HReg hregARM64_X5  ( void );
     55 extern HReg hregARM64_X6  ( void );
     56 extern HReg hregARM64_X7  ( void );
     57 //ZZ extern HReg hregARM_R8  ( void );
     58 extern HReg hregARM64_X9  ( void );
     59 extern HReg hregARM64_X10 ( void );
     60 extern HReg hregARM64_X11 ( void );
     61 extern HReg hregARM64_X12 ( void );
     62 extern HReg hregARM64_X13 ( void );
     63 extern HReg hregARM64_X14 ( void );
     64 extern HReg hregARM64_X15 ( void );
     65 extern HReg hregARM64_X21 ( void );
     66 extern HReg hregARM64_X22 ( void );
     67 extern HReg hregARM64_X23 ( void );
     68 extern HReg hregARM64_X24 ( void );
     69 extern HReg hregARM64_X25 ( void );
     70 extern HReg hregARM64_X26 ( void );
     71 extern HReg hregARM64_X27 ( void );
     72 extern HReg hregARM64_X28 ( void );
     73 extern HReg hregARM64_D8  ( void );
     74 extern HReg hregARM64_D9  ( void );
     75 extern HReg hregARM64_D10 ( void );
     76 extern HReg hregARM64_D11 ( void );
     77 extern HReg hregARM64_D12 ( void );
     78 extern HReg hregARM64_D13 ( void );
     79 extern HReg hregARM64_Q16 ( void );
     80 extern HReg hregARM64_Q17 ( void );
     81 extern HReg hregARM64_Q18 ( void );
     82 
     83 /* Number of registers used arg passing in function calls */
     84 #define ARM64_N_ARGREGS 8   /* x0 .. x7 */
     85 
     86 
     87 /* --------- Condition codes. --------- */
     88 
     89 typedef
     90    enum {
     91       ARM64cc_EQ  = 0,  /* equal                         : Z=1 */
     92       ARM64cc_NE  = 1,  /* not equal                     : Z=0 */
     93 
     94       ARM64cc_CS  = 2,  /* >=u (higher or same)          : C=1 */
     95       ARM64cc_CC  = 3,  /* <u  (lower)                   : C=0 */
     96 
     97       ARM64cc_MI  = 4,  /* minus (negative)              : N=1 */
     98       ARM64cc_PL  = 5,  /* plus (zero or +ve)            : N=0 */
     99 
    100       ARM64cc_VS  = 6,  /* overflow                      : V=1 */
    101       ARM64cc_VC  = 7,  /* no overflow                   : V=0 */
    102 
    103       ARM64cc_HI  = 8,  /* >u   (higher)                 :   C=1 && Z=0 */
    104       ARM64cc_LS  = 9,  /* <=u  (lower or same)          : !(C=1 && Z=0) */
    105 
    106       ARM64cc_GE  = 10, /* >=s (signed greater or equal) :   N=V */
    107       ARM64cc_LT  = 11, /* <s  (signed less than)        : !(N=V) */
    108 
    109       ARM64cc_GT  = 12, /* >s  (signed greater)          :   Z=0 && N=V */
    110       ARM64cc_LE  = 13, /* <=s (signed less or equal)    : !(Z=0 && N=V) */
    111 
    112       ARM64cc_AL  = 14, /* always (unconditional) */
    113       ARM64cc_NV  = 15  /* in 64-bit mode also means "always" */
    114    }
    115    ARM64CondCode;
    116 
    117 
    118 /* --------- Memory address expressions (amodes). --------- */
    119 
    120 typedef
    121    enum {
    122       ARM64am_RI9=10, /* reg + simm9 */
    123       ARM64am_RI12,   /* reg + uimm12 * szB (iow, scaled by access size) */
    124       ARM64am_RR      /* reg1 + reg2 */
    125    }
    126    ARM64AModeTag;
    127 
    128 typedef
    129    struct {
    130       ARM64AModeTag tag;
    131       union {
    132          struct {
    133             HReg reg;
    134             Int  simm9; /* -256 .. +255 */
    135          } RI9;
    136          struct {
    137             HReg  reg;
    138             UInt  uimm12; /* 0 .. 4095 */
    139             UChar szB;    /* 1, 2, 4, 8 (16 ?) */
    140          } RI12;
    141          struct {
    142             HReg base;
    143             HReg index;
    144          } RR;
    145       } ARM64am;
    146    }
    147    ARM64AMode;
    148 
    149 extern ARM64AMode* ARM64AMode_RI9  ( HReg reg, Int simm9 );
    150 extern ARM64AMode* ARM64AMode_RI12 ( HReg reg, Int uimm12, UChar szB );
    151 extern ARM64AMode* ARM64AMode_RR   ( HReg base, HReg index );
    152 
    153 
    154 /* --------- Reg or uimm12 or (uimm12 << 12) operands --------- */
    155 
    156 typedef
    157    enum {
    158       ARM64riA_I12=20, /* uimm12 << 0 or 12 only */
    159       ARM64riA_R       /* reg */
    160    }
    161    ARM64RIATag;
    162 
    163 typedef
    164    struct {
    165       ARM64RIATag tag;
    166       union {
    167          struct {
    168             UShort imm12;  /* 0 .. 4095 */
    169             UChar  shift;  /* 0 or 12 only */
    170          } I12;
    171          struct {
    172             HReg reg;
    173          } R;
    174       } ARM64riA;
    175    }
    176    ARM64RIA;
    177 
    178 extern ARM64RIA* ARM64RIA_I12 ( UShort imm12, UChar shift );
    179 extern ARM64RIA* ARM64RIA_R   ( HReg );
    180 
    181 
    182 /* --------- Reg or "bitfield" (logic immediate) operands --------- */
    183 
    184 typedef
    185    enum {
    186       ARM64riL_I13=6, /* wierd-o bitfield immediate, 13 bits in total */
    187       ARM64riL_R      /* reg */
    188    }
    189    ARM64RILTag;
    190 
    191 typedef
    192    struct {
    193       ARM64RILTag tag;
    194       union {
    195          struct {
    196             UChar bitN; /* 0 .. 1 */
    197             UChar immR; /* 0 .. 63 */
    198             UChar immS; /* 0 .. 63 */
    199          } I13;
    200          struct {
    201             HReg reg;
    202          } R;
    203       } ARM64riL;
    204    }
    205    ARM64RIL;
    206 
    207 extern ARM64RIL* ARM64RIL_I13 ( UChar bitN, UChar immR, UChar immS );
    208 extern ARM64RIL* ARM64RIL_R   ( HReg );
    209 
    210 
    211 /* --------------- Reg or uimm6 operands --------------- */
    212 
    213 typedef
    214    enum {
    215       ARM64ri6_I6=30, /* uimm6, 1 .. 63 only */
    216       ARM64ri6_R      /* reg */
    217    }
    218    ARM64RI6Tag;
    219 
    220 typedef
    221    struct {
    222       ARM64RI6Tag tag;
    223       union {
    224          struct {
    225             UInt imm6;   /* 1 .. 63 */
    226          } I6;
    227          struct {
    228             HReg reg;
    229          } R;
    230       } ARM64ri6;
    231    }
    232    ARM64RI6;
    233 
    234 extern ARM64RI6* ARM64RI6_I6 ( UInt imm6 );
    235 extern ARM64RI6* ARM64RI6_R  ( HReg );
    236 
    237 
    238 /* --------------------- Instructions --------------------- */
    239 
    240 typedef
    241    enum {
    242       ARM64lo_AND=40,
    243       ARM64lo_OR,
    244       ARM64lo_XOR
    245    }
    246    ARM64LogicOp;
    247 
    248 typedef
    249    enum {
    250       ARM64sh_SHL=50,
    251       ARM64sh_SHR,
    252       ARM64sh_SAR
    253    }
    254    ARM64ShiftOp;
    255 
    256 typedef
    257    enum {
    258       ARM64un_NEG=60,
    259       ARM64un_NOT,
    260       ARM64un_CLZ,
    261    }
    262    ARM64UnaryOp;
    263 
    264 typedef
    265    enum {
    266       ARM64mul_PLAIN=70, /* lo64(64 * 64)  */
    267       ARM64mul_ZX,       /* hi64(64 *u 64) */
    268       ARM64mul_SX        /* hi64(64 *s 64) */
    269    }
    270    ARM64MulOp;
    271 
    272 typedef
    273    /* These characterise an integer-FP conversion, but don't imply any
    274       particular direction. */
    275    enum {
    276       ARM64cvt_F32_I32S=80,
    277       ARM64cvt_F64_I32S,
    278       ARM64cvt_F32_I64S,
    279       ARM64cvt_F64_I64S,
    280       ARM64cvt_F32_I32U,
    281       ARM64cvt_F64_I32U,
    282       ARM64cvt_F32_I64U,
    283       ARM64cvt_F64_I64U,
    284       ARM64cvt_INVALID
    285    }
    286    ARM64CvtOp;
    287 
    288 typedef
    289    enum {
    290       ARM64fpb_ADD=100,
    291       ARM64fpb_SUB,
    292       ARM64fpb_MUL,
    293       ARM64fpb_DIV,
    294       ARM64fpb_INVALID
    295    }
    296    ARM64FpBinOp;
    297 
    298 typedef
    299    enum {
    300       ARM64fpu_NEG=110,
    301       ARM64fpu_ABS,
    302       ARM64fpu_SQRT,
    303       ARM64fpu_RINT,
    304       ARM64fpu_INVALID
    305    }
    306    ARM64FpUnaryOp;
    307 
    308 typedef
    309    enum {
    310       ARM64vecb_ADD64x2=120,
    311       ARM64vecb_ADD32x4,
    312       ARM64vecb_ADD16x8,
    313       ARM64vecb_ADD8x16,
    314       ARM64vecb_SUB64x2,
    315       ARM64vecb_SUB32x4,
    316       ARM64vecb_SUB16x8,
    317       ARM64vecb_SUB8x16,
    318       ARM64vecb_MUL32x4,
    319       ARM64vecb_MUL16x8,
    320       ARM64vecb_MUL8x16,
    321       ARM64vecb_FADD64x2,
    322       ARM64vecb_FSUB64x2,
    323       ARM64vecb_FMUL64x2,
    324       ARM64vecb_FDIV64x2,
    325       ARM64vecb_FADD32x4,
    326       ARM64vecb_FSUB32x4,
    327       ARM64vecb_FMUL32x4,
    328       ARM64vecb_FDIV32x4,
    329       ARM64vecb_UMAX32x4,
    330       ARM64vecb_UMAX16x8,
    331       ARM64vecb_UMAX8x16,
    332       ARM64vecb_UMIN32x4,
    333       ARM64vecb_UMIN16x8,
    334       ARM64vecb_UMIN8x16,
    335       ARM64vecb_UMULL32x2,
    336       ARM64vecb_UMULL16x4,
    337       ARM64vecb_UMULL8x8,
    338       ARM64vecb_SMAX32x4,
    339       ARM64vecb_SMAX16x8,
    340       ARM64vecb_SMAX8x16,
    341       ARM64vecb_SMIN32x4,
    342       ARM64vecb_SMIN16x8,
    343       ARM64vecb_SMIN8x16,
    344       ARM64vecb_AND,
    345       ARM64vecb_ORR,
    346       ARM64vecb_XOR,
    347       ARM64vecb_CMEQ64x2,
    348       ARM64vecb_CMEQ32x4,
    349       ARM64vecb_CMEQ16x8,
    350       ARM64vecb_CMEQ8x16,
    351       ARM64vecb_CMHI64x2, /* >u */
    352       ARM64vecb_CMHI32x4,
    353       ARM64vecb_CMHI16x8,
    354       ARM64vecb_CMHI8x16,
    355       ARM64vecb_CMGT64x2, /* >s */
    356       ARM64vecb_CMGT32x4,
    357       ARM64vecb_CMGT16x8,
    358       ARM64vecb_CMGT8x16,
    359       ARM64vecb_FCMEQ64x2,
    360       ARM64vecb_FCMEQ32x4,
    361       ARM64vecb_FCMGE64x2,
    362       ARM64vecb_FCMGE32x4,
    363       ARM64vecb_FCMGT64x2,
    364       ARM64vecb_FCMGT32x4,
    365       ARM64vecb_TBL1,
    366       ARM64vecb_INVALID
    367    }
    368    ARM64VecBinOp;
    369 
    370 typedef
    371    enum {
    372       ARM64vecu_FNEG64x2=300,
    373       ARM64vecu_FNEG32x4,
    374       ARM64vecu_FABS64x2,
    375       ARM64vecu_FABS32x4,
    376       ARM64vecu_VMOVL8U,
    377       ARM64vecu_VMOVL16U,
    378       ARM64vecu_VMOVL32U,
    379       ARM64vecu_VMOVL8S,
    380       ARM64vecu_VMOVL16S,
    381       ARM64vecu_VMOVL32S,
    382       ARM64vecu_NOT,
    383       ARM64vecu_CNT,
    384       ARM64vecu_UADDLV8x16,
    385       ARM64vecu_UADDLV16x8,
    386       ARM64vecu_UADDLV32x4,
    387       ARM64vecu_SADDLV8x16,
    388       ARM64vecu_SADDLV16x8,
    389       ARM64vecu_SADDLV32x4,
    390       ARM64vecu_INVALID
    391    }
    392    ARM64VecUnaryOp;
    393 
    394 typedef
    395    enum {
    396       ARM64vecsh_USHR64x2=350,
    397       ARM64vecsh_USHR32x4,
    398       ARM64vecsh_USHR16x8,
    399       ARM64vecsh_USHR8x16,
    400       ARM64vecsh_SSHR64x2,
    401       ARM64vecsh_SSHR32x4,
    402       ARM64vecsh_SSHR16x8,
    403       ARM64vecsh_SSHR8x16,
    404       ARM64vecsh_SHL64x2,
    405       ARM64vecsh_SHL32x4,
    406       ARM64vecsh_SHL16x8,
    407       ARM64vecsh_SHL8x16,
    408       ARM64vecsh_INVALID
    409    }
    410    ARM64VecShiftOp;
    411 
    412 //ZZ extern const HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
    413 //ZZ
    414 //ZZ typedef
    415 //ZZ    enum {
    416 //ZZ       ARMneon_VAND=90,
    417 //ZZ       ARMneon_VORR,
    418 //ZZ       ARMneon_VXOR,
    419 //ZZ       ARMneon_VADD,
    420 //ZZ       ARMneon_VADDFP,
    421 //ZZ       ARMneon_VRHADDS,
    422 //ZZ       ARMneon_VRHADDU,
    423 //ZZ       ARMneon_VPADDFP,
    424 //ZZ       ARMneon_VABDFP,
    425 //ZZ       ARMneon_VSUB,
    426 //ZZ       ARMneon_VSUBFP,
    427 //ZZ       ARMneon_VMAXU,
    428 //ZZ       ARMneon_VMAXS,
    429 //ZZ       ARMneon_VMAXF,
    430 //ZZ       ARMneon_VMINU,
    431 //ZZ       ARMneon_VMINS,
    432 //ZZ       ARMneon_VMINF,
    433 //ZZ       ARMneon_VQADDU,
    434 //ZZ       ARMneon_VQADDS,
    435 //ZZ       ARMneon_VQSUBU,
    436 //ZZ       ARMneon_VQSUBS,
    437 //ZZ       ARMneon_VCGTU,
    438 //ZZ       ARMneon_VCGTS,
    439 //ZZ       ARMneon_VCGEU,
    440 //ZZ       ARMneon_VCGES,
    441 //ZZ       ARMneon_VCGTF,
    442 //ZZ       ARMneon_VCGEF,
    443 //ZZ       ARMneon_VCEQ,
    444 //ZZ       ARMneon_VCEQF,
    445 //ZZ       ARMneon_VEXT,
    446 //ZZ       ARMneon_VMUL,
    447 //ZZ       ARMneon_VMULFP,
    448 //ZZ       ARMneon_VMULLU,
    449 //ZZ       ARMneon_VMULLS,
    450 //ZZ       ARMneon_VMULP,
    451 //ZZ       ARMneon_VMULLP,
    452 //ZZ       ARMneon_VQDMULH,
    453 //ZZ       ARMneon_VQRDMULH,
    454 //ZZ       ARMneon_VPADD,
    455 //ZZ       ARMneon_VPMINU,
    456 //ZZ       ARMneon_VPMINS,
    457 //ZZ       ARMneon_VPMINF,
    458 //ZZ       ARMneon_VPMAXU,
    459 //ZZ       ARMneon_VPMAXS,
    460 //ZZ       ARMneon_VPMAXF,
    461 //ZZ       ARMneon_VTBL,
    462 //ZZ       ARMneon_VQDMULL,
    463 //ZZ       ARMneon_VRECPS,
    464 //ZZ       ARMneon_VRSQRTS,
    465 //ZZ       /* ... */
    466 //ZZ    }
    467 //ZZ    ARMNeonBinOp;
    468 //ZZ
    469 //ZZ typedef
    470 //ZZ    enum {
    471 //ZZ       ARMneon_VSHL=150,
    472 //ZZ       ARMneon_VSAL, /* Yah, not SAR but SAL */
    473 //ZZ       ARMneon_VQSHL,
    474 //ZZ       ARMneon_VQSAL
    475 //ZZ    }
    476 //ZZ    ARMNeonShiftOp;
    477 //ZZ
    478 //ZZ typedef
    479 //ZZ    enum {
    480 //ZZ       ARMneon_COPY=160,
    481 //ZZ       ARMneon_COPYLU,
    482 //ZZ       ARMneon_COPYLS,
    483 //ZZ       ARMneon_COPYN,
    484 //ZZ       ARMneon_COPYQNSS,
    485 //ZZ       ARMneon_COPYQNUS,
    486 //ZZ       ARMneon_COPYQNUU,
    487 //ZZ       ARMneon_NOT,
    488 //ZZ       ARMneon_EQZ,
    489 //ZZ       ARMneon_DUP,
    490 //ZZ       ARMneon_PADDLS,
    491 //ZZ       ARMneon_PADDLU,
    492 //ZZ       ARMneon_CNT,
    493 //ZZ       ARMneon_CLZ,
    494 //ZZ       ARMneon_CLS,
    495 //ZZ       ARMneon_VCVTxFPxINT,
    496 //ZZ       ARMneon_VQSHLNSS,
    497 //ZZ       ARMneon_VQSHLNUU,
    498 //ZZ       ARMneon_VQSHLNUS,
    499 //ZZ       ARMneon_VCVTFtoU,
    500 //ZZ       ARMneon_VCVTFtoS,
    501 //ZZ       ARMneon_VCVTUtoF,
    502 //ZZ       ARMneon_VCVTStoF,
    503 //ZZ       ARMneon_VCVTFtoFixedU,
    504 //ZZ       ARMneon_VCVTFtoFixedS,
    505 //ZZ       ARMneon_VCVTFixedUtoF,
    506 //ZZ       ARMneon_VCVTFixedStoF,
    507 //ZZ       ARMneon_VCVTF16toF32,
    508 //ZZ       ARMneon_VCVTF32toF16,
    509 //ZZ       ARMneon_REV16,
    510 //ZZ       ARMneon_REV32,
    511 //ZZ       ARMneon_REV64,
    512 //ZZ       ARMneon_ABS,
    513 //ZZ       ARMneon_VNEGF,
    514 //ZZ       ARMneon_VRECIP,
    515 //ZZ       ARMneon_VRECIPF,
    516 //ZZ       ARMneon_VABSFP,
    517 //ZZ       ARMneon_VRSQRTEFP,
    518 //ZZ       ARMneon_VRSQRTE
    519 //ZZ       /* ... */
    520 //ZZ    }
    521 //ZZ    ARMNeonUnOp;
    522 //ZZ
    523 //ZZ typedef
    524 //ZZ    enum {
    525 //ZZ       ARMneon_SETELEM=200,
    526 //ZZ       ARMneon_GETELEMU,
    527 //ZZ       ARMneon_GETELEMS,
    528 //ZZ       ARMneon_VDUP,
    529 //ZZ    }
    530 //ZZ    ARMNeonUnOpS;
    531 //ZZ
    532 //ZZ typedef
    533 //ZZ    enum {
    534 //ZZ       ARMneon_TRN=210,
    535 //ZZ       ARMneon_ZIP,
    536 //ZZ       ARMneon_UZP
    537 //ZZ       /* ... */
    538 //ZZ    }
    539 //ZZ    ARMNeonDualOp;
    540 //ZZ
    541 //ZZ extern const HChar* showARMNeonBinOp ( ARMNeonBinOp op );
    542 //ZZ extern const HChar* showARMNeonUnOp ( ARMNeonUnOp op );
    543 //ZZ extern const HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
    544 //ZZ extern const HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
    545 //ZZ extern const HChar* showARMNeonDualOp ( ARMNeonDualOp op );
    546 //ZZ extern const HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
    547 //ZZ extern const HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
    548 //ZZ extern const HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
    549 //ZZ extern const HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
    550 //ZZ extern const HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
    551 
    552 typedef
    553    enum {
    554       /* baseline */
    555       ARM64in_Arith=1220,
    556       ARM64in_Cmp,
    557       ARM64in_Logic,
    558       ARM64in_Test,
    559       ARM64in_Shift,
    560       ARM64in_Unary,
    561       ARM64in_MovI,        /* int reg-reg move */
    562       ARM64in_Imm64,
    563       ARM64in_LdSt64,
    564       ARM64in_LdSt32,      /* w/ ZX loads */
    565       ARM64in_LdSt16,      /* w/ ZX loads */
    566       ARM64in_LdSt8,       /* w/ ZX loads */
    567       ARM64in_XDirect,     /* direct transfer to GA */
    568       ARM64in_XIndir,      /* indirect transfer to GA */
    569       ARM64in_XAssisted,   /* assisted transfer to GA */
    570       ARM64in_CSel,
    571       ARM64in_Call,
    572       ARM64in_AddToSP,     /* move SP by small, signed constant */
    573       ARM64in_FromSP,      /* move SP to integer register */
    574       ARM64in_Mul,
    575       ARM64in_LdrEX,
    576       ARM64in_StrEX,
    577       ARM64in_MFence,
    578 //ZZ       ARMin_CLREX,
    579       /* ARM64in_V*: scalar ops involving vector registers */
    580       ARM64in_VLdStS,   /* 32-bit FP load/store, with imm offset  */
    581       ARM64in_VLdStD,   /* 64-bit FP load/store, with imm offset  */
    582       ARM64in_VLdStQ,
    583       ARM64in_VCvtI2F,
    584       ARM64in_VCvtF2I,
    585       ARM64in_VCvtSD,
    586       ARM64in_VUnaryD,
    587       ARM64in_VUnaryS,
    588       ARM64in_VBinD,
    589       ARM64in_VBinS,
    590       ARM64in_VCmpD,
    591       ARM64in_VCmpS,
    592       ARM64in_FPCR,
    593       /* ARM64in_V*V: vector ops on vector registers */
    594       ARM64in_VBinV,
    595       ARM64in_VUnaryV,
    596       ARM64in_VNarrowV,
    597       ARM64in_VShiftImmV,
    598 //ZZ       ARMin_VAluS,
    599 //ZZ       ARMin_VCMovD,
    600 //ZZ       ARMin_VCMovS,
    601 //ZZ       ARMin_VXferD,
    602 //ZZ       ARMin_VXferS,
    603 //ZZ       ARMin_VCvtID,
    604 //ZZ       /* Neon */
    605 //ZZ       ARMin_NLdStD,
    606 //ZZ       ARMin_NUnary,
    607 //ZZ       ARMin_NUnaryS,
    608 //ZZ       ARMin_NDual,
    609 //ZZ       ARMin_NBinary,
    610 //ZZ       ARMin_NBinaryS,
    611 //ZZ       ARMin_NShift,
    612 //ZZ       ARMin_NShl64, // special case 64-bit shift of Dreg by immediate
    613       ARM64in_VImmQ,
    614       ARM64in_VDfromX,    /* Move an Xreg to a Dreg */
    615       ARM64in_VQfromXX,   /* Move 2 Xregs to a Qreg */
    616       ARM64in_VXfromQ,    /* Move half a Qreg to an Xreg */
    617       ARM64in_VMov,       /* vector reg-reg move, 16, 8 or 4 bytes */
    618       /* infrastructure */
    619       ARM64in_EvCheck,     /* Event check */
    620 //ZZ       ARMin_ProfInc      /* 64-bit profile counter increment */
    621    }
    622    ARM64InstrTag;
    623 
    624 /* Destinations are on the LEFT (first operand) */
    625 
    626 typedef
    627    struct {
    628       ARM64InstrTag tag;
    629       union {
    630          /* --- INTEGER INSTRUCTIONS --- */
    631          /* 64 bit ADD/SUB reg, reg or uimm12<<{0,12} */
    632          struct {
    633             HReg      dst;
    634             HReg      argL;
    635             ARM64RIA* argR;
    636             Bool      isAdd;
    637          } Arith;
    638          /* 64 or 32 bit CMP reg, reg or aimm (SUB and set flags) */
    639          struct {
    640             HReg      argL;
    641             ARM64RIA* argR;
    642             Bool      is64;
    643          } Cmp;
    644          /* 64 bit AND/OR/XOR reg, reg or bitfield-immediate */
    645          struct {
    646             HReg         dst;
    647             HReg         argL;
    648             ARM64RIL*    argR;
    649             ARM64LogicOp op;
    650          } Logic;
    651          /* 64 bit TST reg, reg or bimm (AND and set flags) */
    652          struct {
    653             HReg      argL;
    654             ARM64RIL* argR;
    655          } Test;
    656          /* 64 bit SHL/SHR/SAR, 2nd arg is reg or imm */
    657          struct {
    658             HReg         dst;
    659             HReg         argL;
    660             ARM64RI6*    argR;
    661             ARM64ShiftOp op;
    662          } Shift;
    663          /* NOT/NEG/CLZ, 64 bit only */
    664          struct {
    665             HReg         dst;
    666             HReg         src;
    667             ARM64UnaryOp op;
    668          } Unary;
    669          /* MOV dst, src -- reg-reg move for integer registers */
    670          struct {
    671             HReg dst;
    672             HReg src;
    673          } MovI;
    674          /* Pseudo-insn; make a 64-bit immediate */
    675          struct {
    676             HReg  dst;
    677             ULong imm64;
    678          } Imm64;
    679          /* 64-bit load or store */
    680          struct {
    681             Bool        isLoad;
    682             HReg        rD;
    683             ARM64AMode* amode;
    684          } LdSt64;
    685          /* zx-32-to-64-bit load, or 32-bit store */
    686          struct {
    687             Bool        isLoad;
    688             HReg        rD;
    689             ARM64AMode* amode;
    690          } LdSt32;
    691          /* zx-16-to-64-bit load, or 16-bit store */
    692          struct {
    693             Bool        isLoad;
    694             HReg        rD;
    695             ARM64AMode* amode;
    696          } LdSt16;
    697          /* zx-8-to-64-bit load, or 8-bit store */
    698          struct {
    699             Bool        isLoad;
    700             HReg        rD;
    701             ARM64AMode* amode;
    702          } LdSt8;
    703          /* Update the guest PC value, then exit requesting to chain
    704             to it.  May be conditional.  Urr, use of Addr64 implicitly
    705             assumes that wordsize(guest) == wordsize(host). */
    706          struct {
    707             Addr64        dstGA;    /* next guest address */
    708             ARM64AMode*   amPC;     /* amode in guest state for PC */
    709             ARM64CondCode cond;     /* can be ARM64cc_AL */
    710             Bool          toFastEP; /* chain to the slow or fast point? */
    711          } XDirect;
    712          /* Boring transfer to a guest address not known at JIT time.
    713             Not chainable.  May be conditional. */
    714          struct {
    715             HReg          dstGA;
    716             ARM64AMode*   amPC;
    717             ARM64CondCode cond; /* can be ARM64cc_AL */
    718          } XIndir;
    719          /* Assisted transfer to a guest address, most general case.
    720             Not chainable.  May be conditional. */
    721          struct {
    722             HReg          dstGA;
    723             ARM64AMode*   amPC;
    724             ARM64CondCode cond; /* can be ARM64cc_AL */
    725             IRJumpKind    jk;
    726          } XAssisted;
    727          /* CSEL: dst = if cond then argL else argR.  cond may be anything. */
    728           struct {
    729             HReg          dst;
    730             HReg          argL;
    731             HReg          argR;
    732             ARM64CondCode cond;
    733          } CSel;
    734          /* Pseudo-insn.  Call target (an absolute address), on given
    735             condition (which could be ARM64cc_AL). */
    736          struct {
    737             RetLoc        rloc;     /* where the return value will be */
    738             HWord         target;
    739             ARM64CondCode cond;
    740             Int           nArgRegs; /* # regs carrying args: 0 .. 8 */
    741          } Call;
    742          /* move SP by small, signed constant */
    743          struct {
    744             Int simm; /* needs to be 0 % 16 and in the range -4095
    745                          .. 4095 inclusive */
    746          } AddToSP;
    747          /* move SP to integer register */
    748          struct {
    749             HReg dst;
    750          } FromSP;
    751          /* Integer multiply, with 3 variants:
    752               (PLAIN) lo64(64 *  64)
    753               (ZX)    hi64(64 *u 64)
    754               (SX)    hi64(64 *s 64)
    755          */
    756          struct {
    757             HReg       dst;
    758             HReg       argL;
    759             HReg       argR;
    760             ARM64MulOp op;
    761          } Mul;
    762          /* LDXR{,H,B} x2, [x4] */
    763          struct {
    764             Int  szB; /* 1, 2, 4 or 8 */
    765          } LdrEX;
    766          /* STXR{,H,B} w0, x2, [x4] */
    767          struct {
    768             Int  szB; /* 1, 2, 4 or 8 */
    769          } StrEX;
    770          /* Mem fence.  An insn which fences all loads and stores as
    771             much as possible before continuing.  On ARM64 we emit the
    772             sequence "dsb sy ; dmb sy ; isb sy", which is probably
    773             total nuclear overkill, but better safe than sorry. */
    774          struct {
    775          } MFence;
    776 //ZZ          /* A CLREX instruction. */
    777 //ZZ          struct {
    778 //ZZ          } CLREX;
    779          /* --- INSTRUCTIONS INVOLVING VECTOR REGISTERS --- */
    780          /* 32-bit Fp load/store */
    781          struct {
    782             Bool isLoad;
    783             HReg sD;
    784             HReg rN;
    785             UInt uimm12;  /* 0 .. 16380 inclusive, 0 % 4 */
    786          } VLdStS;
    787          /* 64-bit Fp load/store */
    788          struct {
    789             Bool isLoad;
    790             HReg dD;
    791             HReg rN;
    792             UInt uimm12;  /* 0 .. 32760 inclusive, 0 % 8 */
    793          } VLdStD;
    794          /* 128-bit Vector load/store. */
    795          struct {
    796             Bool isLoad;
    797             HReg rQ; // data
    798             HReg rN; // address
    799          } VLdStQ;
    800          /* Scalar conversion of int to float. */
    801          struct {
    802             ARM64CvtOp how;
    803             HReg       rD; // dst, a D or S register
    804             HReg       rS; // src, a W or X register
    805          } VCvtI2F;
    806          /* Scalar conversion of float to int, w/ specified RM. */
    807          struct {
    808             ARM64CvtOp how;
    809             HReg       rD; // dst, a W or X register
    810             HReg       rS; // src, a D or S register
    811             UChar      armRM; // ARM encoded RM:
    812                               // 00=nearest, 01=+inf, 10=-inf, 11=zero
    813          } VCvtF2I;
    814          /* Convert between 32-bit and 64-bit FP values (both
    815             ways). (FCVT) */
    816          struct {
    817             Bool sToD; /* True: F32->F64.  False: F64->F32 */
    818             HReg dst;
    819             HReg src;
    820          } VCvtSD;
    821          /* 64-bit FP unary */
    822          struct {
    823             ARM64FpUnaryOp op;
    824             HReg           dst;
    825             HReg           src;
    826          } VUnaryD;
    827          /* 32-bit FP unary */
    828          struct {
    829             ARM64FpUnaryOp op;
    830             HReg           dst;
    831             HReg           src;
    832          } VUnaryS;
    833          /* 64-bit FP binary arithmetic */
    834          struct {
    835             ARM64FpBinOp op;
    836             HReg         dst;
    837             HReg         argL;
    838             HReg         argR;
    839          } VBinD;
    840          /* 32-bit FP binary arithmetic */
    841          struct {
    842             ARM64FpBinOp op;
    843             HReg         dst;
    844             HReg         argL;
    845             HReg         argR;
    846          } VBinS;
    847          /* 64-bit FP compare */
    848          struct {
    849             HReg argL;
    850             HReg argR;
    851          } VCmpD;
    852          /* 32-bit FP compare */
    853          struct {
    854             HReg argL;
    855             HReg argR;
    856          } VCmpS;
    857          /* Move a 32-bit value to/from the FPCR */
    858          struct {
    859             Bool toFPCR;
    860             HReg iReg;
    861          } FPCR;
    862          /* binary vector operation on vector registers */
    863          struct {
    864             ARM64VecBinOp op;
    865             HReg          dst;
    866             HReg          argL;
    867             HReg          argR;
    868          } VBinV;
    869          /* unary vector operation on vector registers */
    870          struct {
    871             ARM64VecUnaryOp op;
    872             HReg            dst;
    873             HReg            arg;
    874          } VUnaryV;
    875          /* vector narrowing, Q -> Q.  Result goes in the bottom half
    876             of dst and the top half is zeroed out.  Iow is XTN. */
    877         struct {
    878            UInt dszBlg2; // 0: 16to8_x8  1: 32to16_x4  2: 64to32_x2
    879            HReg dst;     // Q reg
    880            HReg src;     // Q reg
    881         } VNarrowV;
    882         /* Vector shift by immediate.  |amt| needs to be > 0 and <
    883            implied lane size of |op|.  Zero shifts and out of range
    884            shifts are not allowed. */
    885         struct {
    886            ARM64VecShiftOp op;
    887            HReg            dst;
    888            HReg            src;
    889            UInt            amt;
    890         } VShiftImmV;
    891 //ZZ          /* 32-bit FP binary arithmetic */
    892 //ZZ          struct {
    893 //ZZ             ARMVfpOp op;
    894 //ZZ             HReg     dst;
    895 //ZZ             HReg     argL;
    896 //ZZ             HReg     argR;
    897 //ZZ          } VAluS;
    898 //ZZ          /* 64-bit FP mov src to dst on the given condition, which may
    899 //ZZ             not be ARMcc_AL. */
    900 //ZZ          struct {
    901 //ZZ             ARMCondCode cond;
    902 //ZZ             HReg        dst;
    903 //ZZ             HReg        src;
    904 //ZZ          } VCMovD;
    905 //ZZ          /* 32-bit FP mov src to dst on the given condition, which may
    906 //ZZ             not be ARMcc_AL. */
    907 //ZZ          struct {
    908 //ZZ             ARMCondCode cond;
    909 //ZZ             HReg        dst;
    910 //ZZ             HReg        src;
    911 //ZZ          } VCMovS;
    912 //ZZ          /* Transfer a VFP D reg to/from two integer registers (VMOV) */
    913 //ZZ          struct {
    914 //ZZ             Bool toD;
    915 //ZZ             HReg dD;
    916 //ZZ             HReg rHi;
    917 //ZZ             HReg rLo;
    918 //ZZ          } VXferD;
    919 //ZZ          /* Transfer a VFP S reg to/from an integer register (VMOV) */
    920 //ZZ          struct {
    921 //ZZ             Bool toS;
    922 //ZZ             HReg fD;
    923 //ZZ             HReg rLo;
    924 //ZZ          } VXferS;
    925 //ZZ          /* Convert between 32-bit ints and 64-bit FP values (both ways
    926 //ZZ             and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
    927 //ZZ          struct {
    928 //ZZ             Bool iToD; /* True: I32->F64.  False: F64->I32 */
    929 //ZZ             Bool syned; /* True: I32 is signed.  False: I32 is unsigned */
    930 //ZZ             HReg dst;
    931 //ZZ             HReg src;
    932 //ZZ          } VCvtID;
    933 //ZZ          /* Neon data processing instruction: 3 registers of the same
    934 //ZZ             length */
    935 //ZZ          struct {
    936 //ZZ             ARMNeonBinOp op;
    937 //ZZ             HReg dst;
    938 //ZZ             HReg argL;
    939 //ZZ             HReg argR;
    940 //ZZ             UInt size;
    941 //ZZ             Bool Q;
    942 //ZZ          } NBinary;
    943 //ZZ          struct {
    944 //ZZ             ARMNeonBinOp op;
    945 //ZZ             ARMNRS* dst;
    946 //ZZ             ARMNRS* argL;
    947 //ZZ             ARMNRS* argR;
    948 //ZZ             UInt size;
    949 //ZZ             Bool Q;
    950 //ZZ          } NBinaryS;
    951 //ZZ          struct {
    952 //ZZ             ARMNeonShiftOp op;
    953 //ZZ             HReg dst;
    954 //ZZ             HReg argL;
    955 //ZZ             HReg argR;
    956 //ZZ             UInt size;
    957 //ZZ             Bool Q;
    958 //ZZ          } NShift;
    959 //ZZ          struct {
    960 //ZZ             HReg dst;
    961 //ZZ             HReg src;
    962 //ZZ             UInt amt; /* 1..63 only */
    963 //ZZ          } NShl64;
    964 //ZZ          struct {
    965 //ZZ             Bool isLoad;
    966 //ZZ             HReg dD;
    967 //ZZ             ARMAModeN *amode;
    968 //ZZ          } NLdStD
    969 //ZZ          struct {
    970 //ZZ             ARMNeonUnOpS op;
    971 //ZZ             ARMNRS*  dst;
    972 //ZZ             ARMNRS*  src;
    973 //ZZ             UInt size;
    974 //ZZ             Bool Q;
    975 //ZZ          } NUnaryS;
    976 //ZZ          struct {
    977 //ZZ             ARMNeonUnOp op;
    978 //ZZ             HReg  dst;
    979 //ZZ             HReg  src;
    980 //ZZ             UInt size;
    981 //ZZ             Bool Q;
    982 //ZZ          } NUnary;
    983 //ZZ          /* Takes two arguments and modifies them both. */
    984 //ZZ          struct {
    985 //ZZ             ARMNeonDualOp op;
    986 //ZZ             HReg  arg1;
    987 //ZZ             HReg  arg2;
    988 //ZZ             UInt size;
    989 //ZZ             Bool Q;
    990 //ZZ          } NDual;
    991          struct {
    992             HReg   rQ;
    993             UShort imm; /* Same 1-bit-per-byte encoding as IR */
    994          } VImmQ;
    995          struct {
    996             HReg rD;
    997             HReg rX;
    998          } VDfromX;
    999          struct {
   1000             HReg rQ;
   1001             HReg rXhi;
   1002             HReg rXlo;
   1003          } VQfromXX;
   1004          struct {
   1005             HReg rX;
   1006             HReg rQ;
   1007             UInt laneNo; /* either 0 or 1 */
   1008          } VXfromQ;
   1009          /* MOV dst, src -- reg-reg move for vector registers */
   1010          struct {
   1011             UInt szB; // 16=mov qD,qS;  8=mov dD,dS;  4=mov sD,sS
   1012             HReg dst;
   1013             HReg src;
   1014          } VMov;
   1015          struct {
   1016             ARM64AMode* amCounter;
   1017             ARM64AMode* amFailAddr;
   1018          } EvCheck;
   1019 //ZZ          struct {
   1020 //ZZ             /* No fields.  The address of the counter to inc is
   1021 //ZZ                installed later, post-translation, by patching it in,
   1022 //ZZ                as it is not known at translation time. */
   1023 //ZZ          } ProfInc;
   1024       } ARM64in;
   1025    }
   1026    ARM64Instr;
   1027 
   1028 //ZZ
   1029 extern ARM64Instr* ARM64Instr_Arith   ( HReg, HReg, ARM64RIA*, Bool isAdd );
   1030 extern ARM64Instr* ARM64Instr_Cmp     ( HReg, ARM64RIA*, Bool is64 );
   1031 extern ARM64Instr* ARM64Instr_Logic   ( HReg, HReg, ARM64RIL*, ARM64LogicOp );
   1032 extern ARM64Instr* ARM64Instr_Test    ( HReg, ARM64RIL* );
   1033 extern ARM64Instr* ARM64Instr_Shift   ( HReg, HReg, ARM64RI6*, ARM64ShiftOp );
   1034 extern ARM64Instr* ARM64Instr_Unary   ( HReg, HReg, ARM64UnaryOp );
   1035 //ZZ extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
   1036 extern ARM64Instr* ARM64Instr_MovI    ( HReg, HReg );
   1037 extern ARM64Instr* ARM64Instr_Imm64   ( HReg, ULong );
   1038 extern ARM64Instr* ARM64Instr_LdSt64  ( Bool isLoad, HReg, ARM64AMode* );
   1039 extern ARM64Instr* ARM64Instr_LdSt32  ( Bool isLoad, HReg, ARM64AMode* );
   1040 extern ARM64Instr* ARM64Instr_LdSt16  ( Bool isLoad, HReg, ARM64AMode* );
   1041 extern ARM64Instr* ARM64Instr_LdSt8   ( Bool isLoad, HReg, ARM64AMode* );
   1042 //ZZ extern ARMInstr* ARMInstr_Ld8S     ( ARMCondCode, HReg, ARMAMode2* );
   1043 extern ARM64Instr* ARM64Instr_XDirect ( Addr64 dstGA, ARM64AMode* amPC,
   1044                                         ARM64CondCode cond, Bool toFastEP );
   1045 extern ARM64Instr* ARM64Instr_XIndir  ( HReg dstGA, ARM64AMode* amPC,
   1046                                         ARM64CondCode cond );
   1047 extern ARM64Instr* ARM64Instr_XAssisted ( HReg dstGA, ARM64AMode* amPC,
   1048                                           ARM64CondCode cond, IRJumpKind jk );
   1049 extern ARM64Instr* ARM64Instr_CSel    ( HReg dst, HReg argL, HReg argR,
   1050                                         ARM64CondCode cond );
   1051 extern ARM64Instr* ARM64Instr_Call    ( ARM64CondCode, HWord, Int nArgRegs,
   1052                                         RetLoc rloc );
   1053 extern ARM64Instr* ARM64Instr_AddToSP ( Int simm );
   1054 extern ARM64Instr* ARM64Instr_FromSP  ( HReg dst );
   1055 extern ARM64Instr* ARM64Instr_Mul     ( HReg dst, HReg argL, HReg argR,
   1056                                         ARM64MulOp op );
   1057 extern ARM64Instr* ARM64Instr_LdrEX   ( Int szB );
   1058 extern ARM64Instr* ARM64Instr_StrEX   ( Int szB );
   1059 extern ARM64Instr* ARM64Instr_MFence  ( void );
   1060 //ZZ extern ARMInstr* ARMInstr_CLREX    ( void );
   1061 extern ARM64Instr* ARM64Instr_VLdStS  ( Bool isLoad, HReg sD, HReg rN,
   1062                                         UInt uimm12 /* 0 .. 16380, 0 % 4 */ );
   1063 extern ARM64Instr* ARM64Instr_VLdStD  ( Bool isLoad, HReg dD, HReg rN,
   1064                                         UInt uimm12 /* 0 .. 32760, 0 % 8 */ );
   1065 extern ARM64Instr* ARM64Instr_VLdStQ  ( Bool isLoad, HReg rQ, HReg rN );
   1066 extern ARM64Instr* ARM64Instr_VCvtI2F ( ARM64CvtOp how, HReg rD, HReg rS );
   1067 extern ARM64Instr* ARM64Instr_VCvtF2I ( ARM64CvtOp how, HReg rD, HReg rS,
   1068                                         UChar armRM );
   1069 extern ARM64Instr* ARM64Instr_VCvtSD  ( Bool sToD, HReg dst, HReg src );
   1070 extern ARM64Instr* ARM64Instr_VUnaryD ( ARM64FpUnaryOp op, HReg dst, HReg src );
   1071 extern ARM64Instr* ARM64Instr_VUnaryS ( ARM64FpUnaryOp op, HReg dst, HReg src );
   1072 extern ARM64Instr* ARM64Instr_VBinD   ( ARM64FpBinOp op, HReg, HReg, HReg );
   1073 extern ARM64Instr* ARM64Instr_VBinS   ( ARM64FpBinOp op, HReg, HReg, HReg );
   1074 extern ARM64Instr* ARM64Instr_VCmpD   ( HReg argL, HReg argR );
   1075 extern ARM64Instr* ARM64Instr_VCmpS   ( HReg argL, HReg argR );
   1076 extern ARM64Instr* ARM64Instr_FPCR    ( Bool toFPCR, HReg iReg );
   1077 extern ARM64Instr* ARM64Instr_VBinV   ( ARM64VecBinOp op, HReg, HReg, HReg );
   1078 extern ARM64Instr* ARM64Instr_VUnaryV ( ARM64VecUnaryOp op, HReg, HReg );
   1079 extern ARM64Instr* ARM64Instr_VNarrowV ( UInt dszBlg2, HReg dst, HReg src );
   1080 extern ARM64Instr* ARM64Instr_VShiftImmV ( ARM64VecShiftOp op,
   1081                                            HReg dst, HReg src, UInt amt );
   1082 //ZZ extern ARMInstr* ARMInstr_VAluS    ( ARMVfpOp op, HReg, HReg, HReg );
   1083 //ZZ extern ARMInstr* ARMInstr_VCMovD   ( ARMCondCode, HReg dst, HReg src );
   1084 //ZZ extern ARMInstr* ARMInstr_VCMovS   ( ARMCondCode, HReg dst, HReg src );
   1085 //ZZ extern ARMInstr* ARMInstr_VXferD   ( Bool toD, HReg dD, HReg rHi, HReg rLo );
   1086 //ZZ extern ARMInstr* ARMInstr_VXferS   ( Bool toS, HReg fD, HReg rLo );
   1087 //ZZ extern ARMInstr* ARMInstr_VCvtID   ( Bool iToD, Bool syned,
   1088 //ZZ                                      HReg dst, HReg src );
   1089 //ZZ extern ARMInstr* ARMInstr_NLdStD   ( Bool isLoad, HReg, ARMAModeN* );
   1090 //ZZ extern ARMInstr* ARMInstr_NUnary   ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
   1091 //ZZ extern ARMInstr* ARMInstr_NUnaryS  ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
   1092 //ZZ                                      UInt, Bool );
   1093 //ZZ extern ARMInstr* ARMInstr_NDual    ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
   1094 //ZZ extern ARMInstr* ARMInstr_NBinary  ( ARMNeonBinOp, HReg, HReg, HReg,
   1095 //ZZ                                      UInt, Bool );
   1096 //ZZ extern ARMInstr* ARMInstr_NShift   ( ARMNeonShiftOp, HReg, HReg, HReg,
   1097 //ZZ                                      UInt, Bool );
   1098 //ZZ extern ARMInstr* ARMInstr_NShl64   ( HReg, HReg, UInt );
   1099 extern ARM64Instr* ARM64Instr_VImmQ   ( HReg, UShort );
   1100 extern ARM64Instr* ARM64Instr_VDfromX ( HReg rD, HReg rX );
   1101 extern ARM64Instr* ARM64Instr_VQfromXX( HReg rQ, HReg rXhi, HReg rXlo );
   1102 extern ARM64Instr* ARM64Instr_VXfromQ ( HReg rX, HReg rQ, UInt laneNo );
   1103 extern ARM64Instr* ARM64Instr_VMov    ( UInt szB, HReg dst, HReg src );
   1104 
   1105 extern ARM64Instr* ARM64Instr_EvCheck ( ARM64AMode* amCounter,
   1106                                         ARM64AMode* amFailAddr );
   1107 //ZZ extern ARMInstr* ARMInstr_ProfInc  ( void );
   1108 
   1109 extern void ppARM64Instr ( ARM64Instr* );
   1110 
   1111 
   1112 /* Some functions that insulate the register allocator from details
   1113    of the underlying instruction set. */
   1114 extern void getRegUsage_ARM64Instr ( HRegUsage*, ARM64Instr*, Bool );
   1115 extern void mapRegs_ARM64Instr     ( HRegRemap*, ARM64Instr*, Bool );
   1116 extern Bool isMove_ARM64Instr      ( ARM64Instr*, HReg*, HReg* );
   1117 extern Int  emit_ARM64Instr        ( /*MB_MOD*/Bool* is_profInc,
   1118                                      UChar* buf, Int nbuf, ARM64Instr* i,
   1119                                      Bool mode64,
   1120                                      void* disp_cp_chain_me_to_slowEP,
   1121                                      void* disp_cp_chain_me_to_fastEP,
   1122                                      void* disp_cp_xindir,
   1123                                      void* disp_cp_xassisted );
   1124 
   1125 extern void genSpill_ARM64  ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
   1126                               HReg rreg, Int offset, Bool );
   1127 extern void genReload_ARM64 ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
   1128                               HReg rreg, Int offset, Bool );
   1129 
   1130 extern void getAllocableRegs_ARM64 ( Int*, HReg** );
   1131 extern HInstrArray* iselSB_ARM64 ( IRSB*,
   1132                                    VexArch,
   1133                                    VexArchInfo*,
   1134                                    VexAbiInfo*,
   1135                                    Int offs_Host_EvC_Counter,
   1136                                    Int offs_Host_EvC_FailAddr,
   1137                                    Bool chainingAllowed,
   1138                                    Bool addProfInc,
   1139                                    Addr64 max_ga );
   1140 
   1141 /* How big is an event check?  This is kind of a kludge because it
   1142    depends on the offsets of host_EvC_FAILADDR and
   1143    host_EvC_COUNTER. */
   1144 extern Int evCheckSzB_ARM64 ( void );
   1145 
   1146 /* Perform a chaining and unchaining of an XDirect jump. */
   1147 extern VexInvalRange chainXDirect_ARM64 ( void* place_to_chain,
   1148                                           void* disp_cp_chain_me_EXPECTED,
   1149                                           void* place_to_jump_to );
   1150 
   1151 extern VexInvalRange unchainXDirect_ARM64 ( void* place_to_unchain,
   1152                                             void* place_to_jump_to_EXPECTED,
   1153                                             void* disp_cp_chain_me );
   1154 
   1155 //ZZ /* Patch the counter location into an existing ProfInc point. */
   1156 //ZZ extern VexInvalRange patchProfInc_ARM ( void*  place_to_patch,
   1157 //ZZ                                         ULong* location_of_counter );
   1158 
   1159 
   1160 #endif /* ndef __VEX_HOST_ARM64_DEFS_H */
   1161 
   1162 /*---------------------------------------------------------------*/
   1163 /*--- end                                   host_arm64_defs.h ---*/
   1164 /*---------------------------------------------------------------*/
   1165