Home | History | Annotate | Download | only in priv
      1 /* -*- mode: C; c-basic-offset: 3; -*- */
      2 
      3 /*---------------------------------------------------------------*/
      4 /*--- begin                                  host_s390_defs.h ---*/
      5 /*---------------------------------------------------------------*/
      6 
      7 /*
      8    This file is part of Valgrind, a dynamic binary instrumentation
      9    framework.
     10 
     11    Copyright IBM Corp. 2010-2013
     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 /* Contributed by Florian Krohm */
     32 
     33 #ifndef __VEX_HOST_S390_DEFS_H
     34 #define __VEX_HOST_S390_DEFS_H
     35 
     36 #include "libvex_basictypes.h"            /* Bool */
     37 #include "libvex.h"                       /* VexArchInfo */
     38 #include "host_generic_regs.h"            /* HReg */
     39 #include "s390_defs.h"                    /* s390_cc_t */
     40 
     41 /* --------- Registers --------- */
     42 const HChar *s390_hreg_as_string(HReg);
     43 HReg s390_hreg_gpr(UInt regno);
     44 HReg s390_hreg_fpr(UInt regno);
     45 
     46 /* Dedicated registers */
     47 HReg s390_hreg_guest_state_pointer(void);
     48 
     49 
     50 /* Given the index of a function argument, return the number of the
     51    general purpose register in which it is being passed. Arguments are
     52    counted 0, 1, 2, ... and they are being passed in r2, r3, r4, ... */
     53 static __inline__ UInt
     54 s390_gprno_from_arg_index(UInt ix)
     55 {
     56    return ix + 2;
     57 }
     58 
     59 /* --------- Memory address expressions (amodes). --------- */
     60 
     61 /* These are the address modes:
     62    (1) b12:  base register + 12-bit unsigned offset   (e.g. RS)
     63    (2) b20:  base register + 20-bit signed offset     (e.g. RSY)
     64    (3) bx12: base register + index register + 12-bit unsigned offset (e.g. RX)
     65    (4) bx20: base register + index register + 20-bit signed offset   (e.g. RXY)
     66    fixs390: There is also pc-relative stuff.. e.g. LARL
     67 */
     68 
     69 typedef enum {
     70    S390_AMODE_B12,
     71    S390_AMODE_B20,
     72    S390_AMODE_BX12,
     73    S390_AMODE_BX20
     74 } s390_amode_t;
     75 
     76 typedef struct {
     77    s390_amode_t tag;
     78    HReg b;
     79    HReg x;       /* hregNumber(x) == 0  for S390_AMODE_B12/B20 kinds */
     80    Int  d;       /* 12 bit unsigned or 20 bit signed */
     81 } s390_amode;
     82 
     83 
     84 s390_amode *s390_amode_b12(Int d, HReg b);
     85 s390_amode *s390_amode_b20(Int d, HReg b);
     86 s390_amode *s390_amode_bx12(Int d, HReg b, HReg x);
     87 s390_amode *s390_amode_bx20(Int d, HReg b, HReg x);
     88 s390_amode *s390_amode_for_guest_state(Int d);
     89 Bool        s390_amode_is_sane(const s390_amode *);
     90 
     91 const HChar *s390_amode_as_string(const s390_amode *);
     92 
     93 /* ------------- 2nd (right) operand of binary operation ---------------- */
     94 
     95 typedef enum {
     96    S390_OPND_REG,
     97    S390_OPND_IMMEDIATE,
     98    S390_OPND_AMODE
     99 } s390_opnd_t;
    100 
    101 
    102 /* Naming convention for operand locations:
    103    R    - GPR
    104    I    - immediate value
    105    M    - memory (any Amode may be used)
    106 */
    107 
    108 /* An operand that is either in a GPR or is addressable via a BX20 amode */
    109 typedef struct {
    110    s390_opnd_t tag;
    111    union {
    112       HReg        reg;
    113       s390_amode *am;
    114       ULong       imm;
    115    } variant;
    116 } s390_opnd_RMI;
    117 
    118 
    119 /* The kind of instructions */
    120 typedef enum {
    121    S390_INSN_LOAD,   /* load register from memory */
    122    S390_INSN_STORE,  /* store register to memory */
    123    S390_INSN_MOVE,   /* from register to register */
    124    S390_INSN_MEMCPY, /* from memory to memory */
    125    S390_INSN_COND_MOVE, /* conditonal "move" to register */
    126    S390_INSN_LOAD_IMMEDIATE,
    127    S390_INSN_ALU,
    128    S390_INSN_SMUL,   /*   signed multiply; n-bit operands; 2n-bit result */
    129    S390_INSN_UMUL,   /* unsigned multiply; n-bit operands; 2n-bit result */
    130    S390_INSN_SDIV,   /*   signed division; 2n-bit / n-bit -> n-bit quot/rem */
    131    S390_INSN_UDIV,   /* unsigned division; 2n-bit / n-bit -> n-bit quot/rem */
    132    S390_INSN_DIVS,   /* n-bit dividend; n-bit divisor; n-bit quot/rem */
    133    S390_INSN_CLZ,    /* count left-most zeroes */
    134    S390_INSN_UNOP,
    135    S390_INSN_TEST,   /* test operand and set cc */
    136    S390_INSN_CC2BOOL,/* convert condition code to 0/1 */
    137    S390_INSN_COMPARE,
    138    S390_INSN_HELPER_CALL,
    139    S390_INSN_CAS,    /* compare and swap */
    140    S390_INSN_CDAS,   /* compare double and swap */
    141    S390_INSN_BFP_BINOP, /* Binary floating point */
    142    S390_INSN_BFP_UNOP,
    143    S390_INSN_BFP_TRIOP,
    144    S390_INSN_BFP_COMPARE,
    145    S390_INSN_BFP_CONVERT,
    146    S390_INSN_DFP_BINOP, /* Decimal floating point */
    147    S390_INSN_DFP_UNOP,
    148    S390_INSN_DFP_INTOP,
    149    S390_INSN_DFP_COMPARE,
    150    S390_INSN_DFP_CONVERT,
    151    S390_INSN_DFP_REROUND,
    152    S390_INSN_FP_CONVERT,
    153    S390_INSN_MFENCE,
    154    S390_INSN_MIMM,    /* Assign an immediate constant to a memory location */
    155    S390_INSN_MADD,    /* Add a value to a memory location */
    156    S390_INSN_SET_FPC_BFPRM, /* Set the bfp rounding mode in the FPC */
    157    S390_INSN_SET_FPC_DFPRM, /* Set the dfp rounding mode in the FPC */
    158    /* The following 5 insns are mandated by translation chaining */
    159    S390_INSN_XDIRECT,     /* direct transfer to guest address */
    160    S390_INSN_XINDIR,      /* indirect transfer to guest address */
    161    S390_INSN_XASSISTED,   /* assisted transfer to guest address */
    162    S390_INSN_EVCHECK,     /* Event check */
    163    S390_INSN_PROFINC      /* 64-bit profile counter increment */
    164 } s390_insn_tag;
    165 
    166 
    167 /* The kind of ALU instructions */
    168 typedef enum {
    169    S390_ALU_ADD,
    170    S390_ALU_SUB,
    171    S390_ALU_MUL,   /* n-bit operands; result is lower n-bit of product */
    172    S390_ALU_AND,
    173    S390_ALU_OR,
    174    S390_ALU_XOR,
    175    S390_ALU_LSH,
    176    S390_ALU_RSH,
    177    S390_ALU_RSHA   /* arithmetic */
    178 } s390_alu_t;
    179 
    180 
    181 /* The kind of unary integer operations */
    182 typedef enum {
    183    S390_ZERO_EXTEND_8,
    184    S390_ZERO_EXTEND_16,
    185    S390_ZERO_EXTEND_32,
    186    S390_SIGN_EXTEND_8,
    187    S390_SIGN_EXTEND_16,
    188    S390_SIGN_EXTEND_32,
    189    S390_NEGATE
    190 } s390_unop_t;
    191 
    192 /* The kind of ternary BFP operations */
    193 typedef enum {
    194    S390_BFP_MADD,
    195    S390_BFP_MSUB,
    196 } s390_bfp_triop_t;
    197 
    198 /* The kind of binary BFP operations */
    199 typedef enum {
    200    S390_BFP_ADD,
    201    S390_BFP_SUB,
    202    S390_BFP_MUL,
    203    S390_BFP_DIV
    204 } s390_bfp_binop_t;
    205 
    206 /* The kind of unary BFP operations */
    207 typedef enum {
    208    S390_BFP_ABS,
    209    S390_BFP_NABS,
    210    S390_BFP_NEG,
    211    S390_BFP_SQRT
    212 } s390_bfp_unop_t;
    213 
    214 /* Type conversion operations: to and/or from binary floating point */
    215 typedef enum {
    216    S390_BFP_I32_TO_F32,
    217    S390_BFP_I32_TO_F64,
    218    S390_BFP_I32_TO_F128,
    219    S390_BFP_I64_TO_F32,
    220    S390_BFP_I64_TO_F64,
    221    S390_BFP_I64_TO_F128,
    222    S390_BFP_U32_TO_F32,
    223    S390_BFP_U32_TO_F64,
    224    S390_BFP_U32_TO_F128,
    225    S390_BFP_U64_TO_F32,
    226    S390_BFP_U64_TO_F64,
    227    S390_BFP_U64_TO_F128,
    228    S390_BFP_F32_TO_I32,
    229    S390_BFP_F32_TO_I64,
    230    S390_BFP_F32_TO_U32,
    231    S390_BFP_F32_TO_U64,
    232    S390_BFP_F32_TO_F64,
    233    S390_BFP_F32_TO_F128,
    234    S390_BFP_F64_TO_I32,
    235    S390_BFP_F64_TO_I64,
    236    S390_BFP_F64_TO_U32,
    237    S390_BFP_F64_TO_U64,
    238    S390_BFP_F64_TO_F32,
    239    S390_BFP_F64_TO_F128,
    240    S390_BFP_F128_TO_I32,
    241    S390_BFP_F128_TO_I64,
    242    S390_BFP_F128_TO_U32,
    243    S390_BFP_F128_TO_U64,
    244    S390_BFP_F128_TO_F32,
    245    S390_BFP_F128_TO_F64
    246 } s390_bfp_conv_t;
    247 
    248 /* Type conversion operations: to and/or from decimal floating point */
    249 typedef enum {
    250    S390_DFP_D32_TO_D64,
    251    S390_DFP_D64_TO_D32,
    252    S390_DFP_D64_TO_D128,
    253    S390_DFP_D128_TO_D64,
    254    S390_DFP_I32_TO_D64,
    255    S390_DFP_I32_TO_D128,
    256    S390_DFP_I64_TO_D64,
    257    S390_DFP_I64_TO_D128,
    258    S390_DFP_U32_TO_D64,
    259    S390_DFP_U32_TO_D128,
    260    S390_DFP_U64_TO_D64,
    261    S390_DFP_U64_TO_D128,
    262    S390_DFP_D64_TO_I32,
    263    S390_DFP_D64_TO_I64,
    264    S390_DFP_D64_TO_U32,
    265    S390_DFP_D64_TO_U64,
    266    S390_DFP_D128_TO_I32,
    267    S390_DFP_D128_TO_I64,
    268    S390_DFP_D128_TO_U32,
    269    S390_DFP_D128_TO_U64
    270 } s390_dfp_conv_t;
    271 
    272 typedef enum {
    273    S390_FP_F32_TO_D32,
    274    S390_FP_F32_TO_D64,
    275    S390_FP_F32_TO_D128,
    276    S390_FP_F64_TO_D32,
    277    S390_FP_F64_TO_D64,
    278    S390_FP_F64_TO_D128,
    279    S390_FP_F128_TO_D32,
    280    S390_FP_F128_TO_D64,
    281    S390_FP_F128_TO_D128,
    282    S390_FP_D32_TO_F32,
    283    S390_FP_D32_TO_F64,
    284    S390_FP_D32_TO_F128,
    285    S390_FP_D64_TO_F32,
    286    S390_FP_D64_TO_F64,
    287    S390_FP_D64_TO_F128,
    288    S390_FP_D128_TO_F32,
    289    S390_FP_D128_TO_F64,
    290    S390_FP_D128_TO_F128
    291 } s390_fp_conv_t;
    292 
    293 /* The kind of binary DFP operations */
    294 typedef enum {
    295    S390_DFP_ADD,
    296    S390_DFP_SUB,
    297    S390_DFP_MUL,
    298    S390_DFP_DIV,
    299    S390_DFP_QUANTIZE
    300 } s390_dfp_binop_t;
    301 
    302 /* The kind of unary DFP operations */
    303 typedef enum {
    304    S390_DFP_EXTRACT_EXP_D64,
    305    S390_DFP_EXTRACT_EXP_D128,
    306    S390_DFP_EXTRACT_SIG_D64,
    307    S390_DFP_EXTRACT_SIG_D128,
    308 } s390_dfp_unop_t;
    309 
    310 /* The DFP operations with 2 operands one of them being integer */
    311 typedef enum {
    312    S390_DFP_SHIFT_LEFT,
    313    S390_DFP_SHIFT_RIGHT,
    314    S390_DFP_INSERT_EXP
    315 } s390_dfp_intop_t;
    316 
    317 /* The kind of DFP compare operations */
    318 typedef enum {
    319    S390_DFP_COMPARE,
    320    S390_DFP_COMPARE_EXP,
    321 } s390_dfp_cmp_t;
    322 
    323 /* The details of a CDAS insn. Carved out to keep the size of
    324    s390_insn low */
    325 typedef struct {
    326    HReg        op1_high;
    327    HReg        op1_low;
    328    s390_amode *op2;
    329    HReg        op3_high;
    330    HReg        op3_low;
    331    HReg        old_mem_high;
    332    HReg        old_mem_low;
    333    HReg        scratch;
    334 } s390_cdas;
    335 
    336 /* The details of a binary DFP insn. Carved out to keep the size of
    337    s390_insn low */
    338 typedef struct {
    339    s390_dfp_binop_t tag;
    340    s390_dfp_round_t rounding_mode;
    341    HReg         dst_hi; /* 128-bit result high part; 64-bit result */
    342    HReg         dst_lo; /* 128-bit result low part */
    343    HReg         op2_hi; /* 128-bit operand high part; 64-bit opnd 1 */
    344    HReg         op2_lo; /* 128-bit operand low part */
    345    HReg         op3_hi; /* 128-bit operand high part; 64-bit opnd 2 */
    346    HReg         op3_lo; /* 128-bit operand low part */
    347 } s390_dfp_binop;
    348 
    349 typedef struct {
    350    s390_fp_conv_t  tag;
    351    s390_dfp_round_t rounding_mode;
    352    HReg         dst_hi; /* 128-bit result high part; 32/64-bit result */
    353    HReg         dst_lo; /* 128-bit result low part */
    354    HReg         op_hi;  /* 128-bit operand high part; 32/64-bit opnd */
    355    HReg         op_lo;  /* 128-bit operand low part */
    356    HReg         r1;     /* clobbered register GPR #1 */
    357 } s390_fp_convert;
    358 
    359 /* Pseudo-insn for representing a helper call.
    360    TARGET is the absolute address of the helper function
    361    NUM_ARGS says how many arguments are being passed.
    362    All arguments have integer type and are being passed according to ABI,
    363    i.e. in registers r2, r3, r4, r5, and r6, with argument #0 being
    364    passed in r2 and so forth. */
    365 typedef struct {
    366    s390_cc_t    cond     : 16;
    367    UInt         num_args : 16;
    368    RetLoc       rloc;     /* where the return value will be */
    369    Addr64       target;
    370    const HChar *name;      /* callee's name (for debugging) */
    371 } s390_helper_call;
    372 
    373 typedef struct {
    374    s390_insn_tag tag;
    375    /* Usually, this is the size of the result of an operation.
    376       Exceptions are:
    377       - for comparisons it is the size of the operand
    378    */
    379    UChar size;
    380    union {
    381       struct {
    382          HReg        dst;
    383          s390_amode *src;
    384       } load;
    385       struct {
    386          s390_amode *dst;
    387          HReg        src;
    388       } store;
    389       struct {
    390          HReg        dst;
    391          HReg        src;
    392       } move;
    393       struct {
    394          s390_amode *dst;
    395          s390_amode *src;
    396       } memcpy;
    397       struct {
    398          s390_cc_t     cond;
    399          HReg          dst;
    400          s390_opnd_RMI src;
    401       } cond_move;
    402       struct {
    403          HReg        dst;
    404          ULong       value;  /* not sign extended */
    405       } load_immediate;
    406       /* add, and, or, xor */
    407       struct {
    408          s390_alu_t    tag;
    409          HReg          dst; /* op1 */
    410          s390_opnd_RMI op2;
    411       } alu;
    412       struct {
    413          HReg          dst_hi;  /*           r10 */
    414          HReg          dst_lo;  /* also op1  r11 */
    415          s390_opnd_RMI op2;
    416       } mul;
    417       struct {
    418          HReg          op1_hi;  /* also remainder   r10 */
    419          HReg          op1_lo;  /* also quotient    r11 */
    420          s390_opnd_RMI op2;
    421       } div;
    422       struct {
    423          HReg          rem; /* remainder      r10 */
    424          HReg          op1; /* also quotient  r11 */
    425          s390_opnd_RMI op2;
    426       } divs;
    427       struct {
    428          HReg          num_bits; /* number of leftmost '0' bits  r10 */
    429          HReg          clobber;  /* unspecified                  r11 */
    430          s390_opnd_RMI src;
    431       } clz;
    432       struct {
    433          s390_unop_t   tag;
    434          HReg          dst;
    435          s390_opnd_RMI src;
    436       } unop;
    437       struct {
    438          Bool          signed_comparison;
    439          HReg          src1;
    440          s390_opnd_RMI src2;
    441       } compare;
    442       struct {
    443          s390_opnd_RMI src;
    444       } test;
    445       /* Convert the condition code to a boolean value. */
    446       struct {
    447          s390_cc_t cond;
    448          HReg      dst;
    449       } cc2bool;
    450       struct {
    451          HReg        op1;
    452          s390_amode *op2;
    453          HReg        op3;
    454          HReg        old_mem;
    455       } cas;
    456       struct {
    457          s390_cdas *details;
    458       } cdas;
    459       struct {
    460          s390_helper_call *details;
    461       } helper_call;
    462 
    463       /* Floating point instructions (including conversion to/from floating
    464          point
    465 
    466          128-bit floating point requires register pairs. As the registers
    467          in a register pair cannot be chosen independently it would suffice
    468          to store only one register of the pair in order to represent it.
    469          We chose not to do that as being explicit about all registers
    470          helps with debugging and does not require special handling in
    471          e.g. s390_insn_get_reg_usage, It'd be all too easy to forget about
    472          the "other" register in a pair if it is implicit.
    473 
    474          The convention for all fp s390_insn is that the _hi register will
    475          be used to store the result / operand of a 32/64-bit operation.
    476          The _hi register holds the  8 bytes of HIgher significance of a
    477          128-bit value (hence the suffix). However, it is the lower numbered
    478          register of a register pair. POP says that the lower numbered
    479          register is used to identify the pair in an insn encoding. So,
    480          when an insn is emitted, only the _hi registers need to be looked
    481          at. Nothing special is needed for 128-bit BFP which is nice.
    482       */
    483 
    484       /* There are currently no ternary 128-bit BFP operations. */
    485       struct {
    486          s390_bfp_triop_t tag;
    487          HReg         dst;
    488          HReg         op2;
    489          HReg         op3;
    490       } bfp_triop;
    491       struct {
    492          s390_bfp_binop_t tag;
    493          HReg         dst_hi; /* 128-bit result high part; 32/64-bit result */
    494          HReg         dst_lo; /* 128-bit result low part */
    495          HReg         op2_hi; /* 128-bit operand high part; 32/64-bit opnd */
    496          HReg         op2_lo; /* 128-bit operand low part */
    497       } bfp_binop;
    498       struct {
    499          s390_bfp_unop_t  tag;
    500          HReg         dst_hi; /* 128-bit result high part; 32/64-bit result */
    501          HReg         dst_lo; /* 128-bit result low part */
    502          HReg         op_hi;  /* 128-bit operand high part; 32/64-bit opnd */
    503          HReg         op_lo;  /* 128-bit operand low part */
    504       } bfp_unop;
    505       struct {
    506          s390_bfp_conv_t  tag;
    507          s390_bfp_round_t rounding_mode;
    508          HReg         dst_hi; /* 128-bit result high part; 32/64-bit result */
    509          HReg         dst_lo; /* 128-bit result low part */
    510          HReg         op_hi;  /* 128-bit operand high part; 32/64-bit opnd */
    511          HReg         op_lo;  /* 128-bit operand low part */
    512       } bfp_convert;
    513       struct {
    514          HReg         dst;     /* condition code in s390 encoding */
    515          HReg         op1_hi;  /* 128-bit operand high part; 32/64-bit opnd */
    516          HReg         op1_lo;  /* 128-bit operand low part */
    517          HReg         op2_hi;  /* 128-bit operand high part; 32/64-bit opnd */
    518          HReg         op2_lo;  /* 128-bit operand low part */
    519       } bfp_compare;
    520       struct {
    521          s390_dfp_binop *details;
    522       } dfp_binop;
    523       struct {
    524          s390_dfp_unop_t tag;
    525          HReg         dst_hi; /* 128-bit result high part; 64-bit result */
    526          HReg         dst_lo; /* 128-bit result low part */
    527          HReg         op_hi;  /* 128-bit operand high part; 64-bit opnd */
    528          HReg         op_lo;  /* 128-bit operand low part */
    529       } dfp_unop;
    530       struct {
    531          s390_dfp_intop_t tag;
    532          HReg         dst_hi; /* 128-bit result high part; 64-bit result */
    533          HReg         dst_lo; /* 128-bit result low part */
    534          HReg         op2;    /* integer operand */
    535          HReg         op3_hi; /* 128-bit operand high part; 64-bit opnd */
    536          HReg         op3_lo; /* 128-bit operand low part */
    537       } dfp_intop;
    538       struct {
    539          s390_dfp_conv_t  tag;
    540          s390_dfp_round_t rounding_mode;
    541          HReg         dst_hi; /* 128-bit result high part; 64-bit result */
    542          HReg         dst_lo; /* 128-bit result low part */
    543          HReg         op_hi;  /* 128-bit operand high part; 64-bit opnd */
    544          HReg         op_lo;  /* 128-bit operand low part */
    545       } dfp_convert;
    546       struct {
    547          s390_fp_convert *details;
    548       } fp_convert;
    549       struct {
    550          s390_dfp_cmp_t tag;
    551          HReg         dst;     /* condition code in s390 encoding */
    552          HReg         op1_hi;  /* 128-bit operand high part; 64-bit opnd 1 */
    553          HReg         op1_lo;  /* 128-bit operand low part */
    554          HReg         op2_hi;  /* 128-bit operand high part; 64-bit opnd 2 */
    555          HReg         op2_lo;  /* 128-bit operand low part */
    556       } dfp_compare;
    557       struct {
    558          s390_dfp_round_t rounding_mode;
    559          HReg         dst_hi; /* 128-bit result high part; 64-bit result */
    560          HReg         dst_lo; /* 128-bit result low part */
    561          HReg         op2;    /* integer operand */
    562          HReg         op3_hi; /* 128-bit operand high part; 64-bit opnd */
    563          HReg         op3_lo; /* 128-bit operand low part */
    564       } dfp_reround;
    565 
    566       /* Miscellaneous */
    567       struct {
    568          s390_amode      *dst;
    569          ULong            value;  /* sign extended */
    570       } mimm;
    571       struct {
    572          s390_amode      *dst;
    573          UChar            delta;
    574          ULong            value;  /* for debugging only */
    575       } madd;
    576       struct {
    577          HReg             mode;
    578       } set_fpc_bfprm;
    579       struct {
    580          HReg             mode;
    581       } set_fpc_dfprm;
    582 
    583       /* The next 5 entries are generic to support translation chaining */
    584 
    585       /* Update the guest IA value, then exit requesting to chain
    586          to it.  May be conditional. */
    587       struct {
    588          s390_cc_t     cond;
    589          Bool          to_fast_entry;  /* chain to the what entry point? */
    590          Addr64        dst;            /* next guest address */
    591          s390_amode   *guest_IA;
    592       } xdirect;
    593       /* Boring transfer to a guest address not known at JIT time.
    594          Not chainable.  May be conditional. */
    595       struct {
    596          s390_cc_t     cond;
    597          HReg          dst;
    598          s390_amode   *guest_IA;
    599       } xindir;
    600       /* Assisted transfer to a guest address, most general case.
    601          Not chainable.  May be conditional. */
    602       struct {
    603          s390_cc_t     cond;
    604          IRJumpKind    kind;
    605          HReg          dst;
    606          s390_amode   *guest_IA;
    607       } xassisted;
    608       struct {
    609          /* fixs390: I don't think these are really needed
    610             as the gsp and the offset are fixed  no ? */
    611          s390_amode   *counter;    /* dispatch counter */
    612          s390_amode   *fail_addr;
    613       } evcheck;
    614       struct {
    615          /* No fields.  The address of the counter to increment is
    616             installed later, post-translation, by patching it in,
    617             as it is not known at translation time. */
    618       } profinc;
    619 
    620    } variant;
    621 } s390_insn;
    622 
    623 s390_insn *s390_insn_load(UChar size, HReg dst, s390_amode *src);
    624 s390_insn *s390_insn_store(UChar size, s390_amode *dst, HReg src);
    625 s390_insn *s390_insn_move(UChar size, HReg dst, HReg src);
    626 s390_insn *s390_insn_memcpy(UChar size, s390_amode *dst, s390_amode *src);
    627 s390_insn *s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst,
    628                                s390_opnd_RMI src);
    629 s390_insn *s390_insn_load_immediate(UChar size, HReg dst, ULong val);
    630 s390_insn *s390_insn_alu(UChar size, s390_alu_t, HReg dst,
    631                          s390_opnd_RMI op2);
    632 s390_insn *s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo,
    633                          s390_opnd_RMI op2, Bool signed_multiply);
    634 s390_insn *s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo,
    635                          s390_opnd_RMI op2, Bool signed_divide);
    636 s390_insn *s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2);
    637 s390_insn *s390_insn_clz(UChar size, HReg num_bits, HReg clobber,
    638                          s390_opnd_RMI op);
    639 s390_insn *s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3,
    640                          HReg old);
    641 s390_insn *s390_insn_cdas(UChar size, HReg op1_high, HReg op1_low,
    642                           s390_amode *op2, HReg op3_high, HReg op3_low,
    643                           HReg old_high, HReg old_low, HReg scratch);
    644 s390_insn *s390_insn_unop(UChar size, s390_unop_t tag, HReg dst,
    645                           s390_opnd_RMI opnd);
    646 s390_insn *s390_insn_cc2bool(HReg dst, s390_cc_t src);
    647 s390_insn *s390_insn_test(UChar size, s390_opnd_RMI src);
    648 s390_insn *s390_insn_compare(UChar size, HReg dst, s390_opnd_RMI opnd,
    649                              Bool signed_comparison);
    650 s390_insn *s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args,
    651                                  const HChar *name, RetLoc rloc);
    652 s390_insn *s390_insn_bfp_triop(UChar size, s390_bfp_triop_t, HReg dst,
    653                                HReg op2, HReg op3);
    654 s390_insn *s390_insn_bfp_binop(UChar size, s390_bfp_binop_t, HReg dst,
    655                                HReg op2);
    656 s390_insn *s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst,
    657                               HReg op);
    658 s390_insn *s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
    659 s390_insn *s390_insn_bfp_convert(UChar size, s390_bfp_conv_t tag, HReg dst,
    660                                  HReg op, s390_bfp_round_t);
    661 s390_insn *s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t, HReg dst_hi,
    662                                   HReg dst_lo, HReg op2_hi, HReg op2_lo);
    663 s390_insn *s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t, HReg dst_hi,
    664                                  HReg dst_lo, HReg op_hi, HReg op_lo);
    665 s390_insn *s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi,
    666                                     HReg op1_lo, HReg op2_hi, HReg op2_lo);
    667 s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_bfp_conv_t,
    668                                        HReg dst_hi, HReg dst_lo, HReg op);
    669 s390_insn *s390_insn_bfp128_convert_from(UChar size, s390_bfp_conv_t,
    670                                          HReg dst_hi, HReg dst_lo, HReg op_hi,
    671                                          HReg op_lo, s390_bfp_round_t);
    672 s390_insn *s390_insn_dfp_binop(UChar size, s390_dfp_binop_t, HReg dst,
    673                                HReg op2, HReg op3,
    674                                s390_dfp_round_t rounding_mode);
    675 s390_insn *s390_insn_dfp_unop(UChar size, s390_dfp_unop_t, HReg dst, HReg op);
    676 s390_insn *s390_insn_dfp_intop(UChar size, s390_dfp_intop_t, HReg dst,
    677                                HReg op2, HReg op3);
    678 s390_insn *s390_insn_dfp_compare(UChar size, s390_dfp_cmp_t, HReg dst,
    679                                  HReg op1, HReg op2);
    680 s390_insn *s390_insn_dfp_convert(UChar size, s390_dfp_conv_t tag, HReg dst,
    681                                  HReg op, s390_dfp_round_t);
    682 s390_insn *s390_insn_dfp_reround(UChar size, HReg dst, HReg op2, HReg op3,
    683                                  s390_dfp_round_t);
    684 s390_insn *s390_insn_fp_convert(UChar size, s390_fp_conv_t tag,
    685                                 HReg dst, HReg op, HReg r1, s390_dfp_round_t);
    686 s390_insn *s390_insn_fp128_convert(UChar size, s390_fp_conv_t tag,
    687                                    HReg dst_hi, HReg dst_lo, HReg op_hi,
    688                                    HReg op_lo, HReg r1, s390_dfp_round_t);
    689 s390_insn *s390_insn_dfp128_binop(UChar size, s390_dfp_binop_t, HReg dst_hi,
    690                                   HReg dst_lo, HReg op2_hi, HReg op2_lo,
    691                                   HReg op3_hi, HReg op3_lo,
    692                                   s390_dfp_round_t rounding_mode);
    693 s390_insn *s390_insn_dfp128_unop(UChar size, s390_dfp_unop_t, HReg dst,
    694                                  HReg op_hi, HReg op_lo);
    695 s390_insn *s390_insn_dfp128_intop(UChar size, s390_dfp_intop_t, HReg dst_hi,
    696                                   HReg dst_lo, HReg op2,
    697                                   HReg op3_hi, HReg op3_lo);
    698 s390_insn *s390_insn_dfp128_compare(UChar size, s390_dfp_cmp_t, HReg dst,
    699                                     HReg op1_hi, HReg op1_lo, HReg op2_hi,
    700                                     HReg op2_lo);
    701 s390_insn *s390_insn_dfp128_convert_to(UChar size, s390_dfp_conv_t,
    702                                        HReg dst_hi, HReg dst_lo, HReg op);
    703 s390_insn *s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t,
    704                                          HReg dst_hi, HReg dst_lo, HReg op_hi,
    705                                          HReg op_lo, s390_dfp_round_t);
    706 s390_insn *s390_insn_dfp128_reround(UChar size, HReg dst_hi, HReg dst_lo,
    707                                     HReg op2, HReg op3_hi, HReg op3_lo,
    708                                     s390_dfp_round_t);
    709 s390_insn *s390_insn_mfence(void);
    710 s390_insn *s390_insn_mimm(UChar size, s390_amode *dst, ULong value);
    711 s390_insn *s390_insn_madd(UChar size, s390_amode *dst, UChar delta,
    712                           ULong value);
    713 s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode);
    714 s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode);
    715 
    716 /* Five for translation chaining */
    717 s390_insn *s390_insn_xdirect(s390_cc_t cond, Addr64 dst, s390_amode *guest_IA,
    718                              Bool to_fast_entry);
    719 s390_insn *s390_insn_xindir(s390_cc_t cond, HReg dst, s390_amode *guest_IA);
    720 s390_insn *s390_insn_xassisted(s390_cc_t cond, HReg dst, s390_amode *guest_IA,
    721                                IRJumpKind kind);
    722 s390_insn *s390_insn_evcheck(s390_amode *counter, s390_amode *fail_addr);
    723 s390_insn *s390_insn_profinc(void);
    724 
    725 const HChar *s390_insn_as_string(const s390_insn *);
    726 
    727 /*--------------------------------------------------------*/
    728 /* --- Interface exposed to VEX                       --- */
    729 /*--------------------------------------------------------*/
    730 
    731 void ppS390AMode(const s390_amode *);
    732 void ppS390Instr(const s390_insn *, Bool mode64);
    733 void ppHRegS390(HReg);
    734 
    735 /* Some functions that insulate the register allocator from details
    736    of the underlying instruction set. */
    737 void  getRegUsage_S390Instr( HRegUsage *, const s390_insn *, Bool );
    738 void  mapRegs_S390Instr    ( HRegRemap *, s390_insn *, Bool );
    739 Bool  isMove_S390Instr     ( const s390_insn *, HReg *, HReg * );
    740 Int   emit_S390Instr       ( Bool *, UChar *, Int, const s390_insn *, Bool,
    741                              VexEndness, const void *, const void *,
    742                              const void *, const void *);
    743 const RRegUniverse *getRRegUniverse_S390( void );
    744 void  genSpill_S390        ( HInstr **, HInstr **, HReg , Int , Bool );
    745 void  genReload_S390       ( HInstr **, HInstr **, HReg , Int , Bool );
    746 HInstrArray *iselSB_S390   ( const IRSB *, VexArch, const VexArchInfo *,
    747                              const VexAbiInfo *, Int, Int, Bool, Bool, Addr);
    748 
    749 /* Return the number of bytes of code needed for an event check */
    750 Int evCheckSzB_S390(void);
    751 
    752 /* Perform a chaining and unchaining of an XDirect jump. */
    753 VexInvalRange chainXDirect_S390(VexEndness endness_host,
    754                                 void *place_to_chain,
    755                                 const void *disp_cp_chain_me_EXPECTED,
    756                                 const void *place_to_jump_to);
    757 
    758 VexInvalRange unchainXDirect_S390(VexEndness endness_host,
    759                                   void *place_to_unchain,
    760                                   const void *place_to_jump_to_EXPECTED,
    761                                   const void *disp_cp_chain_me);
    762 
    763 /* Patch the counter location into an existing ProfInc point. */
    764 VexInvalRange patchProfInc_S390(VexEndness endness_host,
    765                                 void  *code_to_patch,
    766                                 const ULong *location_of_counter);
    767 
    768 /* KLUDGE: See detailled comment in host_s390_defs.c. */
    769 extern UInt s390_host_hwcaps;
    770 
    771 /* Convenience macros to test installed facilities */
    772 #define s390_host_has_ldisp \
    773                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_LDISP))
    774 #define s390_host_has_eimm \
    775                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_EIMM))
    776 #define s390_host_has_gie \
    777                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_GIE))
    778 #define s390_host_has_dfp \
    779                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_DFP))
    780 #define s390_host_has_fgx \
    781                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_FGX))
    782 #define s390_host_has_etf2 \
    783                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF2))
    784 #define s390_host_has_stfle \
    785                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_STFLE))
    786 #define s390_host_has_etf3 \
    787                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF3))
    788 #define s390_host_has_stckf \
    789                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_STCKF))
    790 #define s390_host_has_fpext \
    791                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_FPEXT))
    792 #define s390_host_has_lsc \
    793                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_LSC))
    794 #define s390_host_has_pfpo \
    795                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_PFPO))
    796 
    797 #endif /* ndef __VEX_HOST_S390_DEFS_H */
    798 
    799 /*---------------------------------------------------------------*/
    800 /*--- end                                    host_s390_defs.h ---*/
    801 /*---------------------------------------------------------------*/
    802