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