Home | History | Annotate | Download | only in priv
      1 /* -*- mode: C; c-basic-offset: 3; -*- */
      2 
      3 /*---------------------------------------------------------------*/
      4 /*--- begin                                 guest_s390_toIR.c ---*/
      5 /*---------------------------------------------------------------*/
      6 
      7 /*
      8    This file is part of Valgrind, a dynamic binary instrumentation
      9    framework.
     10 
     11    Copyright IBM Corp. 2010-2015
     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 and Christian Borntraeger */
     32 
     33 /* Translates s390 code to IR. */
     34 
     35 #include "libvex_basictypes.h"
     36 #include "libvex_ir.h"
     37 #include "libvex_emnote.h"
     38 #include "libvex_s390x_common.h"
     39 #include "main_util.h"               /* vassert */
     40 #include "main_globals.h"            /* vex_traceflags */
     41 #include "guest_generic_bb_to_IR.h"  /* DisResult */
     42 #include "guest_s390_defs.h"         /* prototypes for this file's functions */
     43 #include "s390_disasm.h"
     44 #include "s390_defs.h"               /* S390_BFP_ROUND_xyzzy */
     45 #include "host_s390_defs.h"          /* s390_host_has_xyzzy */
     46 
     47 
     48 /*------------------------------------------------------------*/
     49 /*--- Forward declarations                                 ---*/
     50 /*------------------------------------------------------------*/
     51 static UInt s390_decode_and_irgen(const UChar *, UInt, DisResult *);
     52 static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
     53 static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
     54 
     55 
     56 /*------------------------------------------------------------*/
     57 /*--- Globals                                              ---*/
     58 /*------------------------------------------------------------*/
     59 
     60 /* The IRSB* into which we're generating code. */
     61 static IRSB *irsb;
     62 
     63 /* The guest address for the instruction currently being
     64    translated. */
     65 static Addr64 guest_IA_curr_instr;
     66 
     67 /* The guest address for the instruction following the current instruction. */
     68 static Addr64 guest_IA_next_instr;
     69 
     70 /* Result of disassembly step. */
     71 static DisResult *dis_res;
     72 
     73 /* Resteer function and callback data */
     74 static Bool (*resteer_fn)(void *, Addr);
     75 static void *resteer_data;
     76 
     77 /* Whether to print diagnostics for illegal instructions. */
     78 static Bool sigill_diag;
     79 
     80 /* The last seen execute target instruction */
     81 ULong last_execute_target;
     82 
     83 /* The possible outcomes of a decoding operation */
     84 typedef enum {
     85    S390_DECODE_OK,
     86    S390_DECODE_UNKNOWN_INSN,
     87    S390_DECODE_UNIMPLEMENTED_INSN,
     88    S390_DECODE_UNKNOWN_SPECIAL_INSN,
     89    S390_DECODE_ERROR
     90 } s390_decode_t;
     91 
     92 
     93 /*------------------------------------------------------------*/
     94 /*--- Helpers for constructing IR.                         ---*/
     95 /*------------------------------------------------------------*/
     96 
     97 /* Add a statement to the current irsb. */
     98 static __inline__ void
     99 stmt(IRStmt *st)
    100 {
    101    addStmtToIRSB(irsb, st);
    102 }
    103 
    104 /* Allocate a new temporary of the given type. */
    105 static __inline__ IRTemp
    106 newTemp(IRType type)
    107 {
    108    vassert(isPlausibleIRType(type));
    109 
    110    return newIRTemp(irsb->tyenv, type);
    111 }
    112 
    113 /* Create an expression node for a temporary */
    114 static __inline__ IRExpr *
    115 mkexpr(IRTemp tmp)
    116 {
    117    return IRExpr_RdTmp(tmp);
    118 }
    119 
    120 /* Generate an expression node for an address. */
    121 static __inline__ IRExpr *
    122 mkaddr_expr(Addr64 addr)
    123 {
    124    return IRExpr_Const(IRConst_U64(addr));
    125 }
    126 
    127 /* Add a statement that assigns to a temporary */
    128 static __inline__ void
    129 assign(IRTemp dst, IRExpr *expr)
    130 {
    131    stmt(IRStmt_WrTmp(dst, expr));
    132 }
    133 
    134 /* Write an address into the guest_IA */
    135 static __inline__ void
    136 put_IA(IRExpr *address)
    137 {
    138    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
    139 }
    140 
    141 /* Create a temporary of the given type and assign the expression to it */
    142 static __inline__ IRTemp
    143 mktemp(IRType type, IRExpr *expr)
    144 {
    145    IRTemp temp = newTemp(type);
    146 
    147    assign(temp, expr);
    148 
    149    return temp;
    150 }
    151 
    152 /* Create a unary expression */
    153 static __inline__ IRExpr *
    154 unop(IROp kind, IRExpr *op)
    155 {
    156    return IRExpr_Unop(kind, op);
    157 }
    158 
    159 /* Create a binary expression */
    160 static __inline__ IRExpr *
    161 binop(IROp kind, IRExpr *op1, IRExpr *op2)
    162 {
    163    return IRExpr_Binop(kind, op1, op2);
    164 }
    165 
    166 /* Create a ternary expression */
    167 static __inline__ IRExpr *
    168 triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
    169 {
    170    return IRExpr_Triop(kind, op1, op2, op3);
    171 }
    172 
    173 /* Create a quaternary expression */
    174 static __inline__  IRExpr *
    175 qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
    176 {
    177    return IRExpr_Qop(kind, op1, op2, op3, op4);
    178 }
    179 
    180 /* Create an expression node for an 8-bit integer constant */
    181 static __inline__ IRExpr *
    182 mkU8(UInt value)
    183 {
    184    vassert(value < 256);
    185 
    186    return IRExpr_Const(IRConst_U8((UChar)value));
    187 }
    188 
    189 /* Create an expression node for a 16-bit integer constant */
    190 static __inline__ IRExpr *
    191 mkU16(UInt value)
    192 {
    193    vassert(value < 65536);
    194 
    195    return IRExpr_Const(IRConst_U16((UShort)value));
    196 }
    197 
    198 /* Create an expression node for a 32-bit integer constant */
    199 static __inline__ IRExpr *
    200 mkU32(UInt value)
    201 {
    202    return IRExpr_Const(IRConst_U32(value));
    203 }
    204 
    205 /* Create an expression node for a 64-bit integer constant */
    206 static __inline__ IRExpr *
    207 mkU64(ULong value)
    208 {
    209    return IRExpr_Const(IRConst_U64(value));
    210 }
    211 
    212 /* Create an expression node for a 32-bit floating point constant
    213    whose value is given by a bit pattern. */
    214 static __inline__ IRExpr *
    215 mkF32i(UInt value)
    216 {
    217    return IRExpr_Const(IRConst_F32i(value));
    218 }
    219 
    220 /* Create an expression node for a 32-bit floating point constant
    221    whose value is given by a bit pattern. */
    222 static __inline__ IRExpr *
    223 mkF64i(ULong value)
    224 {
    225    return IRExpr_Const(IRConst_F64i(value));
    226 }
    227 
    228 /* Little helper function for my sanity. ITE = if-then-else */
    229 static IRExpr *
    230 mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
    231 {
    232    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
    233 
    234    return IRExpr_ITE(condition, iftrue, iffalse);
    235 }
    236 
    237 /* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
    238 static __inline__ void
    239 store(IRExpr *addr, IRExpr *data)
    240 {
    241    stmt(IRStmt_Store(Iend_BE, addr, data));
    242 }
    243 
    244 /* Create an expression that loads a TYPE sized value from ADDR.
    245    This is a big-endian machine. */
    246 static __inline__ IRExpr *
    247 load(IRType type, IRExpr *addr)
    248 {
    249    return IRExpr_Load(Iend_BE, type, addr);
    250 }
    251 
    252 /* Function call */
    253 static void
    254 call_function(IRExpr *callee_address)
    255 {
    256    put_IA(callee_address);
    257 
    258    dis_res->whatNext    = Dis_StopHere;
    259    dis_res->jk_StopHere = Ijk_Call;
    260 }
    261 
    262 /* Function call with known target. */
    263 static void
    264 call_function_and_chase(Addr64 callee_address)
    265 {
    266    if (resteer_fn(resteer_data, callee_address)) {
    267       dis_res->whatNext   = Dis_ResteerU;
    268       dis_res->continueAt = callee_address;
    269    } else {
    270       put_IA(mkaddr_expr(callee_address));
    271 
    272       dis_res->whatNext = Dis_StopHere;
    273       dis_res->jk_StopHere = Ijk_Call;
    274    }
    275 }
    276 
    277 /* Function return sequence */
    278 static void
    279 return_from_function(IRExpr *return_address)
    280 {
    281    put_IA(return_address);
    282 
    283    dis_res->whatNext    = Dis_StopHere;
    284    dis_res->jk_StopHere = Ijk_Ret;
    285 }
    286 
    287 /* A conditional branch whose target is not known at instrumentation time.
    288 
    289    if (condition) goto computed_target;
    290 
    291    Needs to be represented as:
    292 
    293    if (! condition) goto next_instruction;
    294    goto computed_target;
    295 */
    296 static void
    297 if_condition_goto_computed(IRExpr *condition, IRExpr *target)
    298 {
    299    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
    300 
    301    condition = unop(Iop_Not1, condition);
    302 
    303    stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
    304                     S390X_GUEST_OFFSET(guest_IA)));
    305 
    306    put_IA(target);
    307 
    308    dis_res->whatNext    = Dis_StopHere;
    309    dis_res->jk_StopHere = Ijk_Boring;
    310 }
    311 
    312 /* A conditional branch whose target is known at instrumentation time. */
    313 static void
    314 if_condition_goto(IRExpr *condition, Addr64 target)
    315 {
    316    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
    317 
    318    stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
    319                     S390X_GUEST_OFFSET(guest_IA)));
    320 
    321    put_IA(mkaddr_expr(guest_IA_next_instr));
    322 
    323    dis_res->whatNext    = Dis_StopHere;
    324    dis_res->jk_StopHere = Ijk_Boring;
    325 }
    326 
    327 /* An unconditional branch. Target may or may not be known at instrumentation
    328    time. */
    329 static void
    330 always_goto(IRExpr *target)
    331 {
    332    put_IA(target);
    333 
    334    dis_res->whatNext    = Dis_StopHere;
    335    dis_res->jk_StopHere = Ijk_Boring;
    336 }
    337 
    338 
    339 /* An unconditional branch to a known target. */
    340 static void
    341 always_goto_and_chase(Addr64 target)
    342 {
    343    if (resteer_fn(resteer_data, target)) {
    344       /* Follow into the target */
    345       dis_res->whatNext   = Dis_ResteerU;
    346       dis_res->continueAt = target;
    347    } else {
    348       put_IA(mkaddr_expr(target));
    349 
    350       dis_res->whatNext    = Dis_StopHere;
    351       dis_res->jk_StopHere = Ijk_Boring;
    352    }
    353 }
    354 
    355 /* A system call */
    356 static void
    357 system_call(IRExpr *sysno)
    358 {
    359    /* Store the system call number in the pseudo register. */
    360    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
    361 
    362    /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
    363    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
    364                    mkU64(guest_IA_curr_instr)));
    365 
    366    put_IA(mkaddr_expr(guest_IA_next_instr));
    367 
    368    /* It's important that all ArchRegs carry their up-to-date value
    369       at this point.  So we declare an end-of-block here, which
    370       forces any TempRegs caching ArchRegs to be flushed. */
    371    dis_res->whatNext    = Dis_StopHere;
    372    dis_res->jk_StopHere = Ijk_Sys_syscall;
    373 }
    374 
    375 /* A side exit that branches back to the current insn if CONDITION is
    376    true. Does not set DisResult. */
    377 static void
    378 iterate_if(IRExpr *condition)
    379 {
    380    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
    381 
    382    stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
    383                     S390X_GUEST_OFFSET(guest_IA)));
    384 }
    385 
    386 /* A side exit that branches back to the current insn.
    387    Does not set DisResult. */
    388 static __inline__ void
    389 iterate(void)
    390 {
    391    iterate_if(IRExpr_Const(IRConst_U1(True)));
    392 }
    393 
    394 /* A side exit that branches back to the insn immediately following the
    395    current insn if CONDITION is true. Does not set DisResult. */
    396 static void
    397 next_insn_if(IRExpr *condition)
    398 {
    399    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
    400 
    401    stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
    402                     S390X_GUEST_OFFSET(guest_IA)));
    403 }
    404 
    405 /* Convenience function to restart the current insn */
    406 static void
    407 restart_if(IRExpr *condition)
    408 {
    409    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
    410 
    411    stmt(IRStmt_Exit(condition, Ijk_InvalICache,
    412                     IRConst_U64(guest_IA_curr_instr),
    413                     S390X_GUEST_OFFSET(guest_IA)));
    414 }
    415 
    416 /* Convenience function to yield to thread scheduler */
    417 static void
    418 yield_if(IRExpr *condition)
    419 {
    420    stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
    421                     S390X_GUEST_OFFSET(guest_IA)));
    422 }
    423 
    424 static __inline__ IRExpr *get_fpr_dw0(UInt);
    425 static __inline__ void    put_fpr_dw0(UInt, IRExpr *);
    426 static __inline__ IRExpr *get_dpr_dw0(UInt);
    427 static __inline__ void    put_dpr_dw0(UInt, IRExpr *);
    428 
    429 /* Read a floating point register pair and combine their contents into a
    430    128-bit value */
    431 static IRExpr *
    432 get_fpr_pair(UInt archreg)
    433 {
    434    IRExpr *high = get_fpr_dw0(archreg);
    435    IRExpr *low  = get_fpr_dw0(archreg + 2);
    436 
    437    return binop(Iop_F64HLtoF128, high, low);
    438 }
    439 
    440 /* Write a 128-bit floating point value into a register pair. */
    441 static void
    442 put_fpr_pair(UInt archreg, IRExpr *expr)
    443 {
    444    IRExpr *high = unop(Iop_F128HItoF64, expr);
    445    IRExpr *low  = unop(Iop_F128LOtoF64, expr);
    446 
    447    put_fpr_dw0(archreg,     high);
    448    put_fpr_dw0(archreg + 2, low);
    449 }
    450 
    451 /* Read a floating point register pair cointaining DFP value
    452    and combine their contents into a 128-bit value */
    453 
    454 static IRExpr *
    455 get_dpr_pair(UInt archreg)
    456 {
    457    IRExpr *high = get_dpr_dw0(archreg);
    458    IRExpr *low  = get_dpr_dw0(archreg + 2);
    459 
    460    return binop(Iop_D64HLtoD128, high, low);
    461 }
    462 
    463 /* Write a 128-bit decimal floating point value into a register pair. */
    464 static void
    465 put_dpr_pair(UInt archreg, IRExpr *expr)
    466 {
    467    IRExpr *high = unop(Iop_D128HItoD64, expr);
    468    IRExpr *low  = unop(Iop_D128LOtoD64, expr);
    469 
    470    put_dpr_dw0(archreg,     high);
    471    put_dpr_dw0(archreg + 2, low);
    472 }
    473 
    474 /* Terminate the current IRSB with an emulation failure. */
    475 static void
    476 emulation_failure_with_expr(IRExpr *emfailure)
    477 {
    478    vassert(typeOfIRExpr(irsb->tyenv, emfailure) == Ity_I32);
    479 
    480    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emfailure));
    481    dis_res->whatNext = Dis_StopHere;
    482    dis_res->jk_StopHere = Ijk_EmFail;
    483 }
    484 
    485 static void
    486 emulation_failure(VexEmNote fail_kind)
    487 {
    488    emulation_failure_with_expr(mkU32(fail_kind));
    489 }
    490 
    491 /* Terminate the current IRSB with an emulation warning. */
    492 static void
    493 emulation_warning_with_expr(IRExpr *emwarning)
    494 {
    495    vassert(typeOfIRExpr(irsb->tyenv, emwarning) == Ity_I32);
    496 
    497    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emwarning));
    498    dis_res->whatNext = Dis_StopHere;
    499    dis_res->jk_StopHere = Ijk_EmWarn;
    500 }
    501 
    502 static void
    503 emulation_warning(VexEmNote warn_kind)
    504 {
    505    emulation_warning_with_expr(mkU32(warn_kind));
    506 }
    507 
    508 /*------------------------------------------------------------*/
    509 /*--- IR Debugging aids.                                   ---*/
    510 /*------------------------------------------------------------*/
    511 #if 0
    512 
    513 static ULong
    514 s390_do_print(HChar *text, ULong value)
    515 {
    516    vex_printf("%s %llu\n", text, value);
    517    return 0;
    518 }
    519 
    520 static void
    521 s390_print(HChar *text, IRExpr *value)
    522 {
    523    IRDirty *d;
    524 
    525    d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
    526                          mkIRExprVec_2(mkU64((ULong)text), value));
    527    stmt(IRStmt_Dirty(d));
    528 }
    529 #endif
    530 
    531 
    532 /*------------------------------------------------------------*/
    533 /*--- Build the flags thunk.                               ---*/
    534 /*------------------------------------------------------------*/
    535 
    536 /* Completely fill the flags thunk. We're always filling all fields.
    537    Apparently, that is better for redundant PUT elimination. */
    538 static void
    539 s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
    540 {
    541    UInt op_off, dep1_off, dep2_off, ndep_off;
    542 
    543    op_off   = S390X_GUEST_OFFSET(guest_CC_OP);
    544    dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
    545    dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
    546    ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
    547 
    548    stmt(IRStmt_Put(op_off,   op));
    549    stmt(IRStmt_Put(dep1_off, dep1));
    550    stmt(IRStmt_Put(dep2_off, dep2));
    551    stmt(IRStmt_Put(ndep_off, ndep));
    552 }
    553 
    554 
    555 /* Create an expression for V and widen the result to 64 bit. */
    556 static IRExpr *
    557 s390_cc_widen(IRTemp v, Bool sign_extend)
    558 {
    559    IRExpr *expr;
    560 
    561    expr = mkexpr(v);
    562 
    563    switch (typeOfIRTemp(irsb->tyenv, v)) {
    564    case Ity_I64:
    565       break;
    566    case Ity_I32:
    567       expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
    568       break;
    569    case Ity_I16:
    570       expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
    571       break;
    572    case Ity_I8:
    573       expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
    574       break;
    575    default:
    576       vpanic("s390_cc_widen");
    577    }
    578 
    579    return expr;
    580 }
    581 
    582 static void
    583 s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
    584 {
    585    IRExpr *op, *dep1, *dep2, *ndep;
    586 
    587    op   = mkU64(opc);
    588    dep1 = s390_cc_widen(d1, sign_extend);
    589    dep2 = mkU64(0);
    590    ndep = mkU64(0);
    591 
    592    s390_cc_thunk_fill(op, dep1, dep2, ndep);
    593 }
    594 
    595 
    596 static void
    597 s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
    598 {
    599    IRExpr *op, *dep1, *dep2, *ndep;
    600 
    601    op   = mkU64(opc);
    602    dep1 = s390_cc_widen(d1, sign_extend);
    603    dep2 = s390_cc_widen(d2, sign_extend);
    604    ndep = mkU64(0);
    605 
    606    s390_cc_thunk_fill(op, dep1, dep2, ndep);
    607 }
    608 
    609 
    610 /* memcheck believes that the NDEP field in the flags thunk is always
    611    defined. But for some flag computations (e.g. add with carry) that is
    612    just not true. We therefore need to convey to memcheck that the value
    613    of the ndep field does matter and therefore we make the DEP2 field
    614    depend on it:
    615 
    616    DEP2 = original_DEP2 ^ NDEP
    617 
    618    In s390_calculate_cc we exploit that  (a^b)^b == a
    619    I.e. we xor the DEP2 value with the NDEP value to recover the
    620    original_DEP2 value. */
    621 static void
    622 s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
    623 {
    624    IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
    625 
    626    op   = mkU64(opc);
    627    dep1 = s390_cc_widen(d1, sign_extend);
    628    dep2 = s390_cc_widen(d2, sign_extend);
    629    ndep = s390_cc_widen(nd, sign_extend);
    630 
    631    dep2x = binop(Iop_Xor64, dep2, ndep);
    632 
    633    s390_cc_thunk_fill(op, dep1, dep2x, ndep);
    634 }
    635 
    636 
    637 /* Write one floating point value into the flags thunk */
    638 static void
    639 s390_cc_thunk_put1f(UInt opc, IRTemp d1)
    640 {
    641    IRExpr *op, *dep1, *dep2, *ndep;
    642 
    643    /* Make the CC_DEP1 slot appear completely defined.
    644       Otherwise, assigning a 32-bit value will cause memcheck
    645       to trigger an undefinedness error.
    646    */
    647    if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
    648       UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
    649       stmt(IRStmt_Put(dep1_off, mkU64(0)));
    650    }
    651    op   = mkU64(opc);
    652    dep1 = mkexpr(d1);
    653    dep2 = mkU64(0);
    654    ndep = mkU64(0);
    655 
    656    s390_cc_thunk_fill(op, dep1, dep2, ndep);
    657 }
    658 
    659 
    660 /* Write a floating point value and an integer into the flags thunk. The
    661    integer value is zero-extended first. */
    662 static void
    663 s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
    664 {
    665    IRExpr *op, *dep1, *dep2, *ndep;
    666 
    667    /* Make the CC_DEP1 slot appear completely defined.
    668       Otherwise, assigning a 32-bit value will cause memcheck
    669       to trigger an undefinedness error.
    670    */
    671    if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
    672       UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
    673       stmt(IRStmt_Put(dep1_off, mkU64(0)));
    674    }
    675    op   = mkU64(opc);
    676    dep1 = mkexpr(d1);
    677    dep2 = s390_cc_widen(d2, False);
    678    ndep = mkU64(0);
    679 
    680    s390_cc_thunk_fill(op, dep1, dep2, ndep);
    681 }
    682 
    683 
    684 /* Write a 128-bit floating point value into the flags thunk. This is
    685    done by splitting the value into two 64-bits values. */
    686 static void
    687 s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
    688 {
    689    IRExpr *op, *hi, *lo, *ndep;
    690 
    691    op   = mkU64(opc);
    692    hi   = unop(Iop_F128HItoF64, mkexpr(d1));
    693    lo   = unop(Iop_F128LOtoF64, mkexpr(d1));
    694    ndep = mkU64(0);
    695 
    696    s390_cc_thunk_fill(op, hi, lo, ndep);
    697 }
    698 
    699 
    700 /* Write a 128-bit floating point value and an integer into the flags thunk.
    701    The integer value is zero-extended first. */
    702 static void
    703 s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
    704 {
    705    IRExpr *op, *hi, *lo, *lox, *ndep;
    706 
    707    op   = mkU64(opc);
    708    hi   = unop(Iop_F128HItoF64, mkexpr(d1));
    709    lo   = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
    710    ndep = s390_cc_widen(nd, False);
    711 
    712    lox = binop(Iop_Xor64, lo, ndep);  /* convey dependency */
    713 
    714    s390_cc_thunk_fill(op, hi, lox, ndep);
    715 }
    716 
    717 
    718 /* Write a 128-bit decimal floating point value into the flags thunk.
    719    This is done by splitting the value into two 64-bits values. */
    720 static void
    721 s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
    722 {
    723    IRExpr *op, *hi, *lo, *ndep;
    724 
    725    op   = mkU64(opc);
    726    hi   = unop(Iop_D128HItoD64, mkexpr(d1));
    727    lo   = unop(Iop_D128LOtoD64, mkexpr(d1));
    728    ndep = mkU64(0);
    729 
    730    s390_cc_thunk_fill(op, hi, lo, ndep);
    731 }
    732 
    733 
    734 /* Write a 128-bit decimal floating point value and an integer into the flags
    735    thunk. The integer value is zero-extended first. */
    736 static void
    737 s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
    738 {
    739    IRExpr *op, *hi, *lo, *lox, *ndep;
    740 
    741    op   = mkU64(opc);
    742    hi   = unop(Iop_D128HItoD64, mkexpr(d1));
    743    lo   = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
    744    ndep = s390_cc_widen(nd, False);
    745 
    746    lox = binop(Iop_Xor64, lo, ndep);  /* convey dependency */
    747 
    748    s390_cc_thunk_fill(op, hi, lox, ndep);
    749 }
    750 
    751 
    752 static void
    753 s390_cc_set(UInt val)
    754 {
    755    s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
    756                       mkU64(val), mkU64(0), mkU64(0));
    757 }
    758 
    759 /* Build IR to calculate the condition code from flags thunk.
    760    Returns an expression of type Ity_I32 */
    761 static IRExpr *
    762 s390_call_calculate_cc(void)
    763 {
    764    IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
    765 
    766    op   = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP),   Ity_I64);
    767    dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
    768    dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
    769    ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
    770 
    771    args = mkIRExprVec_4(op, dep1, dep2, ndep);
    772    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
    773                         "s390_calculate_cc", &s390_calculate_cc, args);
    774 
    775    /* Exclude OP and NDEP from definedness checking.  We're only
    776       interested in DEP1 and DEP2. */
    777    call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
    778 
    779    return call;
    780 }
    781 
    782 /* Build IR to calculate the internal condition code for a "compare and branch"
    783    insn. Returns an expression of type Ity_I32 */
    784 static IRExpr *
    785 s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
    786 {
    787    IRExpr **args, *call, *op, *dep1, *dep2, *mask;
    788 
    789    switch (opc) {
    790    case S390_CC_OP_SIGNED_COMPARE:
    791       dep1 = s390_cc_widen(op1, True);
    792       dep2 = s390_cc_widen(op2, True);
    793       break;
    794 
    795    case S390_CC_OP_UNSIGNED_COMPARE:
    796       dep1 = s390_cc_widen(op1, False);
    797       dep2 = s390_cc_widen(op2, False);
    798       break;
    799 
    800    default:
    801       vpanic("s390_call_calculate_icc");
    802    }
    803 
    804    mask = mkU64(m);
    805    op   = mkU64(opc);
    806 
    807    args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
    808    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
    809                         "s390_calculate_cond", &s390_calculate_cond, args);
    810 
    811    /* Exclude the requested condition, OP and NDEP from definedness
    812       checking.  We're only interested in DEP1 and DEP2. */
    813    call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
    814 
    815    return call;
    816 }
    817 
    818 /* Build IR to calculate the condition code from flags thunk.
    819    Returns an expression of type Ity_I32 */
    820 static IRExpr *
    821 s390_call_calculate_cond(UInt m)
    822 {
    823    IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
    824 
    825    mask = mkU64(m);
    826    op   = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP),   Ity_I64);
    827    dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
    828    dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
    829    ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
    830 
    831    args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
    832    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
    833                         "s390_calculate_cond", &s390_calculate_cond, args);
    834 
    835    /* Exclude the requested condition, OP and NDEP from definedness
    836       checking.  We're only interested in DEP1 and DEP2. */
    837    call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
    838 
    839    return call;
    840 }
    841 
    842 #define s390_cc_thunk_putZ(op,dep1)  s390_cc_thunk_put1(op,dep1,False)
    843 #define s390_cc_thunk_putS(op,dep1)  s390_cc_thunk_put1(op,dep1,True)
    844 #define s390_cc_thunk_putF(op,dep1)  s390_cc_thunk_put1f(op,dep1)
    845 #define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
    846 #define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
    847 #define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
    848 #define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
    849         s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
    850 #define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
    851         s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
    852 
    853 
    854 
    855 
    856 /*------------------------------------------------------------*/
    857 /*--- Guest register access                                ---*/
    858 /*------------------------------------------------------------*/
    859 
    860 
    861 /*------------------------------------------------------------*/
    862 /*--- ar registers                                         ---*/
    863 /*------------------------------------------------------------*/
    864 
    865 /* Return the guest state offset of a ar register. */
    866 static UInt
    867 ar_offset(UInt archreg)
    868 {
    869    static const UInt offset[16] = {
    870       S390X_GUEST_OFFSET(guest_a0),
    871       S390X_GUEST_OFFSET(guest_a1),
    872       S390X_GUEST_OFFSET(guest_a2),
    873       S390X_GUEST_OFFSET(guest_a3),
    874       S390X_GUEST_OFFSET(guest_a4),
    875       S390X_GUEST_OFFSET(guest_a5),
    876       S390X_GUEST_OFFSET(guest_a6),
    877       S390X_GUEST_OFFSET(guest_a7),
    878       S390X_GUEST_OFFSET(guest_a8),
    879       S390X_GUEST_OFFSET(guest_a9),
    880       S390X_GUEST_OFFSET(guest_a10),
    881       S390X_GUEST_OFFSET(guest_a11),
    882       S390X_GUEST_OFFSET(guest_a12),
    883       S390X_GUEST_OFFSET(guest_a13),
    884       S390X_GUEST_OFFSET(guest_a14),
    885       S390X_GUEST_OFFSET(guest_a15),
    886    };
    887 
    888    vassert(archreg < 16);
    889 
    890    return offset[archreg];
    891 }
    892 
    893 
    894 /* Return the guest state offset of word #0 of a ar register. */
    895 static __inline__ UInt
    896 ar_w0_offset(UInt archreg)
    897 {
    898    return ar_offset(archreg) + 0;
    899 }
    900 
    901 /* Write word #0 of a ar to the guest state. */
    902 static __inline__ void
    903 put_ar_w0(UInt archreg, IRExpr *expr)
    904 {
    905    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
    906 
    907    stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
    908 }
    909 
    910 /* Read word #0 of a ar register. */
    911 static __inline__ IRExpr *
    912 get_ar_w0(UInt archreg)
    913 {
    914    return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
    915 }
    916 
    917 
    918 /*------------------------------------------------------------*/
    919 /*--- fpr registers                                        ---*/
    920 /*------------------------------------------------------------*/
    921 
    922 /* Return the guest state offset of a fpr register. */
    923 static UInt
    924 fpr_offset(UInt archreg)
    925 {
    926    static const UInt offset[16] = {
    927       S390X_GUEST_OFFSET(guest_f0),
    928       S390X_GUEST_OFFSET(guest_f1),
    929       S390X_GUEST_OFFSET(guest_f2),
    930       S390X_GUEST_OFFSET(guest_f3),
    931       S390X_GUEST_OFFSET(guest_f4),
    932       S390X_GUEST_OFFSET(guest_f5),
    933       S390X_GUEST_OFFSET(guest_f6),
    934       S390X_GUEST_OFFSET(guest_f7),
    935       S390X_GUEST_OFFSET(guest_f8),
    936       S390X_GUEST_OFFSET(guest_f9),
    937       S390X_GUEST_OFFSET(guest_f10),
    938       S390X_GUEST_OFFSET(guest_f11),
    939       S390X_GUEST_OFFSET(guest_f12),
    940       S390X_GUEST_OFFSET(guest_f13),
    941       S390X_GUEST_OFFSET(guest_f14),
    942       S390X_GUEST_OFFSET(guest_f15),
    943    };
    944 
    945    vassert(archreg < 16);
    946 
    947    return offset[archreg];
    948 }
    949 
    950 
    951 /* Return the guest state offset of word #0 of a fpr register. */
    952 static __inline__ UInt
    953 fpr_w0_offset(UInt archreg)
    954 {
    955    return fpr_offset(archreg) + 0;
    956 }
    957 
    958 /* Write word #0 of a fpr to the guest state. */
    959 static __inline__ void
    960 put_fpr_w0(UInt archreg, IRExpr *expr)
    961 {
    962    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
    963 
    964    stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
    965 }
    966 
    967 /* Read word #0 of a fpr register. */
    968 static __inline__ IRExpr *
    969 get_fpr_w0(UInt archreg)
    970 {
    971    return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
    972 }
    973 
    974 /* Return the guest state offset of double word #0 of a fpr register. */
    975 static __inline__ UInt
    976 fpr_dw0_offset(UInt archreg)
    977 {
    978    return fpr_offset(archreg) + 0;
    979 }
    980 
    981 /* Write double word #0 of a fpr to the guest state. */
    982 static __inline__ void
    983 put_fpr_dw0(UInt archreg, IRExpr *expr)
    984 {
    985    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
    986 
    987    stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
    988 }
    989 
    990 /* Read double word #0 of a fpr register. */
    991 static __inline__ IRExpr *
    992 get_fpr_dw0(UInt archreg)
    993 {
    994    return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
    995 }
    996 
    997 /* Write word #0 of a dpr to the guest state. */
    998 static __inline__ void
    999 put_dpr_w0(UInt archreg, IRExpr *expr)
   1000 {
   1001    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
   1002 
   1003    stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
   1004 }
   1005 
   1006 /* Read word #0 of a dpr register. */
   1007 static __inline__ IRExpr *
   1008 get_dpr_w0(UInt archreg)
   1009 {
   1010    return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
   1011 }
   1012 
   1013 /* Write double word #0 of a fpr containg DFP value to the guest state. */
   1014 static __inline__ void
   1015 put_dpr_dw0(UInt archreg, IRExpr *expr)
   1016 {
   1017    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
   1018 
   1019    stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
   1020 }
   1021 
   1022 /* Read double word #0 of a fpr register containing DFP value. */
   1023 static __inline__ IRExpr *
   1024 get_dpr_dw0(UInt archreg)
   1025 {
   1026    return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
   1027 }
   1028 
   1029 /*------------------------------------------------------------*/
   1030 /*--- gpr registers                                        ---*/
   1031 /*------------------------------------------------------------*/
   1032 
   1033 /* Return the guest state offset of a gpr register. */
   1034 static UInt
   1035 gpr_offset(UInt archreg)
   1036 {
   1037    static const UInt offset[16] = {
   1038       S390X_GUEST_OFFSET(guest_r0),
   1039       S390X_GUEST_OFFSET(guest_r1),
   1040       S390X_GUEST_OFFSET(guest_r2),
   1041       S390X_GUEST_OFFSET(guest_r3),
   1042       S390X_GUEST_OFFSET(guest_r4),
   1043       S390X_GUEST_OFFSET(guest_r5),
   1044       S390X_GUEST_OFFSET(guest_r6),
   1045       S390X_GUEST_OFFSET(guest_r7),
   1046       S390X_GUEST_OFFSET(guest_r8),
   1047       S390X_GUEST_OFFSET(guest_r9),
   1048       S390X_GUEST_OFFSET(guest_r10),
   1049       S390X_GUEST_OFFSET(guest_r11),
   1050       S390X_GUEST_OFFSET(guest_r12),
   1051       S390X_GUEST_OFFSET(guest_r13),
   1052       S390X_GUEST_OFFSET(guest_r14),
   1053       S390X_GUEST_OFFSET(guest_r15),
   1054    };
   1055 
   1056    vassert(archreg < 16);
   1057 
   1058    return offset[archreg];
   1059 }
   1060 
   1061 
   1062 /* Return the guest state offset of word #0 of a gpr register. */
   1063 static __inline__ UInt
   1064 gpr_w0_offset(UInt archreg)
   1065 {
   1066    return gpr_offset(archreg) + 0;
   1067 }
   1068 
   1069 /* Write word #0 of a gpr to the guest state. */
   1070 static __inline__ void
   1071 put_gpr_w0(UInt archreg, IRExpr *expr)
   1072 {
   1073    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
   1074 
   1075    stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
   1076 }
   1077 
   1078 /* Read word #0 of a gpr register. */
   1079 static __inline__ IRExpr *
   1080 get_gpr_w0(UInt archreg)
   1081 {
   1082    return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
   1083 }
   1084 
   1085 /* Return the guest state offset of double word #0 of a gpr register. */
   1086 static __inline__ UInt
   1087 gpr_dw0_offset(UInt archreg)
   1088 {
   1089    return gpr_offset(archreg) + 0;
   1090 }
   1091 
   1092 /* Write double word #0 of a gpr to the guest state. */
   1093 static __inline__ void
   1094 put_gpr_dw0(UInt archreg, IRExpr *expr)
   1095 {
   1096    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
   1097 
   1098    stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
   1099 }
   1100 
   1101 /* Read double word #0 of a gpr register. */
   1102 static __inline__ IRExpr *
   1103 get_gpr_dw0(UInt archreg)
   1104 {
   1105    return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
   1106 }
   1107 
   1108 /* Return the guest state offset of half word #1 of a gpr register. */
   1109 static __inline__ UInt
   1110 gpr_hw1_offset(UInt archreg)
   1111 {
   1112    return gpr_offset(archreg) + 2;
   1113 }
   1114 
   1115 /* Write half word #1 of a gpr to the guest state. */
   1116 static __inline__ void
   1117 put_gpr_hw1(UInt archreg, IRExpr *expr)
   1118 {
   1119    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
   1120 
   1121    stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
   1122 }
   1123 
   1124 /* Read half word #1 of a gpr register. */
   1125 static __inline__ IRExpr *
   1126 get_gpr_hw1(UInt archreg)
   1127 {
   1128    return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
   1129 }
   1130 
   1131 /* Return the guest state offset of byte #6 of a gpr register. */
   1132 static __inline__ UInt
   1133 gpr_b6_offset(UInt archreg)
   1134 {
   1135    return gpr_offset(archreg) + 6;
   1136 }
   1137 
   1138 /* Write byte #6 of a gpr to the guest state. */
   1139 static __inline__ void
   1140 put_gpr_b6(UInt archreg, IRExpr *expr)
   1141 {
   1142    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
   1143 
   1144    stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
   1145 }
   1146 
   1147 /* Read byte #6 of a gpr register. */
   1148 static __inline__ IRExpr *
   1149 get_gpr_b6(UInt archreg)
   1150 {
   1151    return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
   1152 }
   1153 
   1154 /* Return the guest state offset of byte #3 of a gpr register. */
   1155 static __inline__ UInt
   1156 gpr_b3_offset(UInt archreg)
   1157 {
   1158    return gpr_offset(archreg) + 3;
   1159 }
   1160 
   1161 /* Write byte #3 of a gpr to the guest state. */
   1162 static __inline__ void
   1163 put_gpr_b3(UInt archreg, IRExpr *expr)
   1164 {
   1165    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
   1166 
   1167    stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
   1168 }
   1169 
   1170 /* Read byte #3 of a gpr register. */
   1171 static __inline__ IRExpr *
   1172 get_gpr_b3(UInt archreg)
   1173 {
   1174    return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
   1175 }
   1176 
   1177 /* Return the guest state offset of byte #0 of a gpr register. */
   1178 static __inline__ UInt
   1179 gpr_b0_offset(UInt archreg)
   1180 {
   1181    return gpr_offset(archreg) + 0;
   1182 }
   1183 
   1184 /* Write byte #0 of a gpr to the guest state. */
   1185 static __inline__ void
   1186 put_gpr_b0(UInt archreg, IRExpr *expr)
   1187 {
   1188    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
   1189 
   1190    stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
   1191 }
   1192 
   1193 /* Read byte #0 of a gpr register. */
   1194 static __inline__ IRExpr *
   1195 get_gpr_b0(UInt archreg)
   1196 {
   1197    return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
   1198 }
   1199 
   1200 /* Return the guest state offset of word #1 of a gpr register. */
   1201 static __inline__ UInt
   1202 gpr_w1_offset(UInt archreg)
   1203 {
   1204    return gpr_offset(archreg) + 4;
   1205 }
   1206 
   1207 /* Write word #1 of a gpr to the guest state. */
   1208 static __inline__ void
   1209 put_gpr_w1(UInt archreg, IRExpr *expr)
   1210 {
   1211    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
   1212 
   1213    stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
   1214 }
   1215 
   1216 /* Read word #1 of a gpr register. */
   1217 static __inline__ IRExpr *
   1218 get_gpr_w1(UInt archreg)
   1219 {
   1220    return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
   1221 }
   1222 
   1223 /* Return the guest state offset of half word #3 of a gpr register. */
   1224 static __inline__ UInt
   1225 gpr_hw3_offset(UInt archreg)
   1226 {
   1227    return gpr_offset(archreg) + 6;
   1228 }
   1229 
   1230 /* Write half word #3 of a gpr to the guest state. */
   1231 static __inline__ void
   1232 put_gpr_hw3(UInt archreg, IRExpr *expr)
   1233 {
   1234    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
   1235 
   1236    stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
   1237 }
   1238 
   1239 /* Read half word #3 of a gpr register. */
   1240 static __inline__ IRExpr *
   1241 get_gpr_hw3(UInt archreg)
   1242 {
   1243    return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
   1244 }
   1245 
   1246 /* Return the guest state offset of byte #7 of a gpr register. */
   1247 static __inline__ UInt
   1248 gpr_b7_offset(UInt archreg)
   1249 {
   1250    return gpr_offset(archreg) + 7;
   1251 }
   1252 
   1253 /* Write byte #7 of a gpr to the guest state. */
   1254 static __inline__ void
   1255 put_gpr_b7(UInt archreg, IRExpr *expr)
   1256 {
   1257    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
   1258 
   1259    stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
   1260 }
   1261 
   1262 /* Read byte #7 of a gpr register. */
   1263 static __inline__ IRExpr *
   1264 get_gpr_b7(UInt archreg)
   1265 {
   1266    return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
   1267 }
   1268 
   1269 /* Return the guest state offset of half word #0 of a gpr register. */
   1270 static __inline__ UInt
   1271 gpr_hw0_offset(UInt archreg)
   1272 {
   1273    return gpr_offset(archreg) + 0;
   1274 }
   1275 
   1276 /* Write half word #0 of a gpr to the guest state. */
   1277 static __inline__ void
   1278 put_gpr_hw0(UInt archreg, IRExpr *expr)
   1279 {
   1280    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
   1281 
   1282    stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
   1283 }
   1284 
   1285 /* Read half word #0 of a gpr register. */
   1286 static __inline__ IRExpr *
   1287 get_gpr_hw0(UInt archreg)
   1288 {
   1289    return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
   1290 }
   1291 
   1292 /* Return the guest state offset of byte #4 of a gpr register. */
   1293 static __inline__ UInt
   1294 gpr_b4_offset(UInt archreg)
   1295 {
   1296    return gpr_offset(archreg) + 4;
   1297 }
   1298 
   1299 /* Write byte #4 of a gpr to the guest state. */
   1300 static __inline__ void
   1301 put_gpr_b4(UInt archreg, IRExpr *expr)
   1302 {
   1303    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
   1304 
   1305    stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
   1306 }
   1307 
   1308 /* Read byte #4 of a gpr register. */
   1309 static __inline__ IRExpr *
   1310 get_gpr_b4(UInt archreg)
   1311 {
   1312    return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
   1313 }
   1314 
   1315 /* Return the guest state offset of byte #1 of a gpr register. */
   1316 static __inline__ UInt
   1317 gpr_b1_offset(UInt archreg)
   1318 {
   1319    return gpr_offset(archreg) + 1;
   1320 }
   1321 
   1322 /* Write byte #1 of a gpr to the guest state. */
   1323 static __inline__ void
   1324 put_gpr_b1(UInt archreg, IRExpr *expr)
   1325 {
   1326    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
   1327 
   1328    stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
   1329 }
   1330 
   1331 /* Read byte #1 of a gpr register. */
   1332 static __inline__ IRExpr *
   1333 get_gpr_b1(UInt archreg)
   1334 {
   1335    return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
   1336 }
   1337 
   1338 /* Return the guest state offset of half word #2 of a gpr register. */
   1339 static __inline__ UInt
   1340 gpr_hw2_offset(UInt archreg)
   1341 {
   1342    return gpr_offset(archreg) + 4;
   1343 }
   1344 
   1345 /* Write half word #2 of a gpr to the guest state. */
   1346 static __inline__ void
   1347 put_gpr_hw2(UInt archreg, IRExpr *expr)
   1348 {
   1349    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
   1350 
   1351    stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
   1352 }
   1353 
   1354 /* Read half word #2 of a gpr register. */
   1355 static __inline__ IRExpr *
   1356 get_gpr_hw2(UInt archreg)
   1357 {
   1358    return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
   1359 }
   1360 
   1361 /* Return the guest state offset of byte #5 of a gpr register. */
   1362 static __inline__ UInt
   1363 gpr_b5_offset(UInt archreg)
   1364 {
   1365    return gpr_offset(archreg) + 5;
   1366 }
   1367 
   1368 /* Write byte #5 of a gpr to the guest state. */
   1369 static __inline__ void
   1370 put_gpr_b5(UInt archreg, IRExpr *expr)
   1371 {
   1372    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
   1373 
   1374    stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
   1375 }
   1376 
   1377 /* Read byte #5 of a gpr register. */
   1378 static __inline__ IRExpr *
   1379 get_gpr_b5(UInt archreg)
   1380 {
   1381    return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
   1382 }
   1383 
   1384 /* Return the guest state offset of byte #2 of a gpr register. */
   1385 static __inline__ UInt
   1386 gpr_b2_offset(UInt archreg)
   1387 {
   1388    return gpr_offset(archreg) + 2;
   1389 }
   1390 
   1391 /* Write byte #2 of a gpr to the guest state. */
   1392 static __inline__ void
   1393 put_gpr_b2(UInt archreg, IRExpr *expr)
   1394 {
   1395    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
   1396 
   1397    stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
   1398 }
   1399 
   1400 /* Read byte #2 of a gpr register. */
   1401 static __inline__ IRExpr *
   1402 get_gpr_b2(UInt archreg)
   1403 {
   1404    return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
   1405 }
   1406 
   1407 /* Return the guest state offset of the counter register. */
   1408 static UInt
   1409 counter_offset(void)
   1410 {
   1411    return S390X_GUEST_OFFSET(guest_counter);
   1412 }
   1413 
   1414 /* Return the guest state offset of double word #0 of the counter register. */
   1415 static __inline__ UInt
   1416 counter_dw0_offset(void)
   1417 {
   1418    return counter_offset() + 0;
   1419 }
   1420 
   1421 /* Write double word #0 of the counter to the guest state. */
   1422 static __inline__ void
   1423 put_counter_dw0(IRExpr *expr)
   1424 {
   1425    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
   1426 
   1427    stmt(IRStmt_Put(counter_dw0_offset(), expr));
   1428 }
   1429 
   1430 /* Read double word #0 of the counter register. */
   1431 static __inline__ IRExpr *
   1432 get_counter_dw0(void)
   1433 {
   1434    return IRExpr_Get(counter_dw0_offset(), Ity_I64);
   1435 }
   1436 
   1437 /* Return the guest state offset of word #0 of the counter register. */
   1438 static __inline__ UInt
   1439 counter_w0_offset(void)
   1440 {
   1441    return counter_offset() + 0;
   1442 }
   1443 
   1444 /* Return the guest state offset of word #1 of the counter register. */
   1445 static __inline__ UInt
   1446 counter_w1_offset(void)
   1447 {
   1448    return counter_offset() + 4;
   1449 }
   1450 
   1451 /* Write word #0 of the counter to the guest state. */
   1452 static __inline__ void
   1453 put_counter_w0(IRExpr *expr)
   1454 {
   1455    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
   1456 
   1457    stmt(IRStmt_Put(counter_w0_offset(), expr));
   1458 }
   1459 
   1460 /* Read word #0 of the counter register. */
   1461 static __inline__ IRExpr *
   1462 get_counter_w0(void)
   1463 {
   1464    return IRExpr_Get(counter_w0_offset(), Ity_I32);
   1465 }
   1466 
   1467 /* Write word #1 of the counter to the guest state. */
   1468 static __inline__ void
   1469 put_counter_w1(IRExpr *expr)
   1470 {
   1471    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
   1472 
   1473    stmt(IRStmt_Put(counter_w1_offset(), expr));
   1474 }
   1475 
   1476 /* Read word #1 of the counter register. */
   1477 static __inline__ IRExpr *
   1478 get_counter_w1(void)
   1479 {
   1480    return IRExpr_Get(counter_w1_offset(), Ity_I32);
   1481 }
   1482 
   1483 /* Return the guest state offset of the fpc register. */
   1484 static UInt
   1485 fpc_offset(void)
   1486 {
   1487    return S390X_GUEST_OFFSET(guest_fpc);
   1488 }
   1489 
   1490 /* Return the guest state offset of word #0 of the fpc register. */
   1491 static __inline__ UInt
   1492 fpc_w0_offset(void)
   1493 {
   1494    return fpc_offset() + 0;
   1495 }
   1496 
   1497 /* Write word #0 of the fpc to the guest state. */
   1498 static __inline__ void
   1499 put_fpc_w0(IRExpr *expr)
   1500 {
   1501    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
   1502 
   1503    stmt(IRStmt_Put(fpc_w0_offset(), expr));
   1504 }
   1505 
   1506 /* Read word #0 of the fpc register. */
   1507 static __inline__ IRExpr *
   1508 get_fpc_w0(void)
   1509 {
   1510    return IRExpr_Get(fpc_w0_offset(), Ity_I32);
   1511 }
   1512 
   1513 
   1514 /*------------------------------------------------------------*/
   1515 /*--- Rounding modes                                       ---*/
   1516 /*------------------------------------------------------------*/
   1517 
   1518 /* Extract the bfp rounding mode from the guest FPC reg and encode it as an
   1519    IRRoundingMode:
   1520 
   1521    rounding mode | s390 | IR
   1522    -------------------------
   1523    to nearest    |  00  | 00
   1524    to zero       |  01  | 11
   1525    to +infinity  |  10  | 10
   1526    to -infinity  |  11  | 01
   1527 
   1528    So:  IR = (4 - s390) & 3
   1529 */
   1530 static IRExpr *
   1531 get_bfp_rounding_mode_from_fpc(void)
   1532 {
   1533    IRTemp fpc_bits = newTemp(Ity_I32);
   1534 
   1535    /* For z196 and later the bfp rounding mode is stored in bits [29:31].
   1536       Prior to that bits [30:31] contained the bfp rounding mode with
   1537       bit 29 being unused and having a value of 0. So we can always
   1538       extract the least significant 3 bits. */
   1539    assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
   1540 
   1541    /* fixs390:
   1542 
   1543 
   1544       if (! s390_host_has_fpext && rounding_mode > 3) {
   1545          emulation warning @ runtime and
   1546          set fpc to round nearest
   1547       }
   1548    */
   1549 
   1550    /* For now silently adjust an unsupported rounding mode to "nearest" */
   1551    IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
   1552                            mkexpr(fpc_bits),
   1553                            mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
   1554 
   1555    // rm_IR = (4 - rm_s390) & 3;
   1556    return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
   1557 }
   1558 
   1559 /* Encode the s390 rounding mode as it appears in the m3 field of certain
   1560    instructions to VEX's IRRoundingMode. Rounding modes that cannot be
   1561    represented in VEX are converted to Irrm_NEAREST. The rationale is, that
   1562    Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
   1563    considers the default rounding mode (4.3.3). */
   1564 static IRTemp
   1565 encode_bfp_rounding_mode(UChar mode)
   1566 {
   1567    IRExpr *rm;
   1568 
   1569    switch (mode) {
   1570    case S390_BFP_ROUND_PER_FPC:
   1571       rm = get_bfp_rounding_mode_from_fpc();
   1572       break;
   1573    case S390_BFP_ROUND_NEAREST_AWAY:  /* not supported */
   1574    case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
   1575    case S390_BFP_ROUND_NEAREST_EVEN:  rm = mkU32(Irrm_NEAREST); break;
   1576    case S390_BFP_ROUND_ZERO:          rm = mkU32(Irrm_ZERO);    break;
   1577    case S390_BFP_ROUND_POSINF:        rm = mkU32(Irrm_PosINF);  break;
   1578    case S390_BFP_ROUND_NEGINF:        rm = mkU32(Irrm_NegINF);  break;
   1579    default:
   1580       vpanic("encode_bfp_rounding_mode");
   1581    }
   1582 
   1583    return mktemp(Ity_I32, rm);
   1584 }
   1585 
   1586 /* Extract the DFP rounding mode from the guest FPC reg and encode it as an
   1587    IRRoundingMode:
   1588 
   1589    rounding mode                     | s390  | IR
   1590    ------------------------------------------------
   1591    to nearest, ties to even          |  000  | 000
   1592    to zero                           |  001  | 011
   1593    to +infinity                      |  010  | 010
   1594    to -infinity                      |  011  | 001
   1595    to nearest, ties away from 0      |  100  | 100
   1596    to nearest, ties toward 0         |  101  | 111
   1597    to away from 0                    |  110  | 110
   1598    to prepare for shorter precision  |  111  | 101
   1599 
   1600    So:  IR = (s390 ^ ((s390 << 1) & 2))
   1601 */
   1602 static IRExpr *
   1603 get_dfp_rounding_mode_from_fpc(void)
   1604 {
   1605    IRTemp fpc_bits = newTemp(Ity_I32);
   1606 
   1607    /* The dfp rounding mode is stored in bits [25:27].
   1608       extract the bits at 25:27 and right shift 4 times. */
   1609    assign(fpc_bits, binop(Iop_Shr32,
   1610                           binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
   1611                           mkU8(4)));
   1612 
   1613    IRExpr *rm_s390 = mkexpr(fpc_bits);
   1614    // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
   1615 
   1616    return binop(Iop_Xor32, rm_s390,
   1617                 binop( Iop_And32,
   1618                        binop(Iop_Shl32, rm_s390, mkU8(1)),
   1619                        mkU32(2)));
   1620 }
   1621 
   1622 /* Encode the s390 rounding mode as it appears in the m3 field of certain
   1623    instructions to VEX's IRRoundingMode. */
   1624 static IRTemp
   1625 encode_dfp_rounding_mode(UChar mode)
   1626 {
   1627    IRExpr *rm;
   1628 
   1629    switch (mode) {
   1630    case S390_DFP_ROUND_PER_FPC_0:
   1631    case S390_DFP_ROUND_PER_FPC_2:
   1632       rm = get_dfp_rounding_mode_from_fpc(); break;
   1633    case S390_DFP_ROUND_NEAREST_EVEN_4:
   1634    case S390_DFP_ROUND_NEAREST_EVEN_8:
   1635       rm = mkU32(Irrm_NEAREST); break;
   1636    case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
   1637    case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
   1638       rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
   1639    case S390_DFP_ROUND_PREPARE_SHORT_3:
   1640    case S390_DFP_ROUND_PREPARE_SHORT_15:
   1641       rm = mkU32(Irrm_PREPARE_SHORTER); break;
   1642    case S390_DFP_ROUND_ZERO_5:
   1643    case S390_DFP_ROUND_ZERO_9:
   1644       rm = mkU32(Irrm_ZERO ); break;
   1645    case S390_DFP_ROUND_POSINF_6:
   1646    case S390_DFP_ROUND_POSINF_10:
   1647       rm = mkU32(Irrm_PosINF); break;
   1648    case S390_DFP_ROUND_NEGINF_7:
   1649    case S390_DFP_ROUND_NEGINF_11:
   1650       rm = mkU32(Irrm_NegINF); break;
   1651    case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
   1652       rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
   1653    case S390_DFP_ROUND_AWAY_0:
   1654       rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
   1655    default:
   1656       vpanic("encode_dfp_rounding_mode");
   1657    }
   1658 
   1659    return mktemp(Ity_I32, rm);
   1660 }
   1661 
   1662 
   1663 /*------------------------------------------------------------*/
   1664 /*--- Condition code helpers                               ---*/
   1665 /*------------------------------------------------------------*/
   1666 
   1667 /* The result of a Iop_CmpFxx operation is a condition code. It is
   1668    encoded using the values defined in type IRCmpFxxResult.
   1669    Before we can store the condition code into the guest state (or do
   1670    anything else with it for that matter) we need to convert it to
   1671    the encoding that s390 uses. This is what this function does.
   1672 
   1673    s390     VEX                b6 b2 b0   cc.1  cc.0
   1674    0      0x40 EQ             1  0  0     0     0
   1675    1      0x01 LT             0  0  1     0     1
   1676    2      0x00 GT             0  0  0     1     0
   1677    3      0x45 Unordered      1  1  1     1     1
   1678 
   1679    The following bits from the VEX encoding are interesting:
   1680    b0, b2, b6  with b0 being the LSB. We observe:
   1681 
   1682    cc.0 = b0;
   1683    cc.1 = b2 | (~b0 & ~b6)
   1684 
   1685    with cc being the s390 condition code.
   1686 */
   1687 static IRExpr *
   1688 convert_vex_bfpcc_to_s390(IRTemp vex_cc)
   1689 {
   1690    IRTemp cc0  = newTemp(Ity_I32);
   1691    IRTemp cc1  = newTemp(Ity_I32);
   1692    IRTemp b0   = newTemp(Ity_I32);
   1693    IRTemp b2   = newTemp(Ity_I32);
   1694    IRTemp b6   = newTemp(Ity_I32);
   1695 
   1696    assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
   1697    assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
   1698                     mkU32(1)));
   1699    assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
   1700                     mkU32(1)));
   1701 
   1702    assign(cc0, mkexpr(b0));
   1703    assign(cc1, binop(Iop_Or32, mkexpr(b2),
   1704                      binop(Iop_And32,
   1705                            binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
   1706                            binop(Iop_Sub32, mkU32(1), mkexpr(b6))  /* ~b6 */
   1707                            )));
   1708 
   1709    return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
   1710 }
   1711 
   1712 
   1713 /* The result of a Iop_CmpDxx operation is a condition code. It is
   1714    encoded using the values defined in type IRCmpDxxResult.
   1715    Before we can store the condition code into the guest state (or do
   1716    anything else with it for that matter) we need to convert it to
   1717    the encoding that s390 uses. This is what this function does. */
   1718 static IRExpr *
   1719 convert_vex_dfpcc_to_s390(IRTemp vex_cc)
   1720 {
   1721    /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
   1722       same. currently. */
   1723    return convert_vex_bfpcc_to_s390(vex_cc);
   1724 }
   1725 
   1726 
   1727 /*------------------------------------------------------------*/
   1728 /*--- Build IR for formats                                 ---*/
   1729 /*------------------------------------------------------------*/
   1730 static void
   1731 s390_format_I(const HChar *(*irgen)(UChar i),
   1732               UChar i)
   1733 {
   1734    const HChar *mnm = irgen(i);
   1735 
   1736    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1737       s390_disasm(ENC2(MNM, UINT), mnm, i);
   1738 }
   1739 
   1740 static void
   1741 s390_format_E(const HChar *(*irgen)(void))
   1742 {
   1743    const HChar *mnm = irgen();
   1744 
   1745    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1746       s390_disasm(ENC1(MNM), mnm);
   1747 }
   1748 
   1749 static void
   1750 s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
   1751                UChar r1, UShort i2)
   1752 {
   1753    irgen(r1, i2);
   1754 }
   1755 
   1756 static void
   1757 s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
   1758                   UChar r1, UShort i2)
   1759 {
   1760    const HChar *mnm = irgen(r1, i2);
   1761 
   1762    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1763       s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
   1764 }
   1765 
   1766 static void
   1767 s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
   1768                   UChar r1, UShort i2)
   1769 {
   1770    const HChar *mnm = irgen(r1, i2);
   1771 
   1772    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1773       s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
   1774 }
   1775 
   1776 static void
   1777 s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
   1778                   UChar r1, UShort i2)
   1779 {
   1780    const HChar *mnm = irgen(r1, i2);
   1781 
   1782    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1783       s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
   1784 }
   1785 
   1786 static void
   1787 s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
   1788                     UChar r1, UChar r3, UShort i2)
   1789 {
   1790    const HChar *mnm = irgen(r1, r3, i2);
   1791 
   1792    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1793       s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
   1794 }
   1795 
   1796 static void
   1797 s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
   1798                      UChar r1, UChar r3, UShort i2)
   1799 {
   1800    const HChar *mnm = irgen(r1, r3, i2);
   1801 
   1802    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1803       s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
   1804 }
   1805 
   1806 static void
   1807 s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
   1808                                             UChar i4, UChar i5),
   1809                       UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
   1810 {
   1811    const HChar *mnm = irgen(r1, r2, i3, i4, i5);
   1812 
   1813    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1814       s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
   1815                   i5);
   1816 }
   1817 
   1818 static void
   1819 s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
   1820                                            UChar m3),
   1821                      UChar r1, UChar r2, UShort i4, UChar m3)
   1822 {
   1823    const HChar *mnm = irgen(r1, r2, i4, m3);
   1824 
   1825    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1826       s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
   1827                   r2, m3, (Int)(Short)i4);
   1828 }
   1829 
   1830 static void
   1831 s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
   1832                                            UChar i2),
   1833                      UChar r1, UChar m3, UShort i4, UChar i2)
   1834 {
   1835    const HChar *mnm = irgen(r1, m3, i4, i2);
   1836 
   1837    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1838       s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
   1839                   r1, i2, m3, (Int)(Short)i4);
   1840 }
   1841 
   1842 static void
   1843 s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
   1844                                            UChar i2),
   1845                      UChar r1, UChar m3, UShort i4, UChar i2)
   1846 {
   1847    const HChar *mnm = irgen(r1, m3, i4, i2);
   1848 
   1849    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1850       s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
   1851                   (Int)(Char)i2, m3, (Int)(Short)i4);
   1852 }
   1853 
   1854 static void
   1855 s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
   1856                 UChar r1, UInt i2)
   1857 {
   1858    irgen(r1, i2);
   1859 }
   1860 
   1861 static void
   1862 s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
   1863                    UChar r1, UInt i2)
   1864 {
   1865    const HChar *mnm = irgen(r1, i2);
   1866 
   1867    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1868       s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
   1869 }
   1870 
   1871 static void
   1872 s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
   1873                    UChar r1, UInt i2)
   1874 {
   1875    const HChar *mnm = irgen(r1, i2);
   1876 
   1877    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1878       s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
   1879 }
   1880 
   1881 static void
   1882 s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
   1883                    UChar r1, UInt i2)
   1884 {
   1885    const HChar *mnm = irgen(r1, i2);
   1886 
   1887    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1888       s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
   1889 }
   1890 
   1891 static void
   1892 s390_format_RIL_UP(const HChar *(*irgen)(void),
   1893                    UChar r1, UInt i2)
   1894 {
   1895    const HChar *mnm = irgen();
   1896 
   1897    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1898       s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
   1899 }
   1900 
   1901 static void
   1902 s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
   1903                       IRTemp op4addr),
   1904                       UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
   1905 {
   1906    const HChar *mnm;
   1907    IRTemp op4addr = newTemp(Ity_I64);
   1908 
   1909    assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
   1910           mkU64(0)));
   1911 
   1912    mnm = irgen(r1, m3, i2, op4addr);
   1913 
   1914    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1915       s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
   1916                   (Int)(Char)i2, m3, d4, 0, b4);
   1917 }
   1918 
   1919 static void
   1920 s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
   1921                       IRTemp op4addr),
   1922                       UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
   1923 {
   1924    const HChar *mnm;
   1925    IRTemp op4addr = newTemp(Ity_I64);
   1926 
   1927    assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
   1928           mkU64(0)));
   1929 
   1930    mnm = irgen(r1, m3, i2, op4addr);
   1931 
   1932    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1933       s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
   1934                   i2, m3, d4, 0, b4);
   1935 }
   1936 
   1937 static void
   1938 s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
   1939                UChar r1, UChar r2)
   1940 {
   1941    irgen(r1, r2);
   1942 }
   1943 
   1944 static void
   1945 s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
   1946                   UChar r1, UChar r2)
   1947 {
   1948    const HChar *mnm = irgen(r1, r2);
   1949 
   1950    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1951       s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
   1952 }
   1953 
   1954 static void
   1955 s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
   1956                   UChar r1, UChar r2)
   1957 {
   1958    const HChar *mnm = irgen(r1, r2);
   1959 
   1960    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1961       s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
   1962 }
   1963 
   1964 static void
   1965 s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
   1966                 UChar r1, UChar r2)
   1967 {
   1968    irgen(r1, r2);
   1969 }
   1970 
   1971 static void
   1972 s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
   1973                    UChar r1, UChar r2)
   1974 {
   1975    const HChar *mnm = irgen(r1, r2);
   1976 
   1977    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1978       s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
   1979 }
   1980 
   1981 static void
   1982 s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
   1983                    UChar r1, UChar r2)
   1984 {
   1985    const HChar *mnm = irgen(r1, r2);
   1986 
   1987    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1988       s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
   1989 }
   1990 
   1991 static void
   1992 s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
   1993                    UChar r1, UChar r2)
   1994 {
   1995    const HChar *mnm = irgen(r1, r2);
   1996 
   1997    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   1998       s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
   1999 }
   2000 
   2001 static void
   2002 s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
   2003                    UChar r1, UChar r2)
   2004 {
   2005    const HChar *mnm = irgen(r1, r2);
   2006 
   2007    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2008       s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
   2009 }
   2010 
   2011 static void
   2012 s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
   2013                    UChar r1)
   2014 {
   2015    const HChar *mnm = irgen(r1);
   2016 
   2017    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2018       s390_disasm(ENC2(MNM, GPR), mnm, r1);
   2019 }
   2020 
   2021 static void
   2022 s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
   2023                    UChar r1)
   2024 {
   2025    const HChar *mnm = irgen(r1);
   2026 
   2027    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2028       s390_disasm(ENC2(MNM, FPR), mnm, r1);
   2029 }
   2030 
   2031 static void
   2032 s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
   2033                        UChar m3, UChar r1, UChar r2)
   2034 {
   2035    const HChar *mnm = irgen(m3, r1, r2);
   2036 
   2037    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2038       s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
   2039 }
   2040 
   2041 static void
   2042 s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
   2043                      UChar r1, UChar r3, UChar r2)
   2044 {
   2045    const HChar *mnm = irgen(r1, r3, r2);
   2046 
   2047    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2048       s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
   2049 }
   2050 
   2051 static void
   2052 s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
   2053                      UChar r3, UChar r1, UChar r2)
   2054 {
   2055    const HChar *mnm = irgen(r3, r1, r2);
   2056 
   2057    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2058       s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
   2059 }
   2060 
   2061 static void
   2062 s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
   2063                                            UChar r2),
   2064                      UChar m3, UChar m4, UChar r1, UChar r2)
   2065 {
   2066    const HChar *mnm = irgen(m3, m4, r1, r2);
   2067 
   2068    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2069       s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
   2070 }
   2071 
   2072 static void
   2073 s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
   2074                      UChar m4, UChar r1, UChar r2)
   2075 {
   2076    const HChar *mnm = irgen(m4, r1, r2);
   2077 
   2078    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2079       s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
   2080 }
   2081 
   2082 static void
   2083 s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
   2084                                            UChar r2),
   2085                      UChar m3, UChar m4, UChar r1, UChar r2)
   2086 {
   2087    const HChar *mnm = irgen(m3, m4, r1, r2);
   2088 
   2089    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2090       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
   2091 }
   2092 
   2093 static void
   2094 s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
   2095                                            UChar r2),
   2096                      UChar m3, UChar m4, UChar r1, UChar r2)
   2097 {
   2098    const HChar *mnm = irgen(m3, m4, r1, r2);
   2099 
   2100    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2101       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
   2102 }
   2103 
   2104 
   2105 static void
   2106 s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
   2107                      UChar m3, UChar r1, UChar r2, Int xmnm_kind)
   2108 {
   2109    irgen(m3, r1, r2);
   2110 
   2111    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2112       s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
   2113 }
   2114 
   2115 static void
   2116 s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
   2117                       UChar r3, UChar r1, UChar r2)
   2118 {
   2119    const HChar *mnm = irgen(r3, r1, r2);
   2120 
   2121    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2122       s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
   2123 }
   2124 
   2125 static void
   2126 s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
   2127                      UChar r3, UChar m4, UChar r1, UChar r2)
   2128 {
   2129    const HChar *mnm = irgen(r3, m4, r1, r2);
   2130 
   2131    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2132       s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
   2133 }
   2134 
   2135 static void
   2136 s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
   2137                      UChar r3, UChar m4, UChar r1, UChar r2)
   2138 {
   2139    const HChar *mnm = irgen(r3, m4, r1, r2);
   2140 
   2141    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2142       s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
   2143 }
   2144 
   2145 static void
   2146 s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
   2147                       UChar r3, UChar m4, UChar r1, UChar r2)
   2148 {
   2149    const HChar *mnm = irgen(r3, m4, r1, r2);
   2150 
   2151    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2152       s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
   2153 }
   2154 
   2155 static void
   2156 s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
   2157                       UChar r3, UChar r1, UChar r2)
   2158 {
   2159    const HChar *mnm = irgen(r3, r1, r2);
   2160 
   2161    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2162       s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
   2163 }
   2164 
   2165 static void
   2166 s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
   2167                                       IRTemp op4addr),
   2168                 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
   2169 {
   2170    const HChar *mnm;
   2171    IRTemp op4addr = newTemp(Ity_I64);
   2172 
   2173    assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
   2174           mkU64(0)));
   2175 
   2176    mnm = irgen(r1, r2, m3, op4addr);
   2177 
   2178    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2179       s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
   2180                   r2, m3, d4, 0, b4);
   2181 }
   2182 
   2183 static void
   2184 s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
   2185                     UChar r1, UChar b2, UShort d2)
   2186 {
   2187    const HChar *mnm;
   2188    IRTemp op2addr = newTemp(Ity_I64);
   2189 
   2190    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
   2191           mkU64(0)));
   2192 
   2193    mnm = irgen(r1, op2addr);
   2194 
   2195    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2196       s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
   2197 }
   2198 
   2199 static void
   2200 s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
   2201                     UChar r1, UChar r3, UChar b2, UShort d2)
   2202 {
   2203    const HChar *mnm;
   2204    IRTemp op2addr = newTemp(Ity_I64);
   2205 
   2206    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
   2207           mkU64(0)));
   2208 
   2209    mnm = irgen(r1, r3, op2addr);
   2210 
   2211    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2212       s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
   2213 }
   2214 
   2215 static void
   2216 s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
   2217                     UChar r1, UChar r3, UChar b2, UShort d2)
   2218 {
   2219    const HChar *mnm;
   2220    IRTemp op2addr = newTemp(Ity_I64);
   2221 
   2222    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
   2223           mkU64(0)));
   2224 
   2225    mnm = irgen(r1, r3, op2addr);
   2226 
   2227    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2228       s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
   2229 }
   2230 
   2231 static void
   2232 s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
   2233                     UChar r1, UChar r3, UChar b2, UShort d2)
   2234 {
   2235    const HChar *mnm;
   2236    IRTemp op2addr = newTemp(Ity_I64);
   2237 
   2238    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
   2239           mkU64(0)));
   2240 
   2241    mnm = irgen(r1, r3, op2addr);
   2242 
   2243    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2244       s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
   2245 }
   2246 
   2247 static void
   2248 s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
   2249                     UChar r1, UChar r3, UShort i2)
   2250 {
   2251    const HChar *mnm = irgen(r1, r3, i2);
   2252 
   2253    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2254       s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
   2255 }
   2256 
   2257 static void
   2258 s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
   2259                      UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
   2260 {
   2261    const HChar *mnm;
   2262    IRTemp op2addr = newTemp(Ity_I64);
   2263    IRTemp d2 = newTemp(Ity_I64);
   2264 
   2265    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
   2266    assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
   2267           mkU64(0)));
   2268 
   2269    mnm = irgen(r1, r3, op2addr);
   2270 
   2271    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2272       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
   2273 }
   2274 
   2275 static void
   2276 s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
   2277                      UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
   2278 {
   2279    const HChar *mnm;
   2280    IRTemp op2addr = newTemp(Ity_I64);
   2281    IRTemp d2 = newTemp(Ity_I64);
   2282 
   2283    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
   2284    assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
   2285           mkU64(0)));
   2286 
   2287    mnm = irgen(r1, r3, op2addr);
   2288 
   2289    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2290       s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
   2291 }
   2292 
   2293 static void
   2294 s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
   2295                      UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
   2296 {
   2297    const HChar *mnm;
   2298    IRTemp op2addr = newTemp(Ity_I64);
   2299    IRTemp d2 = newTemp(Ity_I64);
   2300 
   2301    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
   2302    assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
   2303           mkU64(0)));
   2304 
   2305    mnm = irgen(r1, r3, op2addr);
   2306 
   2307    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2308       s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
   2309 }
   2310 
   2311 static void
   2312 s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
   2313                      UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
   2314                      Int xmnm_kind)
   2315 {
   2316    IRTemp op2addr = newTemp(Ity_I64);
   2317    IRTemp d2 = newTemp(Ity_I64);
   2318 
   2319    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
   2320 
   2321    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
   2322    assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
   2323           mkU64(0)));
   2324 
   2325    irgen(r1, op2addr);
   2326 
   2327    vassert(dis_res->whatNext == Dis_Continue);
   2328 
   2329    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2330       s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
   2331 }
   2332 
   2333 static void
   2334 s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
   2335                IRTemp op2addr),
   2336                UChar r1, UChar x2, UChar b2, UShort d2)
   2337 {
   2338    IRTemp op2addr = newTemp(Ity_I64);
   2339 
   2340    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
   2341           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
   2342           mkU64(0)));
   2343 
   2344    irgen(r1, x2, b2, d2, op2addr);
   2345 }
   2346 
   2347 static void
   2348 s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
   2349                     UChar r1, UChar x2, UChar b2, UShort d2)
   2350 {
   2351    const HChar *mnm;
   2352    IRTemp op2addr = newTemp(Ity_I64);
   2353 
   2354    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
   2355           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
   2356           mkU64(0)));
   2357 
   2358    mnm = irgen(r1, op2addr);
   2359 
   2360    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2361       s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
   2362 }
   2363 
   2364 static void
   2365 s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
   2366                     UChar r1, UChar x2, UChar b2, UShort d2)
   2367 {
   2368    const HChar *mnm;
   2369    IRTemp op2addr = newTemp(Ity_I64);
   2370 
   2371    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
   2372           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
   2373           mkU64(0)));
   2374 
   2375    mnm = irgen(r1, op2addr);
   2376 
   2377    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2378       s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
   2379 }
   2380 
   2381 static void
   2382 s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
   2383                      UChar r1, UChar x2, UChar b2, UShort d2)
   2384 {
   2385    const HChar *mnm;
   2386    IRTemp op2addr = newTemp(Ity_I64);
   2387 
   2388    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
   2389           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
   2390           mkU64(0)));
   2391 
   2392    mnm = irgen(r1, op2addr);
   2393 
   2394    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2395       s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
   2396 }
   2397 
   2398 static void
   2399 s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
   2400                       UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
   2401 {
   2402    const HChar *mnm;
   2403    IRTemp op2addr = newTemp(Ity_I64);
   2404 
   2405    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
   2406           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
   2407           mkU64(0)));
   2408 
   2409    mnm = irgen(r3, op2addr, r1);
   2410 
   2411    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2412       s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
   2413 }
   2414 
   2415 static void
   2416 s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
   2417                      UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2418 {
   2419    const HChar *mnm;
   2420    IRTemp op2addr = newTemp(Ity_I64);
   2421    IRTemp d2 = newTemp(Ity_I64);
   2422 
   2423    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
   2424    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
   2425           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
   2426           mkU64(0)));
   2427 
   2428    mnm = irgen(r1, op2addr);
   2429 
   2430    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2431       s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
   2432 }
   2433 
   2434 static void
   2435 s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
   2436                      UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2437 {
   2438    const HChar *mnm;
   2439    IRTemp op2addr = newTemp(Ity_I64);
   2440    IRTemp d2 = newTemp(Ity_I64);
   2441 
   2442    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
   2443    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
   2444           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
   2445           mkU64(0)));
   2446 
   2447    mnm = irgen(r1, op2addr);
   2448 
   2449    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2450       s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
   2451 }
   2452 
   2453 static void
   2454 s390_format_RXY_URRD(const HChar *(*irgen)(void),
   2455                      UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2456 {
   2457    const HChar *mnm;
   2458    IRTemp op2addr = newTemp(Ity_I64);
   2459    IRTemp d2 = newTemp(Ity_I64);
   2460 
   2461    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
   2462    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
   2463           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
   2464           mkU64(0)));
   2465 
   2466    mnm = irgen();
   2467 
   2468    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2469       s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
   2470 }
   2471 
   2472 static void
   2473 s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
   2474                  UChar b2, UShort d2)
   2475 {
   2476    const HChar *mnm;
   2477    IRTemp op2addr = newTemp(Ity_I64);
   2478 
   2479    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
   2480           mkU64(0)));
   2481 
   2482    mnm = irgen(op2addr);
   2483 
   2484    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2485       s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
   2486 }
   2487 
   2488 static void
   2489 s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
   2490                    UChar i2, UChar b1, UShort d1)
   2491 {
   2492    const HChar *mnm;
   2493    IRTemp op1addr = newTemp(Ity_I64);
   2494 
   2495    assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
   2496           mkU64(0)));
   2497 
   2498    mnm = irgen(i2, op1addr);
   2499 
   2500    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2501       s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
   2502 }
   2503 
   2504 static void
   2505 s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
   2506                     UChar i2, UChar b1, UShort dl1, UChar dh1)
   2507 {
   2508    const HChar *mnm;
   2509    IRTemp op1addr = newTemp(Ity_I64);
   2510    IRTemp d1 = newTemp(Ity_I64);
   2511 
   2512    assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
   2513    assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
   2514           mkU64(0)));
   2515 
   2516    mnm = irgen(i2, op1addr);
   2517 
   2518    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2519       s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
   2520 }
   2521 
   2522 static void
   2523 s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
   2524                     UChar i2, UChar b1, UShort dl1, UChar dh1)
   2525 {
   2526    const HChar *mnm;
   2527    IRTemp op1addr = newTemp(Ity_I64);
   2528    IRTemp d1 = newTemp(Ity_I64);
   2529 
   2530    assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
   2531    assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
   2532           mkU64(0)));
   2533 
   2534    mnm = irgen(i2, op1addr);
   2535 
   2536    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2537       s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
   2538 }
   2539 
   2540 static void
   2541 s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
   2542                       UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
   2543 {
   2544    const HChar *mnm;
   2545    IRTemp op1addr = newTemp(Ity_I64);
   2546    IRTemp op2addr = newTemp(Ity_I64);
   2547 
   2548    assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
   2549           mkU64(0)));
   2550    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
   2551           mkU64(0)));
   2552 
   2553    mnm = irgen(l, op1addr, op2addr);
   2554 
   2555    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2556       s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
   2557 }
   2558 
   2559 static void
   2560 s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
   2561                     UChar b1, UShort d1, UShort i2)
   2562 {
   2563    const HChar *mnm;
   2564    IRTemp op1addr = newTemp(Ity_I64);
   2565 
   2566    assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
   2567           mkU64(0)));
   2568 
   2569    mnm = irgen(i2, op1addr);
   2570 
   2571    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2572       s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
   2573 }
   2574 
   2575 static void
   2576 s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
   2577                     UChar b1, UShort d1, UShort i2)
   2578 {
   2579    const HChar *mnm;
   2580    IRTemp op1addr = newTemp(Ity_I64);
   2581 
   2582    assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
   2583           mkU64(0)));
   2584 
   2585    mnm = irgen(i2, op1addr);
   2586 
   2587    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   2588       s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
   2589 }
   2590 
   2591 
   2592 
   2593 /*------------------------------------------------------------*/
   2594 /*--- Build IR for opcodes                                 ---*/
   2595 /*------------------------------------------------------------*/
   2596 
   2597 static const HChar *
   2598 s390_irgen_AR(UChar r1, UChar r2)
   2599 {
   2600    IRTemp op1 = newTemp(Ity_I32);
   2601    IRTemp op2 = newTemp(Ity_I32);
   2602    IRTemp result = newTemp(Ity_I32);
   2603 
   2604    assign(op1, get_gpr_w1(r1));
   2605    assign(op2, get_gpr_w1(r2));
   2606    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
   2607    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
   2608    put_gpr_w1(r1, mkexpr(result));
   2609 
   2610    return "ar";
   2611 }
   2612 
   2613 static const HChar *
   2614 s390_irgen_AGR(UChar r1, UChar r2)
   2615 {
   2616    IRTemp op1 = newTemp(Ity_I64);
   2617    IRTemp op2 = newTemp(Ity_I64);
   2618    IRTemp result = newTemp(Ity_I64);
   2619 
   2620    assign(op1, get_gpr_dw0(r1));
   2621    assign(op2, get_gpr_dw0(r2));
   2622    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
   2623    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
   2624    put_gpr_dw0(r1, mkexpr(result));
   2625 
   2626    return "agr";
   2627 }
   2628 
   2629 static const HChar *
   2630 s390_irgen_AGFR(UChar r1, UChar r2)
   2631 {
   2632    IRTemp op1 = newTemp(Ity_I64);
   2633    IRTemp op2 = newTemp(Ity_I64);
   2634    IRTemp result = newTemp(Ity_I64);
   2635 
   2636    assign(op1, get_gpr_dw0(r1));
   2637    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
   2638    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
   2639    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
   2640    put_gpr_dw0(r1, mkexpr(result));
   2641 
   2642    return "agfr";
   2643 }
   2644 
   2645 static const HChar *
   2646 s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
   2647 {
   2648    IRTemp op2 = newTemp(Ity_I32);
   2649    IRTemp op3 = newTemp(Ity_I32);
   2650    IRTemp result = newTemp(Ity_I32);
   2651 
   2652    assign(op2, get_gpr_w1(r2));
   2653    assign(op3, get_gpr_w1(r3));
   2654    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
   2655    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
   2656    put_gpr_w1(r1, mkexpr(result));
   2657 
   2658    return "ark";
   2659 }
   2660 
   2661 static const HChar *
   2662 s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
   2663 {
   2664    IRTemp op2 = newTemp(Ity_I64);
   2665    IRTemp op3 = newTemp(Ity_I64);
   2666    IRTemp result = newTemp(Ity_I64);
   2667 
   2668    assign(op2, get_gpr_dw0(r2));
   2669    assign(op3, get_gpr_dw0(r3));
   2670    assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
   2671    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
   2672    put_gpr_dw0(r1, mkexpr(result));
   2673 
   2674    return "agrk";
   2675 }
   2676 
   2677 static const HChar *
   2678 s390_irgen_A(UChar r1, IRTemp op2addr)
   2679 {
   2680    IRTemp op1 = newTemp(Ity_I32);
   2681    IRTemp op2 = newTemp(Ity_I32);
   2682    IRTemp result = newTemp(Ity_I32);
   2683 
   2684    assign(op1, get_gpr_w1(r1));
   2685    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   2686    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
   2687    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
   2688    put_gpr_w1(r1, mkexpr(result));
   2689 
   2690    return "a";
   2691 }
   2692 
   2693 static const HChar *
   2694 s390_irgen_AY(UChar r1, IRTemp op2addr)
   2695 {
   2696    IRTemp op1 = newTemp(Ity_I32);
   2697    IRTemp op2 = newTemp(Ity_I32);
   2698    IRTemp result = newTemp(Ity_I32);
   2699 
   2700    assign(op1, get_gpr_w1(r1));
   2701    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   2702    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
   2703    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
   2704    put_gpr_w1(r1, mkexpr(result));
   2705 
   2706    return "ay";
   2707 }
   2708 
   2709 static const HChar *
   2710 s390_irgen_AG(UChar r1, IRTemp op2addr)
   2711 {
   2712    IRTemp op1 = newTemp(Ity_I64);
   2713    IRTemp op2 = newTemp(Ity_I64);
   2714    IRTemp result = newTemp(Ity_I64);
   2715 
   2716    assign(op1, get_gpr_dw0(r1));
   2717    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   2718    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
   2719    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
   2720    put_gpr_dw0(r1, mkexpr(result));
   2721 
   2722    return "ag";
   2723 }
   2724 
   2725 static const HChar *
   2726 s390_irgen_AGF(UChar r1, IRTemp op2addr)
   2727 {
   2728    IRTemp op1 = newTemp(Ity_I64);
   2729    IRTemp op2 = newTemp(Ity_I64);
   2730    IRTemp result = newTemp(Ity_I64);
   2731 
   2732    assign(op1, get_gpr_dw0(r1));
   2733    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
   2734    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
   2735    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
   2736    put_gpr_dw0(r1, mkexpr(result));
   2737 
   2738    return "agf";
   2739 }
   2740 
   2741 static const HChar *
   2742 s390_irgen_AFI(UChar r1, UInt i2)
   2743 {
   2744    IRTemp op1 = newTemp(Ity_I32);
   2745    Int op2;
   2746    IRTemp result = newTemp(Ity_I32);
   2747 
   2748    assign(op1, get_gpr_w1(r1));
   2749    op2 = (Int)i2;
   2750    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
   2751    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
   2752                        mkU32((UInt)op2)));
   2753    put_gpr_w1(r1, mkexpr(result));
   2754 
   2755    return "afi";
   2756 }
   2757 
   2758 static const HChar *
   2759 s390_irgen_AGFI(UChar r1, UInt i2)
   2760 {
   2761    IRTemp op1 = newTemp(Ity_I64);
   2762    Long op2;
   2763    IRTemp result = newTemp(Ity_I64);
   2764 
   2765    assign(op1, get_gpr_dw0(r1));
   2766    op2 = (Long)(Int)i2;
   2767    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
   2768    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
   2769                        mkU64((ULong)op2)));
   2770    put_gpr_dw0(r1, mkexpr(result));
   2771 
   2772    return "agfi";
   2773 }
   2774 
   2775 static const HChar *
   2776 s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
   2777 {
   2778    Int op2;
   2779    IRTemp op3 = newTemp(Ity_I32);
   2780    IRTemp result = newTemp(Ity_I32);
   2781 
   2782    op2 = (Int)(Short)i2;
   2783    assign(op3, get_gpr_w1(r3));
   2784    assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
   2785    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
   2786                        op2)), op3);
   2787    put_gpr_w1(r1, mkexpr(result));
   2788 
   2789    return "ahik";
   2790 }
   2791 
   2792 static const HChar *
   2793 s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
   2794 {
   2795    Long op2;
   2796    IRTemp op3 = newTemp(Ity_I64);
   2797    IRTemp result = newTemp(Ity_I64);
   2798 
   2799    op2 = (Long)(Short)i2;
   2800    assign(op3, get_gpr_dw0(r3));
   2801    assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
   2802    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
   2803                        op2)), op3);
   2804    put_gpr_dw0(r1, mkexpr(result));
   2805 
   2806    return "aghik";
   2807 }
   2808 
   2809 static const HChar *
   2810 s390_irgen_ASI(UChar i2, IRTemp op1addr)
   2811 {
   2812    IRTemp op1 = newTemp(Ity_I32);
   2813    Int op2;
   2814    IRTemp result = newTemp(Ity_I32);
   2815 
   2816    assign(op1, load(Ity_I32, mkexpr(op1addr)));
   2817    op2 = (Int)(Char)i2;
   2818    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
   2819    store(mkexpr(op1addr), mkexpr(result));
   2820    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
   2821                        mkU32((UInt)op2)));
   2822 
   2823    return "asi";
   2824 }
   2825 
   2826 static const HChar *
   2827 s390_irgen_AGSI(UChar i2, IRTemp op1addr)
   2828 {
   2829    IRTemp op1 = newTemp(Ity_I64);
   2830    Long op2;
   2831    IRTemp result = newTemp(Ity_I64);
   2832 
   2833    assign(op1, load(Ity_I64, mkexpr(op1addr)));
   2834    op2 = (Long)(Char)i2;
   2835    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
   2836    store(mkexpr(op1addr), mkexpr(result));
   2837    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
   2838                        mkU64((ULong)op2)));
   2839 
   2840    return "agsi";
   2841 }
   2842 
   2843 static const HChar *
   2844 s390_irgen_AH(UChar r1, IRTemp op2addr)
   2845 {
   2846    IRTemp op1 = newTemp(Ity_I32);
   2847    IRTemp op2 = newTemp(Ity_I32);
   2848    IRTemp result = newTemp(Ity_I32);
   2849 
   2850    assign(op1, get_gpr_w1(r1));
   2851    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
   2852    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
   2853    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
   2854    put_gpr_w1(r1, mkexpr(result));
   2855 
   2856    return "ah";
   2857 }
   2858 
   2859 static const HChar *
   2860 s390_irgen_AHY(UChar r1, IRTemp op2addr)
   2861 {
   2862    IRTemp op1 = newTemp(Ity_I32);
   2863    IRTemp op2 = newTemp(Ity_I32);
   2864    IRTemp result = newTemp(Ity_I32);
   2865 
   2866    assign(op1, get_gpr_w1(r1));
   2867    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
   2868    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
   2869    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
   2870    put_gpr_w1(r1, mkexpr(result));
   2871 
   2872    return "ahy";
   2873 }
   2874 
   2875 static const HChar *
   2876 s390_irgen_AHI(UChar r1, UShort i2)
   2877 {
   2878    IRTemp op1 = newTemp(Ity_I32);
   2879    Int op2;
   2880    IRTemp result = newTemp(Ity_I32);
   2881 
   2882    assign(op1, get_gpr_w1(r1));
   2883    op2 = (Int)(Short)i2;
   2884    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
   2885    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
   2886                        mkU32((UInt)op2)));
   2887    put_gpr_w1(r1, mkexpr(result));
   2888 
   2889    return "ahi";
   2890 }
   2891 
   2892 static const HChar *
   2893 s390_irgen_AGHI(UChar r1, UShort i2)
   2894 {
   2895    IRTemp op1 = newTemp(Ity_I64);
   2896    Long op2;
   2897    IRTemp result = newTemp(Ity_I64);
   2898 
   2899    assign(op1, get_gpr_dw0(r1));
   2900    op2 = (Long)(Short)i2;
   2901    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
   2902    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
   2903                        mkU64((ULong)op2)));
   2904    put_gpr_dw0(r1, mkexpr(result));
   2905 
   2906    return "aghi";
   2907 }
   2908 
   2909 static const HChar *
   2910 s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
   2911 {
   2912    IRTemp op2 = newTemp(Ity_I32);
   2913    IRTemp op3 = newTemp(Ity_I32);
   2914    IRTemp result = newTemp(Ity_I32);
   2915 
   2916    assign(op2, get_gpr_w0(r2));
   2917    assign(op3, get_gpr_w0(r3));
   2918    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
   2919    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
   2920    put_gpr_w0(r1, mkexpr(result));
   2921 
   2922    return "ahhhr";
   2923 }
   2924 
   2925 static const HChar *
   2926 s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
   2927 {
   2928    IRTemp op2 = newTemp(Ity_I32);
   2929    IRTemp op3 = newTemp(Ity_I32);
   2930    IRTemp result = newTemp(Ity_I32);
   2931 
   2932    assign(op2, get_gpr_w0(r2));
   2933    assign(op3, get_gpr_w1(r3));
   2934    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
   2935    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
   2936    put_gpr_w0(r1, mkexpr(result));
   2937 
   2938    return "ahhlr";
   2939 }
   2940 
   2941 static const HChar *
   2942 s390_irgen_AIH(UChar r1, UInt i2)
   2943 {
   2944    IRTemp op1 = newTemp(Ity_I32);
   2945    Int op2;
   2946    IRTemp result = newTemp(Ity_I32);
   2947 
   2948    assign(op1, get_gpr_w0(r1));
   2949    op2 = (Int)i2;
   2950    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
   2951    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
   2952                        mkU32((UInt)op2)));
   2953    put_gpr_w0(r1, mkexpr(result));
   2954 
   2955    return "aih";
   2956 }
   2957 
   2958 static const HChar *
   2959 s390_irgen_ALR(UChar r1, UChar r2)
   2960 {
   2961    IRTemp op1 = newTemp(Ity_I32);
   2962    IRTemp op2 = newTemp(Ity_I32);
   2963    IRTemp result = newTemp(Ity_I32);
   2964 
   2965    assign(op1, get_gpr_w1(r1));
   2966    assign(op2, get_gpr_w1(r2));
   2967    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
   2968    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
   2969    put_gpr_w1(r1, mkexpr(result));
   2970 
   2971    return "alr";
   2972 }
   2973 
   2974 static const HChar *
   2975 s390_irgen_ALGR(UChar r1, UChar r2)
   2976 {
   2977    IRTemp op1 = newTemp(Ity_I64);
   2978    IRTemp op2 = newTemp(Ity_I64);
   2979    IRTemp result = newTemp(Ity_I64);
   2980 
   2981    assign(op1, get_gpr_dw0(r1));
   2982    assign(op2, get_gpr_dw0(r2));
   2983    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
   2984    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
   2985    put_gpr_dw0(r1, mkexpr(result));
   2986 
   2987    return "algr";
   2988 }
   2989 
   2990 static const HChar *
   2991 s390_irgen_ALGFR(UChar r1, UChar r2)
   2992 {
   2993    IRTemp op1 = newTemp(Ity_I64);
   2994    IRTemp op2 = newTemp(Ity_I64);
   2995    IRTemp result = newTemp(Ity_I64);
   2996 
   2997    assign(op1, get_gpr_dw0(r1));
   2998    assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
   2999    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
   3000    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
   3001    put_gpr_dw0(r1, mkexpr(result));
   3002 
   3003    return "algfr";
   3004 }
   3005 
   3006 static const HChar *
   3007 s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
   3008 {
   3009    IRTemp op2 = newTemp(Ity_I32);
   3010    IRTemp op3 = newTemp(Ity_I32);
   3011    IRTemp result = newTemp(Ity_I32);
   3012 
   3013    assign(op2, get_gpr_w1(r2));
   3014    assign(op3, get_gpr_w1(r3));
   3015    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
   3016    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
   3017    put_gpr_w1(r1, mkexpr(result));
   3018 
   3019    return "alrk";
   3020 }
   3021 
   3022 static const HChar *
   3023 s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
   3024 {
   3025    IRTemp op2 = newTemp(Ity_I64);
   3026    IRTemp op3 = newTemp(Ity_I64);
   3027    IRTemp result = newTemp(Ity_I64);
   3028 
   3029    assign(op2, get_gpr_dw0(r2));
   3030    assign(op3, get_gpr_dw0(r3));
   3031    assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
   3032    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
   3033    put_gpr_dw0(r1, mkexpr(result));
   3034 
   3035    return "algrk";
   3036 }
   3037 
   3038 static const HChar *
   3039 s390_irgen_AL(UChar r1, IRTemp op2addr)
   3040 {
   3041    IRTemp op1 = newTemp(Ity_I32);
   3042    IRTemp op2 = newTemp(Ity_I32);
   3043    IRTemp result = newTemp(Ity_I32);
   3044 
   3045    assign(op1, get_gpr_w1(r1));
   3046    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   3047    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
   3048    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
   3049    put_gpr_w1(r1, mkexpr(result));
   3050 
   3051    return "al";
   3052 }
   3053 
   3054 static const HChar *
   3055 s390_irgen_ALY(UChar r1, IRTemp op2addr)
   3056 {
   3057    IRTemp op1 = newTemp(Ity_I32);
   3058    IRTemp op2 = newTemp(Ity_I32);
   3059    IRTemp result = newTemp(Ity_I32);
   3060 
   3061    assign(op1, get_gpr_w1(r1));
   3062    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   3063    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
   3064    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
   3065    put_gpr_w1(r1, mkexpr(result));
   3066 
   3067    return "aly";
   3068 }
   3069 
   3070 static const HChar *
   3071 s390_irgen_ALG(UChar r1, IRTemp op2addr)
   3072 {
   3073    IRTemp op1 = newTemp(Ity_I64);
   3074    IRTemp op2 = newTemp(Ity_I64);
   3075    IRTemp result = newTemp(Ity_I64);
   3076 
   3077    assign(op1, get_gpr_dw0(r1));
   3078    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   3079    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
   3080    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
   3081    put_gpr_dw0(r1, mkexpr(result));
   3082 
   3083    return "alg";
   3084 }
   3085 
   3086 static const HChar *
   3087 s390_irgen_ALGF(UChar r1, IRTemp op2addr)
   3088 {
   3089    IRTemp op1 = newTemp(Ity_I64);
   3090    IRTemp op2 = newTemp(Ity_I64);
   3091    IRTemp result = newTemp(Ity_I64);
   3092 
   3093    assign(op1, get_gpr_dw0(r1));
   3094    assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
   3095    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
   3096    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
   3097    put_gpr_dw0(r1, mkexpr(result));
   3098 
   3099    return "algf";
   3100 }
   3101 
   3102 static const HChar *
   3103 s390_irgen_ALFI(UChar r1, UInt i2)
   3104 {
   3105    IRTemp op1 = newTemp(Ity_I32);
   3106    UInt op2;
   3107    IRTemp result = newTemp(Ity_I32);
   3108 
   3109    assign(op1, get_gpr_w1(r1));
   3110    op2 = i2;
   3111    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
   3112    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
   3113                        mkU32(op2)));
   3114    put_gpr_w1(r1, mkexpr(result));
   3115 
   3116    return "alfi";
   3117 }
   3118 
   3119 static const HChar *
   3120 s390_irgen_ALGFI(UChar r1, UInt i2)
   3121 {
   3122    IRTemp op1 = newTemp(Ity_I64);
   3123    ULong op2;
   3124    IRTemp result = newTemp(Ity_I64);
   3125 
   3126    assign(op1, get_gpr_dw0(r1));
   3127    op2 = (ULong)i2;
   3128    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
   3129    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
   3130                        mkU64(op2)));
   3131    put_gpr_dw0(r1, mkexpr(result));
   3132 
   3133    return "algfi";
   3134 }
   3135 
   3136 static const HChar *
   3137 s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
   3138 {
   3139    IRTemp op2 = newTemp(Ity_I32);
   3140    IRTemp op3 = newTemp(Ity_I32);
   3141    IRTemp result = newTemp(Ity_I32);
   3142 
   3143    assign(op2, get_gpr_w0(r2));
   3144    assign(op3, get_gpr_w0(r3));
   3145    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
   3146    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
   3147    put_gpr_w0(r1, mkexpr(result));
   3148 
   3149    return "alhhhr";
   3150 }
   3151 
   3152 static const HChar *
   3153 s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
   3154 {
   3155    IRTemp op2 = newTemp(Ity_I32);
   3156    IRTemp op3 = newTemp(Ity_I32);
   3157    IRTemp result = newTemp(Ity_I32);
   3158 
   3159    assign(op2, get_gpr_w0(r2));
   3160    assign(op3, get_gpr_w1(r3));
   3161    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
   3162    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
   3163    put_gpr_w0(r1, mkexpr(result));
   3164 
   3165    return "alhhlr";
   3166 }
   3167 
   3168 static const HChar *
   3169 s390_irgen_ALCR(UChar r1, UChar r2)
   3170 {
   3171    IRTemp op1 = newTemp(Ity_I32);
   3172    IRTemp op2 = newTemp(Ity_I32);
   3173    IRTemp result = newTemp(Ity_I32);
   3174    IRTemp carry_in = newTemp(Ity_I32);
   3175 
   3176    assign(op1, get_gpr_w1(r1));
   3177    assign(op2, get_gpr_w1(r2));
   3178    assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
   3179    assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
   3180           mkexpr(carry_in)));
   3181    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
   3182    put_gpr_w1(r1, mkexpr(result));
   3183 
   3184    return "alcr";
   3185 }
   3186 
   3187 static const HChar *
   3188 s390_irgen_ALCGR(UChar r1, UChar r2)
   3189 {
   3190    IRTemp op1 = newTemp(Ity_I64);
   3191    IRTemp op2 = newTemp(Ity_I64);
   3192    IRTemp result = newTemp(Ity_I64);
   3193    IRTemp carry_in = newTemp(Ity_I64);
   3194 
   3195    assign(op1, get_gpr_dw0(r1));
   3196    assign(op2, get_gpr_dw0(r2));
   3197    assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
   3198           mkU8(1))));
   3199    assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
   3200           mkexpr(carry_in)));
   3201    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
   3202    put_gpr_dw0(r1, mkexpr(result));
   3203 
   3204    return "alcgr";
   3205 }
   3206 
   3207 static const HChar *
   3208 s390_irgen_ALC(UChar r1, IRTemp op2addr)
   3209 {
   3210    IRTemp op1 = newTemp(Ity_I32);
   3211    IRTemp op2 = newTemp(Ity_I32);
   3212    IRTemp result = newTemp(Ity_I32);
   3213    IRTemp carry_in = newTemp(Ity_I32);
   3214 
   3215    assign(op1, get_gpr_w1(r1));
   3216    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   3217    assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
   3218    assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
   3219           mkexpr(carry_in)));
   3220    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
   3221    put_gpr_w1(r1, mkexpr(result));
   3222 
   3223    return "alc";
   3224 }
   3225 
   3226 static const HChar *
   3227 s390_irgen_ALCG(UChar r1, IRTemp op2addr)
   3228 {
   3229    IRTemp op1 = newTemp(Ity_I64);
   3230    IRTemp op2 = newTemp(Ity_I64);
   3231    IRTemp result = newTemp(Ity_I64);
   3232    IRTemp carry_in = newTemp(Ity_I64);
   3233 
   3234    assign(op1, get_gpr_dw0(r1));
   3235    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   3236    assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
   3237           mkU8(1))));
   3238    assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
   3239           mkexpr(carry_in)));
   3240    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
   3241    put_gpr_dw0(r1, mkexpr(result));
   3242 
   3243    return "alcg";
   3244 }
   3245 
   3246 static const HChar *
   3247 s390_irgen_ALSI(UChar i2, IRTemp op1addr)
   3248 {
   3249    IRTemp op1 = newTemp(Ity_I32);
   3250    UInt op2;
   3251    IRTemp result = newTemp(Ity_I32);
   3252 
   3253    assign(op1, load(Ity_I32, mkexpr(op1addr)));
   3254    op2 = (UInt)(Int)(Char)i2;
   3255    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
   3256    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
   3257                        mkU32(op2)));
   3258    store(mkexpr(op1addr), mkexpr(result));
   3259 
   3260    return "alsi";
   3261 }
   3262 
   3263 static const HChar *
   3264 s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
   3265 {
   3266    IRTemp op1 = newTemp(Ity_I64);
   3267    ULong op2;
   3268    IRTemp result = newTemp(Ity_I64);
   3269 
   3270    assign(op1, load(Ity_I64, mkexpr(op1addr)));
   3271    op2 = (ULong)(Long)(Char)i2;
   3272    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
   3273    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
   3274                        mkU64(op2)));
   3275    store(mkexpr(op1addr), mkexpr(result));
   3276 
   3277    return "algsi";
   3278 }
   3279 
   3280 static const HChar *
   3281 s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
   3282 {
   3283    UInt op2;
   3284    IRTemp op3 = newTemp(Ity_I32);
   3285    IRTemp result = newTemp(Ity_I32);
   3286 
   3287    op2 = (UInt)(Int)(Short)i2;
   3288    assign(op3, get_gpr_w1(r3));
   3289    assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
   3290    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
   3291                        op3);
   3292    put_gpr_w1(r1, mkexpr(result));
   3293 
   3294    return "alhsik";
   3295 }
   3296 
   3297 static const HChar *
   3298 s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
   3299 {
   3300    ULong op2;
   3301    IRTemp op3 = newTemp(Ity_I64);
   3302    IRTemp result = newTemp(Ity_I64);
   3303 
   3304    op2 = (ULong)(Long)(Short)i2;
   3305    assign(op3, get_gpr_dw0(r3));
   3306    assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
   3307    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
   3308                        op3);
   3309    put_gpr_dw0(r1, mkexpr(result));
   3310 
   3311    return "alghsik";
   3312 }
   3313 
   3314 static const HChar *
   3315 s390_irgen_ALSIH(UChar r1, UInt i2)
   3316 {
   3317    IRTemp op1 = newTemp(Ity_I32);
   3318    UInt op2;
   3319    IRTemp result = newTemp(Ity_I32);
   3320 
   3321    assign(op1, get_gpr_w0(r1));
   3322    op2 = i2;
   3323    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
   3324    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
   3325                        mkU32(op2)));
   3326    put_gpr_w0(r1, mkexpr(result));
   3327 
   3328    return "alsih";
   3329 }
   3330 
   3331 static const HChar *
   3332 s390_irgen_ALSIHN(UChar r1, UInt i2)
   3333 {
   3334    IRTemp op1 = newTemp(Ity_I32);
   3335    UInt op2;
   3336    IRTemp result = newTemp(Ity_I32);
   3337 
   3338    assign(op1, get_gpr_w0(r1));
   3339    op2 = i2;
   3340    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
   3341    put_gpr_w0(r1, mkexpr(result));
   3342 
   3343    return "alsihn";
   3344 }
   3345 
   3346 static const HChar *
   3347 s390_irgen_NR(UChar r1, UChar r2)
   3348 {
   3349    IRTemp op1 = newTemp(Ity_I32);
   3350    IRTemp op2 = newTemp(Ity_I32);
   3351    IRTemp result = newTemp(Ity_I32);
   3352 
   3353    assign(op1, get_gpr_w1(r1));
   3354    assign(op2, get_gpr_w1(r2));
   3355    assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
   3356    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3357    put_gpr_w1(r1, mkexpr(result));
   3358 
   3359    return "nr";
   3360 }
   3361 
   3362 static const HChar *
   3363 s390_irgen_NGR(UChar r1, UChar r2)
   3364 {
   3365    IRTemp op1 = newTemp(Ity_I64);
   3366    IRTemp op2 = newTemp(Ity_I64);
   3367    IRTemp result = newTemp(Ity_I64);
   3368 
   3369    assign(op1, get_gpr_dw0(r1));
   3370    assign(op2, get_gpr_dw0(r2));
   3371    assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
   3372    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3373    put_gpr_dw0(r1, mkexpr(result));
   3374 
   3375    return "ngr";
   3376 }
   3377 
   3378 static const HChar *
   3379 s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
   3380 {
   3381    IRTemp op2 = newTemp(Ity_I32);
   3382    IRTemp op3 = newTemp(Ity_I32);
   3383    IRTemp result = newTemp(Ity_I32);
   3384 
   3385    assign(op2, get_gpr_w1(r2));
   3386    assign(op3, get_gpr_w1(r3));
   3387    assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
   3388    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3389    put_gpr_w1(r1, mkexpr(result));
   3390 
   3391    return "nrk";
   3392 }
   3393 
   3394 static const HChar *
   3395 s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
   3396 {
   3397    IRTemp op2 = newTemp(Ity_I64);
   3398    IRTemp op3 = newTemp(Ity_I64);
   3399    IRTemp result = newTemp(Ity_I64);
   3400 
   3401    assign(op2, get_gpr_dw0(r2));
   3402    assign(op3, get_gpr_dw0(r3));
   3403    assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
   3404    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3405    put_gpr_dw0(r1, mkexpr(result));
   3406 
   3407    return "ngrk";
   3408 }
   3409 
   3410 static const HChar *
   3411 s390_irgen_N(UChar r1, IRTemp op2addr)
   3412 {
   3413    IRTemp op1 = newTemp(Ity_I32);
   3414    IRTemp op2 = newTemp(Ity_I32);
   3415    IRTemp result = newTemp(Ity_I32);
   3416 
   3417    assign(op1, get_gpr_w1(r1));
   3418    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   3419    assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
   3420    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3421    put_gpr_w1(r1, mkexpr(result));
   3422 
   3423    return "n";
   3424 }
   3425 
   3426 static const HChar *
   3427 s390_irgen_NY(UChar r1, IRTemp op2addr)
   3428 {
   3429    IRTemp op1 = newTemp(Ity_I32);
   3430    IRTemp op2 = newTemp(Ity_I32);
   3431    IRTemp result = newTemp(Ity_I32);
   3432 
   3433    assign(op1, get_gpr_w1(r1));
   3434    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   3435    assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
   3436    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3437    put_gpr_w1(r1, mkexpr(result));
   3438 
   3439    return "ny";
   3440 }
   3441 
   3442 static const HChar *
   3443 s390_irgen_NG(UChar r1, IRTemp op2addr)
   3444 {
   3445    IRTemp op1 = newTemp(Ity_I64);
   3446    IRTemp op2 = newTemp(Ity_I64);
   3447    IRTemp result = newTemp(Ity_I64);
   3448 
   3449    assign(op1, get_gpr_dw0(r1));
   3450    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   3451    assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
   3452    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3453    put_gpr_dw0(r1, mkexpr(result));
   3454 
   3455    return "ng";
   3456 }
   3457 
   3458 static const HChar *
   3459 s390_irgen_NI(UChar i2, IRTemp op1addr)
   3460 {
   3461    IRTemp op1 = newTemp(Ity_I8);
   3462    UChar op2;
   3463    IRTemp result = newTemp(Ity_I8);
   3464 
   3465    assign(op1, load(Ity_I8, mkexpr(op1addr)));
   3466    op2 = i2;
   3467    assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
   3468    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3469    store(mkexpr(op1addr), mkexpr(result));
   3470 
   3471    return "ni";
   3472 }
   3473 
   3474 static const HChar *
   3475 s390_irgen_NIY(UChar i2, IRTemp op1addr)
   3476 {
   3477    IRTemp op1 = newTemp(Ity_I8);
   3478    UChar op2;
   3479    IRTemp result = newTemp(Ity_I8);
   3480 
   3481    assign(op1, load(Ity_I8, mkexpr(op1addr)));
   3482    op2 = i2;
   3483    assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
   3484    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3485    store(mkexpr(op1addr), mkexpr(result));
   3486 
   3487    return "niy";
   3488 }
   3489 
   3490 static const HChar *
   3491 s390_irgen_NIHF(UChar r1, UInt i2)
   3492 {
   3493    IRTemp op1 = newTemp(Ity_I32);
   3494    UInt op2;
   3495    IRTemp result = newTemp(Ity_I32);
   3496 
   3497    assign(op1, get_gpr_w0(r1));
   3498    op2 = i2;
   3499    assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
   3500    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3501    put_gpr_w0(r1, mkexpr(result));
   3502 
   3503    return "nihf";
   3504 }
   3505 
   3506 static const HChar *
   3507 s390_irgen_NIHH(UChar r1, UShort i2)
   3508 {
   3509    IRTemp op1 = newTemp(Ity_I16);
   3510    UShort op2;
   3511    IRTemp result = newTemp(Ity_I16);
   3512 
   3513    assign(op1, get_gpr_hw0(r1));
   3514    op2 = i2;
   3515    assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
   3516    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3517    put_gpr_hw0(r1, mkexpr(result));
   3518 
   3519    return "nihh";
   3520 }
   3521 
   3522 static const HChar *
   3523 s390_irgen_NIHL(UChar r1, UShort i2)
   3524 {
   3525    IRTemp op1 = newTemp(Ity_I16);
   3526    UShort op2;
   3527    IRTemp result = newTemp(Ity_I16);
   3528 
   3529    assign(op1, get_gpr_hw1(r1));
   3530    op2 = i2;
   3531    assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
   3532    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3533    put_gpr_hw1(r1, mkexpr(result));
   3534 
   3535    return "nihl";
   3536 }
   3537 
   3538 static const HChar *
   3539 s390_irgen_NILF(UChar r1, UInt i2)
   3540 {
   3541    IRTemp op1 = newTemp(Ity_I32);
   3542    UInt op2;
   3543    IRTemp result = newTemp(Ity_I32);
   3544 
   3545    assign(op1, get_gpr_w1(r1));
   3546    op2 = i2;
   3547    assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
   3548    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3549    put_gpr_w1(r1, mkexpr(result));
   3550 
   3551    return "nilf";
   3552 }
   3553 
   3554 static const HChar *
   3555 s390_irgen_NILH(UChar r1, UShort i2)
   3556 {
   3557    IRTemp op1 = newTemp(Ity_I16);
   3558    UShort op2;
   3559    IRTemp result = newTemp(Ity_I16);
   3560 
   3561    assign(op1, get_gpr_hw2(r1));
   3562    op2 = i2;
   3563    assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
   3564    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3565    put_gpr_hw2(r1, mkexpr(result));
   3566 
   3567    return "nilh";
   3568 }
   3569 
   3570 static const HChar *
   3571 s390_irgen_NILL(UChar r1, UShort i2)
   3572 {
   3573    IRTemp op1 = newTemp(Ity_I16);
   3574    UShort op2;
   3575    IRTemp result = newTemp(Ity_I16);
   3576 
   3577    assign(op1, get_gpr_hw3(r1));
   3578    op2 = i2;
   3579    assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
   3580    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   3581    put_gpr_hw3(r1, mkexpr(result));
   3582 
   3583    return "nill";
   3584 }
   3585 
   3586 static const HChar *
   3587 s390_irgen_BASR(UChar r1, UChar r2)
   3588 {
   3589    IRTemp target = newTemp(Ity_I64);
   3590 
   3591    if (r2 == 0) {
   3592       put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
   3593    } else {
   3594       if (r1 != r2) {
   3595          put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
   3596          call_function(get_gpr_dw0(r2));
   3597       } else {
   3598          assign(target, get_gpr_dw0(r2));
   3599          put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
   3600          call_function(mkexpr(target));
   3601       }
   3602    }
   3603 
   3604    return "basr";
   3605 }
   3606 
   3607 static const HChar *
   3608 s390_irgen_BAS(UChar r1, IRTemp op2addr)
   3609 {
   3610    IRTemp target = newTemp(Ity_I64);
   3611 
   3612    put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
   3613    assign(target, mkexpr(op2addr));
   3614    call_function(mkexpr(target));
   3615 
   3616    return "bas";
   3617 }
   3618 
   3619 static const HChar *
   3620 s390_irgen_BCR(UChar r1, UChar r2)
   3621 {
   3622    IRTemp cond = newTemp(Ity_I32);
   3623 
   3624    if (r2 == 0 && (r1 >= 14)) {    /* serialization */
   3625       stmt(IRStmt_MBE(Imbe_Fence));
   3626    }
   3627 
   3628    if ((r2 == 0) || (r1 == 0)) {
   3629    } else {
   3630       if (r1 == 15) {
   3631          return_from_function(get_gpr_dw0(r2));
   3632       } else {
   3633          assign(cond, s390_call_calculate_cond(r1));
   3634          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   3635                                     get_gpr_dw0(r2));
   3636       }
   3637    }
   3638    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   3639       s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
   3640 
   3641    return "bcr";
   3642 }
   3643 
   3644 static const HChar *
   3645 s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
   3646 {
   3647    IRTemp cond = newTemp(Ity_I32);
   3648 
   3649    if (r1 == 0) {
   3650    } else {
   3651       if (r1 == 15) {
   3652          always_goto(mkexpr(op2addr));
   3653       } else {
   3654          assign(cond, s390_call_calculate_cond(r1));
   3655          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   3656                                     mkexpr(op2addr));
   3657       }
   3658    }
   3659    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   3660       s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
   3661 
   3662    return "bc";
   3663 }
   3664 
   3665 static const HChar *
   3666 s390_irgen_BCTR(UChar r1, UChar r2)
   3667 {
   3668    put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
   3669    if (r2 != 0) {
   3670       if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
   3671                                  get_gpr_dw0(r2));
   3672    }
   3673 
   3674    return "bctr";
   3675 }
   3676 
   3677 static const HChar *
   3678 s390_irgen_BCTGR(UChar r1, UChar r2)
   3679 {
   3680    put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
   3681    if (r2 != 0) {
   3682       if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
   3683                                  get_gpr_dw0(r2));
   3684    }
   3685 
   3686    return "bctgr";
   3687 }
   3688 
   3689 static const HChar *
   3690 s390_irgen_BCT(UChar r1, IRTemp op2addr)
   3691 {
   3692    put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
   3693    if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
   3694                               mkexpr(op2addr));
   3695 
   3696    return "bct";
   3697 }
   3698 
   3699 static const HChar *
   3700 s390_irgen_BCTG(UChar r1, IRTemp op2addr)
   3701 {
   3702    put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
   3703    if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
   3704                               mkexpr(op2addr));
   3705 
   3706    return "bctg";
   3707 }
   3708 
   3709 static const HChar *
   3710 s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
   3711 {
   3712    IRTemp value = newTemp(Ity_I32);
   3713 
   3714    assign(value, get_gpr_w1(r3 | 1));
   3715    put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
   3716    if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
   3717                                     get_gpr_w1(r1)), mkexpr(op2addr));
   3718 
   3719    return "bxh";
   3720 }
   3721 
   3722 static const HChar *
   3723 s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
   3724 {
   3725    IRTemp value = newTemp(Ity_I64);
   3726 
   3727    assign(value, get_gpr_dw0(r3 | 1));
   3728    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
   3729    if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
   3730                                     get_gpr_dw0(r1)), mkexpr(op2addr));
   3731 
   3732    return "bxhg";
   3733 }
   3734 
   3735 static const HChar *
   3736 s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
   3737 {
   3738    IRTemp value = newTemp(Ity_I32);
   3739 
   3740    assign(value, get_gpr_w1(r3 | 1));
   3741    put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
   3742    if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
   3743                                     mkexpr(value)), mkexpr(op2addr));
   3744 
   3745    return "bxle";
   3746 }
   3747 
   3748 static const HChar *
   3749 s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
   3750 {
   3751    IRTemp value = newTemp(Ity_I64);
   3752 
   3753    assign(value, get_gpr_dw0(r3 | 1));
   3754    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
   3755    if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
   3756                                     mkexpr(value)), mkexpr(op2addr));
   3757 
   3758    return "bxleg";
   3759 }
   3760 
   3761 static const HChar *
   3762 s390_irgen_BRAS(UChar r1, UShort i2)
   3763 {
   3764    put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
   3765    call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
   3766 
   3767    return "bras";
   3768 }
   3769 
   3770 static const HChar *
   3771 s390_irgen_BRASL(UChar r1, UInt i2)
   3772 {
   3773    put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
   3774    call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
   3775 
   3776    return "brasl";
   3777 }
   3778 
   3779 static const HChar *
   3780 s390_irgen_BRC(UChar r1, UShort i2)
   3781 {
   3782    IRTemp cond = newTemp(Ity_I32);
   3783 
   3784    if (r1 == 0) {
   3785    } else {
   3786       if (r1 == 15) {
   3787          always_goto_and_chase(
   3788                guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
   3789       } else {
   3790          assign(cond, s390_call_calculate_cond(r1));
   3791          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   3792                            guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
   3793 
   3794       }
   3795    }
   3796    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   3797       s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
   3798 
   3799    return "brc";
   3800 }
   3801 
   3802 static const HChar *
   3803 s390_irgen_BRCL(UChar r1, UInt i2)
   3804 {
   3805    IRTemp cond = newTemp(Ity_I32);
   3806 
   3807    if (r1 == 0) {
   3808    } else {
   3809       if (r1 == 15) {
   3810          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
   3811       } else {
   3812          assign(cond, s390_call_calculate_cond(r1));
   3813          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   3814                            guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
   3815       }
   3816    }
   3817    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   3818       s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
   3819 
   3820    return "brcl";
   3821 }
   3822 
   3823 static const HChar *
   3824 s390_irgen_BRCT(UChar r1, UShort i2)
   3825 {
   3826    put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
   3827    if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
   3828                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
   3829 
   3830    return "brct";
   3831 }
   3832 
   3833 static const HChar *
   3834 s390_irgen_BRCTG(UChar r1, UShort i2)
   3835 {
   3836    put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
   3837    if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
   3838                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
   3839 
   3840    return "brctg";
   3841 }
   3842 
   3843 static const HChar *
   3844 s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
   3845 {
   3846    IRTemp value = newTemp(Ity_I32);
   3847 
   3848    assign(value, get_gpr_w1(r3 | 1));
   3849    put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
   3850    if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
   3851                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
   3852 
   3853    return "brxh";
   3854 }
   3855 
   3856 static const HChar *
   3857 s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
   3858 {
   3859    IRTemp value = newTemp(Ity_I64);
   3860 
   3861    assign(value, get_gpr_dw0(r3 | 1));
   3862    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
   3863    if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
   3864                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
   3865 
   3866    return "brxhg";
   3867 }
   3868 
   3869 static const HChar *
   3870 s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
   3871 {
   3872    IRTemp value = newTemp(Ity_I32);
   3873 
   3874    assign(value, get_gpr_w1(r3 | 1));
   3875    put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
   3876    if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
   3877                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
   3878 
   3879    return "brxle";
   3880 }
   3881 
   3882 static const HChar *
   3883 s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
   3884 {
   3885    IRTemp value = newTemp(Ity_I64);
   3886 
   3887    assign(value, get_gpr_dw0(r3 | 1));
   3888    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
   3889    if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
   3890                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
   3891 
   3892    return "brxlg";
   3893 }
   3894 
   3895 static const HChar *
   3896 s390_irgen_CR(UChar r1, UChar r2)
   3897 {
   3898    IRTemp op1 = newTemp(Ity_I32);
   3899    IRTemp op2 = newTemp(Ity_I32);
   3900 
   3901    assign(op1, get_gpr_w1(r1));
   3902    assign(op2, get_gpr_w1(r2));
   3903    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   3904 
   3905    return "cr";
   3906 }
   3907 
   3908 static const HChar *
   3909 s390_irgen_CGR(UChar r1, UChar r2)
   3910 {
   3911    IRTemp op1 = newTemp(Ity_I64);
   3912    IRTemp op2 = newTemp(Ity_I64);
   3913 
   3914    assign(op1, get_gpr_dw0(r1));
   3915    assign(op2, get_gpr_dw0(r2));
   3916    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   3917 
   3918    return "cgr";
   3919 }
   3920 
   3921 static const HChar *
   3922 s390_irgen_CGFR(UChar r1, UChar r2)
   3923 {
   3924    IRTemp op1 = newTemp(Ity_I64);
   3925    IRTemp op2 = newTemp(Ity_I64);
   3926 
   3927    assign(op1, get_gpr_dw0(r1));
   3928    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
   3929    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   3930 
   3931    return "cgfr";
   3932 }
   3933 
   3934 static const HChar *
   3935 s390_irgen_C(UChar r1, IRTemp op2addr)
   3936 {
   3937    IRTemp op1 = newTemp(Ity_I32);
   3938    IRTemp op2 = newTemp(Ity_I32);
   3939 
   3940    assign(op1, get_gpr_w1(r1));
   3941    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   3942    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   3943 
   3944    return "c";
   3945 }
   3946 
   3947 static const HChar *
   3948 s390_irgen_CY(UChar r1, IRTemp op2addr)
   3949 {
   3950    IRTemp op1 = newTemp(Ity_I32);
   3951    IRTemp op2 = newTemp(Ity_I32);
   3952 
   3953    assign(op1, get_gpr_w1(r1));
   3954    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   3955    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   3956 
   3957    return "cy";
   3958 }
   3959 
   3960 static const HChar *
   3961 s390_irgen_CG(UChar r1, IRTemp op2addr)
   3962 {
   3963    IRTemp op1 = newTemp(Ity_I64);
   3964    IRTemp op2 = newTemp(Ity_I64);
   3965 
   3966    assign(op1, get_gpr_dw0(r1));
   3967    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   3968    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   3969 
   3970    return "cg";
   3971 }
   3972 
   3973 static const HChar *
   3974 s390_irgen_CGF(UChar r1, IRTemp op2addr)
   3975 {
   3976    IRTemp op1 = newTemp(Ity_I64);
   3977    IRTemp op2 = newTemp(Ity_I64);
   3978 
   3979    assign(op1, get_gpr_dw0(r1));
   3980    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
   3981    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   3982 
   3983    return "cgf";
   3984 }
   3985 
   3986 static const HChar *
   3987 s390_irgen_CFI(UChar r1, UInt i2)
   3988 {
   3989    IRTemp op1 = newTemp(Ity_I32);
   3990    Int op2;
   3991 
   3992    assign(op1, get_gpr_w1(r1));
   3993    op2 = (Int)i2;
   3994    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
   3995                        mkU32((UInt)op2)));
   3996 
   3997    return "cfi";
   3998 }
   3999 
   4000 static const HChar *
   4001 s390_irgen_CGFI(UChar r1, UInt i2)
   4002 {
   4003    IRTemp op1 = newTemp(Ity_I64);
   4004    Long op2;
   4005 
   4006    assign(op1, get_gpr_dw0(r1));
   4007    op2 = (Long)(Int)i2;
   4008    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
   4009                        mkU64((ULong)op2)));
   4010 
   4011    return "cgfi";
   4012 }
   4013 
   4014 static const HChar *
   4015 s390_irgen_CRL(UChar r1, UInt i2)
   4016 {
   4017    IRTemp op1 = newTemp(Ity_I32);
   4018    IRTemp op2 = newTemp(Ity_I32);
   4019 
   4020    assign(op1, get_gpr_w1(r1));
   4021    assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
   4022           i2 << 1))));
   4023    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   4024 
   4025    return "crl";
   4026 }
   4027 
   4028 static const HChar *
   4029 s390_irgen_CGRL(UChar r1, UInt i2)
   4030 {
   4031    IRTemp op1 = newTemp(Ity_I64);
   4032    IRTemp op2 = newTemp(Ity_I64);
   4033 
   4034    assign(op1, get_gpr_dw0(r1));
   4035    assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
   4036           i2 << 1))));
   4037    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   4038 
   4039    return "cgrl";
   4040 }
   4041 
   4042 static const HChar *
   4043 s390_irgen_CGFRL(UChar r1, UInt i2)
   4044 {
   4045    IRTemp op1 = newTemp(Ity_I64);
   4046    IRTemp op2 = newTemp(Ity_I64);
   4047 
   4048    assign(op1, get_gpr_dw0(r1));
   4049    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
   4050           ((ULong)(Long)(Int)i2 << 1)))));
   4051    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   4052 
   4053    return "cgfrl";
   4054 }
   4055 
   4056 static const HChar *
   4057 s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
   4058 {
   4059    IRTemp op1 = newTemp(Ity_I32);
   4060    IRTemp op2 = newTemp(Ity_I32);
   4061    IRTemp cond = newTemp(Ity_I32);
   4062 
   4063    if (m3 == 0) {
   4064    } else {
   4065       if (m3 == 14) {
   4066          always_goto(mkexpr(op4addr));
   4067       } else {
   4068          assign(op1, get_gpr_w1(r1));
   4069          assign(op2, get_gpr_w1(r2));
   4070          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
   4071                                               op1, op2));
   4072          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
   4073                                           mkU32(0)), mkexpr(op4addr));
   4074       }
   4075    }
   4076 
   4077    return "crb";
   4078 }
   4079 
   4080 static const HChar *
   4081 s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
   4082 {
   4083    IRTemp op1 = newTemp(Ity_I64);
   4084    IRTemp op2 = newTemp(Ity_I64);
   4085    IRTemp cond = newTemp(Ity_I32);
   4086 
   4087    if (m3 == 0) {
   4088    } else {
   4089       if (m3 == 14) {
   4090          always_goto(mkexpr(op4addr));
   4091       } else {
   4092          assign(op1, get_gpr_dw0(r1));
   4093          assign(op2, get_gpr_dw0(r2));
   4094          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
   4095                                               op1, op2));
   4096          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
   4097                                           mkU32(0)), mkexpr(op4addr));
   4098       }
   4099    }
   4100 
   4101    return "cgrb";
   4102 }
   4103 
   4104 static const HChar *
   4105 s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
   4106 {
   4107    IRTemp op1 = newTemp(Ity_I32);
   4108    IRTemp op2 = newTemp(Ity_I32);
   4109    IRTemp cond = newTemp(Ity_I32);
   4110 
   4111    if (m3 == 0) {
   4112    } else {
   4113       if (m3 == 14) {
   4114          always_goto_and_chase(
   4115                 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4116       } else {
   4117          assign(op1, get_gpr_w1(r1));
   4118          assign(op2, get_gpr_w1(r2));
   4119          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
   4120                                               op1, op2));
   4121          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4122                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4123 
   4124       }
   4125    }
   4126 
   4127    return "crj";
   4128 }
   4129 
   4130 static const HChar *
   4131 s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
   4132 {
   4133    IRTemp op1 = newTemp(Ity_I64);
   4134    IRTemp op2 = newTemp(Ity_I64);
   4135    IRTemp cond = newTemp(Ity_I32);
   4136 
   4137    if (m3 == 0) {
   4138    } else {
   4139       if (m3 == 14) {
   4140          always_goto_and_chase(
   4141                 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4142       } else {
   4143          assign(op1, get_gpr_dw0(r1));
   4144          assign(op2, get_gpr_dw0(r2));
   4145          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
   4146                                               op1, op2));
   4147          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4148                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4149 
   4150       }
   4151    }
   4152 
   4153    return "cgrj";
   4154 }
   4155 
   4156 static const HChar *
   4157 s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
   4158 {
   4159    IRTemp op1 = newTemp(Ity_I32);
   4160    Int op2;
   4161    IRTemp cond = newTemp(Ity_I32);
   4162 
   4163    if (m3 == 0) {
   4164    } else {
   4165       if (m3 == 14) {
   4166          always_goto(mkexpr(op4addr));
   4167       } else {
   4168          assign(op1, get_gpr_w1(r1));
   4169          op2 = (Int)(Char)i2;
   4170          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
   4171                                               mktemp(Ity_I32, mkU32((UInt)op2))));
   4172          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4173                                     mkexpr(op4addr));
   4174       }
   4175    }
   4176 
   4177    return "cib";
   4178 }
   4179 
   4180 static const HChar *
   4181 s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
   4182 {
   4183    IRTemp op1 = newTemp(Ity_I64);
   4184    Long op2;
   4185    IRTemp cond = newTemp(Ity_I32);
   4186 
   4187    if (m3 == 0) {
   4188    } else {
   4189       if (m3 == 14) {
   4190          always_goto(mkexpr(op4addr));
   4191       } else {
   4192          assign(op1, get_gpr_dw0(r1));
   4193          op2 = (Long)(Char)i2;
   4194          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
   4195                                               mktemp(Ity_I64, mkU64((ULong)op2))));
   4196          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4197                                     mkexpr(op4addr));
   4198       }
   4199    }
   4200 
   4201    return "cgib";
   4202 }
   4203 
   4204 static const HChar *
   4205 s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
   4206 {
   4207    IRTemp op1 = newTemp(Ity_I32);
   4208    Int op2;
   4209    IRTemp cond = newTemp(Ity_I32);
   4210 
   4211    if (m3 == 0) {
   4212    } else {
   4213       if (m3 == 14) {
   4214          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4215       } else {
   4216          assign(op1, get_gpr_w1(r1));
   4217          op2 = (Int)(Char)i2;
   4218          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
   4219                                               mktemp(Ity_I32, mkU32((UInt)op2))));
   4220          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4221                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4222 
   4223       }
   4224    }
   4225 
   4226    return "cij";
   4227 }
   4228 
   4229 static const HChar *
   4230 s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
   4231 {
   4232    IRTemp op1 = newTemp(Ity_I64);
   4233    Long op2;
   4234    IRTemp cond = newTemp(Ity_I32);
   4235 
   4236    if (m3 == 0) {
   4237    } else {
   4238       if (m3 == 14) {
   4239          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4240       } else {
   4241          assign(op1, get_gpr_dw0(r1));
   4242          op2 = (Long)(Char)i2;
   4243          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
   4244                                               mktemp(Ity_I64, mkU64((ULong)op2))));
   4245          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4246                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4247 
   4248       }
   4249    }
   4250 
   4251    return "cgij";
   4252 }
   4253 
   4254 static const HChar *
   4255 s390_irgen_CH(UChar r1, IRTemp op2addr)
   4256 {
   4257    IRTemp op1 = newTemp(Ity_I32);
   4258    IRTemp op2 = newTemp(Ity_I32);
   4259 
   4260    assign(op1, get_gpr_w1(r1));
   4261    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
   4262    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   4263 
   4264    return "ch";
   4265 }
   4266 
   4267 static const HChar *
   4268 s390_irgen_CHY(UChar r1, IRTemp op2addr)
   4269 {
   4270    IRTemp op1 = newTemp(Ity_I32);
   4271    IRTemp op2 = newTemp(Ity_I32);
   4272 
   4273    assign(op1, get_gpr_w1(r1));
   4274    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
   4275    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   4276 
   4277    return "chy";
   4278 }
   4279 
   4280 static const HChar *
   4281 s390_irgen_CGH(UChar r1, IRTemp op2addr)
   4282 {
   4283    IRTemp op1 = newTemp(Ity_I64);
   4284    IRTemp op2 = newTemp(Ity_I64);
   4285 
   4286    assign(op1, get_gpr_dw0(r1));
   4287    assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
   4288    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   4289 
   4290    return "cgh";
   4291 }
   4292 
   4293 static const HChar *
   4294 s390_irgen_CHI(UChar r1, UShort i2)
   4295 {
   4296    IRTemp op1 = newTemp(Ity_I32);
   4297    Int op2;
   4298 
   4299    assign(op1, get_gpr_w1(r1));
   4300    op2 = (Int)(Short)i2;
   4301    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
   4302                        mkU32((UInt)op2)));
   4303 
   4304    return "chi";
   4305 }
   4306 
   4307 static const HChar *
   4308 s390_irgen_CGHI(UChar r1, UShort i2)
   4309 {
   4310    IRTemp op1 = newTemp(Ity_I64);
   4311    Long op2;
   4312 
   4313    assign(op1, get_gpr_dw0(r1));
   4314    op2 = (Long)(Short)i2;
   4315    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
   4316                        mkU64((ULong)op2)));
   4317 
   4318    return "cghi";
   4319 }
   4320 
   4321 static const HChar *
   4322 s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
   4323 {
   4324    IRTemp op1 = newTemp(Ity_I16);
   4325    Short op2;
   4326 
   4327    assign(op1, load(Ity_I16, mkexpr(op1addr)));
   4328    op2 = (Short)i2;
   4329    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
   4330                        mkU16((UShort)op2)));
   4331 
   4332    return "chhsi";
   4333 }
   4334 
   4335 static const HChar *
   4336 s390_irgen_CHSI(UShort i2, IRTemp op1addr)
   4337 {
   4338    IRTemp op1 = newTemp(Ity_I32);
   4339    Int op2;
   4340 
   4341    assign(op1, load(Ity_I32, mkexpr(op1addr)));
   4342    op2 = (Int)(Short)i2;
   4343    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
   4344                        mkU32((UInt)op2)));
   4345 
   4346    return "chsi";
   4347 }
   4348 
   4349 static const HChar *
   4350 s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
   4351 {
   4352    IRTemp op1 = newTemp(Ity_I64);
   4353    Long op2;
   4354 
   4355    assign(op1, load(Ity_I64, mkexpr(op1addr)));
   4356    op2 = (Long)(Short)i2;
   4357    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
   4358                        mkU64((ULong)op2)));
   4359 
   4360    return "cghsi";
   4361 }
   4362 
   4363 static const HChar *
   4364 s390_irgen_CHRL(UChar r1, UInt i2)
   4365 {
   4366    IRTemp op1 = newTemp(Ity_I32);
   4367    IRTemp op2 = newTemp(Ity_I32);
   4368 
   4369    assign(op1, get_gpr_w1(r1));
   4370    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
   4371           ((ULong)(Long)(Int)i2 << 1)))));
   4372    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   4373 
   4374    return "chrl";
   4375 }
   4376 
   4377 static const HChar *
   4378 s390_irgen_CGHRL(UChar r1, UInt i2)
   4379 {
   4380    IRTemp op1 = newTemp(Ity_I64);
   4381    IRTemp op2 = newTemp(Ity_I64);
   4382 
   4383    assign(op1, get_gpr_dw0(r1));
   4384    assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
   4385           ((ULong)(Long)(Int)i2 << 1)))));
   4386    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   4387 
   4388    return "cghrl";
   4389 }
   4390 
   4391 static const HChar *
   4392 s390_irgen_CHHR(UChar r1, UChar r2)
   4393 {
   4394    IRTemp op1 = newTemp(Ity_I32);
   4395    IRTemp op2 = newTemp(Ity_I32);
   4396 
   4397    assign(op1, get_gpr_w0(r1));
   4398    assign(op2, get_gpr_w0(r2));
   4399    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   4400 
   4401    return "chhr";
   4402 }
   4403 
   4404 static const HChar *
   4405 s390_irgen_CHLR(UChar r1, UChar r2)
   4406 {
   4407    IRTemp op1 = newTemp(Ity_I32);
   4408    IRTemp op2 = newTemp(Ity_I32);
   4409 
   4410    assign(op1, get_gpr_w0(r1));
   4411    assign(op2, get_gpr_w1(r2));
   4412    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   4413 
   4414    return "chlr";
   4415 }
   4416 
   4417 static const HChar *
   4418 s390_irgen_CHF(UChar r1, IRTemp op2addr)
   4419 {
   4420    IRTemp op1 = newTemp(Ity_I32);
   4421    IRTemp op2 = newTemp(Ity_I32);
   4422 
   4423    assign(op1, get_gpr_w0(r1));
   4424    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   4425    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
   4426 
   4427    return "chf";
   4428 }
   4429 
   4430 static const HChar *
   4431 s390_irgen_CIH(UChar r1, UInt i2)
   4432 {
   4433    IRTemp op1 = newTemp(Ity_I32);
   4434    Int op2;
   4435 
   4436    assign(op1, get_gpr_w0(r1));
   4437    op2 = (Int)i2;
   4438    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
   4439                        mkU32((UInt)op2)));
   4440 
   4441    return "cih";
   4442 }
   4443 
   4444 static const HChar *
   4445 s390_irgen_CLR(UChar r1, UChar r2)
   4446 {
   4447    IRTemp op1 = newTemp(Ity_I32);
   4448    IRTemp op2 = newTemp(Ity_I32);
   4449 
   4450    assign(op1, get_gpr_w1(r1));
   4451    assign(op2, get_gpr_w1(r2));
   4452    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4453 
   4454    return "clr";
   4455 }
   4456 
   4457 static const HChar *
   4458 s390_irgen_CLGR(UChar r1, UChar r2)
   4459 {
   4460    IRTemp op1 = newTemp(Ity_I64);
   4461    IRTemp op2 = newTemp(Ity_I64);
   4462 
   4463    assign(op1, get_gpr_dw0(r1));
   4464    assign(op2, get_gpr_dw0(r2));
   4465    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4466 
   4467    return "clgr";
   4468 }
   4469 
   4470 static const HChar *
   4471 s390_irgen_CLGFR(UChar r1, UChar r2)
   4472 {
   4473    IRTemp op1 = newTemp(Ity_I64);
   4474    IRTemp op2 = newTemp(Ity_I64);
   4475 
   4476    assign(op1, get_gpr_dw0(r1));
   4477    assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
   4478    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4479 
   4480    return "clgfr";
   4481 }
   4482 
   4483 static const HChar *
   4484 s390_irgen_CL(UChar r1, IRTemp op2addr)
   4485 {
   4486    IRTemp op1 = newTemp(Ity_I32);
   4487    IRTemp op2 = newTemp(Ity_I32);
   4488 
   4489    assign(op1, get_gpr_w1(r1));
   4490    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   4491    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4492 
   4493    return "cl";
   4494 }
   4495 
   4496 static const HChar *
   4497 s390_irgen_CLY(UChar r1, IRTemp op2addr)
   4498 {
   4499    IRTemp op1 = newTemp(Ity_I32);
   4500    IRTemp op2 = newTemp(Ity_I32);
   4501 
   4502    assign(op1, get_gpr_w1(r1));
   4503    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   4504    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4505 
   4506    return "cly";
   4507 }
   4508 
   4509 static const HChar *
   4510 s390_irgen_CLG(UChar r1, IRTemp op2addr)
   4511 {
   4512    IRTemp op1 = newTemp(Ity_I64);
   4513    IRTemp op2 = newTemp(Ity_I64);
   4514 
   4515    assign(op1, get_gpr_dw0(r1));
   4516    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   4517    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4518 
   4519    return "clg";
   4520 }
   4521 
   4522 static const HChar *
   4523 s390_irgen_CLGF(UChar r1, IRTemp op2addr)
   4524 {
   4525    IRTemp op1 = newTemp(Ity_I64);
   4526    IRTemp op2 = newTemp(Ity_I64);
   4527 
   4528    assign(op1, get_gpr_dw0(r1));
   4529    assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
   4530    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4531 
   4532    return "clgf";
   4533 }
   4534 
   4535 static const HChar *
   4536 s390_irgen_CLFI(UChar r1, UInt i2)
   4537 {
   4538    IRTemp op1 = newTemp(Ity_I32);
   4539    UInt op2;
   4540 
   4541    assign(op1, get_gpr_w1(r1));
   4542    op2 = i2;
   4543    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
   4544                        mkU32(op2)));
   4545 
   4546    return "clfi";
   4547 }
   4548 
   4549 static const HChar *
   4550 s390_irgen_CLGFI(UChar r1, UInt i2)
   4551 {
   4552    IRTemp op1 = newTemp(Ity_I64);
   4553    ULong op2;
   4554 
   4555    assign(op1, get_gpr_dw0(r1));
   4556    op2 = (ULong)i2;
   4557    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
   4558                        mkU64(op2)));
   4559 
   4560    return "clgfi";
   4561 }
   4562 
   4563 static const HChar *
   4564 s390_irgen_CLI(UChar i2, IRTemp op1addr)
   4565 {
   4566    IRTemp op1 = newTemp(Ity_I8);
   4567    UChar op2;
   4568 
   4569    assign(op1, load(Ity_I8, mkexpr(op1addr)));
   4570    op2 = i2;
   4571    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
   4572                        mkU8(op2)));
   4573 
   4574    return "cli";
   4575 }
   4576 
   4577 static const HChar *
   4578 s390_irgen_CLIY(UChar i2, IRTemp op1addr)
   4579 {
   4580    IRTemp op1 = newTemp(Ity_I8);
   4581    UChar op2;
   4582 
   4583    assign(op1, load(Ity_I8, mkexpr(op1addr)));
   4584    op2 = i2;
   4585    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
   4586                        mkU8(op2)));
   4587 
   4588    return "cliy";
   4589 }
   4590 
   4591 static const HChar *
   4592 s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
   4593 {
   4594    IRTemp op1 = newTemp(Ity_I32);
   4595    UInt op2;
   4596 
   4597    assign(op1, load(Ity_I32, mkexpr(op1addr)));
   4598    op2 = (UInt)i2;
   4599    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
   4600                        mkU32(op2)));
   4601 
   4602    return "clfhsi";
   4603 }
   4604 
   4605 static const HChar *
   4606 s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
   4607 {
   4608    IRTemp op1 = newTemp(Ity_I64);
   4609    ULong op2;
   4610 
   4611    assign(op1, load(Ity_I64, mkexpr(op1addr)));
   4612    op2 = (ULong)i2;
   4613    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
   4614                        mkU64(op2)));
   4615 
   4616    return "clghsi";
   4617 }
   4618 
   4619 static const HChar *
   4620 s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
   4621 {
   4622    IRTemp op1 = newTemp(Ity_I16);
   4623    UShort op2;
   4624 
   4625    assign(op1, load(Ity_I16, mkexpr(op1addr)));
   4626    op2 = i2;
   4627    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
   4628                        mkU16(op2)));
   4629 
   4630    return "clhhsi";
   4631 }
   4632 
   4633 static const HChar *
   4634 s390_irgen_CLRL(UChar r1, UInt i2)
   4635 {
   4636    IRTemp op1 = newTemp(Ity_I32);
   4637    IRTemp op2 = newTemp(Ity_I32);
   4638 
   4639    assign(op1, get_gpr_w1(r1));
   4640    assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
   4641           i2 << 1))));
   4642    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4643 
   4644    return "clrl";
   4645 }
   4646 
   4647 static const HChar *
   4648 s390_irgen_CLGRL(UChar r1, UInt i2)
   4649 {
   4650    IRTemp op1 = newTemp(Ity_I64);
   4651    IRTemp op2 = newTemp(Ity_I64);
   4652 
   4653    assign(op1, get_gpr_dw0(r1));
   4654    assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
   4655           i2 << 1))));
   4656    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4657 
   4658    return "clgrl";
   4659 }
   4660 
   4661 static const HChar *
   4662 s390_irgen_CLGFRL(UChar r1, UInt i2)
   4663 {
   4664    IRTemp op1 = newTemp(Ity_I64);
   4665    IRTemp op2 = newTemp(Ity_I64);
   4666 
   4667    assign(op1, get_gpr_dw0(r1));
   4668    assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
   4669           ((ULong)(Long)(Int)i2 << 1)))));
   4670    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4671 
   4672    return "clgfrl";
   4673 }
   4674 
   4675 static const HChar *
   4676 s390_irgen_CLHRL(UChar r1, UInt i2)
   4677 {
   4678    IRTemp op1 = newTemp(Ity_I32);
   4679    IRTemp op2 = newTemp(Ity_I32);
   4680 
   4681    assign(op1, get_gpr_w1(r1));
   4682    assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
   4683           ((ULong)(Long)(Int)i2 << 1)))));
   4684    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4685 
   4686    return "clhrl";
   4687 }
   4688 
   4689 static const HChar *
   4690 s390_irgen_CLGHRL(UChar r1, UInt i2)
   4691 {
   4692    IRTemp op1 = newTemp(Ity_I64);
   4693    IRTemp op2 = newTemp(Ity_I64);
   4694 
   4695    assign(op1, get_gpr_dw0(r1));
   4696    assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
   4697           ((ULong)(Long)(Int)i2 << 1)))));
   4698    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4699 
   4700    return "clghrl";
   4701 }
   4702 
   4703 static const HChar *
   4704 s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
   4705 {
   4706    IRTemp op1 = newTemp(Ity_I32);
   4707    IRTemp op2 = newTemp(Ity_I32);
   4708    IRTemp cond = newTemp(Ity_I32);
   4709 
   4710    if (m3 == 0) {
   4711    } else {
   4712       if (m3 == 14) {
   4713          always_goto(mkexpr(op4addr));
   4714       } else {
   4715          assign(op1, get_gpr_w1(r1));
   4716          assign(op2, get_gpr_w1(r2));
   4717          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
   4718                                               op1, op2));
   4719          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4720                                     mkexpr(op4addr));
   4721       }
   4722    }
   4723 
   4724    return "clrb";
   4725 }
   4726 
   4727 static const HChar *
   4728 s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
   4729 {
   4730    IRTemp op1 = newTemp(Ity_I64);
   4731    IRTemp op2 = newTemp(Ity_I64);
   4732    IRTemp cond = newTemp(Ity_I32);
   4733 
   4734    if (m3 == 0) {
   4735    } else {
   4736       if (m3 == 14) {
   4737          always_goto(mkexpr(op4addr));
   4738       } else {
   4739          assign(op1, get_gpr_dw0(r1));
   4740          assign(op2, get_gpr_dw0(r2));
   4741          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
   4742                                               op1, op2));
   4743          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4744                                     mkexpr(op4addr));
   4745       }
   4746    }
   4747 
   4748    return "clgrb";
   4749 }
   4750 
   4751 static const HChar *
   4752 s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
   4753 {
   4754    IRTemp op1 = newTemp(Ity_I32);
   4755    IRTemp op2 = newTemp(Ity_I32);
   4756    IRTemp cond = newTemp(Ity_I32);
   4757 
   4758    if (m3 == 0) {
   4759    } else {
   4760       if (m3 == 14) {
   4761          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4762       } else {
   4763          assign(op1, get_gpr_w1(r1));
   4764          assign(op2, get_gpr_w1(r2));
   4765          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
   4766                                               op1, op2));
   4767          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4768                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4769 
   4770       }
   4771    }
   4772 
   4773    return "clrj";
   4774 }
   4775 
   4776 static const HChar *
   4777 s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
   4778 {
   4779    IRTemp op1 = newTemp(Ity_I64);
   4780    IRTemp op2 = newTemp(Ity_I64);
   4781    IRTemp cond = newTemp(Ity_I32);
   4782 
   4783    if (m3 == 0) {
   4784    } else {
   4785       if (m3 == 14) {
   4786          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4787       } else {
   4788          assign(op1, get_gpr_dw0(r1));
   4789          assign(op2, get_gpr_dw0(r2));
   4790          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
   4791                                               op1, op2));
   4792          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4793                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4794 
   4795       }
   4796    }
   4797 
   4798    return "clgrj";
   4799 }
   4800 
   4801 static const HChar *
   4802 s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
   4803 {
   4804    IRTemp op1 = newTemp(Ity_I32);
   4805    UInt op2;
   4806    IRTemp cond = newTemp(Ity_I32);
   4807 
   4808    if (m3 == 0) {
   4809    } else {
   4810       if (m3 == 14) {
   4811          always_goto(mkexpr(op4addr));
   4812       } else {
   4813          assign(op1, get_gpr_w1(r1));
   4814          op2 = (UInt)i2;
   4815          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
   4816                                               mktemp(Ity_I32, mkU32(op2))));
   4817          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4818                                     mkexpr(op4addr));
   4819       }
   4820    }
   4821 
   4822    return "clib";
   4823 }
   4824 
   4825 static const HChar *
   4826 s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
   4827 {
   4828    IRTemp op1 = newTemp(Ity_I64);
   4829    ULong op2;
   4830    IRTemp cond = newTemp(Ity_I32);
   4831 
   4832    if (m3 == 0) {
   4833    } else {
   4834       if (m3 == 14) {
   4835          always_goto(mkexpr(op4addr));
   4836       } else {
   4837          assign(op1, get_gpr_dw0(r1));
   4838          op2 = (ULong)i2;
   4839          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
   4840                                               mktemp(Ity_I64, mkU64(op2))));
   4841          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4842                                     mkexpr(op4addr));
   4843       }
   4844    }
   4845 
   4846    return "clgib";
   4847 }
   4848 
   4849 static const HChar *
   4850 s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
   4851 {
   4852    IRTemp op1 = newTemp(Ity_I32);
   4853    UInt op2;
   4854    IRTemp cond = newTemp(Ity_I32);
   4855 
   4856    if (m3 == 0) {
   4857    } else {
   4858       if (m3 == 14) {
   4859          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4860       } else {
   4861          assign(op1, get_gpr_w1(r1));
   4862          op2 = (UInt)i2;
   4863          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
   4864                                               mktemp(Ity_I32, mkU32(op2))));
   4865          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4866                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4867 
   4868       }
   4869    }
   4870 
   4871    return "clij";
   4872 }
   4873 
   4874 static const HChar *
   4875 s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
   4876 {
   4877    IRTemp op1 = newTemp(Ity_I64);
   4878    ULong op2;
   4879    IRTemp cond = newTemp(Ity_I32);
   4880 
   4881    if (m3 == 0) {
   4882    } else {
   4883       if (m3 == 14) {
   4884          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4885       } else {
   4886          assign(op1, get_gpr_dw0(r1));
   4887          op2 = (ULong)i2;
   4888          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
   4889                                               mktemp(Ity_I64, mkU64(op2))));
   4890          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
   4891                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
   4892 
   4893       }
   4894    }
   4895 
   4896    return "clgij";
   4897 }
   4898 
   4899 static const HChar *
   4900 s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
   4901 {
   4902    IRTemp op1 = newTemp(Ity_I32);
   4903    IRTemp op2 = newTemp(Ity_I32);
   4904    IRTemp b0 = newTemp(Ity_I32);
   4905    IRTemp b1 = newTemp(Ity_I32);
   4906    IRTemp b2 = newTemp(Ity_I32);
   4907    IRTemp b3 = newTemp(Ity_I32);
   4908    IRTemp c0 = newTemp(Ity_I32);
   4909    IRTemp c1 = newTemp(Ity_I32);
   4910    IRTemp c2 = newTemp(Ity_I32);
   4911    IRTemp c3 = newTemp(Ity_I32);
   4912    UChar n;
   4913 
   4914    n = 0;
   4915    if ((r3 & 8) != 0) {
   4916       assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
   4917       assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
   4918       n = n + 1;
   4919    } else {
   4920       assign(b0, mkU32(0));
   4921       assign(c0, mkU32(0));
   4922    }
   4923    if ((r3 & 4) != 0) {
   4924       assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
   4925       assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
   4926              mkU64(n)))));
   4927       n = n + 1;
   4928    } else {
   4929       assign(b1, mkU32(0));
   4930       assign(c1, mkU32(0));
   4931    }
   4932    if ((r3 & 2) != 0) {
   4933       assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
   4934       assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
   4935              mkU64(n)))));
   4936       n = n + 1;
   4937    } else {
   4938       assign(b2, mkU32(0));
   4939       assign(c2, mkU32(0));
   4940    }
   4941    if ((r3 & 1) != 0) {
   4942       assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
   4943       assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
   4944              mkU64(n)))));
   4945       n = n + 1;
   4946    } else {
   4947       assign(b3, mkU32(0));
   4948       assign(c3, mkU32(0));
   4949    }
   4950    assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
   4951           mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
   4952           binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
   4953    assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
   4954           mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
   4955           binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
   4956    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   4957 
   4958    return "clm";
   4959 }
   4960 
   4961 static const HChar *
   4962 s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
   4963 {
   4964    IRTemp op1 = newTemp(Ity_I32);
   4965    IRTemp op2 = newTemp(Ity_I32);
   4966    IRTemp b0 = newTemp(Ity_I32);
   4967    IRTemp b1 = newTemp(Ity_I32);
   4968    IRTemp b2 = newTemp(Ity_I32);
   4969    IRTemp b3 = newTemp(Ity_I32);
   4970    IRTemp c0 = newTemp(Ity_I32);
   4971    IRTemp c1 = newTemp(Ity_I32);
   4972    IRTemp c2 = newTemp(Ity_I32);
   4973    IRTemp c3 = newTemp(Ity_I32);
   4974    UChar n;
   4975 
   4976    n = 0;
   4977    if ((r3 & 8) != 0) {
   4978       assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
   4979       assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
   4980       n = n + 1;
   4981    } else {
   4982       assign(b0, mkU32(0));
   4983       assign(c0, mkU32(0));
   4984    }
   4985    if ((r3 & 4) != 0) {
   4986       assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
   4987       assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
   4988              mkU64(n)))));
   4989       n = n + 1;
   4990    } else {
   4991       assign(b1, mkU32(0));
   4992       assign(c1, mkU32(0));
   4993    }
   4994    if ((r3 & 2) != 0) {
   4995       assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
   4996       assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
   4997              mkU64(n)))));
   4998       n = n + 1;
   4999    } else {
   5000       assign(b2, mkU32(0));
   5001       assign(c2, mkU32(0));
   5002    }
   5003    if ((r3 & 1) != 0) {
   5004       assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
   5005       assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
   5006              mkU64(n)))));
   5007       n = n + 1;
   5008    } else {
   5009       assign(b3, mkU32(0));
   5010       assign(c3, mkU32(0));
   5011    }
   5012    assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
   5013           mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
   5014           binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
   5015    assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
   5016           mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
   5017           binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
   5018    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   5019 
   5020    return "clmy";
   5021 }
   5022 
   5023 static const HChar *
   5024 s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
   5025 {
   5026    IRTemp op1 = newTemp(Ity_I32);
   5027    IRTemp op2 = newTemp(Ity_I32);
   5028    IRTemp b0 = newTemp(Ity_I32);
   5029    IRTemp b1 = newTemp(Ity_I32);
   5030    IRTemp b2 = newTemp(Ity_I32);
   5031    IRTemp b3 = newTemp(Ity_I32);
   5032    IRTemp c0 = newTemp(Ity_I32);
   5033    IRTemp c1 = newTemp(Ity_I32);
   5034    IRTemp c2 = newTemp(Ity_I32);
   5035    IRTemp c3 = newTemp(Ity_I32);
   5036    UChar n;
   5037 
   5038    n = 0;
   5039    if ((r3 & 8) != 0) {
   5040       assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
   5041       assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
   5042       n = n + 1;
   5043    } else {
   5044       assign(b0, mkU32(0));
   5045       assign(c0, mkU32(0));
   5046    }
   5047    if ((r3 & 4) != 0) {
   5048       assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
   5049       assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
   5050              mkU64(n)))));
   5051       n = n + 1;
   5052    } else {
   5053       assign(b1, mkU32(0));
   5054       assign(c1, mkU32(0));
   5055    }
   5056    if ((r3 & 2) != 0) {
   5057       assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
   5058       assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
   5059              mkU64(n)))));
   5060       n = n + 1;
   5061    } else {
   5062       assign(b2, mkU32(0));
   5063       assign(c2, mkU32(0));
   5064    }
   5065    if ((r3 & 1) != 0) {
   5066       assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
   5067       assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
   5068              mkU64(n)))));
   5069       n = n + 1;
   5070    } else {
   5071       assign(b3, mkU32(0));
   5072       assign(c3, mkU32(0));
   5073    }
   5074    assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
   5075           mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
   5076           binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
   5077    assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
   5078           mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
   5079           binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
   5080    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   5081 
   5082    return "clmh";
   5083 }
   5084 
   5085 static const HChar *
   5086 s390_irgen_CLHHR(UChar r1, UChar r2)
   5087 {
   5088    IRTemp op1 = newTemp(Ity_I32);
   5089    IRTemp op2 = newTemp(Ity_I32);
   5090 
   5091    assign(op1, get_gpr_w0(r1));
   5092    assign(op2, get_gpr_w0(r2));
   5093    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   5094 
   5095    return "clhhr";
   5096 }
   5097 
   5098 static const HChar *
   5099 s390_irgen_CLHLR(UChar r1, UChar r2)
   5100 {
   5101    IRTemp op1 = newTemp(Ity_I32);
   5102    IRTemp op2 = newTemp(Ity_I32);
   5103 
   5104    assign(op1, get_gpr_w0(r1));
   5105    assign(op2, get_gpr_w1(r2));
   5106    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   5107 
   5108    return "clhlr";
   5109 }
   5110 
   5111 static const HChar *
   5112 s390_irgen_CLHF(UChar r1, IRTemp op2addr)
   5113 {
   5114    IRTemp op1 = newTemp(Ity_I32);
   5115    IRTemp op2 = newTemp(Ity_I32);
   5116 
   5117    assign(op1, get_gpr_w0(r1));
   5118    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   5119    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
   5120 
   5121    return "clhf";
   5122 }
   5123 
   5124 static const HChar *
   5125 s390_irgen_CLIH(UChar r1, UInt i2)
   5126 {
   5127    IRTemp op1 = newTemp(Ity_I32);
   5128    UInt op2;
   5129 
   5130    assign(op1, get_gpr_w0(r1));
   5131    op2 = i2;
   5132    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
   5133                        mkU32(op2)));
   5134 
   5135    return "clih";
   5136 }
   5137 
   5138 static const HChar *
   5139 s390_irgen_CPYA(UChar r1, UChar r2)
   5140 {
   5141    put_ar_w0(r1, get_ar_w0(r2));
   5142    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   5143       s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
   5144 
   5145    return "cpya";
   5146 }
   5147 
   5148 static const HChar *
   5149 s390_irgen_XR(UChar r1, UChar r2)
   5150 {
   5151    IRTemp op1 = newTemp(Ity_I32);
   5152    IRTemp op2 = newTemp(Ity_I32);
   5153    IRTemp result = newTemp(Ity_I32);
   5154 
   5155    if (r1 == r2) {
   5156       assign(result, mkU32(0));
   5157    } else {
   5158       assign(op1, get_gpr_w1(r1));
   5159       assign(op2, get_gpr_w1(r2));
   5160       assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
   5161    }
   5162    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5163    put_gpr_w1(r1, mkexpr(result));
   5164 
   5165    return "xr";
   5166 }
   5167 
   5168 static const HChar *
   5169 s390_irgen_XGR(UChar r1, UChar r2)
   5170 {
   5171    IRTemp op1 = newTemp(Ity_I64);
   5172    IRTemp op2 = newTemp(Ity_I64);
   5173    IRTemp result = newTemp(Ity_I64);
   5174 
   5175    if (r1 == r2) {
   5176       assign(result, mkU64(0));
   5177    } else {
   5178       assign(op1, get_gpr_dw0(r1));
   5179       assign(op2, get_gpr_dw0(r2));
   5180       assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
   5181    }
   5182    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5183    put_gpr_dw0(r1, mkexpr(result));
   5184 
   5185    return "xgr";
   5186 }
   5187 
   5188 static const HChar *
   5189 s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
   5190 {
   5191    IRTemp op2 = newTemp(Ity_I32);
   5192    IRTemp op3 = newTemp(Ity_I32);
   5193    IRTemp result = newTemp(Ity_I32);
   5194 
   5195    assign(op2, get_gpr_w1(r2));
   5196    assign(op3, get_gpr_w1(r3));
   5197    assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
   5198    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5199    put_gpr_w1(r1, mkexpr(result));
   5200 
   5201    return "xrk";
   5202 }
   5203 
   5204 static const HChar *
   5205 s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
   5206 {
   5207    IRTemp op2 = newTemp(Ity_I64);
   5208    IRTemp op3 = newTemp(Ity_I64);
   5209    IRTemp result = newTemp(Ity_I64);
   5210 
   5211    assign(op2, get_gpr_dw0(r2));
   5212    assign(op3, get_gpr_dw0(r3));
   5213    assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
   5214    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5215    put_gpr_dw0(r1, mkexpr(result));
   5216 
   5217    return "xgrk";
   5218 }
   5219 
   5220 static const HChar *
   5221 s390_irgen_X(UChar r1, IRTemp op2addr)
   5222 {
   5223    IRTemp op1 = newTemp(Ity_I32);
   5224    IRTemp op2 = newTemp(Ity_I32);
   5225    IRTemp result = newTemp(Ity_I32);
   5226 
   5227    assign(op1, get_gpr_w1(r1));
   5228    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   5229    assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
   5230    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5231    put_gpr_w1(r1, mkexpr(result));
   5232 
   5233    return "x";
   5234 }
   5235 
   5236 static const HChar *
   5237 s390_irgen_XY(UChar r1, IRTemp op2addr)
   5238 {
   5239    IRTemp op1 = newTemp(Ity_I32);
   5240    IRTemp op2 = newTemp(Ity_I32);
   5241    IRTemp result = newTemp(Ity_I32);
   5242 
   5243    assign(op1, get_gpr_w1(r1));
   5244    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   5245    assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
   5246    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5247    put_gpr_w1(r1, mkexpr(result));
   5248 
   5249    return "xy";
   5250 }
   5251 
   5252 static const HChar *
   5253 s390_irgen_XG(UChar r1, IRTemp op2addr)
   5254 {
   5255    IRTemp op1 = newTemp(Ity_I64);
   5256    IRTemp op2 = newTemp(Ity_I64);
   5257    IRTemp result = newTemp(Ity_I64);
   5258 
   5259    assign(op1, get_gpr_dw0(r1));
   5260    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   5261    assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
   5262    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5263    put_gpr_dw0(r1, mkexpr(result));
   5264 
   5265    return "xg";
   5266 }
   5267 
   5268 static const HChar *
   5269 s390_irgen_XI(UChar i2, IRTemp op1addr)
   5270 {
   5271    IRTemp op1 = newTemp(Ity_I8);
   5272    UChar op2;
   5273    IRTemp result = newTemp(Ity_I8);
   5274 
   5275    assign(op1, load(Ity_I8, mkexpr(op1addr)));
   5276    op2 = i2;
   5277    assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
   5278    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5279    store(mkexpr(op1addr), mkexpr(result));
   5280 
   5281    return "xi";
   5282 }
   5283 
   5284 static const HChar *
   5285 s390_irgen_XIY(UChar i2, IRTemp op1addr)
   5286 {
   5287    IRTemp op1 = newTemp(Ity_I8);
   5288    UChar op2;
   5289    IRTemp result = newTemp(Ity_I8);
   5290 
   5291    assign(op1, load(Ity_I8, mkexpr(op1addr)));
   5292    op2 = i2;
   5293    assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
   5294    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5295    store(mkexpr(op1addr), mkexpr(result));
   5296 
   5297    return "xiy";
   5298 }
   5299 
   5300 static const HChar *
   5301 s390_irgen_XIHF(UChar r1, UInt i2)
   5302 {
   5303    IRTemp op1 = newTemp(Ity_I32);
   5304    UInt op2;
   5305    IRTemp result = newTemp(Ity_I32);
   5306 
   5307    assign(op1, get_gpr_w0(r1));
   5308    op2 = i2;
   5309    assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
   5310    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5311    put_gpr_w0(r1, mkexpr(result));
   5312 
   5313    return "xihf";
   5314 }
   5315 
   5316 static const HChar *
   5317 s390_irgen_XILF(UChar r1, UInt i2)
   5318 {
   5319    IRTemp op1 = newTemp(Ity_I32);
   5320    UInt op2;
   5321    IRTemp result = newTemp(Ity_I32);
   5322 
   5323    assign(op1, get_gpr_w1(r1));
   5324    op2 = i2;
   5325    assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
   5326    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5327    put_gpr_w1(r1, mkexpr(result));
   5328 
   5329    return "xilf";
   5330 }
   5331 
   5332 static const HChar *
   5333 s390_irgen_EAR(UChar r1, UChar r2)
   5334 {
   5335    put_gpr_w1(r1, get_ar_w0(r2));
   5336    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   5337       s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
   5338 
   5339    return "ear";
   5340 }
   5341 
   5342 static const HChar *
   5343 s390_irgen_IC(UChar r1, IRTemp op2addr)
   5344 {
   5345    put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
   5346 
   5347    return "ic";
   5348 }
   5349 
   5350 static const HChar *
   5351 s390_irgen_ICY(UChar r1, IRTemp op2addr)
   5352 {
   5353    put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
   5354 
   5355    return "icy";
   5356 }
   5357 
   5358 static const HChar *
   5359 s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
   5360 {
   5361    UChar n;
   5362    IRTemp result = newTemp(Ity_I32);
   5363    UInt mask;
   5364 
   5365    n = 0;
   5366    mask = (UInt)r3;
   5367    if ((mask & 8) != 0) {
   5368       put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
   5369       n = n + 1;
   5370    }
   5371    if ((mask & 4) != 0) {
   5372       put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
   5373 
   5374       n = n + 1;
   5375    }
   5376    if ((mask & 2) != 0) {
   5377       put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
   5378 
   5379       n = n + 1;
   5380    }
   5381    if ((mask & 1) != 0) {
   5382       put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
   5383 
   5384       n = n + 1;
   5385    }
   5386    assign(result, get_gpr_w1(r1));
   5387    s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
   5388                        mkU32(mask)));
   5389 
   5390    return "icm";
   5391 }
   5392 
   5393 static const HChar *
   5394 s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
   5395 {
   5396    UChar n;
   5397    IRTemp result = newTemp(Ity_I32);
   5398    UInt mask;
   5399 
   5400    n = 0;
   5401    mask = (UInt)r3;
   5402    if ((mask & 8) != 0) {
   5403       put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
   5404       n = n + 1;
   5405    }
   5406    if ((mask & 4) != 0) {
   5407       put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
   5408 
   5409       n = n + 1;
   5410    }
   5411    if ((mask & 2) != 0) {
   5412       put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
   5413 
   5414       n = n + 1;
   5415    }
   5416    if ((mask & 1) != 0) {
   5417       put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
   5418 
   5419       n = n + 1;
   5420    }
   5421    assign(result, get_gpr_w1(r1));
   5422    s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
   5423                        mkU32(mask)));
   5424 
   5425    return "icmy";
   5426 }
   5427 
   5428 static const HChar *
   5429 s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
   5430 {
   5431    UChar n;
   5432    IRTemp result = newTemp(Ity_I32);
   5433    UInt mask;
   5434 
   5435    n = 0;
   5436    mask = (UInt)r3;
   5437    if ((mask & 8) != 0) {
   5438       put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
   5439       n = n + 1;
   5440    }
   5441    if ((mask & 4) != 0) {
   5442       put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
   5443 
   5444       n = n + 1;
   5445    }
   5446    if ((mask & 2) != 0) {
   5447       put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
   5448 
   5449       n = n + 1;
   5450    }
   5451    if ((mask & 1) != 0) {
   5452       put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
   5453 
   5454       n = n + 1;
   5455    }
   5456    assign(result, get_gpr_w0(r1));
   5457    s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
   5458                        mkU32(mask)));
   5459 
   5460    return "icmh";
   5461 }
   5462 
   5463 static const HChar *
   5464 s390_irgen_IIHF(UChar r1, UInt i2)
   5465 {
   5466    put_gpr_w0(r1, mkU32(i2));
   5467 
   5468    return "iihf";
   5469 }
   5470 
   5471 static const HChar *
   5472 s390_irgen_IIHH(UChar r1, UShort i2)
   5473 {
   5474    put_gpr_hw0(r1, mkU16(i2));
   5475 
   5476    return "iihh";
   5477 }
   5478 
   5479 static const HChar *
   5480 s390_irgen_IIHL(UChar r1, UShort i2)
   5481 {
   5482    put_gpr_hw1(r1, mkU16(i2));
   5483 
   5484    return "iihl";
   5485 }
   5486 
   5487 static const HChar *
   5488 s390_irgen_IILF(UChar r1, UInt i2)
   5489 {
   5490    put_gpr_w1(r1, mkU32(i2));
   5491 
   5492    return "iilf";
   5493 }
   5494 
   5495 static const HChar *
   5496 s390_irgen_IILH(UChar r1, UShort i2)
   5497 {
   5498    put_gpr_hw2(r1, mkU16(i2));
   5499 
   5500    return "iilh";
   5501 }
   5502 
   5503 static const HChar *
   5504 s390_irgen_IILL(UChar r1, UShort i2)
   5505 {
   5506    put_gpr_hw3(r1, mkU16(i2));
   5507 
   5508    return "iill";
   5509 }
   5510 
   5511 static const HChar *
   5512 s390_irgen_LR(UChar r1, UChar r2)
   5513 {
   5514    put_gpr_w1(r1, get_gpr_w1(r2));
   5515 
   5516    return "lr";
   5517 }
   5518 
   5519 static const HChar *
   5520 s390_irgen_LGR(UChar r1, UChar r2)
   5521 {
   5522    put_gpr_dw0(r1, get_gpr_dw0(r2));
   5523 
   5524    return "lgr";
   5525 }
   5526 
   5527 static const HChar *
   5528 s390_irgen_LGFR(UChar r1, UChar r2)
   5529 {
   5530    put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
   5531 
   5532    return "lgfr";
   5533 }
   5534 
   5535 static const HChar *
   5536 s390_irgen_L(UChar r1, IRTemp op2addr)
   5537 {
   5538    put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
   5539 
   5540    return "l";
   5541 }
   5542 
   5543 static const HChar *
   5544 s390_irgen_LY(UChar r1, IRTemp op2addr)
   5545 {
   5546    put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
   5547 
   5548    return "ly";
   5549 }
   5550 
   5551 static const HChar *
   5552 s390_irgen_LG(UChar r1, IRTemp op2addr)
   5553 {
   5554    put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
   5555 
   5556    return "lg";
   5557 }
   5558 
   5559 static const HChar *
   5560 s390_irgen_LGF(UChar r1, IRTemp op2addr)
   5561 {
   5562    put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
   5563 
   5564    return "lgf";
   5565 }
   5566 
   5567 static const HChar *
   5568 s390_irgen_LGFI(UChar r1, UInt i2)
   5569 {
   5570    put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
   5571 
   5572    return "lgfi";
   5573 }
   5574 
   5575 static const HChar *
   5576 s390_irgen_LRL(UChar r1, UInt i2)
   5577 {
   5578    put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
   5579               i2 << 1))));
   5580 
   5581    return "lrl";
   5582 }
   5583 
   5584 static const HChar *
   5585 s390_irgen_LGRL(UChar r1, UInt i2)
   5586 {
   5587    put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
   5588                i2 << 1))));
   5589 
   5590    return "lgrl";
   5591 }
   5592 
   5593 static const HChar *
   5594 s390_irgen_LGFRL(UChar r1, UInt i2)
   5595 {
   5596    put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
   5597                ((ULong)(Long)(Int)i2 << 1)))));
   5598 
   5599    return "lgfrl";
   5600 }
   5601 
   5602 static const HChar *
   5603 s390_irgen_LA(UChar r1, IRTemp op2addr)
   5604 {
   5605    put_gpr_dw0(r1, mkexpr(op2addr));
   5606 
   5607    return "la";
   5608 }
   5609 
   5610 static const HChar *
   5611 s390_irgen_LAY(UChar r1, IRTemp op2addr)
   5612 {
   5613    put_gpr_dw0(r1, mkexpr(op2addr));
   5614 
   5615    return "lay";
   5616 }
   5617 
   5618 static const HChar *
   5619 s390_irgen_LAE(UChar r1, IRTemp op2addr)
   5620 {
   5621    put_gpr_dw0(r1, mkexpr(op2addr));
   5622 
   5623    return "lae";
   5624 }
   5625 
   5626 static const HChar *
   5627 s390_irgen_LAEY(UChar r1, IRTemp op2addr)
   5628 {
   5629    put_gpr_dw0(r1, mkexpr(op2addr));
   5630 
   5631    return "laey";
   5632 }
   5633 
   5634 static const HChar *
   5635 s390_irgen_LARL(UChar r1, UInt i2)
   5636 {
   5637    put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
   5638 
   5639    return "larl";
   5640 }
   5641 
   5642 /* The IR representation of LAA and friends is an approximation of what
   5643    happens natively. Essentially a loop containing a compare-and-swap is
   5644    constructed which will iterate until the CAS succeeds. As a consequence,
   5645    instrumenters may see more memory accesses than happen natively. See also
   5646    discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
   5647 static void
   5648 s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
   5649 {
   5650    IRCAS *cas;
   5651    IRTemp old_mem = newTemp(Ity_I32);
   5652    IRTemp op2 = newTemp(Ity_I32);
   5653    IRTemp op3 = newTemp(Ity_I32);
   5654    IRTemp result = newTemp(Ity_I32);
   5655 
   5656    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   5657    assign(op3, get_gpr_w1(r3));
   5658    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
   5659 
   5660    /* Place the addition of second operand and third operand at the
   5661       second-operand location everytime */
   5662    cas = mkIRCAS(IRTemp_INVALID, old_mem,
   5663                  Iend_BE, mkexpr(op2addr),
   5664                  NULL, mkexpr(op2), /* expected value */
   5665                  NULL, mkexpr(result)  /* new value */);
   5666    stmt(IRStmt_CAS(cas));
   5667 
   5668    /* Set CC according to 32-bit addition */
   5669    if (is_signed) {
   5670       s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
   5671    } else {
   5672       s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
   5673    }
   5674 
   5675    /* If old_mem contains the expected value, then the CAS succeeded.
   5676       Otherwise, it did not */
   5677    yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
   5678    put_gpr_w1(r1, mkexpr(old_mem));
   5679 }
   5680 
   5681 static void
   5682 s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
   5683 {
   5684    IRCAS *cas;
   5685    IRTemp old_mem = newTemp(Ity_I64);
   5686    IRTemp op2 = newTemp(Ity_I64);
   5687    IRTemp op3 = newTemp(Ity_I64);
   5688    IRTemp result = newTemp(Ity_I64);
   5689 
   5690    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   5691    assign(op3, get_gpr_dw0(r3));
   5692    assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
   5693 
   5694    /* Place the addition of second operand and third operand at the
   5695       second-operand location everytime */
   5696    cas = mkIRCAS(IRTemp_INVALID, old_mem,
   5697                  Iend_BE, mkexpr(op2addr),
   5698                  NULL, mkexpr(op2), /* expected value */
   5699                  NULL, mkexpr(result)  /* new value */);
   5700    stmt(IRStmt_CAS(cas));
   5701 
   5702    /* Set CC according to 64-bit addition */
   5703    if (is_signed) {
   5704       s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
   5705    } else {
   5706       s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
   5707    }
   5708 
   5709    /* If old_mem contains the expected value, then the CAS succeeded.
   5710       Otherwise, it did not */
   5711    yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
   5712    put_gpr_dw0(r1, mkexpr(old_mem));
   5713 }
   5714 
   5715 static void
   5716 s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
   5717 {
   5718    IRCAS *cas;
   5719    IRTemp old_mem = newTemp(Ity_I32);
   5720    IRTemp op2 = newTemp(Ity_I32);
   5721    IRTemp op3 = newTemp(Ity_I32);
   5722    IRTemp result = newTemp(Ity_I32);
   5723 
   5724    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   5725    assign(op3, get_gpr_w1(r3));
   5726    assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
   5727 
   5728    /* Place the addition of second operand and third operand at the
   5729       second-operand location everytime */
   5730    cas = mkIRCAS(IRTemp_INVALID, old_mem,
   5731                  Iend_BE, mkexpr(op2addr),
   5732                  NULL, mkexpr(op2), /* expected value */
   5733                  NULL, mkexpr(result)  /* new value */);
   5734    stmt(IRStmt_CAS(cas));
   5735 
   5736    /* Set CC according to bitwise operation */
   5737    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5738 
   5739    /* If old_mem contains the expected value, then the CAS succeeded.
   5740       Otherwise, it did not */
   5741    yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
   5742    put_gpr_w1(r1, mkexpr(old_mem));
   5743 }
   5744 
   5745 static void
   5746 s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
   5747 {
   5748    IRCAS *cas;
   5749    IRTemp old_mem = newTemp(Ity_I64);
   5750    IRTemp op2 = newTemp(Ity_I64);
   5751    IRTemp op3 = newTemp(Ity_I64);
   5752    IRTemp result = newTemp(Ity_I64);
   5753 
   5754    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   5755    assign(op3, get_gpr_dw0(r3));
   5756    assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
   5757 
   5758    /* Place the addition of second operand and third operand at the
   5759       second-operand location everytime */
   5760    cas = mkIRCAS(IRTemp_INVALID, old_mem,
   5761                  Iend_BE, mkexpr(op2addr),
   5762                  NULL, mkexpr(op2), /* expected value */
   5763                  NULL, mkexpr(result)  /* new value */);
   5764    stmt(IRStmt_CAS(cas));
   5765 
   5766    /* Set CC according to bitwise operation */
   5767    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   5768 
   5769    /* If old_mem contains the expected value, then the CAS succeeded.
   5770       Otherwise, it did not */
   5771    yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
   5772    put_gpr_dw0(r1, mkexpr(old_mem));
   5773 }
   5774 
   5775 static const HChar *
   5776 s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
   5777 {
   5778    s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
   5779 
   5780    return "laa";
   5781 }
   5782 
   5783 static const HChar *
   5784 s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
   5785 {
   5786    s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
   5787 
   5788    return "laag";
   5789 }
   5790 
   5791 static const HChar *
   5792 s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
   5793 {
   5794    s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
   5795 
   5796    return "laal";
   5797 }
   5798 
   5799 static const HChar *
   5800 s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
   5801 {
   5802    s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
   5803 
   5804    return "laalg";
   5805 }
   5806 
   5807 static const HChar *
   5808 s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
   5809 {
   5810    s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
   5811 
   5812    return "lan";
   5813 }
   5814 
   5815 static const HChar *
   5816 s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
   5817 {
   5818    s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
   5819 
   5820    return "lang";
   5821 }
   5822 
   5823 static const HChar *
   5824 s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
   5825 {
   5826    s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
   5827 
   5828    return "lax";
   5829 }
   5830 
   5831 static const HChar *
   5832 s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
   5833 {
   5834    s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
   5835 
   5836    return "laxg";
   5837 }
   5838 
   5839 static const HChar *
   5840 s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
   5841 {
   5842    s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
   5843 
   5844    return "lao";
   5845 }
   5846 
   5847 static const HChar *
   5848 s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
   5849 {
   5850    s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
   5851 
   5852    return "laog";
   5853 }
   5854 
   5855 static const HChar *
   5856 s390_irgen_LTR(UChar r1, UChar r2)
   5857 {
   5858    IRTemp op2 = newTemp(Ity_I32);
   5859 
   5860    assign(op2, get_gpr_w1(r2));
   5861    put_gpr_w1(r1, mkexpr(op2));
   5862    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
   5863 
   5864    return "ltr";
   5865 }
   5866 
   5867 static const HChar *
   5868 s390_irgen_LTGR(UChar r1, UChar r2)
   5869 {
   5870    IRTemp op2 = newTemp(Ity_I64);
   5871 
   5872    assign(op2, get_gpr_dw0(r2));
   5873    put_gpr_dw0(r1, mkexpr(op2));
   5874    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
   5875 
   5876    return "ltgr";
   5877 }
   5878 
   5879 static const HChar *
   5880 s390_irgen_LTGFR(UChar r1, UChar r2)
   5881 {
   5882    IRTemp op2 = newTemp(Ity_I64);
   5883 
   5884    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
   5885    put_gpr_dw0(r1, mkexpr(op2));
   5886    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
   5887 
   5888    return "ltgfr";
   5889 }
   5890 
   5891 static const HChar *
   5892 s390_irgen_LT(UChar r1, IRTemp op2addr)
   5893 {
   5894    IRTemp op2 = newTemp(Ity_I32);
   5895 
   5896    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   5897    put_gpr_w1(r1, mkexpr(op2));
   5898    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
   5899 
   5900    return "lt";
   5901 }
   5902 
   5903 static const HChar *
   5904 s390_irgen_LTG(UChar r1, IRTemp op2addr)
   5905 {
   5906    IRTemp op2 = newTemp(Ity_I64);
   5907 
   5908    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   5909    put_gpr_dw0(r1, mkexpr(op2));
   5910    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
   5911 
   5912    return "ltg";
   5913 }
   5914 
   5915 static const HChar *
   5916 s390_irgen_LTGF(UChar r1, IRTemp op2addr)
   5917 {
   5918    IRTemp op2 = newTemp(Ity_I64);
   5919 
   5920    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
   5921    put_gpr_dw0(r1, mkexpr(op2));
   5922    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
   5923 
   5924    return "ltgf";
   5925 }
   5926 
   5927 static const HChar *
   5928 s390_irgen_LBR(UChar r1, UChar r2)
   5929 {
   5930    put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
   5931 
   5932    return "lbr";
   5933 }
   5934 
   5935 static const HChar *
   5936 s390_irgen_LGBR(UChar r1, UChar r2)
   5937 {
   5938    put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
   5939 
   5940    return "lgbr";
   5941 }
   5942 
   5943 static const HChar *
   5944 s390_irgen_LB(UChar r1, IRTemp op2addr)
   5945 {
   5946    put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
   5947 
   5948    return "lb";
   5949 }
   5950 
   5951 static const HChar *
   5952 s390_irgen_LGB(UChar r1, IRTemp op2addr)
   5953 {
   5954    put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
   5955 
   5956    return "lgb";
   5957 }
   5958 
   5959 static const HChar *
   5960 s390_irgen_LBH(UChar r1, IRTemp op2addr)
   5961 {
   5962    put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
   5963 
   5964    return "lbh";
   5965 }
   5966 
   5967 static const HChar *
   5968 s390_irgen_LCR(UChar r1, UChar r2)
   5969 {
   5970    Int op1;
   5971    IRTemp op2 = newTemp(Ity_I32);
   5972    IRTemp result = newTemp(Ity_I32);
   5973 
   5974    op1 = 0;
   5975    assign(op2, get_gpr_w1(r2));
   5976    assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
   5977    put_gpr_w1(r1, mkexpr(result));
   5978    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
   5979                        op1)), op2);
   5980 
   5981    return "lcr";
   5982 }
   5983 
   5984 static const HChar *
   5985 s390_irgen_LCGR(UChar r1, UChar r2)
   5986 {
   5987    Long op1;
   5988    IRTemp op2 = newTemp(Ity_I64);
   5989    IRTemp result = newTemp(Ity_I64);
   5990 
   5991    op1 = 0ULL;
   5992    assign(op2, get_gpr_dw0(r2));
   5993    assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
   5994    put_gpr_dw0(r1, mkexpr(result));
   5995    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
   5996                        op1)), op2);
   5997 
   5998    return "lcgr";
   5999 }
   6000 
   6001 static const HChar *
   6002 s390_irgen_LCGFR(UChar r1, UChar r2)
   6003 {
   6004    Long op1;
   6005    IRTemp op2 = newTemp(Ity_I64);
   6006    IRTemp result = newTemp(Ity_I64);
   6007 
   6008    op1 = 0ULL;
   6009    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
   6010    assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
   6011    put_gpr_dw0(r1, mkexpr(result));
   6012    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
   6013                        op1)), op2);
   6014 
   6015    return "lcgfr";
   6016 }
   6017 
   6018 static const HChar *
   6019 s390_irgen_LHR(UChar r1, UChar r2)
   6020 {
   6021    put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
   6022 
   6023    return "lhr";
   6024 }
   6025 
   6026 static const HChar *
   6027 s390_irgen_LGHR(UChar r1, UChar r2)
   6028 {
   6029    put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
   6030 
   6031    return "lghr";
   6032 }
   6033 
   6034 static const HChar *
   6035 s390_irgen_LH(UChar r1, IRTemp op2addr)
   6036 {
   6037    put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
   6038 
   6039    return "lh";
   6040 }
   6041 
   6042 static const HChar *
   6043 s390_irgen_LHY(UChar r1, IRTemp op2addr)
   6044 {
   6045    put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
   6046 
   6047    return "lhy";
   6048 }
   6049 
   6050 static const HChar *
   6051 s390_irgen_LGH(UChar r1, IRTemp op2addr)
   6052 {
   6053    put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
   6054 
   6055    return "lgh";
   6056 }
   6057 
   6058 static const HChar *
   6059 s390_irgen_LHI(UChar r1, UShort i2)
   6060 {
   6061    put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
   6062 
   6063    return "lhi";
   6064 }
   6065 
   6066 static const HChar *
   6067 s390_irgen_LGHI(UChar r1, UShort i2)
   6068 {
   6069    put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
   6070 
   6071    return "lghi";
   6072 }
   6073 
   6074 static const HChar *
   6075 s390_irgen_LHRL(UChar r1, UInt i2)
   6076 {
   6077    put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
   6078               ((ULong)(Long)(Int)i2 << 1)))));
   6079 
   6080    return "lhrl";
   6081 }
   6082 
   6083 static const HChar *
   6084 s390_irgen_LGHRL(UChar r1, UInt i2)
   6085 {
   6086    put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
   6087                ((ULong)(Long)(Int)i2 << 1)))));
   6088 
   6089    return "lghrl";
   6090 }
   6091 
   6092 static const HChar *
   6093 s390_irgen_LHH(UChar r1, IRTemp op2addr)
   6094 {
   6095    put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
   6096 
   6097    return "lhh";
   6098 }
   6099 
   6100 static const HChar *
   6101 s390_irgen_LFH(UChar r1, IRTemp op2addr)
   6102 {
   6103    put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
   6104 
   6105    return "lfh";
   6106 }
   6107 
   6108 static const HChar *
   6109 s390_irgen_LLGFR(UChar r1, UChar r2)
   6110 {
   6111    put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
   6112 
   6113    return "llgfr";
   6114 }
   6115 
   6116 static const HChar *
   6117 s390_irgen_LLGF(UChar r1, IRTemp op2addr)
   6118 {
   6119    put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
   6120 
   6121    return "llgf";
   6122 }
   6123 
   6124 static const HChar *
   6125 s390_irgen_LLGFRL(UChar r1, UInt i2)
   6126 {
   6127    put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
   6128                ((ULong)(Long)(Int)i2 << 1)))));
   6129 
   6130    return "llgfrl";
   6131 }
   6132 
   6133 static const HChar *
   6134 s390_irgen_LLCR(UChar r1, UChar r2)
   6135 {
   6136    put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
   6137 
   6138    return "llcr";
   6139 }
   6140 
   6141 static const HChar *
   6142 s390_irgen_LLGCR(UChar r1, UChar r2)
   6143 {
   6144    put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
   6145 
   6146    return "llgcr";
   6147 }
   6148 
   6149 static const HChar *
   6150 s390_irgen_LLC(UChar r1, IRTemp op2addr)
   6151 {
   6152    put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
   6153 
   6154    return "llc";
   6155 }
   6156 
   6157 static const HChar *
   6158 s390_irgen_LLGC(UChar r1, IRTemp op2addr)
   6159 {
   6160    put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
   6161 
   6162    return "llgc";
   6163 }
   6164 
   6165 static const HChar *
   6166 s390_irgen_LLCH(UChar r1, IRTemp op2addr)
   6167 {
   6168    put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
   6169 
   6170    return "llch";
   6171 }
   6172 
   6173 static const HChar *
   6174 s390_irgen_LLHR(UChar r1, UChar r2)
   6175 {
   6176    put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
   6177 
   6178    return "llhr";
   6179 }
   6180 
   6181 static const HChar *
   6182 s390_irgen_LLGHR(UChar r1, UChar r2)
   6183 {
   6184    put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
   6185 
   6186    return "llghr";
   6187 }
   6188 
   6189 static const HChar *
   6190 s390_irgen_LLH(UChar r1, IRTemp op2addr)
   6191 {
   6192    put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
   6193 
   6194    return "llh";
   6195 }
   6196 
   6197 static const HChar *
   6198 s390_irgen_LLGH(UChar r1, IRTemp op2addr)
   6199 {
   6200    put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
   6201 
   6202    return "llgh";
   6203 }
   6204 
   6205 static const HChar *
   6206 s390_irgen_LLHRL(UChar r1, UInt i2)
   6207 {
   6208    put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
   6209               ((ULong)(Long)(Int)i2 << 1)))));
   6210 
   6211    return "llhrl";
   6212 }
   6213 
   6214 static const HChar *
   6215 s390_irgen_LLGHRL(UChar r1, UInt i2)
   6216 {
   6217    put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
   6218                ((ULong)(Long)(Int)i2 << 1)))));
   6219 
   6220    return "llghrl";
   6221 }
   6222 
   6223 static const HChar *
   6224 s390_irgen_LLHH(UChar r1, IRTemp op2addr)
   6225 {
   6226    put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
   6227 
   6228    return "llhh";
   6229 }
   6230 
   6231 static const HChar *
   6232 s390_irgen_LLIHF(UChar r1, UInt i2)
   6233 {
   6234    put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
   6235 
   6236    return "llihf";
   6237 }
   6238 
   6239 static const HChar *
   6240 s390_irgen_LLIHH(UChar r1, UShort i2)
   6241 {
   6242    put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
   6243 
   6244    return "llihh";
   6245 }
   6246 
   6247 static const HChar *
   6248 s390_irgen_LLIHL(UChar r1, UShort i2)
   6249 {
   6250    put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
   6251 
   6252    return "llihl";
   6253 }
   6254 
   6255 static const HChar *
   6256 s390_irgen_LLILF(UChar r1, UInt i2)
   6257 {
   6258    put_gpr_dw0(r1, mkU64(i2));
   6259 
   6260    return "llilf";
   6261 }
   6262 
   6263 static const HChar *
   6264 s390_irgen_LLILH(UChar r1, UShort i2)
   6265 {
   6266    put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
   6267 
   6268    return "llilh";
   6269 }
   6270 
   6271 static const HChar *
   6272 s390_irgen_LLILL(UChar r1, UShort i2)
   6273 {
   6274    put_gpr_dw0(r1, mkU64(i2));
   6275 
   6276    return "llill";
   6277 }
   6278 
   6279 static const HChar *
   6280 s390_irgen_LLGTR(UChar r1, UChar r2)
   6281 {
   6282    put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
   6283                mkU32(2147483647))));
   6284 
   6285    return "llgtr";
   6286 }
   6287 
   6288 static const HChar *
   6289 s390_irgen_LLGT(UChar r1, IRTemp op2addr)
   6290 {
   6291    put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
   6292                mkexpr(op2addr)), mkU32(2147483647))));
   6293 
   6294    return "llgt";
   6295 }
   6296 
   6297 static const HChar *
   6298 s390_irgen_LNR(UChar r1, UChar r2)
   6299 {
   6300    IRTemp op2 = newTemp(Ity_I32);
   6301    IRTemp result = newTemp(Ity_I32);
   6302 
   6303    assign(op2, get_gpr_w1(r2));
   6304    assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
   6305           binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
   6306    put_gpr_w1(r1, mkexpr(result));
   6307    s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
   6308 
   6309    return "lnr";
   6310 }
   6311 
   6312 static const HChar *
   6313 s390_irgen_LNGR(UChar r1, UChar r2)
   6314 {
   6315    IRTemp op2 = newTemp(Ity_I64);
   6316    IRTemp result = newTemp(Ity_I64);
   6317 
   6318    assign(op2, get_gpr_dw0(r2));
   6319    assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
   6320           binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
   6321    put_gpr_dw0(r1, mkexpr(result));
   6322    s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
   6323 
   6324    return "lngr";
   6325 }
   6326 
   6327 static const HChar *
   6328 s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
   6329 {
   6330    IRTemp op2 = newTemp(Ity_I64);
   6331    IRTemp result = newTemp(Ity_I64);
   6332 
   6333    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
   6334    assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
   6335           binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
   6336    put_gpr_dw0(r1, mkexpr(result));
   6337    s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
   6338 
   6339    return "lngfr";
   6340 }
   6341 
   6342 static const HChar *
   6343 s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
   6344 {
   6345    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
   6346    put_gpr_w1(r1, get_gpr_w1(r2));
   6347 
   6348    return "locr";
   6349 }
   6350 
   6351 static const HChar *
   6352 s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
   6353 {
   6354    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
   6355    put_gpr_dw0(r1, get_gpr_dw0(r2));
   6356 
   6357    return "locgr";
   6358 }
   6359 
   6360 static const HChar *
   6361 s390_irgen_LOC(UChar r1, IRTemp op2addr)
   6362 {
   6363    /* condition is checked in format handler */
   6364    put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
   6365 
   6366    return "loc";
   6367 }
   6368 
   6369 static const HChar *
   6370 s390_irgen_LOCG(UChar r1, IRTemp op2addr)
   6371 {
   6372    /* condition is checked in format handler */
   6373    put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
   6374 
   6375    return "locg";
   6376 }
   6377 
   6378 static const HChar *
   6379 s390_irgen_LPQ(UChar r1, IRTemp op2addr)
   6380 {
   6381    put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
   6382    put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
   6383                ));
   6384 
   6385    return "lpq";
   6386 }
   6387 
   6388 static const HChar *
   6389 s390_irgen_LPR(UChar r1, UChar r2)
   6390 {
   6391    IRTemp op2 = newTemp(Ity_I32);
   6392    IRTemp result = newTemp(Ity_I32);
   6393 
   6394    assign(op2, get_gpr_w1(r2));
   6395    assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
   6396           binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
   6397    put_gpr_w1(r1, mkexpr(result));
   6398    s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
   6399 
   6400    return "lpr";
   6401 }
   6402 
   6403 static const HChar *
   6404 s390_irgen_LPGR(UChar r1, UChar r2)
   6405 {
   6406    IRTemp op2 = newTemp(Ity_I64);
   6407    IRTemp result = newTemp(Ity_I64);
   6408 
   6409    assign(op2, get_gpr_dw0(r2));
   6410    assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
   6411           binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
   6412    put_gpr_dw0(r1, mkexpr(result));
   6413    s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
   6414 
   6415    return "lpgr";
   6416 }
   6417 
   6418 static const HChar *
   6419 s390_irgen_LPGFR(UChar r1, UChar r2)
   6420 {
   6421    IRTemp op2 = newTemp(Ity_I64);
   6422    IRTemp result = newTemp(Ity_I64);
   6423 
   6424    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
   6425    assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
   6426           binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
   6427    put_gpr_dw0(r1, mkexpr(result));
   6428    s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
   6429 
   6430    return "lpgfr";
   6431 }
   6432 
   6433 static const HChar *
   6434 s390_irgen_LRVR(UChar r1, UChar r2)
   6435 {
   6436    IRTemp b0 = newTemp(Ity_I8);
   6437    IRTemp b1 = newTemp(Ity_I8);
   6438    IRTemp b2 = newTemp(Ity_I8);
   6439    IRTemp b3 = newTemp(Ity_I8);
   6440 
   6441    assign(b3, get_gpr_b7(r2));
   6442    assign(b2, get_gpr_b6(r2));
   6443    assign(b1, get_gpr_b5(r2));
   6444    assign(b0, get_gpr_b4(r2));
   6445    put_gpr_b4(r1, mkexpr(b3));
   6446    put_gpr_b5(r1, mkexpr(b2));
   6447    put_gpr_b6(r1, mkexpr(b1));
   6448    put_gpr_b7(r1, mkexpr(b0));
   6449 
   6450    return "lrvr";
   6451 }
   6452 
   6453 static const HChar *
   6454 s390_irgen_LRVGR(UChar r1, UChar r2)
   6455 {
   6456    IRTemp b0 = newTemp(Ity_I8);
   6457    IRTemp b1 = newTemp(Ity_I8);
   6458    IRTemp b2 = newTemp(Ity_I8);
   6459    IRTemp b3 = newTemp(Ity_I8);
   6460    IRTemp b4 = newTemp(Ity_I8);
   6461    IRTemp b5 = newTemp(Ity_I8);
   6462    IRTemp b6 = newTemp(Ity_I8);
   6463    IRTemp b7 = newTemp(Ity_I8);
   6464 
   6465    assign(b7, get_gpr_b7(r2));
   6466    assign(b6, get_gpr_b6(r2));
   6467    assign(b5, get_gpr_b5(r2));
   6468    assign(b4, get_gpr_b4(r2));
   6469    assign(b3, get_gpr_b3(r2));
   6470    assign(b2, get_gpr_b2(r2));
   6471    assign(b1, get_gpr_b1(r2));
   6472    assign(b0, get_gpr_b0(r2));
   6473    put_gpr_b0(r1, mkexpr(b7));
   6474    put_gpr_b1(r1, mkexpr(b6));
   6475    put_gpr_b2(r1, mkexpr(b5));
   6476    put_gpr_b3(r1, mkexpr(b4));
   6477    put_gpr_b4(r1, mkexpr(b3));
   6478    put_gpr_b5(r1, mkexpr(b2));
   6479    put_gpr_b6(r1, mkexpr(b1));
   6480    put_gpr_b7(r1, mkexpr(b0));
   6481 
   6482    return "lrvgr";
   6483 }
   6484 
   6485 static const HChar *
   6486 s390_irgen_LRVH(UChar r1, IRTemp op2addr)
   6487 {
   6488    IRTemp op2 = newTemp(Ity_I16);
   6489 
   6490    assign(op2, load(Ity_I16, mkexpr(op2addr)));
   6491    put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
   6492    put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
   6493 
   6494    return "lrvh";
   6495 }
   6496 
   6497 static const HChar *
   6498 s390_irgen_LRV(UChar r1, IRTemp op2addr)
   6499 {
   6500    IRTemp op2 = newTemp(Ity_I32);
   6501 
   6502    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   6503    put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
   6504    put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
   6505               mkU8(8)), mkU32(255))));
   6506    put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
   6507               mkU8(16)), mkU32(255))));
   6508    put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
   6509               mkU8(24)), mkU32(255))));
   6510 
   6511    return "lrv";
   6512 }
   6513 
   6514 static const HChar *
   6515 s390_irgen_LRVG(UChar r1, IRTemp op2addr)
   6516 {
   6517    IRTemp op2 = newTemp(Ity_I64);
   6518 
   6519    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   6520    put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
   6521    put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
   6522               mkU8(8)), mkU64(255))));
   6523    put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
   6524               mkU8(16)), mkU64(255))));
   6525    put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
   6526               mkU8(24)), mkU64(255))));
   6527    put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
   6528               mkU8(32)), mkU64(255))));
   6529    put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
   6530               mkU8(40)), mkU64(255))));
   6531    put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
   6532               mkU8(48)), mkU64(255))));
   6533    put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
   6534               mkU8(56)), mkU64(255))));
   6535 
   6536    return "lrvg";
   6537 }
   6538 
   6539 static const HChar *
   6540 s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
   6541 {
   6542    store(mkexpr(op1addr), mkU16(i2));
   6543 
   6544    return "mvhhi";
   6545 }
   6546 
   6547 static const HChar *
   6548 s390_irgen_MVHI(UShort i2, IRTemp op1addr)
   6549 {
   6550    store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
   6551 
   6552    return "mvhi";
   6553 }
   6554 
   6555 static const HChar *
   6556 s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
   6557 {
   6558    store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
   6559 
   6560    return "mvghi";
   6561 }
   6562 
   6563 static const HChar *
   6564 s390_irgen_MVI(UChar i2, IRTemp op1addr)
   6565 {
   6566    store(mkexpr(op1addr), mkU8(i2));
   6567 
   6568    return "mvi";
   6569 }
   6570 
   6571 static const HChar *
   6572 s390_irgen_MVIY(UChar i2, IRTemp op1addr)
   6573 {
   6574    store(mkexpr(op1addr), mkU8(i2));
   6575 
   6576    return "mviy";
   6577 }
   6578 
   6579 static const HChar *
   6580 s390_irgen_MR(UChar r1, UChar r2)
   6581 {
   6582    IRTemp op1 = newTemp(Ity_I32);
   6583    IRTemp op2 = newTemp(Ity_I32);
   6584    IRTemp result = newTemp(Ity_I64);
   6585 
   6586    assign(op1, get_gpr_w1(r1 + 1));
   6587    assign(op2, get_gpr_w1(r2));
   6588    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
   6589    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
   6590    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
   6591 
   6592    return "mr";
   6593 }
   6594 
   6595 static const HChar *
   6596 s390_irgen_M(UChar r1, IRTemp op2addr)
   6597 {
   6598    IRTemp op1 = newTemp(Ity_I32);
   6599    IRTemp op2 = newTemp(Ity_I32);
   6600    IRTemp result = newTemp(Ity_I64);
   6601 
   6602    assign(op1, get_gpr_w1(r1 + 1));
   6603    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   6604    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
   6605    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
   6606    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
   6607 
   6608    return "m";
   6609 }
   6610 
   6611 static const HChar *
   6612 s390_irgen_MFY(UChar r1, IRTemp op2addr)
   6613 {
   6614    IRTemp op1 = newTemp(Ity_I32);
   6615    IRTemp op2 = newTemp(Ity_I32);
   6616    IRTemp result = newTemp(Ity_I64);
   6617 
   6618    assign(op1, get_gpr_w1(r1 + 1));
   6619    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   6620    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
   6621    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
   6622    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
   6623 
   6624    return "mfy";
   6625 }
   6626 
   6627 static const HChar *
   6628 s390_irgen_MH(UChar r1, IRTemp op2addr)
   6629 {
   6630    IRTemp op1 = newTemp(Ity_I32);
   6631    IRTemp op2 = newTemp(Ity_I16);
   6632    IRTemp result = newTemp(Ity_I64);
   6633 
   6634    assign(op1, get_gpr_w1(r1));
   6635    assign(op2, load(Ity_I16, mkexpr(op2addr)));
   6636    assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
   6637           ));
   6638    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
   6639 
   6640    return "mh";
   6641 }
   6642 
   6643 static const HChar *
   6644 s390_irgen_MHY(UChar r1, IRTemp op2addr)
   6645 {
   6646    IRTemp op1 = newTemp(Ity_I32);
   6647    IRTemp op2 = newTemp(Ity_I16);
   6648    IRTemp result = newTemp(Ity_I64);
   6649 
   6650    assign(op1, get_gpr_w1(r1));
   6651    assign(op2, load(Ity_I16, mkexpr(op2addr)));
   6652    assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
   6653           ));
   6654    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
   6655 
   6656    return "mhy";
   6657 }
   6658 
   6659 static const HChar *
   6660 s390_irgen_MHI(UChar r1, UShort i2)
   6661 {
   6662    IRTemp op1 = newTemp(Ity_I32);
   6663    Short op2;
   6664    IRTemp result = newTemp(Ity_I64);
   6665 
   6666    assign(op1, get_gpr_w1(r1));
   6667    op2 = (Short)i2;
   6668    assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
   6669           mkU16((UShort)op2))));
   6670    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
   6671 
   6672    return "mhi";
   6673 }
   6674 
   6675 static const HChar *
   6676 s390_irgen_MGHI(UChar r1, UShort i2)
   6677 {
   6678    IRTemp op1 = newTemp(Ity_I64);
   6679    Short op2;
   6680    IRTemp result = newTemp(Ity_I128);
   6681 
   6682    assign(op1, get_gpr_dw0(r1));
   6683    op2 = (Short)i2;
   6684    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
   6685           mkU16((UShort)op2))));
   6686    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
   6687 
   6688    return "mghi";
   6689 }
   6690 
   6691 static const HChar *
   6692 s390_irgen_MLR(UChar r1, UChar r2)
   6693 {
   6694    IRTemp op1 = newTemp(Ity_I32);
   6695    IRTemp op2 = newTemp(Ity_I32);
   6696    IRTemp result = newTemp(Ity_I64);
   6697 
   6698    assign(op1, get_gpr_w1(r1 + 1));
   6699    assign(op2, get_gpr_w1(r2));
   6700    assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
   6701    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
   6702    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
   6703 
   6704    return "mlr";
   6705 }
   6706 
   6707 static const HChar *
   6708 s390_irgen_MLGR(UChar r1, UChar r2)
   6709 {
   6710    IRTemp op1 = newTemp(Ity_I64);
   6711    IRTemp op2 = newTemp(Ity_I64);
   6712    IRTemp result = newTemp(Ity_I128);
   6713 
   6714    assign(op1, get_gpr_dw0(r1 + 1));
   6715    assign(op2, get_gpr_dw0(r2));
   6716    assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
   6717    put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
   6718    put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
   6719 
   6720    return "mlgr";
   6721 }
   6722 
   6723 static const HChar *
   6724 s390_irgen_ML(UChar r1, IRTemp op2addr)
   6725 {
   6726    IRTemp op1 = newTemp(Ity_I32);
   6727    IRTemp op2 = newTemp(Ity_I32);
   6728    IRTemp result = newTemp(Ity_I64);
   6729 
   6730    assign(op1, get_gpr_w1(r1 + 1));
   6731    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   6732    assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
   6733    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
   6734    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
   6735 
   6736    return "ml";
   6737 }
   6738 
   6739 static const HChar *
   6740 s390_irgen_MLG(UChar r1, IRTemp op2addr)
   6741 {
   6742    IRTemp op1 = newTemp(Ity_I64);
   6743    IRTemp op2 = newTemp(Ity_I64);
   6744    IRTemp result = newTemp(Ity_I128);
   6745 
   6746    assign(op1, get_gpr_dw0(r1 + 1));
   6747    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   6748    assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
   6749    put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
   6750    put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
   6751 
   6752    return "mlg";
   6753 }
   6754 
   6755 static const HChar *
   6756 s390_irgen_MSR(UChar r1, UChar r2)
   6757 {
   6758    IRTemp op1 = newTemp(Ity_I32);
   6759    IRTemp op2 = newTemp(Ity_I32);
   6760    IRTemp result = newTemp(Ity_I64);
   6761 
   6762    assign(op1, get_gpr_w1(r1));
   6763    assign(op2, get_gpr_w1(r2));
   6764    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
   6765    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
   6766 
   6767    return "msr";
   6768 }
   6769 
   6770 static const HChar *
   6771 s390_irgen_MSGR(UChar r1, UChar r2)
   6772 {
   6773    IRTemp op1 = newTemp(Ity_I64);
   6774    IRTemp op2 = newTemp(Ity_I64);
   6775    IRTemp result = newTemp(Ity_I128);
   6776 
   6777    assign(op1, get_gpr_dw0(r1));
   6778    assign(op2, get_gpr_dw0(r2));
   6779    assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
   6780    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
   6781 
   6782    return "msgr";
   6783 }
   6784 
   6785 static const HChar *
   6786 s390_irgen_MSGFR(UChar r1, UChar r2)
   6787 {
   6788    IRTemp op1 = newTemp(Ity_I64);
   6789    IRTemp op2 = newTemp(Ity_I32);
   6790    IRTemp result = newTemp(Ity_I128);
   6791 
   6792    assign(op1, get_gpr_dw0(r1));
   6793    assign(op2, get_gpr_w1(r2));
   6794    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
   6795           ));
   6796    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
   6797 
   6798    return "msgfr";
   6799 }
   6800 
   6801 static const HChar *
   6802 s390_irgen_MS(UChar r1, IRTemp op2addr)
   6803 {
   6804    IRTemp op1 = newTemp(Ity_I32);
   6805    IRTemp op2 = newTemp(Ity_I32);
   6806    IRTemp result = newTemp(Ity_I64);
   6807 
   6808    assign(op1, get_gpr_w1(r1));
   6809    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   6810    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
   6811    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
   6812 
   6813    return "ms";
   6814 }
   6815 
   6816 static const HChar *
   6817 s390_irgen_MSY(UChar r1, IRTemp op2addr)
   6818 {
   6819    IRTemp op1 = newTemp(Ity_I32);
   6820    IRTemp op2 = newTemp(Ity_I32);
   6821    IRTemp result = newTemp(Ity_I64);
   6822 
   6823    assign(op1, get_gpr_w1(r1));
   6824    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   6825    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
   6826    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
   6827 
   6828    return "msy";
   6829 }
   6830 
   6831 static const HChar *
   6832 s390_irgen_MSG(UChar r1, IRTemp op2addr)
   6833 {
   6834    IRTemp op1 = newTemp(Ity_I64);
   6835    IRTemp op2 = newTemp(Ity_I64);
   6836    IRTemp result = newTemp(Ity_I128);
   6837 
   6838    assign(op1, get_gpr_dw0(r1));
   6839    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   6840    assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
   6841    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
   6842 
   6843    return "msg";
   6844 }
   6845 
   6846 static const HChar *
   6847 s390_irgen_MSGF(UChar r1, IRTemp op2addr)
   6848 {
   6849    IRTemp op1 = newTemp(Ity_I64);
   6850    IRTemp op2 = newTemp(Ity_I32);
   6851    IRTemp result = newTemp(Ity_I128);
   6852 
   6853    assign(op1, get_gpr_dw0(r1));
   6854    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   6855    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
   6856           ));
   6857    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
   6858 
   6859    return "msgf";
   6860 }
   6861 
   6862 static const HChar *
   6863 s390_irgen_MSFI(UChar r1, UInt i2)
   6864 {
   6865    IRTemp op1 = newTemp(Ity_I32);
   6866    Int op2;
   6867    IRTemp result = newTemp(Ity_I64);
   6868 
   6869    assign(op1, get_gpr_w1(r1));
   6870    op2 = (Int)i2;
   6871    assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
   6872    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
   6873 
   6874    return "msfi";
   6875 }
   6876 
   6877 static const HChar *
   6878 s390_irgen_MSGFI(UChar r1, UInt i2)
   6879 {
   6880    IRTemp op1 = newTemp(Ity_I64);
   6881    Int op2;
   6882    IRTemp result = newTemp(Ity_I128);
   6883 
   6884    assign(op1, get_gpr_dw0(r1));
   6885    op2 = (Int)i2;
   6886    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
   6887           op2))));
   6888    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
   6889 
   6890    return "msgfi";
   6891 }
   6892 
   6893 static const HChar *
   6894 s390_irgen_OR(UChar r1, UChar r2)
   6895 {
   6896    IRTemp op1 = newTemp(Ity_I32);
   6897    IRTemp op2 = newTemp(Ity_I32);
   6898    IRTemp result = newTemp(Ity_I32);
   6899 
   6900    assign(op1, get_gpr_w1(r1));
   6901    assign(op2, get_gpr_w1(r2));
   6902    assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
   6903    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   6904    put_gpr_w1(r1, mkexpr(result));
   6905 
   6906    return "or";
   6907 }
   6908 
   6909 static const HChar *
   6910 s390_irgen_OGR(UChar r1, UChar r2)
   6911 {
   6912    IRTemp op1 = newTemp(Ity_I64);
   6913    IRTemp op2 = newTemp(Ity_I64);
   6914    IRTemp result = newTemp(Ity_I64);
   6915 
   6916    assign(op1, get_gpr_dw0(r1));
   6917    assign(op2, get_gpr_dw0(r2));
   6918    assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
   6919    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   6920    put_gpr_dw0(r1, mkexpr(result));
   6921 
   6922    return "ogr";
   6923 }
   6924 
   6925 static const HChar *
   6926 s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
   6927 {
   6928    IRTemp op2 = newTemp(Ity_I32);
   6929    IRTemp op3 = newTemp(Ity_I32);
   6930    IRTemp result = newTemp(Ity_I32);
   6931 
   6932    assign(op2, get_gpr_w1(r2));
   6933    assign(op3, get_gpr_w1(r3));
   6934    assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
   6935    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   6936    put_gpr_w1(r1, mkexpr(result));
   6937 
   6938    return "ork";
   6939 }
   6940 
   6941 static const HChar *
   6942 s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
   6943 {
   6944    IRTemp op2 = newTemp(Ity_I64);
   6945    IRTemp op3 = newTemp(Ity_I64);
   6946    IRTemp result = newTemp(Ity_I64);
   6947 
   6948    assign(op2, get_gpr_dw0(r2));
   6949    assign(op3, get_gpr_dw0(r3));
   6950    assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
   6951    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   6952    put_gpr_dw0(r1, mkexpr(result));
   6953 
   6954    return "ogrk";
   6955 }
   6956 
   6957 static const HChar *
   6958 s390_irgen_O(UChar r1, IRTemp op2addr)
   6959 {
   6960    IRTemp op1 = newTemp(Ity_I32);
   6961    IRTemp op2 = newTemp(Ity_I32);
   6962    IRTemp result = newTemp(Ity_I32);
   6963 
   6964    assign(op1, get_gpr_w1(r1));
   6965    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   6966    assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
   6967    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   6968    put_gpr_w1(r1, mkexpr(result));
   6969 
   6970    return "o";
   6971 }
   6972 
   6973 static const HChar *
   6974 s390_irgen_OY(UChar r1, IRTemp op2addr)
   6975 {
   6976    IRTemp op1 = newTemp(Ity_I32);
   6977    IRTemp op2 = newTemp(Ity_I32);
   6978    IRTemp result = newTemp(Ity_I32);
   6979 
   6980    assign(op1, get_gpr_w1(r1));
   6981    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   6982    assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
   6983    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   6984    put_gpr_w1(r1, mkexpr(result));
   6985 
   6986    return "oy";
   6987 }
   6988 
   6989 static const HChar *
   6990 s390_irgen_OG(UChar r1, IRTemp op2addr)
   6991 {
   6992    IRTemp op1 = newTemp(Ity_I64);
   6993    IRTemp op2 = newTemp(Ity_I64);
   6994    IRTemp result = newTemp(Ity_I64);
   6995 
   6996    assign(op1, get_gpr_dw0(r1));
   6997    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   6998    assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
   6999    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   7000    put_gpr_dw0(r1, mkexpr(result));
   7001 
   7002    return "og";
   7003 }
   7004 
   7005 static const HChar *
   7006 s390_irgen_OI(UChar i2, IRTemp op1addr)
   7007 {
   7008    IRTemp op1 = newTemp(Ity_I8);
   7009    UChar op2;
   7010    IRTemp result = newTemp(Ity_I8);
   7011 
   7012    assign(op1, load(Ity_I8, mkexpr(op1addr)));
   7013    op2 = i2;
   7014    assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
   7015    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   7016    store(mkexpr(op1addr), mkexpr(result));
   7017 
   7018    return "oi";
   7019 }
   7020 
   7021 static const HChar *
   7022 s390_irgen_OIY(UChar i2, IRTemp op1addr)
   7023 {
   7024    IRTemp op1 = newTemp(Ity_I8);
   7025    UChar op2;
   7026    IRTemp result = newTemp(Ity_I8);
   7027 
   7028    assign(op1, load(Ity_I8, mkexpr(op1addr)));
   7029    op2 = i2;
   7030    assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
   7031    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   7032    store(mkexpr(op1addr), mkexpr(result));
   7033 
   7034    return "oiy";
   7035 }
   7036 
   7037 static const HChar *
   7038 s390_irgen_OIHF(UChar r1, UInt i2)
   7039 {
   7040    IRTemp op1 = newTemp(Ity_I32);
   7041    UInt op2;
   7042    IRTemp result = newTemp(Ity_I32);
   7043 
   7044    assign(op1, get_gpr_w0(r1));
   7045    op2 = i2;
   7046    assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
   7047    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   7048    put_gpr_w0(r1, mkexpr(result));
   7049 
   7050    return "oihf";
   7051 }
   7052 
   7053 static const HChar *
   7054 s390_irgen_OIHH(UChar r1, UShort i2)
   7055 {
   7056    IRTemp op1 = newTemp(Ity_I16);
   7057    UShort op2;
   7058    IRTemp result = newTemp(Ity_I16);
   7059 
   7060    assign(op1, get_gpr_hw0(r1));
   7061    op2 = i2;
   7062    assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
   7063    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   7064    put_gpr_hw0(r1, mkexpr(result));
   7065 
   7066    return "oihh";
   7067 }
   7068 
   7069 static const HChar *
   7070 s390_irgen_OIHL(UChar r1, UShort i2)
   7071 {
   7072    IRTemp op1 = newTemp(Ity_I16);
   7073    UShort op2;
   7074    IRTemp result = newTemp(Ity_I16);
   7075 
   7076    assign(op1, get_gpr_hw1(r1));
   7077    op2 = i2;
   7078    assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
   7079    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   7080    put_gpr_hw1(r1, mkexpr(result));
   7081 
   7082    return "oihl";
   7083 }
   7084 
   7085 static const HChar *
   7086 s390_irgen_OILF(UChar r1, UInt i2)
   7087 {
   7088    IRTemp op1 = newTemp(Ity_I32);
   7089    UInt op2;
   7090    IRTemp result = newTemp(Ity_I32);
   7091 
   7092    assign(op1, get_gpr_w1(r1));
   7093    op2 = i2;
   7094    assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
   7095    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   7096    put_gpr_w1(r1, mkexpr(result));
   7097 
   7098    return "oilf";
   7099 }
   7100 
   7101 static const HChar *
   7102 s390_irgen_OILH(UChar r1, UShort i2)
   7103 {
   7104    IRTemp op1 = newTemp(Ity_I16);
   7105    UShort op2;
   7106    IRTemp result = newTemp(Ity_I16);
   7107 
   7108    assign(op1, get_gpr_hw2(r1));
   7109    op2 = i2;
   7110    assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
   7111    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   7112    put_gpr_hw2(r1, mkexpr(result));
   7113 
   7114    return "oilh";
   7115 }
   7116 
   7117 static const HChar *
   7118 s390_irgen_OILL(UChar r1, UShort i2)
   7119 {
   7120    IRTemp op1 = newTemp(Ity_I16);
   7121    UShort op2;
   7122    IRTemp result = newTemp(Ity_I16);
   7123 
   7124    assign(op1, get_gpr_hw3(r1));
   7125    op2 = i2;
   7126    assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
   7127    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   7128    put_gpr_hw3(r1, mkexpr(result));
   7129 
   7130    return "oill";
   7131 }
   7132 
   7133 static const HChar *
   7134 s390_irgen_PFD(void)
   7135 {
   7136 
   7137    return "pfd";
   7138 }
   7139 
   7140 static const HChar *
   7141 s390_irgen_PFDRL(void)
   7142 {
   7143 
   7144    return "pfdrl";
   7145 }
   7146 
   7147 static IRExpr *
   7148 get_rounding_mode_from_gr0(void)
   7149 {
   7150    IRTemp rm_bits = newTemp(Ity_I32);
   7151    IRExpr *s390rm;
   7152    IRExpr *irrm;
   7153 
   7154    /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
   7155       when PFPO insn is called. So, extract the bits at [60:63] */
   7156    assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
   7157    s390rm = mkexpr(rm_bits);
   7158    irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
   7159             mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
   7160             mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
   7161               mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
   7162               mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
   7163                 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
   7164                 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
   7165                   mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
   7166                   mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
   7167                     mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
   7168                     mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
   7169                       mkexpr(encode_dfp_rounding_mode(
   7170                                S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
   7171                       mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
   7172                         mkexpr(encode_dfp_rounding_mode(
   7173                                  S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
   7174                         mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
   7175                           mkexpr(encode_dfp_rounding_mode(
   7176                                    S390_DFP_ROUND_AWAY_0)),
   7177                           mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
   7178                             mkexpr(encode_dfp_rounding_mode(
   7179                                      S390_DFP_ROUND_PREPARE_SHORT_15)),
   7180                                 /* if rounding mode is 0 or invalid (2-7)
   7181                                    set S390_DFP_ROUND_PER_FPC_0 */
   7182                             mkexpr(encode_dfp_rounding_mode(
   7183                                      S390_DFP_ROUND_PER_FPC_0)))))))))));
   7184 
   7185    return irrm;
   7186 }
   7187 
   7188 static IRExpr *
   7189 s390_call_pfpo_helper(IRExpr *gr0)
   7190 {
   7191    IRExpr **args, *call;
   7192 
   7193    args = mkIRExprVec_1(gr0);
   7194    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
   7195                         "s390_do_pfpo", &s390_do_pfpo, args);
   7196    /* Nothing is excluded from definedness checking. */
   7197    call->Iex.CCall.cee->mcx_mask = 0;
   7198 
   7199    return call;
   7200 }
   7201 
   7202 static const HChar *
   7203 s390_irgen_PFPO(void)
   7204 {
   7205    IRTemp gr0 = newTemp(Ity_I32);     /* word 1 [32:63] of GR 0 */
   7206    IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
   7207    IRTemp fn = newTemp(Ity_I32);       /* [33:55] of GR 0 - function code */
   7208    IRTemp ef = newTemp(Ity_I32);       /* Emulation Failure */
   7209    IRTemp src1 = newTemp(Ity_F32);
   7210    IRTemp dst1 = newTemp(Ity_D32);
   7211    IRTemp src2 = newTemp(Ity_F32);
   7212    IRTemp dst2 = newTemp(Ity_D64);
   7213    IRTemp src3 = newTemp(Ity_F32);
   7214    IRTemp dst3 = newTemp(Ity_D128);
   7215    IRTemp src4 = newTemp(Ity_F64);
   7216    IRTemp dst4 = newTemp(Ity_D32);
   7217    IRTemp src5 = newTemp(Ity_F64);
   7218    IRTemp dst5 = newTemp(Ity_D64);
   7219    IRTemp src6 = newTemp(Ity_F64);
   7220    IRTemp dst6 = newTemp(Ity_D128);
   7221    IRTemp src7 = newTemp(Ity_F128);
   7222    IRTemp dst7 = newTemp(Ity_D32);
   7223    IRTemp src8 = newTemp(Ity_F128);
   7224    IRTemp dst8 = newTemp(Ity_D64);
   7225    IRTemp src9 = newTemp(Ity_F128);
   7226    IRTemp dst9 = newTemp(Ity_D128);
   7227    IRTemp src10 = newTemp(Ity_D32);
   7228    IRTemp dst10 = newTemp(Ity_F32);
   7229    IRTemp src11 = newTemp(Ity_D32);
   7230    IRTemp dst11 = newTemp(Ity_F64);
   7231    IRTemp src12 = newTemp(Ity_D32);
   7232    IRTemp dst12 = newTemp(Ity_F128);
   7233    IRTemp src13 = newTemp(Ity_D64);
   7234    IRTemp dst13 = newTemp(Ity_F32);
   7235    IRTemp src14 = newTemp(Ity_D64);
   7236    IRTemp dst14 = newTemp(Ity_F64);
   7237    IRTemp src15 = newTemp(Ity_D64);
   7238    IRTemp dst15 = newTemp(Ity_F128);
   7239    IRTemp src16 = newTemp(Ity_D128);
   7240    IRTemp dst16 = newTemp(Ity_F32);
   7241    IRTemp src17 = newTemp(Ity_D128);
   7242    IRTemp dst17 = newTemp(Ity_F64);
   7243    IRTemp src18 = newTemp(Ity_D128);
   7244    IRTemp dst18 = newTemp(Ity_F128);
   7245    IRExpr *irrm;
   7246 
   7247    if (! s390_host_has_pfpo) {
   7248       emulation_failure(EmFail_S390X_pfpo);
   7249       goto done;
   7250    }
   7251 
   7252    assign(gr0, get_gpr_w1(0));
   7253    /* get function code */
   7254    assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
   7255                     mkU32(0x7fffff)));
   7256    /* get validity test bit */
   7257    assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
   7258                           mkU32(0x1)));
   7259    irrm = get_rounding_mode_from_gr0();
   7260 
   7261    /* test_bit is 1 */
   7262    assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
   7263    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
   7264 
   7265    /* Return code set in GR1 is usually 0. Non-zero value is set only
   7266       when exceptions are raised. See Programming Notes point 5 in the
   7267       instrcution description of pfpo in POP. Since valgrind does not
   7268       model exception, it might be safe to just set 0 to GR 1. */
   7269    put_gpr_w1(1, mkU32(0x0));
   7270    next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
   7271 
   7272    /* Check validity of function code in GR 0 */
   7273    assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
   7274    emulation_failure_with_expr(mkexpr(ef));
   7275 
   7276    stmt(
   7277         IRStmt_Exit(
   7278                     binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
   7279                     Ijk_EmFail,
   7280                     IRConst_U64(guest_IA_next_instr),
   7281                     S390X_GUEST_OFFSET(guest_IA)
   7282                     )
   7283         );
   7284 
   7285    /* F32 -> D32 */
   7286    /* get source from FPR 4,6 - already set in src1 */
   7287    assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
   7288    put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
   7289    put_gpr_w1(1, mkU32(0x0));
   7290    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
   7291    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
   7292 
   7293    /* F32 -> D64 */
   7294    assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
   7295    assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
   7296    put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
   7297    put_gpr_w1(1, mkU32(0x0));
   7298    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
   7299    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
   7300 
   7301    /* F32 -> D128 */
   7302    assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
   7303    assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
   7304    put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
   7305    put_gpr_w1(1, mkU32(0x0));
   7306    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
   7307    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
   7308 
   7309    /* F64 -> D32 */
   7310    assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
   7311    assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
   7312    put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
   7313    put_gpr_w1(1, mkU32(0x0));
   7314    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
   7315    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
   7316 
   7317    /* F64 -> D64 */
   7318    assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
   7319    assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
   7320    put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
   7321    put_gpr_w1(1, mkU32(0x0));
   7322    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
   7323    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
   7324 
   7325    /* F64 -> D128 */
   7326    assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
   7327    assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
   7328    put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
   7329    put_gpr_w1(1, mkU32(0x0));
   7330    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
   7331    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
   7332 
   7333    /* F128 -> D32 */
   7334    assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
   7335    assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
   7336    put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
   7337    put_gpr_w1(1, mkU32(0x0));
   7338    s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
   7339    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
   7340 
   7341    /* F128 -> D64 */
   7342    assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
   7343    assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
   7344    put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
   7345    put_gpr_w1(1, mkU32(0x0));
   7346    s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
   7347    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
   7348 
   7349    /* F128 -> D128 */
   7350    assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
   7351    assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
   7352    put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
   7353    put_gpr_w1(1, mkU32(0x0));
   7354    s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
   7355    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
   7356 
   7357    /* D32 -> F32 */
   7358    assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
   7359    assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
   7360    put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
   7361    put_gpr_w1(1, mkU32(0x0));
   7362    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
   7363    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
   7364 
   7365    /* D32 -> F64 */
   7366    assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
   7367    assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
   7368    put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
   7369    put_gpr_w1(1, mkU32(0x0));
   7370    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
   7371    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
   7372 
   7373    /* D32 -> F128 */
   7374    assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
   7375    assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
   7376    put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
   7377    put_gpr_w1(1, mkU32(0x0));
   7378    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
   7379    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
   7380 
   7381    /* D64 -> F32 */
   7382    assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
   7383    assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
   7384    put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
   7385    put_gpr_w1(1, mkU32(0x0));
   7386    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
   7387    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
   7388 
   7389    /* D64 -> F64 */
   7390    assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
   7391    assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
   7392    put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
   7393    put_gpr_w1(1, mkU32(0x0));
   7394    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
   7395    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
   7396 
   7397    /* D64 -> F128 */
   7398    assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
   7399    assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
   7400    put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
   7401    put_gpr_w1(1, mkU32(0x0));
   7402    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
   7403    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
   7404 
   7405    /* D128 -> F32 */
   7406    assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
   7407    assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
   7408    put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
   7409    put_gpr_w1(1, mkU32(0x0));
   7410    s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
   7411    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
   7412 
   7413    /* D128 -> F64 */
   7414    assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
   7415    assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
   7416    put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
   7417    put_gpr_w1(1, mkU32(0x0));
   7418    s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
   7419    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
   7420 
   7421    /* D128 -> F128 */
   7422    assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
   7423    assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
   7424    put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
   7425    put_gpr_w1(1, mkU32(0x0));
   7426    s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
   7427    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
   7428 
   7429  done:
   7430    return "pfpo";
   7431 }
   7432 
   7433 static const HChar *
   7434 s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
   7435 {
   7436    IRTemp amount = newTemp(Ity_I64);
   7437    IRTemp op = newTemp(Ity_I32);
   7438 
   7439    assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
   7440    assign(op, get_gpr_w1(r3));
   7441    put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
   7442               mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
   7443               binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
   7444 
   7445    return "rll";
   7446 }
   7447 
   7448 static const HChar *
   7449 s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
   7450 {
   7451    IRTemp amount = newTemp(Ity_I64);
   7452    IRTemp op = newTemp(Ity_I64);
   7453 
   7454    assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
   7455    assign(op, get_gpr_dw0(r3));
   7456    put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
   7457                mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
   7458                binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
   7459 
   7460    return "rllg";
   7461 }
   7462 
   7463 static const HChar *
   7464 s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
   7465 {
   7466    UChar from;
   7467    UChar to;
   7468    UChar rot;
   7469    UChar t_bit;
   7470    ULong mask;
   7471    ULong maskc;
   7472    IRTemp result = newTemp(Ity_I64);
   7473    IRTemp op2 = newTemp(Ity_I64);
   7474 
   7475    from = i3 & 63;
   7476    to = i4 & 63;
   7477    rot = i5 & 63;
   7478    t_bit = i3 & 128;
   7479    assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
   7480           get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
   7481           mkU8(64 - rot))));
   7482    if (from <= to) {
   7483       mask = ~0ULL;
   7484       mask = (mask >> from) & (mask << (63 - to));
   7485       maskc = ~mask;
   7486    } else {
   7487       maskc = ~0ULL;
   7488       maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
   7489       mask = ~maskc;
   7490    }
   7491    assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
   7492           ), mkU64(mask)));
   7493    if (t_bit == 0) {
   7494       put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
   7495                   mkU64(maskc)), mkexpr(result)));
   7496    }
   7497    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   7498 
   7499    return "rnsbg";
   7500 }
   7501 
   7502 static const HChar *
   7503 s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
   7504 {
   7505    UChar from;
   7506    UChar to;
   7507    UChar rot;
   7508    UChar t_bit;
   7509    ULong mask;
   7510    ULong maskc;
   7511    IRTemp result = newTemp(Ity_I64);
   7512    IRTemp op2 = newTemp(Ity_I64);
   7513 
   7514    from = i3 & 63;
   7515    to = i4 & 63;
   7516    rot = i5 & 63;
   7517    t_bit = i3 & 128;
   7518    assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
   7519           get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
   7520           mkU8(64 - rot))));
   7521    if (from <= to) {
   7522       mask = ~0ULL;
   7523       mask = (mask >> from) & (mask << (63 - to));
   7524       maskc = ~mask;
   7525    } else {
   7526       maskc = ~0ULL;
   7527       maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
   7528       mask = ~maskc;
   7529    }
   7530    assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
   7531           ), mkU64(mask)));
   7532    if (t_bit == 0) {
   7533       put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
   7534                   mkU64(maskc)), mkexpr(result)));
   7535    }
   7536    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   7537 
   7538    return "rxsbg";
   7539 }
   7540 
   7541 static const HChar *
   7542 s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
   7543 {
   7544    UChar from;
   7545    UChar to;
   7546    UChar rot;
   7547    UChar t_bit;
   7548    ULong mask;
   7549    ULong maskc;
   7550    IRTemp result = newTemp(Ity_I64);
   7551    IRTemp op2 = newTemp(Ity_I64);
   7552 
   7553    from = i3 & 63;
   7554    to = i4 & 63;
   7555    rot = i5 & 63;
   7556    t_bit = i3 & 128;
   7557    assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
   7558           get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
   7559           mkU8(64 - rot))));
   7560    if (from <= to) {
   7561       mask = ~0ULL;
   7562       mask = (mask >> from) & (mask << (63 - to));
   7563       maskc = ~mask;
   7564    } else {
   7565       maskc = ~0ULL;
   7566       maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
   7567       mask = ~maskc;
   7568    }
   7569    assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
   7570           ), mkU64(mask)));
   7571    if (t_bit == 0) {
   7572       put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
   7573                   mkU64(maskc)), mkexpr(result)));
   7574    }
   7575    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
   7576 
   7577    return "rosbg";
   7578 }
   7579 
   7580 static const HChar *
   7581 s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
   7582 {
   7583    UChar from;
   7584    UChar to;
   7585    UChar rot;
   7586    UChar z_bit;
   7587    ULong mask;
   7588    ULong maskc;
   7589    IRTemp op2 = newTemp(Ity_I64);
   7590    IRTemp result = newTemp(Ity_I64);
   7591 
   7592    from = i3 & 63;
   7593    to = i4 & 63;
   7594    rot = i5 & 63;
   7595    z_bit = i4 & 128;
   7596    assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
   7597           get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
   7598           mkU8(64 - rot))));
   7599    if (from <= to) {
   7600       mask = ~0ULL;
   7601       mask = (mask >> from) & (mask << (63 - to));
   7602       maskc = ~mask;
   7603    } else {
   7604       maskc = ~0ULL;
   7605       maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
   7606       mask = ~maskc;
   7607    }
   7608    if (z_bit == 0) {
   7609       put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
   7610                   mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
   7611    } else {
   7612       put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
   7613    }
   7614    assign(result, get_gpr_dw0(r1));
   7615    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
   7616 
   7617    return "risbg";
   7618 }
   7619 
   7620 static const HChar *
   7621 s390_irgen_SAR(UChar r1, UChar r2)
   7622 {
   7623    put_ar_w0(r1, get_gpr_w1(r2));
   7624    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
   7625       s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
   7626 
   7627    return "sar";
   7628 }
   7629 
   7630 static const HChar *
   7631 s390_irgen_SLDA(UChar r1, IRTemp op2addr)
   7632 {
   7633    IRTemp p1 = newTemp(Ity_I64);
   7634    IRTemp p2 = newTemp(Ity_I64);
   7635    IRTemp op = newTemp(Ity_I64);
   7636    IRTemp result = newTemp(Ity_I64);
   7637    ULong sign_mask;
   7638    IRTemp shift_amount = newTemp(Ity_I64);
   7639 
   7640    assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
   7641    assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
   7642    assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
   7643           ));
   7644    sign_mask = 1ULL << 63;
   7645    assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
   7646    assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
   7647           unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
   7648           binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
   7649    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
   7650    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
   7651    s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
   7652 
   7653    return "slda";
   7654 }
   7655 
   7656 static const HChar *
   7657 s390_irgen_SLDL(UChar r1, IRTemp op2addr)
   7658 {
   7659    IRTemp p1 = newTemp(Ity_I64);
   7660    IRTemp p2 = newTemp(Ity_I64);
   7661    IRTemp result = newTemp(Ity_I64);
   7662 
   7663    assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
   7664    assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
   7665    assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
   7666           mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
   7667           mkexpr(op2addr), mkU64(63)))));
   7668    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
   7669    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
   7670 
   7671    return "sldl";
   7672 }
   7673 
   7674 static const HChar *
   7675 s390_irgen_SLA(UChar r1, IRTemp op2addr)
   7676 {
   7677    IRTemp uop = newTemp(Ity_I32);
   7678    IRTemp result = newTemp(Ity_I32);
   7679    UInt sign_mask;
   7680    IRTemp shift_amount = newTemp(Ity_I64);
   7681    IRTemp op = newTemp(Ity_I32);
   7682 
   7683    assign(op, get_gpr_w1(r1));
   7684    assign(uop, get_gpr_w1(r1));
   7685    sign_mask = 2147483648U;
   7686    assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
   7687    assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
   7688           unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
   7689           binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
   7690    put_gpr_w1(r1, mkexpr(result));
   7691    s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
   7692 
   7693    return "sla";
   7694 }
   7695 
   7696 static const HChar *
   7697 s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
   7698 {
   7699    IRTemp uop = newTemp(Ity_I32);
   7700    IRTemp result = newTemp(Ity_I32);
   7701    UInt sign_mask;
   7702    IRTemp shift_amount = newTemp(Ity_I64);
   7703    IRTemp op = newTemp(Ity_I32);
   7704 
   7705    assign(op, get_gpr_w1(r3));
   7706    assign(uop, get_gpr_w1(r3));
   7707    sign_mask = 2147483648U;
   7708    assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
   7709    assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
   7710           unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
   7711           binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
   7712    put_gpr_w1(r1, mkexpr(result));
   7713    s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
   7714 
   7715    return "slak";
   7716 }
   7717 
   7718 static const HChar *
   7719 s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
   7720 {
   7721    IRTemp uop = newTemp(Ity_I64);
   7722    IRTemp result = newTemp(Ity_I64);
   7723    ULong sign_mask;
   7724    IRTemp shift_amount = newTemp(Ity_I64);
   7725    IRTemp op = newTemp(Ity_I64);
   7726 
   7727    assign(op, get_gpr_dw0(r3));
   7728    assign(uop, get_gpr_dw0(r3));
   7729    sign_mask = 9223372036854775808ULL;
   7730    assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
   7731    assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
   7732           unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
   7733           binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
   7734    put_gpr_dw0(r1, mkexpr(result));
   7735    s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
   7736 
   7737    return "slag";
   7738 }
   7739 
   7740 static const HChar *
   7741 s390_irgen_SLL(UChar r1, IRTemp op2addr)
   7742 {
   7743    put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
   7744               binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
   7745 
   7746    return "sll";
   7747 }
   7748 
   7749 static const HChar *
   7750 s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
   7751 {
   7752    put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
   7753               binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
   7754 
   7755    return "sllk";
   7756 }
   7757 
   7758 static const HChar *
   7759 s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
   7760 {
   7761    put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
   7762                binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
   7763 
   7764    return "sllg";
   7765 }
   7766 
   7767 static const HChar *
   7768 s390_irgen_SRDA(UChar r1, IRTemp op2addr)
   7769 {
   7770    IRTemp p1 = newTemp(Ity_I64);
   7771    IRTemp p2 = newTemp(Ity_I64);
   7772    IRTemp result = newTemp(Ity_I64);
   7773 
   7774    assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
   7775    assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
   7776    assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
   7777           mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
   7778           mkexpr(op2addr), mkU64(63)))));
   7779    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
   7780    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
   7781    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
   7782 
   7783    return "srda";
   7784 }
   7785 
   7786 static const HChar *
   7787 s390_irgen_SRDL(UChar r1, IRTemp op2addr)
   7788 {
   7789    IRTemp p1 = newTemp(Ity_I64);
   7790    IRTemp p2 = newTemp(Ity_I64);
   7791    IRTemp result = newTemp(Ity_I64);
   7792 
   7793    assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
   7794    assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
   7795    assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
   7796           mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
   7797           mkexpr(op2addr), mkU64(63)))));
   7798    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
   7799    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
   7800 
   7801    return "srdl";
   7802 }
   7803 
   7804 static const HChar *
   7805 s390_irgen_SRA(UChar r1, IRTemp op2addr)
   7806 {
   7807    IRTemp result = newTemp(Ity_I32);
   7808    IRTemp op = newTemp(Ity_I32);
   7809 
   7810    assign(op, get_gpr_w1(r1));
   7811    assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
   7812           mkexpr(op2addr), mkU64(63)))));
   7813    put_gpr_w1(r1, mkexpr(result));
   7814    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
   7815 
   7816    return "sra";
   7817 }
   7818 
   7819 static const HChar *
   7820 s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
   7821 {
   7822    IRTemp result = newTemp(Ity_I32);
   7823    IRTemp op = newTemp(Ity_I32);
   7824 
   7825    assign(op, get_gpr_w1(r3));
   7826    assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
   7827           mkexpr(op2addr), mkU64(63)))));
   7828    put_gpr_w1(r1, mkexpr(result));
   7829    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
   7830 
   7831    return "srak";
   7832 }
   7833 
   7834 static const HChar *
   7835 s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
   7836 {
   7837    IRTemp result = newTemp(Ity_I64);
   7838    IRTemp op = newTemp(Ity_I64);
   7839 
   7840    assign(op, get_gpr_dw0(r3));
   7841    assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
   7842           mkexpr(op2addr), mkU64(63)))));
   7843    put_gpr_dw0(r1, mkexpr(result));
   7844    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
   7845 
   7846    return "srag";
   7847 }
   7848 
   7849 static const HChar *
   7850 s390_irgen_SRL(UChar r1, IRTemp op2addr)
   7851 {
   7852    IRTemp op = newTemp(Ity_I32);
   7853 
   7854    assign(op, get_gpr_w1(r1));
   7855    put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
   7856               mkexpr(op2addr), mkU64(63)))));
   7857 
   7858    return "srl";
   7859 }
   7860 
   7861 static const HChar *
   7862 s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
   7863 {
   7864    IRTemp op = newTemp(Ity_I32);
   7865 
   7866    assign(op, get_gpr_w1(r3));
   7867    put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
   7868               mkexpr(op2addr), mkU64(63)))));
   7869 
   7870    return "srlk";
   7871 }
   7872 
   7873 static const HChar *
   7874 s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
   7875 {
   7876    IRTemp op = newTemp(Ity_I64);
   7877 
   7878    assign(op, get_gpr_dw0(r3));
   7879    put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
   7880                mkexpr(op2addr), mkU64(63)))));
   7881 
   7882    return "srlg";
   7883 }
   7884 
   7885 static const HChar *
   7886 s390_irgen_ST(UChar r1, IRTemp op2addr)
   7887 {
   7888    store(mkexpr(op2addr), get_gpr_w1(r1));
   7889 
   7890    return "st";
   7891 }
   7892 
   7893 static const HChar *
   7894 s390_irgen_STY(UChar r1, IRTemp op2addr)
   7895 {
   7896    store(mkexpr(op2addr), get_gpr_w1(r1));
   7897 
   7898    return "sty";
   7899 }
   7900 
   7901 static const HChar *
   7902 s390_irgen_STG(UChar r1, IRTemp op2addr)
   7903 {
   7904    store(mkexpr(op2addr), get_gpr_dw0(r1));
   7905 
   7906    return "stg";
   7907 }
   7908 
   7909 static const HChar *
   7910 s390_irgen_STRL(UChar r1, UInt i2)
   7911 {
   7912    store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
   7913          get_gpr_w1(r1));
   7914 
   7915    return "strl";
   7916 }
   7917 
   7918 static const HChar *
   7919 s390_irgen_STGRL(UChar r1, UInt i2)
   7920 {
   7921    store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
   7922          get_gpr_dw0(r1));
   7923 
   7924    return "stgrl";
   7925 }
   7926 
   7927 static const HChar *
   7928 s390_irgen_STC(UChar r1, IRTemp op2addr)
   7929 {
   7930    store(mkexpr(op2addr), get_gpr_b7(r1));
   7931 
   7932    return "stc";
   7933 }
   7934 
   7935 static const HChar *
   7936 s390_irgen_STCY(UChar r1, IRTemp op2addr)
   7937 {
   7938    store(mkexpr(op2addr), get_gpr_b7(r1));
   7939 
   7940    return "stcy";
   7941 }
   7942 
   7943 static const HChar *
   7944 s390_irgen_STCH(UChar r1, IRTemp op2addr)
   7945 {
   7946    store(mkexpr(op2addr), get_gpr_b3(r1));
   7947 
   7948    return "stch";
   7949 }
   7950 
   7951 static const HChar *
   7952 s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
   7953 {
   7954    UChar mask;
   7955    UChar n;
   7956 
   7957    mask = (UChar)r3;
   7958    n = 0;
   7959    if ((mask & 8) != 0) {
   7960       store(mkexpr(op2addr), get_gpr_b4(r1));
   7961       n = n + 1;
   7962    }
   7963    if ((mask & 4) != 0) {
   7964       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
   7965       n = n + 1;
   7966    }
   7967    if ((mask & 2) != 0) {
   7968       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
   7969       n = n + 1;
   7970    }
   7971    if ((mask & 1) != 0) {
   7972       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
   7973    }
   7974 
   7975    return "stcm";
   7976 }
   7977 
   7978 static const HChar *
   7979 s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
   7980 {
   7981    UChar mask;
   7982    UChar n;
   7983 
   7984    mask = (UChar)r3;
   7985    n = 0;
   7986    if ((mask & 8) != 0) {
   7987       store(mkexpr(op2addr), get_gpr_b4(r1));
   7988       n = n + 1;
   7989    }
   7990    if ((mask & 4) != 0) {
   7991       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
   7992       n = n + 1;
   7993    }
   7994    if ((mask & 2) != 0) {
   7995       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
   7996       n = n + 1;
   7997    }
   7998    if ((mask & 1) != 0) {
   7999       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
   8000    }
   8001 
   8002    return "stcmy";
   8003 }
   8004 
   8005 static const HChar *
   8006 s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
   8007 {
   8008    UChar mask;
   8009    UChar n;
   8010 
   8011    mask = (UChar)r3;
   8012    n = 0;
   8013    if ((mask & 8) != 0) {
   8014       store(mkexpr(op2addr), get_gpr_b0(r1));
   8015       n = n + 1;
   8016    }
   8017    if ((mask & 4) != 0) {
   8018       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
   8019       n = n + 1;
   8020    }
   8021    if ((mask & 2) != 0) {
   8022       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
   8023       n = n + 1;
   8024    }
   8025    if ((mask & 1) != 0) {
   8026       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
   8027    }
   8028 
   8029    return "stcmh";
   8030 }
   8031 
   8032 static const HChar *
   8033 s390_irgen_STH(UChar r1, IRTemp op2addr)
   8034 {
   8035    store(mkexpr(op2addr), get_gpr_hw3(r1));
   8036 
   8037    return "sth";
   8038 }
   8039 
   8040 static const HChar *
   8041 s390_irgen_STHY(UChar r1, IRTemp op2addr)
   8042 {
   8043    store(mkexpr(op2addr), get_gpr_hw3(r1));
   8044 
   8045    return "sthy";
   8046 }
   8047 
   8048 static const HChar *
   8049 s390_irgen_STHRL(UChar r1, UInt i2)
   8050 {
   8051    store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
   8052          get_gpr_hw3(r1));
   8053 
   8054    return "sthrl";
   8055 }
   8056 
   8057 static const HChar *
   8058 s390_irgen_STHH(UChar r1, IRTemp op2addr)
   8059 {
   8060    store(mkexpr(op2addr), get_gpr_hw1(r1));
   8061 
   8062    return "sthh";
   8063 }
   8064 
   8065 static const HChar *
   8066 s390_irgen_STFH(UChar r1, IRTemp op2addr)
   8067 {
   8068    store(mkexpr(op2addr), get_gpr_w0(r1));
   8069 
   8070    return "stfh";
   8071 }
   8072 
   8073 static const HChar *
   8074 s390_irgen_STOC(UChar r1, IRTemp op2addr)
   8075 {
   8076    /* condition is checked in format handler */
   8077    store(mkexpr(op2addr), get_gpr_w1(r1));
   8078 
   8079    return "stoc";
   8080 }
   8081 
   8082 static const HChar *
   8083 s390_irgen_STOCG(UChar r1, IRTemp op2addr)
   8084 {
   8085    /* condition is checked in format handler */
   8086    store(mkexpr(op2addr), get_gpr_dw0(r1));
   8087 
   8088    return "stocg";
   8089 }
   8090 
   8091 static const HChar *
   8092 s390_irgen_STPQ(UChar r1, IRTemp op2addr)
   8093 {
   8094    store(mkexpr(op2addr), get_gpr_dw0(r1));
   8095    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
   8096 
   8097    return "stpq";
   8098 }
   8099 
   8100 static const HChar *
   8101 s390_irgen_STRVH(UChar r1, IRTemp op2addr)
   8102 {
   8103    store(mkexpr(op2addr), get_gpr_b7(r1));
   8104    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
   8105 
   8106    return "strvh";
   8107 }
   8108 
   8109 static const HChar *
   8110 s390_irgen_STRV(UChar r1, IRTemp op2addr)
   8111 {
   8112    store(mkexpr(op2addr), get_gpr_b7(r1));
   8113    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
   8114    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
   8115    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
   8116 
   8117    return "strv";
   8118 }
   8119 
   8120 static const HChar *
   8121 s390_irgen_STRVG(UChar r1, IRTemp op2addr)
   8122 {
   8123    store(mkexpr(op2addr), get_gpr_b7(r1));
   8124    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
   8125    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
   8126    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
   8127    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
   8128    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
   8129    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
   8130    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
   8131 
   8132    return "strvg";
   8133 }
   8134 
   8135 static const HChar *
   8136 s390_irgen_SR(UChar r1, UChar r2)
   8137 {
   8138    IRTemp op1 = newTemp(Ity_I32);
   8139    IRTemp op2 = newTemp(Ity_I32);
   8140    IRTemp result = newTemp(Ity_I32);
   8141 
   8142    assign(op1, get_gpr_w1(r1));
   8143    assign(op2, get_gpr_w1(r2));
   8144    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
   8145    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
   8146    put_gpr_w1(r1, mkexpr(result));
   8147 
   8148    return "sr";
   8149 }
   8150 
   8151 static const HChar *
   8152 s390_irgen_SGR(UChar r1, UChar r2)
   8153 {
   8154    IRTemp op1 = newTemp(Ity_I64);
   8155    IRTemp op2 = newTemp(Ity_I64);
   8156    IRTemp result = newTemp(Ity_I64);
   8157 
   8158    assign(op1, get_gpr_dw0(r1));
   8159    assign(op2, get_gpr_dw0(r2));
   8160    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
   8161    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
   8162    put_gpr_dw0(r1, mkexpr(result));
   8163 
   8164    return "sgr";
   8165 }
   8166 
   8167 static const HChar *
   8168 s390_irgen_SGFR(UChar r1, UChar r2)
   8169 {
   8170    IRTemp op1 = newTemp(Ity_I64);
   8171    IRTemp op2 = newTemp(Ity_I64);
   8172    IRTemp result = newTemp(Ity_I64);
   8173 
   8174    assign(op1, get_gpr_dw0(r1));
   8175    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
   8176    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
   8177    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
   8178    put_gpr_dw0(r1, mkexpr(result));
   8179 
   8180    return "sgfr";
   8181 }
   8182 
   8183 static const HChar *
   8184 s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
   8185 {
   8186    IRTemp op2 = newTemp(Ity_I32);
   8187    IRTemp op3 = newTemp(Ity_I32);
   8188    IRTemp result = newTemp(Ity_I32);
   8189 
   8190    assign(op2, get_gpr_w1(r2));
   8191    assign(op3, get_gpr_w1(r3));
   8192    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
   8193    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
   8194    put_gpr_w1(r1, mkexpr(result));
   8195 
   8196    return "srk";
   8197 }
   8198 
   8199 static const HChar *
   8200 s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
   8201 {
   8202    IRTemp op2 = newTemp(Ity_I64);
   8203    IRTemp op3 = newTemp(Ity_I64);
   8204    IRTemp result = newTemp(Ity_I64);
   8205 
   8206    assign(op2, get_gpr_dw0(r2));
   8207    assign(op3, get_gpr_dw0(r3));
   8208    assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
   8209    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
   8210    put_gpr_dw0(r1, mkexpr(result));
   8211 
   8212    return "sgrk";
   8213 }
   8214 
   8215 static const HChar *
   8216 s390_irgen_S(UChar r1, IRTemp op2addr)
   8217 {
   8218    IRTemp op1 = newTemp(Ity_I32);
   8219    IRTemp op2 = newTemp(Ity_I32);
   8220    IRTemp result = newTemp(Ity_I32);
   8221 
   8222    assign(op1, get_gpr_w1(r1));
   8223    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   8224    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
   8225    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
   8226    put_gpr_w1(r1, mkexpr(result));
   8227 
   8228    return "s";
   8229 }
   8230 
   8231 static const HChar *
   8232 s390_irgen_SY(UChar r1, IRTemp op2addr)
   8233 {
   8234    IRTemp op1 = newTemp(Ity_I32);
   8235    IRTemp op2 = newTemp(Ity_I32);
   8236    IRTemp result = newTemp(Ity_I32);
   8237 
   8238    assign(op1, get_gpr_w1(r1));
   8239    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   8240    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
   8241    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
   8242    put_gpr_w1(r1, mkexpr(result));
   8243 
   8244    return "sy";
   8245 }
   8246 
   8247 static const HChar *
   8248 s390_irgen_SG(UChar r1, IRTemp op2addr)
   8249 {
   8250    IRTemp op1 = newTemp(Ity_I64);
   8251    IRTemp op2 = newTemp(Ity_I64);
   8252    IRTemp result = newTemp(Ity_I64);
   8253 
   8254    assign(op1, get_gpr_dw0(r1));
   8255    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   8256    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
   8257    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
   8258    put_gpr_dw0(r1, mkexpr(result));
   8259 
   8260    return "sg";
   8261 }
   8262 
   8263 static const HChar *
   8264 s390_irgen_SGF(UChar r1, IRTemp op2addr)
   8265 {
   8266    IRTemp op1 = newTemp(Ity_I64);
   8267    IRTemp op2 = newTemp(Ity_I64);
   8268    IRTemp result = newTemp(Ity_I64);
   8269 
   8270    assign(op1, get_gpr_dw0(r1));
   8271    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
   8272    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
   8273    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
   8274    put_gpr_dw0(r1, mkexpr(result));
   8275 
   8276    return "sgf";
   8277 }
   8278 
   8279 static const HChar *
   8280 s390_irgen_SH(UChar r1, IRTemp op2addr)
   8281 {
   8282    IRTemp op1 = newTemp(Ity_I32);
   8283    IRTemp op2 = newTemp(Ity_I32);
   8284    IRTemp result = newTemp(Ity_I32);
   8285 
   8286    assign(op1, get_gpr_w1(r1));
   8287    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
   8288    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
   8289    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
   8290    put_gpr_w1(r1, mkexpr(result));
   8291 
   8292    return "sh";
   8293 }
   8294 
   8295 static const HChar *
   8296 s390_irgen_SHY(UChar r1, IRTemp op2addr)
   8297 {
   8298    IRTemp op1 = newTemp(Ity_I32);
   8299    IRTemp op2 = newTemp(Ity_I32);
   8300    IRTemp result = newTemp(Ity_I32);
   8301 
   8302    assign(op1, get_gpr_w1(r1));
   8303    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
   8304    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
   8305    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
   8306    put_gpr_w1(r1, mkexpr(result));
   8307 
   8308    return "shy";
   8309 }
   8310 
   8311 static const HChar *
   8312 s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
   8313 {
   8314    IRTemp op2 = newTemp(Ity_I32);
   8315    IRTemp op3 = newTemp(Ity_I32);
   8316    IRTemp result = newTemp(Ity_I32);
   8317 
   8318    assign(op2, get_gpr_w0(r1));
   8319    assign(op3, get_gpr_w0(r2));
   8320    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
   8321    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
   8322    put_gpr_w0(r1, mkexpr(result));
   8323 
   8324    return "shhhr";
   8325 }
   8326 
   8327 static const HChar *
   8328 s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
   8329 {
   8330    IRTemp op2 = newTemp(Ity_I32);
   8331    IRTemp op3 = newTemp(Ity_I32);
   8332    IRTemp result = newTemp(Ity_I32);
   8333 
   8334    assign(op2, get_gpr_w0(r1));
   8335    assign(op3, get_gpr_w1(r2));
   8336    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
   8337    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
   8338    put_gpr_w0(r1, mkexpr(result));
   8339 
   8340    return "shhlr";
   8341 }
   8342 
   8343 static const HChar *
   8344 s390_irgen_SLR(UChar r1, UChar r2)
   8345 {
   8346    IRTemp op1 = newTemp(Ity_I32);
   8347    IRTemp op2 = newTemp(Ity_I32);
   8348    IRTemp result = newTemp(Ity_I32);
   8349 
   8350    assign(op1, get_gpr_w1(r1));
   8351    assign(op2, get_gpr_w1(r2));
   8352    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
   8353    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
   8354    put_gpr_w1(r1, mkexpr(result));
   8355 
   8356    return "slr";
   8357 }
   8358 
   8359 static const HChar *
   8360 s390_irgen_SLGR(UChar r1, UChar r2)
   8361 {
   8362    IRTemp op1 = newTemp(Ity_I64);
   8363    IRTemp op2 = newTemp(Ity_I64);
   8364    IRTemp result = newTemp(Ity_I64);
   8365 
   8366    assign(op1, get_gpr_dw0(r1));
   8367    assign(op2, get_gpr_dw0(r2));
   8368    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
   8369    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
   8370    put_gpr_dw0(r1, mkexpr(result));
   8371 
   8372    return "slgr";
   8373 }
   8374 
   8375 static const HChar *
   8376 s390_irgen_SLGFR(UChar r1, UChar r2)
   8377 {
   8378    IRTemp op1 = newTemp(Ity_I64);
   8379    IRTemp op2 = newTemp(Ity_I64);
   8380    IRTemp result = newTemp(Ity_I64);
   8381 
   8382    assign(op1, get_gpr_dw0(r1));
   8383    assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
   8384    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
   8385    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
   8386    put_gpr_dw0(r1, mkexpr(result));
   8387 
   8388    return "slgfr";
   8389 }
   8390 
   8391 static const HChar *
   8392 s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
   8393 {
   8394    IRTemp op2 = newTemp(Ity_I32);
   8395    IRTemp op3 = newTemp(Ity_I32);
   8396    IRTemp result = newTemp(Ity_I32);
   8397 
   8398    assign(op2, get_gpr_w1(r2));
   8399    assign(op3, get_gpr_w1(r3));
   8400    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
   8401    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
   8402    put_gpr_w1(r1, mkexpr(result));
   8403 
   8404    return "slrk";
   8405 }
   8406 
   8407 static const HChar *
   8408 s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
   8409 {
   8410    IRTemp op2 = newTemp(Ity_I64);
   8411    IRTemp op3 = newTemp(Ity_I64);
   8412    IRTemp result = newTemp(Ity_I64);
   8413 
   8414    assign(op2, get_gpr_dw0(r2));
   8415    assign(op3, get_gpr_dw0(r3));
   8416    assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
   8417    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
   8418    put_gpr_dw0(r1, mkexpr(result));
   8419 
   8420    return "slgrk";
   8421 }
   8422 
   8423 static const HChar *
   8424 s390_irgen_SL(UChar r1, IRTemp op2addr)
   8425 {
   8426    IRTemp op1 = newTemp(Ity_I32);
   8427    IRTemp op2 = newTemp(Ity_I32);
   8428    IRTemp result = newTemp(Ity_I32);
   8429 
   8430    assign(op1, get_gpr_w1(r1));
   8431    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   8432    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
   8433    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
   8434    put_gpr_w1(r1, mkexpr(result));
   8435 
   8436    return "sl";
   8437 }
   8438 
   8439 static const HChar *
   8440 s390_irgen_SLY(UChar r1, IRTemp op2addr)
   8441 {
   8442    IRTemp op1 = newTemp(Ity_I32);
   8443    IRTemp op2 = newTemp(Ity_I32);
   8444    IRTemp result = newTemp(Ity_I32);
   8445 
   8446    assign(op1, get_gpr_w1(r1));
   8447    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   8448    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
   8449    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
   8450    put_gpr_w1(r1, mkexpr(result));
   8451 
   8452    return "sly";
   8453 }
   8454 
   8455 static const HChar *
   8456 s390_irgen_SLG(UChar r1, IRTemp op2addr)
   8457 {
   8458    IRTemp op1 = newTemp(Ity_I64);
   8459    IRTemp op2 = newTemp(Ity_I64);
   8460    IRTemp result = newTemp(Ity_I64);
   8461 
   8462    assign(op1, get_gpr_dw0(r1));
   8463    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   8464    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
   8465    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
   8466    put_gpr_dw0(r1, mkexpr(result));
   8467 
   8468    return "slg";
   8469 }
   8470 
   8471 static const HChar *
   8472 s390_irgen_SLGF(UChar r1, IRTemp op2addr)
   8473 {
   8474    IRTemp op1 = newTemp(Ity_I64);
   8475    IRTemp op2 = newTemp(Ity_I64);
   8476    IRTemp result = newTemp(Ity_I64);
   8477 
   8478    assign(op1, get_gpr_dw0(r1));
   8479    assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
   8480    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
   8481    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
   8482    put_gpr_dw0(r1, mkexpr(result));
   8483 
   8484    return "slgf";
   8485 }
   8486 
   8487 static const HChar *
   8488 s390_irgen_SLFI(UChar r1, UInt i2)
   8489 {
   8490    IRTemp op1 = newTemp(Ity_I32);
   8491    UInt op2;
   8492    IRTemp result = newTemp(Ity_I32);
   8493 
   8494    assign(op1, get_gpr_w1(r1));
   8495    op2 = i2;
   8496    assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
   8497    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
   8498                        mkU32(op2)));
   8499    put_gpr_w1(r1, mkexpr(result));
   8500 
   8501    return "slfi";
   8502 }
   8503 
   8504 static const HChar *
   8505 s390_irgen_SLGFI(UChar r1, UInt i2)
   8506 {
   8507    IRTemp op1 = newTemp(Ity_I64);
   8508    ULong op2;
   8509    IRTemp result = newTemp(Ity_I64);
   8510 
   8511    assign(op1, get_gpr_dw0(r1));
   8512    op2 = (ULong)i2;
   8513    assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
   8514    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
   8515                        mkU64(op2)));
   8516    put_gpr_dw0(r1, mkexpr(result));
   8517 
   8518    return "slgfi";
   8519 }
   8520 
   8521 static const HChar *
   8522 s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
   8523 {
   8524    IRTemp op2 = newTemp(Ity_I32);
   8525    IRTemp op3 = newTemp(Ity_I32);
   8526    IRTemp result = newTemp(Ity_I32);
   8527 
   8528    assign(op2, get_gpr_w0(r1));
   8529    assign(op3, get_gpr_w0(r2));
   8530    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
   8531    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
   8532    put_gpr_w0(r1, mkexpr(result));
   8533 
   8534    return "slhhhr";
   8535 }
   8536 
   8537 static const HChar *
   8538 s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
   8539 {
   8540    IRTemp op2 = newTemp(Ity_I32);
   8541    IRTemp op3 = newTemp(Ity_I32);
   8542    IRTemp result = newTemp(Ity_I32);
   8543 
   8544    assign(op2, get_gpr_w0(r1));
   8545    assign(op3, get_gpr_w1(r2));
   8546    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
   8547    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
   8548    put_gpr_w0(r1, mkexpr(result));
   8549 
   8550    return "slhhlr";
   8551 }
   8552 
   8553 static const HChar *
   8554 s390_irgen_SLBR(UChar r1, UChar r2)
   8555 {
   8556    IRTemp op1 = newTemp(Ity_I32);
   8557    IRTemp op2 = newTemp(Ity_I32);
   8558    IRTemp result = newTemp(Ity_I32);
   8559    IRTemp borrow_in = newTemp(Ity_I32);
   8560 
   8561    assign(op1, get_gpr_w1(r1));
   8562    assign(op2, get_gpr_w1(r2));
   8563    assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
   8564           s390_call_calculate_cc(), mkU8(1))));
   8565    assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
   8566           mkexpr(borrow_in)));
   8567    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
   8568    put_gpr_w1(r1, mkexpr(result));
   8569 
   8570    return "slbr";
   8571 }
   8572 
   8573 static const HChar *
   8574 s390_irgen_SLBGR(UChar r1, UChar r2)
   8575 {
   8576    IRTemp op1 = newTemp(Ity_I64);
   8577    IRTemp op2 = newTemp(Ity_I64);
   8578    IRTemp result = newTemp(Ity_I64);
   8579    IRTemp borrow_in = newTemp(Ity_I64);
   8580 
   8581    assign(op1, get_gpr_dw0(r1));
   8582    assign(op2, get_gpr_dw0(r2));
   8583    assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
   8584           binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
   8585    assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
   8586           mkexpr(borrow_in)));
   8587    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
   8588    put_gpr_dw0(r1, mkexpr(result));
   8589 
   8590    return "slbgr";
   8591 }
   8592 
   8593 static const HChar *
   8594 s390_irgen_SLB(UChar r1, IRTemp op2addr)
   8595 {
   8596    IRTemp op1 = newTemp(Ity_I32);
   8597    IRTemp op2 = newTemp(Ity_I32);
   8598    IRTemp result = newTemp(Ity_I32);
   8599    IRTemp borrow_in = newTemp(Ity_I32);
   8600 
   8601    assign(op1, get_gpr_w1(r1));
   8602    assign(op2, load(Ity_I32, mkexpr(op2addr)));
   8603    assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
   8604           s390_call_calculate_cc(), mkU8(1))));
   8605    assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
   8606           mkexpr(borrow_in)));
   8607    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
   8608    put_gpr_w1(r1, mkexpr(result));
   8609 
   8610    return "slb";
   8611 }
   8612 
   8613 static const HChar *
   8614 s390_irgen_SLBG(UChar r1, IRTemp op2addr)
   8615 {
   8616    IRTemp op1 = newTemp(Ity_I64);
   8617    IRTemp op2 = newTemp(Ity_I64);
   8618    IRTemp result = newTemp(Ity_I64);
   8619    IRTemp borrow_in = newTemp(Ity_I64);
   8620 
   8621    assign(op1, get_gpr_dw0(r1));
   8622    assign(op2, load(Ity_I64, mkexpr(op2addr)));
   8623    assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
   8624           binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
   8625    assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
   8626           mkexpr(borrow_in)));
   8627    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
   8628    put_gpr_dw0(r1, mkexpr(result));
   8629 
   8630    return "slbg";
   8631 }
   8632 
   8633 static const HChar *
   8634 s390_irgen_SVC(UChar i)
   8635 {
   8636    IRTemp sysno = newTemp(Ity_I64);
   8637 
   8638    if (i != 0) {
   8639       assign(sysno, mkU64(i));
   8640    } else {
   8641       assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
   8642    }
   8643    system_call(mkexpr(sysno));
   8644 
   8645    return "svc";
   8646 }
   8647 
   8648 static const HChar *
   8649 s390_irgen_TM(UChar i2, IRTemp op1addr)
   8650 {
   8651    UChar mask;
   8652    IRTemp value = newTemp(Ity_I8);
   8653 
   8654    mask = i2;
   8655    assign(value, load(Ity_I8, mkexpr(op1addr)));
   8656    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
   8657                        mkU8(mask)));
   8658 
   8659    return "tm";
   8660 }
   8661 
   8662 static const HChar *
   8663 s390_irgen_TMY(UChar i2, IRTemp op1addr)
   8664 {
   8665    UChar mask;
   8666    IRTemp value = newTemp(Ity_I8);
   8667 
   8668    mask = i2;
   8669    assign(value, load(Ity_I8, mkexpr(op1addr)));
   8670    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
   8671                        mkU8(mask)));
   8672 
   8673    return "tmy";
   8674 }
   8675 
   8676 static const HChar *
   8677 s390_irgen_TMHH(UChar r1, UShort i2)
   8678 {
   8679    UShort mask;
   8680    IRTemp value = newTemp(Ity_I16);
   8681 
   8682    mask = i2;
   8683    assign(value, get_gpr_hw0(r1));
   8684    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
   8685                        mkU16(mask)));
   8686 
   8687    return "tmhh";
   8688 }
   8689 
   8690 static const HChar *
   8691 s390_irgen_TMHL(UChar r1, UShort i2)
   8692 {
   8693    UShort mask;
   8694    IRTemp value = newTemp(Ity_I16);
   8695 
   8696    mask = i2;
   8697    assign(value, get_gpr_hw1(r1));
   8698    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
   8699                        mkU16(mask)));
   8700 
   8701    return "tmhl";
   8702 }
   8703 
   8704 static const HChar *
   8705 s390_irgen_TMLH(UChar r1, UShort i2)
   8706 {
   8707    UShort mask;
   8708    IRTemp value = newTemp(Ity_I16);
   8709 
   8710    mask = i2;
   8711    assign(value, get_gpr_hw2(r1));
   8712    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
   8713                        mkU16(mask)));
   8714 
   8715    return "tmlh";
   8716 }
   8717 
   8718 static const HChar *
   8719 s390_irgen_TMLL(UChar r1, UShort i2)
   8720 {
   8721    UShort mask;
   8722    IRTemp value = newTemp(Ity_I16);
   8723 
   8724    mask = i2;
   8725    assign(value, get_gpr_hw3(r1));
   8726    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
   8727                        mkU16(mask)));
   8728 
   8729    return "tmll";
   8730 }
   8731 
   8732 static const HChar *
   8733 s390_irgen_EFPC(UChar r1)
   8734 {
   8735    put_gpr_w1(r1, get_fpc_w0());
   8736 
   8737    return "efpc";
   8738 }
   8739 
   8740 static const HChar *
   8741 s390_irgen_LER(UChar r1, UChar r2)
   8742 {
   8743    put_fpr_w0(r1, get_fpr_w0(r2));
   8744 
   8745    return "ler";
   8746 }
   8747 
   8748 static const HChar *
   8749 s390_irgen_LDR(UChar r1, UChar r2)
   8750 {
   8751    put_fpr_dw0(r1, get_fpr_dw0(r2));
   8752 
   8753    return "ldr";
   8754 }
   8755 
   8756 static const HChar *
   8757 s390_irgen_LXR(UChar r1, UChar r2)
   8758 {
   8759    put_fpr_dw0(r1, get_fpr_dw0(r2));
   8760    put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
   8761 
   8762    return "lxr";
   8763 }
   8764 
   8765 static const HChar *
   8766 s390_irgen_LE(UChar r1, IRTemp op2addr)
   8767 {
   8768    put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
   8769 
   8770    return "le";
   8771 }
   8772 
   8773 static const HChar *
   8774 s390_irgen_LD(UChar r1, IRTemp op2addr)
   8775 {
   8776    put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
   8777 
   8778    return "ld";
   8779 }
   8780 
   8781 static const HChar *
   8782 s390_irgen_LEY(UChar r1, IRTemp op2addr)
   8783 {
   8784    put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
   8785 
   8786    return "ley";
   8787 }
   8788 
   8789 static const HChar *
   8790 s390_irgen_LDY(UChar r1, IRTemp op2addr)
   8791 {
   8792    put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
   8793 
   8794    return "ldy";
   8795 }
   8796 
   8797 static const HChar *
   8798 s390_irgen_LFPC(IRTemp op2addr)
   8799 {
   8800    put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
   8801 
   8802    return "lfpc";
   8803 }
   8804 
   8805 static const HChar *
   8806 s390_irgen_LZER(UChar r1)
   8807 {
   8808    put_fpr_w0(r1, mkF32i(0x0));
   8809 
   8810    return "lzer";
   8811 }
   8812 
   8813 static const HChar *
   8814 s390_irgen_LZDR(UChar r1)
   8815 {
   8816    put_fpr_dw0(r1, mkF64i(0x0));
   8817 
   8818    return "lzdr";
   8819 }
   8820 
   8821 static const HChar *
   8822 s390_irgen_LZXR(UChar r1)
   8823 {
   8824    put_fpr_dw0(r1, mkF64i(0x0));
   8825    put_fpr_dw0(r1 + 2, mkF64i(0x0));
   8826 
   8827    return "lzxr";
   8828 }
   8829 
   8830 static const HChar *
   8831 s390_irgen_SRNM(IRTemp op2addr)
   8832 {
   8833    UInt input_mask, fpc_mask;
   8834 
   8835    input_mask = 3;
   8836    fpc_mask = s390_host_has_fpext ? 7 : 3;
   8837 
   8838    put_fpc_w0(binop(Iop_Or32,
   8839                     binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
   8840                     binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
   8841                           mkU32(input_mask))));
   8842    return "srnm";
   8843 }
   8844 
   8845 static const HChar *
   8846 s390_irgen_SRNMB(IRTemp op2addr)
   8847 {
   8848    UInt input_mask, fpc_mask;
   8849 
   8850    input_mask = 7;
   8851    fpc_mask = 7;
   8852 
   8853    put_fpc_w0(binop(Iop_Or32,
   8854                     binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
   8855                     binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
   8856                           mkU32(input_mask))));
   8857    return "srnmb";
   8858 }
   8859 
   8860 static void
   8861 s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
   8862 {
   8863    if (b2 == 0) {  /* This is the typical case */
   8864       if (d2 > 3) {
   8865          if (s390_host_has_fpext && d2 == 7) {
   8866             /* ok */
   8867          } else {
   8868             emulation_warning(EmWarn_S390X_invalid_rounding);
   8869             d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
   8870          }
   8871       }
   8872    }
   8873 
   8874    s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
   8875 }
   8876 
   8877 /* Wrapper to validate the parameter as in SRNMB is not required, as all
   8878    the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
   8879 static const HChar *
   8880 s390_irgen_SRNMT(IRTemp op2addr)
   8881 {
   8882    UInt input_mask, fpc_mask;
   8883 
   8884    input_mask = 7;
   8885    fpc_mask = 0x70;
   8886 
   8887    /* fpc[25:27] <- op2addr[61:63]
   8888       fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
   8889    put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
   8890                     binop(Iop_Shl32, binop(Iop_And32,
   8891                                            unop(Iop_64to32, mkexpr(op2addr)),
   8892                                            mkU32(input_mask)), mkU8(4))));
   8893    return "srnmt";
   8894 }
   8895 
   8896 
   8897 static const HChar *
   8898 s390_irgen_SFPC(UChar r1)
   8899 {
   8900    put_fpc_w0(get_gpr_w1(r1));
   8901 
   8902    return "sfpc";
   8903 }
   8904 
   8905 static const HChar *
   8906 s390_irgen_STE(UChar r1, IRTemp op2addr)
   8907 {
   8908    store(mkexpr(op2addr), get_fpr_w0(r1));
   8909 
   8910    return "ste";
   8911 }
   8912 
   8913 static const HChar *
   8914 s390_irgen_STD(UChar r1, IRTemp op2addr)
   8915 {
   8916    store(mkexpr(op2addr), get_fpr_dw0(r1));
   8917 
   8918    return "std";
   8919 }
   8920 
   8921 static const HChar *
   8922 s390_irgen_STEY(UChar r1, IRTemp op2addr)
   8923 {
   8924    store(mkexpr(op2addr), get_fpr_w0(r1));
   8925 
   8926    return "stey";
   8927 }
   8928 
   8929 static const HChar *
   8930 s390_irgen_STDY(UChar r1, IRTemp op2addr)
   8931 {
   8932    store(mkexpr(op2addr), get_fpr_dw0(r1));
   8933 
   8934    return "stdy";
   8935 }
   8936 
   8937 static const HChar *
   8938 s390_irgen_STFPC(IRTemp op2addr)
   8939 {
   8940    store(mkexpr(op2addr), get_fpc_w0());
   8941 
   8942    return "stfpc";
   8943 }
   8944 
   8945 static const HChar *
   8946 s390_irgen_AEBR(UChar r1, UChar r2)
   8947 {
   8948    IRTemp op1 = newTemp(Ity_F32);
   8949    IRTemp op2 = newTemp(Ity_F32);
   8950    IRTemp result = newTemp(Ity_F32);
   8951    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
   8952 
   8953    assign(op1, get_fpr_w0(r1));
   8954    assign(op2, get_fpr_w0(r2));
   8955    assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
   8956           mkexpr(op2)));
   8957    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
   8958    put_fpr_w0(r1, mkexpr(result));
   8959 
   8960    return "aebr";
   8961 }
   8962 
   8963 static const HChar *
   8964 s390_irgen_ADBR(UChar r1, UChar r2)
   8965 {
   8966    IRTemp op1 = newTemp(Ity_F64);
   8967    IRTemp op2 = newTemp(Ity_F64);
   8968    IRTemp result = newTemp(Ity_F64);
   8969    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
   8970 
   8971    assign(op1, get_fpr_dw0(r1));
   8972    assign(op2, get_fpr_dw0(r2));
   8973    assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
   8974           mkexpr(op2)));
   8975    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
   8976    put_fpr_dw0(r1, mkexpr(result));
   8977 
   8978    return "adbr";
   8979 }
   8980 
   8981 static const HChar *
   8982 s390_irgen_AEB(UChar r1, IRTemp op2addr)
   8983 {
   8984    IRTemp op1 = newTemp(Ity_F32);
   8985    IRTemp op2 = newTemp(Ity_F32);
   8986    IRTemp result = newTemp(Ity_F32);
   8987    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
   8988 
   8989    assign(op1, get_fpr_w0(r1));
   8990    assign(op2, load(Ity_F32, mkexpr(op2addr)));
   8991    assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
   8992           mkexpr(op2)));
   8993    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
   8994    put_fpr_w0(r1, mkexpr(result));
   8995 
   8996    return "aeb";
   8997 }
   8998 
   8999 static const HChar *
   9000 s390_irgen_ADB(UChar r1, IRTemp op2addr)
   9001 {
   9002    IRTemp op1 = newTemp(Ity_F64);
   9003    IRTemp op2 = newTemp(Ity_F64);
   9004    IRTemp result = newTemp(Ity_F64);
   9005    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
   9006 
   9007    assign(op1, get_fpr_dw0(r1));
   9008    assign(op2, load(Ity_F64, mkexpr(op2addr)));
   9009    assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
   9010           mkexpr(op2)));
   9011    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
   9012    put_fpr_dw0(r1, mkexpr(result));
   9013 
   9014    return "adb";
   9015 }
   9016 
   9017 static const HChar *
   9018 s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
   9019                  UChar r1, UChar r2)
   9020 {
   9021    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
   9022       emulation_warning(EmWarn_S390X_fpext_rounding);
   9023       m3 = S390_BFP_ROUND_PER_FPC;
   9024    }
   9025    IRTemp op2 = newTemp(Ity_I32);
   9026 
   9027    assign(op2, get_gpr_w1(r2));
   9028    put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
   9029                         mkexpr(op2)));
   9030 
   9031    return "cefbr";
   9032 }
   9033 
   9034 static const HChar *
   9035 s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
   9036                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
   9037 {
   9038    IRTemp op2 = newTemp(Ity_I32);
   9039 
   9040    assign(op2, get_gpr_w1(r2));
   9041    put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
   9042 
   9043    return "cdfbr";
   9044 }
   9045 
   9046 static const HChar *
   9047 s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
   9048                  UChar r1, UChar r2)
   9049 {
   9050    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
   9051       emulation_warning(EmWarn_S390X_fpext_rounding);
   9052       m3 = S390_BFP_ROUND_PER_FPC;
   9053    }
   9054    IRTemp op2 = newTemp(Ity_I64);
   9055 
   9056    assign(op2, get_gpr_dw0(r2));
   9057    put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
   9058                         mkexpr(op2)));
   9059 
   9060    return "cegbr";
   9061 }
   9062 
   9063 static const HChar *
   9064 s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
   9065                  UChar r1, UChar r2)
   9066 {
   9067    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
   9068       emulation_warning(EmWarn_S390X_fpext_rounding);
   9069       m3 = S390_BFP_ROUND_PER_FPC;
   9070    }
   9071    IRTemp op2 = newTemp(Ity_I64);
   9072 
   9073    assign(op2, get_gpr_dw0(r2));
   9074    put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
   9075                          mkexpr(op2)));
   9076 
   9077    return "cdgbr";
   9078 }
   9079 
   9080 static const HChar *
   9081 s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
   9082                   UChar r1, UChar r2)
   9083 {
   9084    if (! s390_host_has_fpext) {
   9085       emulation_failure(EmFail_S390X_fpext);
   9086    } else {
   9087       IRTemp op2 = newTemp(Ity_I32);
   9088 
   9089       assign(op2, get_gpr_w1(r2));
   9090       put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
   9091                            mkexpr(op2)));
   9092    }
   9093    return "celfbr";
   9094 }
   9095 
   9096 static const HChar *
   9097 s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
   9098                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
   9099 {
   9100    if (! s390_host_has_fpext) {
   9101       emulation_failure(EmFail_S390X_fpext);
   9102    } else {
   9103       IRTemp op2 = newTemp(Ity_I32);
   9104 
   9105       assign(op2, get_gpr_w1(r2));
   9106       put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
   9107    }
   9108    return "cdlfbr";
   9109 }
   9110 
   9111 static const HChar *
   9112 s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
   9113                   UChar r1, UChar r2)
   9114 {
   9115    if (! s390_host_has_fpext) {
   9116       emulation_failure(EmFail_S390X_fpext);
   9117    } else {
   9118       IRTemp op2 = newTemp(Ity_I64);
   9119 
   9120       assign(op2, get_gpr_dw0(r2));
   9121       put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
   9122                            mkexpr(op2)));
   9123    }
   9124    return "celgbr";
   9125 }
   9126 
   9127 static const HChar *
   9128 s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
   9129                   UChar r1, UChar r2)
   9130 {
   9131    if (! s390_host_has_fpext) {
   9132       emulation_failure(EmFail_S390X_fpext);
   9133    } else {
   9134       IRTemp op2 = newTemp(Ity_I64);
   9135 
   9136       assign(op2, get_gpr_dw0(r2));
   9137       put_fpr_dw0(r1, binop(Iop_I64UtoF64,
   9138                             mkexpr(encode_bfp_rounding_mode(m3)),
   9139                             mkexpr(op2)));
   9140    }
   9141    return "cdlgbr";
   9142 }
   9143 
   9144 static const HChar *
   9145 s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
   9146                   UChar r1, UChar r2)
   9147 {
   9148    if (! s390_host_has_fpext) {
   9149       emulation_failure(EmFail_S390X_fpext);
   9150    } else {
   9151       IRTemp op = newTemp(Ity_F32);
   9152       IRTemp result = newTemp(Ity_I32);
   9153       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
   9154 
   9155       assign(op, get_fpr_w0(r2));
   9156       assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
   9157                            mkexpr(op)));
   9158       put_gpr_w1(r1, mkexpr(result));
   9159       s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
   9160    }
   9161    return "clfebr";
   9162 }
   9163 
   9164 static const HChar *
   9165 s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
   9166                   UChar r1, UChar r2)
   9167 {
   9168    if (! s390_host_has_fpext) {
   9169       emulation_failure(EmFail_S390X_fpext);
   9170    } else {
   9171       IRTemp op = newTemp(Ity_F64);
   9172       IRTemp result = newTemp(Ity_I32);
   9173       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
   9174 
   9175       assign(op, get_fpr_dw0(r2));
   9176       assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
   9177                            mkexpr(op)));
   9178       put_gpr_w1(r1, mkexpr(result));
   9179       s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
   9180    }
   9181    return "clfdbr";
   9182 }
   9183 
   9184 static const HChar *
   9185 s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
   9186                   UChar r1, UChar r2)
   9187 {
   9188    if (! s390_host_has_fpext) {
   9189       emulation_failure(EmFail_S390X_fpext);
   9190    } else {
   9191       IRTemp op = newTemp(Ity_F32);
   9192       IRTemp result = newTemp(Ity_I64);
   9193       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
   9194 
   9195       assign(op, get_fpr_w0(r2));
   9196       assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
   9197                            mkexpr(op)));
   9198       put_gpr_dw0(r1, mkexpr(result));
   9199       s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
   9200    }
   9201    return "clgebr";
   9202 }
   9203 
   9204 static const HChar *
   9205 s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
   9206                   UChar r1, UChar r2)
   9207 {
   9208    if (! s390_host_has_fpext) {
   9209       emulation_failure(EmFail_S390X_fpext);
   9210    } else {
   9211       IRTemp op = newTemp(Ity_F64);
   9212       IRTemp result = newTemp(Ity_I64);
   9213       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
   9214 
   9215       assign(op, get_fpr_dw0(r2));
   9216       assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
   9217                            mkexpr(op)));
   9218       put_gpr_dw0(r1, mkexpr(result));
   9219       s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
   9220    }
   9221    return "clgdbr";
   9222 }
   9223 
   9224 static const HChar *
   9225 s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
   9226                  UChar r1, UChar r2)
   9227 {
   9228    IRTemp op = newTemp(Ity_F32);
   9229    IRTemp result = newTemp(Ity_I32);
   9230    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
   9231 
   9232    assign(op, get_fpr_w0(r2));
   9233    assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
   9234           mkexpr(op)));
   9235    put_gpr_w1(r1, mkexpr(result));
   9236    s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
   9237 
   9238    return "cfebr";
   9239 }
   9240 
   9241 static const HChar *
   9242 s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
   9243                  UChar r1, UChar r2)
   9244 {
   9245    IRTemp op = newTemp(Ity_F64);
   9246    IRTemp result = newTemp(Ity_I32);
   9247    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
   9248 
   9249    assign(op, get_fpr_dw0(r2));
   9250    assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
   9251           mkexpr(op)));
   9252    put_gpr_w1(r1, mkexpr(result));
   9253    s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
   9254 
   9255    return "cfdbr";
   9256 }
   9257 
   9258 static const HChar *
   9259 s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
   9260                  UChar r1, UChar r2)
   9261 {
   9262    IRTemp op = newTemp(Ity_F32);
   9263    IRTemp result = newTemp(Ity_I64);
   9264    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
   9265 
   9266    assign(op, get_fpr_w0(r2));
   9267    assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
   9268           mkexpr(op)));
   9269    put_gpr_dw0(r1, mkexpr(result));
   9270    s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
   9271 
   9272    return "cgebr";
   9273 }
   9274 
   9275 static const HChar *
   9276 s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
   9277                  UChar r1, UChar r2)
   9278 {
   9279    IRTemp op = newTemp(Ity_F64);
   9280    IRTemp result = newTemp(Ity_I64);
   9281    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
   9282 
   9283    assign(op, get_fpr_dw0(r2));
   9284    assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
   9285           mkexpr(op)));
   9286    put_gpr_dw0(r1, mkexpr(result));
   9287    s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
   9288 
   9289    return "cgdbr";
   9290 }
   9291 
   9292 static const HChar *
   9293 s390_irgen_DEBR(UChar r1, UChar r2)
   9294 {
   9295    IRTemp op1 = newTemp(Ity_F32);
   9296    IRTemp op2 = newTemp(Ity_F32);
   9297    IRTemp result = newTemp(Ity_F32);
   9298    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
   9299 
   9300    assign(op1, get_fpr_w0(r1));
   9301    assign(op2, get_fpr_w0(r2));
   9302    assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
   9303           mkexpr(op2)));
   9304    put_fpr_w0(r1, mkexpr(result));
   9305 
   9306    return "debr";
   9307 }
   9308 
   9309 static const HChar *
   9310 s390_irgen_DDBR(UChar r1, UChar r2)
   9311 {
   9312    IRTemp op1 = newTemp(Ity_F64);
   9313    IRTemp op2 = newTemp(Ity_F64);
   9314    IRTemp result = newTemp(Ity_F64);
   9315    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
   9316 
   9317    assign(op1, get_fpr_dw0(r1));
   9318    assign(op2, get_fpr_dw0(r2));
   9319    assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
   9320           mkexpr(op2)));
   9321    put_fpr_dw0(r1, mkexpr(result));
   9322 
   9323    return "ddbr";
   9324 }
   9325 
   9326 static const HChar *
   9327 s390_irgen_DEB(UChar r1, IRTemp op2addr)
   9328 {
   9329    IRTemp op1 = newTemp(Ity_F32);
   9330    IRTemp op2 = newTemp(Ity_F32);
   9331    IRTemp result = newTemp(Ity_F32);
   9332    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
   9333 
   9334    assign(op1, get_fpr_w0(r1));
   9335    assign(op2, load(Ity_F32, mkexpr(op2addr)));
   9336    assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
   9337           mkexpr(op2)));
   9338    put_fpr_w0(r1, mkexpr(result));
   9339 
   9340    return "deb";
   9341 }
   9342 
   9343 static const HChar *
   9344 s390_irgen_DDB(UChar r1, IRTemp op2addr)
   9345 {
   9346    IRTemp op1 = newTemp(Ity_F64);
   9347    IRTemp op2 = newTemp(Ity_F64);
   9348    IRTemp result = newTemp(Ity_F64);
   9349    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
   9350 
   9351    assign(op1, get_fpr_dw0(r1));
   9352    assign(op2, load(Ity_F64, mkexpr(op2addr)));
   9353    assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
   9354           mkexpr(op2)));
   9355    put_fpr_dw0(r1, mkexpr(result));
   9356 
   9357    return "ddb";
   9358 }
   9359 
   9360 static const HChar *
   9361 s390_irgen_LTEBR(UChar r1, UChar r2)
   9362 {
   9363    IRTemp result = newTemp(Ity_F32);
   9364 
   9365    assign(result, get_fpr_w0(r2));
   9366    put_fpr_w0(r1, mkexpr(result));
   9367    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
   9368 
   9369    return "ltebr";
   9370 }
   9371 
   9372 static const HChar *
   9373 s390_irgen_LTDBR(UChar r1, UChar r2)
   9374 {
   9375    IRTemp result = newTemp(Ity_F64);
   9376 
   9377    assign(result, get_fpr_dw0(r2));
   9378    put_fpr_dw0(r1, mkexpr(result));
   9379    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
   9380 
   9381    return "ltdbr";
   9382 }
   9383 
   9384 static const HChar *
   9385 s390_irgen_LCEBR(UChar r1, UChar r2)
   9386 {
   9387    IRTemp result = newTemp(Ity_F32);
   9388 
   9389    assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
   9390    put_fpr_w0(r1, mkexpr(result));
   9391    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
   9392 
   9393    return "lcebr";
   9394 }
   9395 
   9396 static const HChar *
   9397 s390_irgen_LCDBR(UChar r1, UChar r2)
   9398 {
   9399    IRTemp result = newTemp(Ity_F64);
   9400 
   9401    assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
   9402    put_fpr_dw0(r1, mkexpr(result));
   9403    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
   9404 
   9405    return "lcdbr";
   9406 }
   9407 
   9408 static const HChar *
   9409 s390_irgen_LDEBR(UChar r1, UChar r2)
   9410 {
   9411    IRTemp op = newTemp(Ity_F32);
   9412 
   9413    assign(op, get_fpr_w0(r2));
   9414    put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
   9415 
   9416    return "ldebr";
   9417 }
   9418 
   9419 static const HChar *
   9420 s390_irgen_LDEB(UChar r1, IRTemp op2addr)
   9421 {
   9422    IRTemp op = newTemp(Ity_F32);
   9423 
   9424    assign(op, load(Ity_F32, mkexpr(op2addr)));
   9425    put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
   9426 
   9427    return "ldeb";
   9428 }
   9429 
   9430 static const HChar *
   9431 s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
   9432                  UChar r1, UChar r2)
   9433 {
   9434    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
   9435       emulation_warning(EmWarn_S390X_fpext_rounding);
   9436       m3 = S390_BFP_ROUND_PER_FPC;
   9437    }
   9438    IRTemp op = newTemp(Ity_F64);
   9439 
   9440    assign(op, get_fpr_dw0(r2));
   9441    put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
   9442                         mkexpr(op)));
   9443 
   9444    return "ledbr";
   9445 }
   9446 
   9447 static const HChar *
   9448 s390_irgen_MEEBR(UChar r1, UChar r2)
   9449 {
   9450    IRTemp op1 = newTemp(Ity_F32);
   9451    IRTemp op2 = newTemp(Ity_F32);
   9452    IRTemp result = newTemp(Ity_F32);
   9453    IRRoundingMode rounding_mode =
   9454       encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
   9455 
   9456    assign(op1, get_fpr_w0(r1));
   9457    assign(op2, get_fpr_w0(r2));
   9458    assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
   9459           mkexpr(op2)));
   9460    put_fpr_w0(r1, mkexpr(result));
   9461 
   9462    return "meebr";
   9463 }
   9464 
   9465 static const HChar *
   9466 s390_irgen_MDBR(UChar r1, UChar r2)
   9467 {
   9468    IRTemp op1 = newTemp(Ity_F64);
   9469    IRTemp op2 = newTemp(Ity_F64);
   9470    IRTemp result = newTemp(Ity_F64);
   9471    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
   9472 
   9473    assign(op1, get_fpr_dw0(r1));
   9474    assign(op2, get_fpr_dw0(r2));
   9475    assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
   9476           mkexpr(op2)));
   9477    put_fpr_dw0(r1, mkexpr(result));
   9478 
   9479    return "mdbr";
   9480 }
   9481 
   9482 static const HChar *
   9483 s390_irgen_MEEB(UChar r1, IRTemp op2addr)
   9484 {
   9485    IRTemp op1 = newTemp(Ity_F32);
   9486    IRTemp op2 = newTemp(Ity_F32);
   9487    IRTemp result = newTemp(Ity_F32);
   9488    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
   9489 
   9490    assign(op1, get_fpr_w0(r1));
   9491    assign(op2, load(Ity_F32, mkexpr(op2addr)));
   9492    assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
   9493