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-2017
     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_F32_TO_F32I,
    247    S390_BFP_F64_TO_F64I,
    248    S390_BFP_F128_TO_F128I
    249 } s390_bfp_conv_t;
    250 
    251 /* Type conversion operations: to and/or from decimal floating point */
    252 typedef enum {
    253    S390_DFP_D32_TO_D64,
    254    S390_DFP_D64_TO_D32,
    255    S390_DFP_D64_TO_D128,
    256    S390_DFP_D128_TO_D64,
    257    S390_DFP_I32_TO_D64,
    258    S390_DFP_I32_TO_D128,
    259    S390_DFP_I64_TO_D64,
    260    S390_DFP_I64_TO_D128,
    261    S390_DFP_U32_TO_D64,
    262    S390_DFP_U32_TO_D128,
    263    S390_DFP_U64_TO_D64,
    264    S390_DFP_U64_TO_D128,
    265    S390_DFP_D64_TO_I32,
    266    S390_DFP_D64_TO_I64,
    267    S390_DFP_D64_TO_U32,
    268    S390_DFP_D64_TO_U64,
    269    S390_DFP_D128_TO_I32,
    270    S390_DFP_D128_TO_I64,
    271    S390_DFP_D128_TO_U32,
    272    S390_DFP_D128_TO_U64
    273 } s390_dfp_conv_t;
    274 
    275 typedef enum {
    276    S390_FP_F32_TO_D32,
    277    S390_FP_F32_TO_D64,
    278    S390_FP_F32_TO_D128,
    279    S390_FP_F64_TO_D32,
    280    S390_FP_F64_TO_D64,
    281    S390_FP_F64_TO_D128,
    282    S390_FP_F128_TO_D32,
    283    S390_FP_F128_TO_D64,
    284    S390_FP_F128_TO_D128,
    285    S390_FP_D32_TO_F32,
    286    S390_FP_D32_TO_F64,
    287    S390_FP_D32_TO_F128,
    288    S390_FP_D64_TO_F32,
    289    S390_FP_D64_TO_F64,
    290    S390_FP_D64_TO_F128,
    291    S390_FP_D128_TO_F32,
    292    S390_FP_D128_TO_F64,
    293    S390_FP_D128_TO_F128
    294 } s390_fp_conv_t;
    295 
    296 /* The kind of binary DFP operations */
    297 typedef enum {
    298    S390_DFP_ADD,
    299    S390_DFP_SUB,
    300    S390_DFP_MUL,
    301    S390_DFP_DIV,
    302    S390_DFP_QUANTIZE
    303 } s390_dfp_binop_t;
    304 
    305 /* The kind of unary DFP operations */
    306 typedef enum {
    307    S390_DFP_EXTRACT_EXP_D64,
    308    S390_DFP_EXTRACT_EXP_D128,
    309    S390_DFP_EXTRACT_SIG_D64,
    310    S390_DFP_EXTRACT_SIG_D128,
    311 } s390_dfp_unop_t;
    312 
    313 /* The DFP operations with 2 operands one of them being integer */
    314 typedef enum {
    315    S390_DFP_SHIFT_LEFT,
    316    S390_DFP_SHIFT_RIGHT,
    317    S390_DFP_INSERT_EXP
    318 } s390_dfp_intop_t;
    319 
    320 /* The kind of DFP compare operations */
    321 typedef enum {
    322    S390_DFP_COMPARE,
    323    S390_DFP_COMPARE_EXP,
    324 } s390_dfp_cmp_t;
    325 
    326 /* The details of a CDAS insn. Carved out to keep the size of
    327    s390_insn low */
    328 typedef struct {
    329    HReg        op1_high;
    330    HReg        op1_low;
    331    s390_amode *op2;
    332    HReg        op3_high;
    333    HReg        op3_low;
    334    HReg        old_mem_high;
    335    HReg        old_mem_low;
    336    HReg        scratch;
    337 } s390_cdas;
    338 
    339 /* The details of a binary DFP insn. Carved out to keep the size of
    340    s390_insn low */
    341 typedef struct {
    342    s390_dfp_binop_t tag;
    343    s390_dfp_round_t rounding_mode;
    344    HReg         dst_hi; /* 128-bit result high part; 64-bit result */
    345    HReg         dst_lo; /* 128-bit result low part */
    346    HReg         op2_hi; /* 128-bit operand high part; 64-bit opnd 1 */
    347    HReg         op2_lo; /* 128-bit operand low part */
    348    HReg         op3_hi; /* 128-bit operand high part; 64-bit opnd 2 */
    349    HReg         op3_lo; /* 128-bit operand low part */
    350 } s390_dfp_binop;
    351 
    352 typedef struct {
    353    s390_fp_conv_t  tag;
    354    s390_dfp_round_t rounding_mode;
    355    HReg         dst_hi; /* 128-bit result high part; 32/64-bit result */
    356    HReg         dst_lo; /* 128-bit result low part */
    357    HReg         op_hi;  /* 128-bit operand high part; 32/64-bit opnd */
    358    HReg         op_lo;  /* 128-bit operand low part */
    359    HReg         r1;     /* clobbered register GPR #1 */
    360 } s390_fp_convert;
    361 
    362 /* Pseudo-insn for representing a helper call.
    363    TARGET is the absolute address of the helper function
    364    NUM_ARGS says how many arguments are being passed.
    365    All arguments have integer type and are being passed according to ABI,
    366    i.e. in registers r2, r3, r4, r5, and r6, with argument #0 being
    367    passed in r2 and so forth. */
    368 typedef struct {
    369    s390_cc_t    cond     : 16;
    370    UInt         num_args : 16;
    371    RetLoc       rloc;     /* where the return value will be */
    372    Addr64       target;
    373    const HChar *name;      /* callee's name (for debugging) */
    374 } s390_helper_call;
    375 
    376 typedef struct {
    377    s390_insn_tag tag;
    378    /* Usually, this is the size of the result of an operation.
    379       Exceptions are:
    380       - for comparisons it is the size of the operand
    381    */
    382    UChar size;
    383    union {
    384       struct {
    385          HReg        dst;
    386          s390_amode *src;
    387       } load;
    388       struct {
    389          s390_amode *dst;
    390          HReg        src;
    391       } store;
    392       struct {
    393          HReg        dst;
    394          HReg        src;
    395       } move;
    396       struct {
    397          s390_amode *dst;
    398          s390_amode *src;
    399       } memcpy;
    400       struct {
    401          s390_cc_t     cond;
    402          HReg          dst;
    403          s390_opnd_RMI src;
    404       } cond_move;
    405       struct {
    406          HReg        dst;
    407          ULong       value;  /* not sign extended */
    408       } load_immediate;
    409       /* add, and, or, xor */
    410       struct {
    411          s390_alu_t    tag;
    412          HReg          dst; /* op1 */
    413          s390_opnd_RMI op2;
    414       } alu;
    415       struct {
    416          HReg          dst_hi;  /*           r10 */
    417          HReg          dst_lo;  /* also op1  r11 */
    418          s390_opnd_RMI op2;
    419       } mul;
    420       struct {
    421          HReg          op1_hi;  /* also remainder   r10 */
    422          HReg          op1_lo;  /* also quotient    r11 */
    423          s390_opnd_RMI op2;
    424       } div;
    425       struct {
    426          HReg          rem; /* remainder      r10 */
    427          HReg          op1; /* also quotient  r11 */
    428          s390_opnd_RMI op2;
    429       } divs;
    430       struct {
    431          HReg          num_bits; /* number of leftmost '0' bits  r10 */
    432          HReg          clobber;  /* unspecified                  r11 */
    433          s390_opnd_RMI src;
    434       } clz;
    435       struct {
    436          s390_unop_t   tag;
    437          HReg          dst;
    438          s390_opnd_RMI src;
    439       } unop;
    440       struct {
    441          Bool          signed_comparison;
    442          HReg          src1;
    443          s390_opnd_RMI src2;
    444       } compare;
    445       struct {
    446          s390_opnd_RMI src;
    447       } test;
    448       /* Convert the condition code to a boolean value. */
    449       struct {
    450          s390_cc_t cond;
    451          HReg      dst;
    452       } cc2bool;
    453       struct {
    454          HReg        op1;
    455          s390_amode *op2;
    456          HReg        op3;
    457          HReg        old_mem;
    458       } cas;
    459       struct {
    460          s390_cdas *details;
    461       } cdas;
    462       struct {
    463          s390_helper_call *details;
    464       } helper_call;
    465 
    466       /* Floating point instructions (including conversion to/from floating
    467          point
    468 
    469          128-bit floating point requires register pairs. As the registers
    470          in a register pair cannot be chosen independently it would suffice
    471          to store only one register of the pair in order to represent it.
    472          We chose not to do that as being explicit about all registers
    473          helps with debugging and does not require special handling in
    474          e.g. s390_insn_get_reg_usage, It'd be all too easy to forget about
    475          the "other" register in a pair if it is implicit.
    476 
    477          The convention for all fp s390_insn is that the _hi register will
    478          be used to store the result / operand of a 32/64-bit operation.
    479          The _hi register holds the  8 bytes of HIgher significance of a
    480          128-bit value (hence the suffix). However, it is the lower numbered
    481          register of a register pair. POP says that the lower numbered
    482          register is used to identify the pair in an insn encoding. So,
    483          when an insn is emitted, only the _hi registers need to be looked
    484          at. Nothing special is needed for 128-bit BFP which is nice.
    485       */
    486 
    487       /* There are currently no ternary 128-bit BFP operations. */
    488       struct {
    489          s390_bfp_triop_t tag;
    490          HReg         dst;
    491          HReg         op2;
    492          HReg         op3;
    493       } bfp_triop;
    494       struct {
    495          s390_bfp_binop_t tag;
    496          HReg         dst_hi; /* 128-bit result high part; 32/64-bit result */
    497          HReg         dst_lo; /* 128-bit result low part */
    498          HReg         op2_hi; /* 128-bit operand high part; 32/64-bit opnd */
    499          HReg         op2_lo; /* 128-bit operand low part */
    500       } bfp_binop;
    501       struct {
    502          s390_bfp_unop_t  tag;
    503          HReg         dst_hi; /* 128-bit result high part; 32/64-bit result */
    504          HReg         dst_lo; /* 128-bit result low part */
    505          HReg         op_hi;  /* 128-bit operand high part; 32/64-bit opnd */
    506          HReg         op_lo;  /* 128-bit operand low part */
    507       } bfp_unop;
    508       struct {
    509          s390_bfp_conv_t  tag;
    510          s390_bfp_round_t rounding_mode;
    511          HReg         dst_hi; /* 128-bit result high part; 32/64-bit result */
    512          HReg         dst_lo; /* 128-bit result low part */
    513          HReg         op_hi;  /* 128-bit operand high part; 32/64-bit opnd */
    514          HReg         op_lo;  /* 128-bit operand low part */
    515       } bfp_convert;
    516       struct {
    517          HReg         dst;     /* condition code in s390 encoding */
    518          HReg         op1_hi;  /* 128-bit operand high part; 32/64-bit opnd */
    519          HReg         op1_lo;  /* 128-bit operand low part */
    520          HReg         op2_hi;  /* 128-bit operand high part; 32/64-bit opnd */
    521          HReg         op2_lo;  /* 128-bit operand low part */
    522       } bfp_compare;
    523       struct {
    524          s390_dfp_binop *details;
    525       } dfp_binop;
    526       struct {
    527          s390_dfp_unop_t tag;
    528          HReg         dst_hi; /* 128-bit result high part; 64-bit result */
    529          HReg         dst_lo; /* 128-bit result low part */
    530          HReg         op_hi;  /* 128-bit operand high part; 64-bit opnd */
    531          HReg         op_lo;  /* 128-bit operand low part */
    532       } dfp_unop;
    533       struct {
    534          s390_dfp_intop_t tag;
    535          HReg         dst_hi; /* 128-bit result high part; 64-bit result */
    536          HReg         dst_lo; /* 128-bit result low part */
    537          HReg         op2;    /* integer operand */
    538          HReg         op3_hi; /* 128-bit operand high part; 64-bit opnd */
    539          HReg         op3_lo; /* 128-bit operand low part */
    540       } dfp_intop;
    541       struct {
    542          s390_dfp_conv_t  tag;
    543          s390_dfp_round_t rounding_mode;
    544          HReg         dst_hi; /* 128-bit result high part; 64-bit result */
    545          HReg         dst_lo; /* 128-bit result low part */
    546          HReg         op_hi;  /* 128-bit operand high part; 64-bit opnd */
    547          HReg         op_lo;  /* 128-bit operand low part */
    548       } dfp_convert;
    549       struct {
    550          s390_fp_convert *details;
    551       } fp_convert;
    552       struct {
    553          s390_dfp_cmp_t tag;
    554          HReg         dst;     /* condition code in s390 encoding */
    555          HReg         op1_hi;  /* 128-bit operand high part; 64-bit opnd 1 */
    556          HReg         op1_lo;  /* 128-bit operand low part */
    557          HReg         op2_hi;  /* 128-bit operand high part; 64-bit opnd 2 */
    558          HReg         op2_lo;  /* 128-bit operand low part */
    559       } dfp_compare;
    560       struct {
    561          s390_dfp_round_t rounding_mode;
    562          HReg         dst_hi; /* 128-bit result high part; 64-bit result */
    563          HReg         dst_lo; /* 128-bit result low part */
    564          HReg         op2;    /* integer operand */
    565          HReg         op3_hi; /* 128-bit operand high part; 64-bit opnd */
    566          HReg         op3_lo; /* 128-bit operand low part */
    567       } dfp_reround;
    568 
    569       /* Miscellaneous */
    570       struct {
    571          s390_amode      *dst;
    572          ULong            value;  /* sign extended */
    573       } mimm;
    574       struct {
    575          s390_amode      *dst;
    576          UChar            delta;
    577          ULong            value;  /* for debugging only */
    578       } madd;
    579       struct {
    580          HReg             mode;
    581       } set_fpc_bfprm;
    582       struct {
    583          HReg             mode;
    584       } set_fpc_dfprm;
    585 
    586       /* The next 5 entries are generic to support translation chaining */
    587 
    588       /* Update the guest IA value, then exit requesting to chain
    589          to it.  May be conditional. */
    590       struct {
    591          s390_cc_t     cond;
    592          Bool          to_fast_entry;  /* chain to the what entry point? */
    593          Addr64        dst;            /* next guest address */
    594          s390_amode   *guest_IA;
    595       } xdirect;
    596       /* Boring transfer to a guest address not known at JIT time.
    597          Not chainable.  May be conditional. */
    598       struct {
    599          s390_cc_t     cond;
    600          HReg          dst;
    601          s390_amode   *guest_IA;
    602       } xindir;
    603       /* Assisted transfer to a guest address, most general case.
    604          Not chainable.  May be conditional. */
    605       struct {
    606          s390_cc_t     cond;
    607          IRJumpKind    kind;
    608          HReg          dst;
    609          s390_amode   *guest_IA;
    610       } xassisted;
    611       struct {
    612          /* fixs390: I don't think these are really needed
    613             as the gsp and the offset are fixed  no ? */
    614          s390_amode   *counter;    /* dispatch counter */
    615          s390_amode   *fail_addr;
    616       } evcheck;
    617       struct {
    618          /* No fields.  The address of the counter to increment is
    619             installed later, post-translation, by patching it in,
    620             as it is not known at translation time. */
    621       } profinc;
    622 
    623    } variant;
    624 } s390_insn;
    625 
    626 s390_insn *s390_insn_load(UChar size, HReg dst, s390_amode *src);
    627 s390_insn *s390_insn_store(UChar size, s390_amode *dst, HReg src);
    628 s390_insn *s390_insn_move(UChar size, HReg dst, HReg src);
    629 s390_insn *s390_insn_memcpy(UChar size, s390_amode *dst, s390_amode *src);
    630 s390_insn *s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst,
    631                                s390_opnd_RMI src);
    632 s390_insn *s390_insn_load_immediate(UChar size, HReg dst, ULong val);
    633 s390_insn *s390_insn_alu(UChar size, s390_alu_t, HReg dst,
    634                          s390_opnd_RMI op2);
    635 s390_insn *s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo,
    636                          s390_opnd_RMI op2, Bool signed_multiply);
    637 s390_insn *s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo,
    638                          s390_opnd_RMI op2, Bool signed_divide);
    639 s390_insn *s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2);
    640 s390_insn *s390_insn_clz(UChar size, HReg num_bits, HReg clobber,
    641                          s390_opnd_RMI op);
    642 s390_insn *s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3,
    643                          HReg old);
    644 s390_insn *s390_insn_cdas(UChar size, HReg op1_high, HReg op1_low,
    645                           s390_amode *op2, HReg op3_high, HReg op3_low,
    646                           HReg old_high, HReg old_low, HReg scratch);
    647 s390_insn *s390_insn_unop(UChar size, s390_unop_t tag, HReg dst,
    648                           s390_opnd_RMI opnd);
    649 s390_insn *s390_insn_cc2bool(HReg dst, s390_cc_t src);
    650 s390_insn *s390_insn_test(UChar size, s390_opnd_RMI src);
    651 s390_insn *s390_insn_compare(UChar size, HReg dst, s390_opnd_RMI opnd,
    652                              Bool signed_comparison);
    653 s390_insn *s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args,
    654                                  const HChar *name, RetLoc rloc);
    655 s390_insn *s390_insn_bfp_triop(UChar size, s390_bfp_triop_t, HReg dst,
    656                                HReg op2, HReg op3);
    657 s390_insn *s390_insn_bfp_binop(UChar size, s390_bfp_binop_t, HReg dst,
    658                                HReg op2);
    659 s390_insn *s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst,
    660                               HReg op);
    661 s390_insn *s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
    662 s390_insn *s390_insn_bfp_convert(UChar size, s390_bfp_conv_t tag, HReg dst,
    663                                  HReg op, s390_bfp_round_t);
    664 s390_insn *s390_insn_bfp128_convert(UChar size, s390_bfp_conv_t tag, HReg dst_hi,
    665                                     HReg dst_lo, HReg op_hi, HReg op_lo,
    666                                     s390_bfp_round_t rounding_mode);
    667 s390_insn *s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t, HReg dst_hi,
    668                                   HReg dst_lo, HReg op2_hi, HReg op2_lo);
    669 s390_insn *s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t, HReg dst_hi,
    670                                  HReg dst_lo, HReg op_hi, HReg op_lo);
    671 s390_insn *s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi,
    672                                     HReg op1_lo, HReg op2_hi, HReg op2_lo);
    673 s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_bfp_conv_t,
    674                                        HReg dst_hi, HReg dst_lo, HReg op);
    675 s390_insn *s390_insn_bfp128_convert_from(UChar size, s390_bfp_conv_t,
    676                                          HReg dst_hi, HReg dst_lo, HReg op_hi,
    677                                          HReg op_lo, s390_bfp_round_t);
    678 s390_insn *s390_insn_dfp_binop(UChar size, s390_dfp_binop_t, HReg dst,
    679                                HReg op2, HReg op3,
    680                                s390_dfp_round_t rounding_mode);
    681 s390_insn *s390_insn_dfp_unop(UChar size, s390_dfp_unop_t, HReg dst, HReg op);
    682 s390_insn *s390_insn_dfp_intop(UChar size, s390_dfp_intop_t, HReg dst,
    683                                HReg op2, HReg op3);
    684 s390_insn *s390_insn_dfp_compare(UChar size, s390_dfp_cmp_t, HReg dst,
    685                                  HReg op1, HReg op2);
    686 s390_insn *s390_insn_dfp_convert(UChar size, s390_dfp_conv_t tag, HReg dst,
    687                                  HReg op, s390_dfp_round_t);
    688 s390_insn *s390_insn_dfp_reround(UChar size, HReg dst, HReg op2, HReg op3,
    689                                  s390_dfp_round_t);
    690 s390_insn *s390_insn_fp_convert(UChar size, s390_fp_conv_t tag,
    691                                 HReg dst, HReg op, HReg r1, s390_dfp_round_t);
    692 s390_insn *s390_insn_fp128_convert(UChar size, s390_fp_conv_t tag,
    693                                    HReg dst_hi, HReg dst_lo, HReg op_hi,
    694                                    HReg op_lo, HReg r1, s390_dfp_round_t);
    695 s390_insn *s390_insn_dfp128_binop(UChar size, s390_dfp_binop_t, HReg dst_hi,
    696                                   HReg dst_lo, HReg op2_hi, HReg op2_lo,
    697                                   HReg op3_hi, HReg op3_lo,
    698                                   s390_dfp_round_t rounding_mode);
    699 s390_insn *s390_insn_dfp128_unop(UChar size, s390_dfp_unop_t, HReg dst,
    700                                  HReg op_hi, HReg op_lo);
    701 s390_insn *s390_insn_dfp128_intop(UChar size, s390_dfp_intop_t, HReg dst_hi,
    702                                   HReg dst_lo, HReg op2,
    703                                   HReg op3_hi, HReg op3_lo);
    704 s390_insn *s390_insn_dfp128_compare(UChar size, s390_dfp_cmp_t, HReg dst,
    705                                     HReg op1_hi, HReg op1_lo, HReg op2_hi,
    706                                     HReg op2_lo);
    707 s390_insn *s390_insn_dfp128_convert_to(UChar size, s390_dfp_conv_t,
    708                                        HReg dst_hi, HReg dst_lo, HReg op);
    709 s390_insn *s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t,
    710                                          HReg dst_hi, HReg dst_lo, HReg op_hi,
    711                                          HReg op_lo, s390_dfp_round_t);
    712 s390_insn *s390_insn_dfp128_reround(UChar size, HReg dst_hi, HReg dst_lo,
    713                                     HReg op2, HReg op3_hi, HReg op3_lo,
    714                                     s390_dfp_round_t);
    715 s390_insn *s390_insn_mfence(void);
    716 s390_insn *s390_insn_mimm(UChar size, s390_amode *dst, ULong value);
    717 s390_insn *s390_insn_madd(UChar size, s390_amode *dst, UChar delta,
    718                           ULong value);
    719 s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode);
    720 s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode);
    721 
    722 /* Five for translation chaining */
    723 s390_insn *s390_insn_xdirect(s390_cc_t cond, Addr64 dst, s390_amode *guest_IA,
    724                              Bool to_fast_entry);
    725 s390_insn *s390_insn_xindir(s390_cc_t cond, HReg dst, s390_amode *guest_IA);
    726 s390_insn *s390_insn_xassisted(s390_cc_t cond, HReg dst, s390_amode *guest_IA,
    727                                IRJumpKind kind);
    728 s390_insn *s390_insn_evcheck(s390_amode *counter, s390_amode *fail_addr);
    729 s390_insn *s390_insn_profinc(void);
    730 
    731 const HChar *s390_insn_as_string(const s390_insn *);
    732 
    733 /*--------------------------------------------------------*/
    734 /* --- Interface exposed to VEX                       --- */
    735 /*--------------------------------------------------------*/
    736 
    737 void ppS390AMode(const s390_amode *);
    738 void ppS390Instr(const s390_insn *, Bool mode64);
    739 void ppHRegS390(HReg);
    740 
    741 /* Some functions that insulate the register allocator from details
    742    of the underlying instruction set. */
    743 void  getRegUsage_S390Instr( HRegUsage *, const s390_insn *, Bool );
    744 void  mapRegs_S390Instr    ( HRegRemap *, s390_insn *, Bool );
    745 Bool  isMove_S390Instr     ( const s390_insn *, HReg *, HReg * );
    746 Int   emit_S390Instr       ( Bool *, UChar *, Int, const s390_insn *, Bool,
    747                              VexEndness, const void *, const void *,
    748                              const void *, const void *);
    749 const RRegUniverse *getRRegUniverse_S390( void );
    750 void  genSpill_S390        ( HInstr **, HInstr **, HReg , Int , Bool );
    751 void  genReload_S390       ( HInstr **, HInstr **, HReg , Int , Bool );
    752 HInstrArray *iselSB_S390   ( const IRSB *, VexArch, const VexArchInfo *,
    753                              const VexAbiInfo *, Int, Int, Bool, Bool, Addr);
    754 
    755 /* Return the number of bytes of code needed for an event check */
    756 Int evCheckSzB_S390(void);
    757 
    758 /* Perform a chaining and unchaining of an XDirect jump. */
    759 VexInvalRange chainXDirect_S390(VexEndness endness_host,
    760                                 void *place_to_chain,
    761                                 const void *disp_cp_chain_me_EXPECTED,
    762                                 const void *place_to_jump_to);
    763 
    764 VexInvalRange unchainXDirect_S390(VexEndness endness_host,
    765                                   void *place_to_unchain,
    766                                   const void *place_to_jump_to_EXPECTED,
    767                                   const void *disp_cp_chain_me);
    768 
    769 /* Patch the counter location into an existing ProfInc point. */
    770 VexInvalRange patchProfInc_S390(VexEndness endness_host,
    771                                 void  *code_to_patch,
    772                                 const ULong *location_of_counter);
    773 
    774 /* KLUDGE: See detailled comment in host_s390_defs.c. */
    775 extern UInt s390_host_hwcaps;
    776 
    777 /* Convenience macros to test installed facilities */
    778 #define s390_host_has_ldisp \
    779                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_LDISP))
    780 #define s390_host_has_eimm \
    781                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_EIMM))
    782 #define s390_host_has_gie \
    783                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_GIE))
    784 #define s390_host_has_dfp \
    785                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_DFP))
    786 #define s390_host_has_fgx \
    787                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_FGX))
    788 #define s390_host_has_etf2 \
    789                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF2))
    790 #define s390_host_has_stfle \
    791                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_STFLE))
    792 #define s390_host_has_etf3 \
    793                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_ETF3))
    794 #define s390_host_has_stckf \
    795                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_STCKF))
    796 #define s390_host_has_fpext \
    797                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_FPEXT))
    798 #define s390_host_has_lsc \
    799                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_LSC))
    800 #define s390_host_has_pfpo \
    801                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_PFPO))
    802 
    803 #endif /* ndef __VEX_HOST_S390_DEFS_H */
    804 
    805 /*---------------------------------------------------------------*/
    806 /*--- end                                    host_s390_defs.h ---*/
    807 /*---------------------------------------------------------------*/
    808