Home | History | Annotate | Download | only in priv
      1 /* -*- mode: C; c-basic-offset: 3; -*- */
      2 
      3 /*---------------------------------------------------------------*/
      4 /*--- begin                                  host_s390_defs.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    Copyright (C) 2012-2015  Florian Krohm   (britzel (at) acm.org)
     13 
     14    This program is free software; you can redistribute it and/or
     15    modify it under the terms of the GNU General Public License as
     16    published by the Free Software Foundation; either version 2 of the
     17    License, or (at your option) any later version.
     18 
     19    This program is distributed in the hope that it will be useful, but
     20    WITHOUT ANY WARRANTY; without even the implied warranty of
     21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     22    General Public License for more details.
     23 
     24    You should have received a copy of the GNU General Public License
     25    along with this program; if not, write to the Free Software
     26    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     27    02110-1301, USA.
     28 
     29    The GNU General Public License is contained in the file COPYING.
     30 */
     31 
     32 /* Contributed by Florian Krohm */
     33 
     34 #include "libvex_basictypes.h"
     35 #include "libvex.h"
     36 #include "libvex_trc_values.h"
     37 #include "libvex_s390x_common.h"
     38 
     39 #include "main_util.h"
     40 #include "main_globals.h"
     41 #include "host_generic_regs.h"
     42 #include "host_s390_defs.h"
     43 #include "s390_disasm.h"
     44 #include "guest_s390_defs.h"    /* S390X_GUEST_OFFSET */
     45 #include <stdarg.h>
     46 
     47 /*------------------------------------------------------------*/
     48 /*--- Forward declarations                                 ---*/
     49 /*------------------------------------------------------------*/
     50 
     51 static Bool s390_insn_is_reg_reg_move(const s390_insn *, HReg *src, HReg *dst);
     52 static void s390_insn_map_regs(HRegRemap *, s390_insn *);
     53 static void s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *);
     54 static UInt s390_tchain_load64_len(void);
     55 
     56 
     57 /*------------------------------------------------------------*/
     58 /*--- Registers                                            ---*/
     59 /*------------------------------------------------------------*/
     60 
     61 /* A mapping from register number to register index */
     62 static Int gpr_index[16];  // GPR regno -> register index
     63 static Int fpr_index[16];  // FPR regno -> register index
     64 
     65 HReg
     66 s390_hreg_gpr(UInt regno)
     67 {
     68    Int ix = gpr_index[regno];
     69    vassert(ix >= 0);
     70    return mkHReg(/*virtual*/False, HRcInt64, regno, ix);
     71 }
     72 
     73 HReg
     74 s390_hreg_fpr(UInt regno)
     75 {
     76    Int ix = fpr_index[regno];
     77    vassert(ix >= 0);
     78    return mkHReg(/*virtual*/False, HRcFlt64, regno, ix);
     79 }
     80 
     81 static __inline__ UInt
     82 hregNumber(HReg reg)
     83 {
     84    return hregEncoding(reg);
     85 }
     86 
     87 /* Decompile the given register into a static buffer and return it */
     88 const HChar *
     89 s390_hreg_as_string(HReg reg)
     90 {
     91    static HChar buf[10];
     92 
     93    static const HChar ireg_names[16][5] = {
     94       "%r0",  "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",
     95       "%r8",  "%r9",  "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
     96    };
     97 
     98    static const HChar freg_names[16][5] = {
     99       "%f0",  "%f1",  "%f2",  "%f3",  "%f4",  "%f5",  "%f6",  "%f7",
    100       "%f8",  "%f9",  "%f10", "%f11", "%f12", "%f13", "%f14", "%f15"
    101    };
    102 
    103    UInt r;  /* hregNumber() returns an UInt */
    104 
    105    r = hregNumber(reg);
    106 
    107    /* Be generic for all virtual regs. */
    108    if (hregIsVirtual(reg)) {
    109       buf[0] = '\0';
    110       switch (hregClass(reg)) {
    111       case HRcInt64: vex_sprintf(buf, "%%vR%u", r); break;
    112       case HRcFlt64: vex_sprintf(buf, "%%vF%u", r); break;
    113       default:       goto fail;
    114       }
    115       return buf;
    116    }
    117 
    118    /* But specific for real regs. */
    119    vassert(r < 16);
    120 
    121    switch (hregClass(reg)) {
    122    case HRcInt64: return ireg_names[r];
    123    case HRcFlt64: return freg_names[r];
    124    default:       goto fail;
    125    }
    126 
    127  fail: vpanic("s390_hreg_as_string");
    128 }
    129 
    130 
    131 /* Return the real register that holds the guest state pointer */
    132 HReg
    133 s390_hreg_guest_state_pointer(void)
    134 {
    135    return s390_hreg_gpr(S390_REGNO_GUEST_STATE_POINTER);
    136 }
    137 
    138 
    139 /* Is VALUE within the domain of a 20-bit signed integer. */
    140 static __inline__ Bool
    141 fits_signed_20bit(Int value)
    142 {
    143    UInt uval = value;
    144    return ((Int)(uval << 12) >> 12) == value;
    145 }
    146 
    147 
    148 /* Is VALUE within the domain of a 12-bit unsigned integer. */
    149 static __inline__ Bool
    150 fits_unsigned_12bit(Int value)
    151 {
    152    return (value & 0xFFF) == value;
    153 }
    154 
    155 /*------------------------------------------------------------*/
    156 /*--- Addressing modes (amodes)                            ---*/
    157 /*------------------------------------------------------------*/
    158 
    159 /* Construct a b12 amode. */
    160 s390_amode *
    161 s390_amode_b12(Int d, HReg b)
    162 {
    163    s390_amode *am = LibVEX_Alloc_inline(sizeof(s390_amode));
    164 
    165    vassert(fits_unsigned_12bit(d));
    166 
    167    am->tag = S390_AMODE_B12;
    168    am->d = d;
    169    am->b = b;
    170    am->x = s390_hreg_gpr(0);  /* hregNumber(am->x) == 0 */
    171 
    172    return am;
    173 }
    174 
    175 
    176 /* Construct a b20 amode. */
    177 s390_amode *
    178 s390_amode_b20(Int d, HReg b)
    179 {
    180    s390_amode *am = LibVEX_Alloc_inline(sizeof(s390_amode));
    181 
    182    vassert(fits_signed_20bit(d));
    183 
    184    am->tag = S390_AMODE_B20;
    185    am->d = d;
    186    am->b = b;
    187    am->x = s390_hreg_gpr(0);  /* hregNumber(am->x) == 0 */
    188 
    189    return am;
    190 }
    191 
    192 
    193 /* Construct a bx12 amode. */
    194 s390_amode *
    195 s390_amode_bx12(Int d, HReg b, HReg x)
    196 {
    197    s390_amode *am = LibVEX_Alloc_inline(sizeof(s390_amode));
    198 
    199    vassert(fits_unsigned_12bit(d));
    200    vassert(hregNumber(b) != 0);
    201    vassert(hregNumber(x) != 0);
    202 
    203    am->tag = S390_AMODE_BX12;
    204    am->d = d;
    205    am->b = b;
    206    am->x = x;
    207 
    208    return am;
    209 }
    210 
    211 
    212 /* Construct a bx20 amode. */
    213 s390_amode *
    214 s390_amode_bx20(Int d, HReg b, HReg x)
    215 {
    216    s390_amode *am = LibVEX_Alloc_inline(sizeof(s390_amode));
    217 
    218    vassert(fits_signed_20bit(d));
    219    vassert(hregNumber(b) != 0);
    220    vassert(hregNumber(x) != 0);
    221 
    222    am->tag = S390_AMODE_BX20;
    223    am->d = d;
    224    am->b = b;
    225    am->x = x;
    226 
    227    return am;
    228 }
    229 
    230 
    231 /* Construct an AMODE for accessing the guest state at OFFSET.
    232    OFFSET can be at most 3 * sizeof(VexGuestS390XState) + LibVEX_N_SPILL_BYTES
    233    which may be too large for a B12 addressing mode.
    234    Use a B20 amode as a fallback which will be safe for any offset.
    235 */
    236 s390_amode *
    237 s390_amode_for_guest_state(Int offset)
    238 {
    239    if (fits_unsigned_12bit(offset))
    240       return s390_amode_b12(offset, s390_hreg_guest_state_pointer());
    241 
    242    if (fits_signed_20bit(offset))
    243       return s390_amode_b20(offset, s390_hreg_guest_state_pointer());
    244 
    245    vpanic("invalid guest state offset");
    246 }
    247 
    248 
    249 /* Decompile the given amode into a static buffer and return it. */
    250 const HChar *
    251 s390_amode_as_string(const s390_amode *am)
    252 {
    253    static HChar buf[30];
    254    HChar *p;
    255 
    256    buf[0] = '\0';
    257    p = buf;
    258 
    259    switch (am->tag) {
    260    case S390_AMODE_B12:
    261    case S390_AMODE_B20:
    262       vex_sprintf(p, "%d(%s)", am->d, s390_hreg_as_string(am->b));
    263       break;
    264 
    265    case S390_AMODE_BX12:
    266    case S390_AMODE_BX20:
    267       /* s390_hreg_as_string returns pointer to local buffer. Need to
    268          split this into two printfs */
    269       p += vex_sprintf(p, "%d(%s,", am->d, s390_hreg_as_string(am->x));
    270       vex_sprintf(p, "%s)", s390_hreg_as_string(am->b));
    271       break;
    272 
    273    default:
    274       vpanic("s390_amode_as_string");
    275    }
    276 
    277    return buf;
    278 }
    279 
    280 
    281 /* Helper function for s390_amode_is_sane */
    282 static __inline__ Bool
    283 is_virtual_gpr(HReg reg)
    284 {
    285    return hregIsVirtual(reg) && hregClass(reg) == HRcInt64;
    286 }
    287 
    288 
    289 /* Sanity check for an amode */
    290 Bool
    291 s390_amode_is_sane(const s390_amode *am)
    292 {
    293    switch (am->tag) {
    294    case S390_AMODE_B12:
    295       return is_virtual_gpr(am->b) && fits_unsigned_12bit(am->d);
    296 
    297    case S390_AMODE_B20:
    298       return is_virtual_gpr(am->b) && fits_signed_20bit(am->d);
    299 
    300    case S390_AMODE_BX12:
    301       return is_virtual_gpr(am->b) && is_virtual_gpr(am->x) &&
    302              fits_unsigned_12bit(am->d);
    303 
    304    case S390_AMODE_BX20:
    305       return is_virtual_gpr(am->b) && is_virtual_gpr(am->x) &&
    306              fits_signed_20bit(am->d);
    307 
    308    default:
    309       vpanic("s390_amode_is_sane");
    310    }
    311 }
    312 
    313 
    314 /* Record the register use of an amode */
    315 static void
    316 s390_amode_get_reg_usage(HRegUsage *u, const s390_amode *am)
    317 {
    318    switch (am->tag) {
    319    case S390_AMODE_B12:
    320    case S390_AMODE_B20:
    321       addHRegUse(u, HRmRead, am->b);
    322       return;
    323 
    324    case S390_AMODE_BX12:
    325    case S390_AMODE_BX20:
    326       addHRegUse(u, HRmRead, am->b);
    327       addHRegUse(u, HRmRead, am->x);
    328       return;
    329 
    330    default:
    331       vpanic("s390_amode_get_reg_usage");
    332    }
    333 }
    334 
    335 
    336 static void
    337 s390_amode_map_regs(HRegRemap *m, s390_amode *am)
    338 {
    339    switch (am->tag) {
    340    case S390_AMODE_B12:
    341    case S390_AMODE_B20:
    342       am->b = lookupHRegRemap(m, am->b);
    343       return;
    344 
    345    case S390_AMODE_BX12:
    346    case S390_AMODE_BX20:
    347       am->b = lookupHRegRemap(m, am->b);
    348       am->x = lookupHRegRemap(m, am->x);
    349       return;
    350 
    351    default:
    352       vpanic("s390_amode_map_regs");
    353    }
    354 }
    355 
    356 
    357 void
    358 ppS390AMode(const s390_amode *am)
    359 {
    360    vex_printf("%s", s390_amode_as_string(am));
    361 }
    362 
    363 void
    364 ppS390Instr(const s390_insn *insn, Bool mode64)
    365 {
    366    vex_printf("%s", s390_insn_as_string(insn));
    367 }
    368 
    369 void
    370 ppHRegS390(HReg reg)
    371 {
    372    vex_printf("%s", s390_hreg_as_string(reg));
    373 }
    374 
    375 /*------------------------------------------------------------*/
    376 /*--- Helpers for register allocation                      ---*/
    377 /*------------------------------------------------------------*/
    378 
    379 /* Initialise and return the "register universe", i.e. a list of
    380    all hardware registers. Called once. */
    381 const RRegUniverse *
    382 getRRegUniverse_S390(void)
    383 {
    384    static RRegUniverse all_regs;
    385    static Bool initialised = False;
    386    RRegUniverse *ru = &all_regs;
    387 
    388    if (LIKELY(initialised))
    389       return ru;
    390 
    391    RRegUniverse__init(ru);
    392 
    393    /* Assign invalid values to the gpr/fpr_index */
    394    for (UInt i = 0; i < sizeof gpr_index / sizeof gpr_index[0]; ++i)
    395       gpr_index[i] = -1;
    396    for (UInt i = 0; i < sizeof fpr_index / sizeof fpr_index[0]; ++i)
    397       fpr_index[i] = -1;
    398 
    399    /* Add the registers that are available to the register allocator.
    400       GPRs:  registers 1..11 are available
    401       FPRs:  registers 0..15 are available
    402              FPR12 - FPR15 are also used as register pairs for 128-bit
    403              floating point operations
    404    */
    405    UInt regno;
    406    for (regno = 1; regno <= 11; ++regno) {
    407       gpr_index[regno] = ru->size;
    408       ru->regs[ru->size++] = s390_hreg_gpr(regno);
    409    }
    410    for (regno = 0; regno <= 15; ++regno) {
    411       fpr_index[regno] = ru->size;
    412       ru->regs[ru->size++] = s390_hreg_fpr(regno);
    413    }
    414    ru->allocable = ru->size;
    415 
    416    /* Add the registers that are not available for allocation.
    417       r0  -- cannot be used as a base or index register
    418       r12 -- scratch register for translation chaining support
    419       r13 -- guest state pointer
    420       r14 -- link register
    421       r15 -- stack pointer
    422    */
    423    UInt other[] = { 0, 12, 13, 14, 15 };
    424    for (UInt i = 0; i < sizeof other / sizeof other[0]; ++i) {
    425       gpr_index[other[i]] = ru->size;
    426       ru->regs[ru->size++] = s390_hreg_gpr(other[i]);
    427    }
    428 
    429    /* Sanity checking */
    430    for (UInt i = 0; i < sizeof gpr_index / sizeof gpr_index[0]; ++i)
    431       vassert(gpr_index[i] >= 0);
    432    for (UInt i = 0; i < sizeof fpr_index / sizeof fpr_index[0]; ++i)
    433       vassert(fpr_index[i] >= 0);
    434 
    435    initialised = True;
    436    return ru;
    437 }
    438 
    439 /* Tell the register allocator how the given instruction uses the registers
    440    it refers to. */
    441 void
    442 getRegUsage_S390Instr(HRegUsage *u, const s390_insn *insn, Bool mode64)
    443 {
    444    s390_insn_get_reg_usage(u, insn);
    445 }
    446 
    447 
    448 /* Map the registers of the given instruction */
    449 void
    450 mapRegs_S390Instr(HRegRemap *m, s390_insn *insn, Bool mode64)
    451 {
    452    s390_insn_map_regs(m, insn);
    453 }
    454 
    455 
    456 /* Figure out if the given insn represents a reg-reg move, and if so
    457    assign the source and destination to *src and *dst.  If in doubt say No.
    458    Used by the register allocator to do move coalescing. */
    459 Bool
    460 isMove_S390Instr(const s390_insn *insn, HReg *src, HReg *dst)
    461 {
    462    return s390_insn_is_reg_reg_move(insn, src, dst);
    463 }
    464 
    465 
    466 /* Generate s390 spill/reload instructions under the direction of the
    467    register allocator.  Note it's critical these don't write the
    468    condition codes. This is like an Ist_Put */
    469 void
    470 genSpill_S390(HInstr **i1, HInstr **i2, HReg rreg, Int offsetB, Bool mode64)
    471 {
    472    s390_amode *am;
    473 
    474    vassert(offsetB >= 0);
    475    vassert(!hregIsVirtual(rreg));
    476 
    477    *i1 = *i2 = NULL;
    478 
    479    am = s390_amode_for_guest_state(offsetB);
    480 
    481    switch (hregClass(rreg)) {
    482    case HRcInt64:
    483    case HRcFlt64:
    484       *i1 = s390_insn_store(8, am, rreg);
    485       return;
    486 
    487    default:
    488       ppHRegClass(hregClass(rreg));
    489       vpanic("genSpill_S390: unimplemented regclass");
    490    }
    491 }
    492 
    493 
    494 /* This is like an Iex_Get */
    495 void
    496 genReload_S390(HInstr **i1, HInstr **i2, HReg rreg, Int offsetB, Bool mode64)
    497 {
    498    s390_amode *am;
    499 
    500    vassert(offsetB >= 0);
    501    vassert(!hregIsVirtual(rreg));
    502 
    503    *i1 = *i2 = NULL;
    504 
    505    am = s390_amode_for_guest_state(offsetB);
    506 
    507    switch (hregClass(rreg)) {
    508    case HRcInt64:
    509    case HRcFlt64:
    510       *i1 = s390_insn_load(8, rreg, am);
    511       return;
    512 
    513    default:
    514       ppHRegClass(hregClass(rreg));
    515       vpanic("genReload_S390: unimplemented regclass");
    516    }
    517 }
    518 
    519 /* Helper function for s390_insn_get_reg_usage */
    520 static void
    521 s390_opnd_RMI_get_reg_usage(HRegUsage *u, s390_opnd_RMI op)
    522 {
    523    switch (op.tag) {
    524    case S390_OPND_REG:
    525       addHRegUse(u, HRmRead, op.variant.reg);
    526       break;
    527 
    528    case S390_OPND_AMODE:
    529       s390_amode_get_reg_usage(u, op.variant.am);
    530       break;
    531 
    532    case S390_OPND_IMMEDIATE:
    533       break;
    534 
    535    default:
    536       vpanic("s390_opnd_RMI_get_reg_usage");
    537    }
    538 }
    539 
    540 
    541 /* Tell the register allocator how the given insn uses the registers */
    542 static void
    543 s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *insn)
    544 {
    545    initHRegUsage(u);
    546 
    547    switch (insn->tag) {
    548    case S390_INSN_LOAD:
    549       addHRegUse(u, HRmWrite, insn->variant.load.dst);
    550       s390_amode_get_reg_usage(u, insn->variant.load.src);
    551       break;
    552 
    553    case S390_INSN_LOAD_IMMEDIATE:
    554       addHRegUse(u, HRmWrite, insn->variant.load_immediate.dst);
    555       break;
    556 
    557    case S390_INSN_STORE:
    558       addHRegUse(u, HRmRead, insn->variant.store.src);
    559       s390_amode_get_reg_usage(u, insn->variant.store.dst);
    560       break;
    561 
    562    case S390_INSN_MOVE:
    563       addHRegUse(u, HRmRead,  insn->variant.move.src);
    564       addHRegUse(u, HRmWrite, insn->variant.move.dst);
    565       break;
    566 
    567    case S390_INSN_MEMCPY:
    568       s390_amode_get_reg_usage(u, insn->variant.memcpy.src);
    569       s390_amode_get_reg_usage(u, insn->variant.memcpy.dst);
    570       break;
    571 
    572    case S390_INSN_COND_MOVE:
    573       s390_opnd_RMI_get_reg_usage(u, insn->variant.cond_move.src);
    574       addHRegUse(u, HRmWrite, insn->variant.cond_move.dst);
    575       break;
    576 
    577    case S390_INSN_ALU:
    578       addHRegUse(u, HRmWrite, insn->variant.alu.dst);
    579       addHRegUse(u, HRmRead,  insn->variant.alu.dst);  /* op1 */
    580       s390_opnd_RMI_get_reg_usage(u, insn->variant.alu.op2);
    581       break;
    582 
    583    case S390_INSN_SMUL:
    584    case S390_INSN_UMUL:
    585       addHRegUse(u, HRmRead,  insn->variant.mul.dst_lo);  /* op1 */
    586       addHRegUse(u, HRmWrite, insn->variant.mul.dst_lo);
    587       addHRegUse(u, HRmWrite, insn->variant.mul.dst_hi);
    588       s390_opnd_RMI_get_reg_usage(u, insn->variant.mul.op2);
    589       break;
    590 
    591    case S390_INSN_SDIV:
    592    case S390_INSN_UDIV:
    593       addHRegUse(u, HRmRead,  insn->variant.div.op1_lo);
    594       addHRegUse(u, HRmRead,  insn->variant.div.op1_hi);
    595       addHRegUse(u, HRmWrite, insn->variant.div.op1_lo);
    596       addHRegUse(u, HRmWrite, insn->variant.div.op1_hi);
    597       s390_opnd_RMI_get_reg_usage(u, insn->variant.div.op2);
    598       break;
    599 
    600    case S390_INSN_DIVS:
    601       addHRegUse(u, HRmRead,  insn->variant.divs.op1);
    602       addHRegUse(u, HRmWrite, insn->variant.divs.op1); /* quotient */
    603       addHRegUse(u, HRmWrite, insn->variant.divs.rem); /* remainder */
    604       s390_opnd_RMI_get_reg_usage(u, insn->variant.divs.op2);
    605       break;
    606 
    607    case S390_INSN_CLZ:
    608       addHRegUse(u, HRmWrite, insn->variant.clz.num_bits);
    609       addHRegUse(u, HRmWrite, insn->variant.clz.clobber);
    610       s390_opnd_RMI_get_reg_usage(u, insn->variant.clz.src);
    611       break;
    612 
    613    case S390_INSN_UNOP:
    614       addHRegUse(u, HRmWrite, insn->variant.unop.dst);
    615       s390_opnd_RMI_get_reg_usage(u, insn->variant.unop.src);
    616       break;
    617 
    618    case S390_INSN_TEST:
    619       s390_opnd_RMI_get_reg_usage(u, insn->variant.test.src);
    620       break;
    621 
    622    case S390_INSN_CC2BOOL:
    623       addHRegUse(u, HRmWrite, insn->variant.cc2bool.dst);
    624       break;
    625 
    626    case S390_INSN_CAS:
    627       addHRegUse(u, HRmRead,  insn->variant.cas.op1);
    628       s390_amode_get_reg_usage(u, insn->variant.cas.op2);
    629       addHRegUse(u, HRmRead,  insn->variant.cas.op3);
    630       addHRegUse(u, HRmWrite,  insn->variant.cas.old_mem);
    631       break;
    632 
    633    case S390_INSN_CDAS: {
    634       s390_cdas *cdas = insn->variant.cdas.details;
    635 
    636       addHRegUse(u, HRmRead,  cdas->op1_high);
    637       addHRegUse(u, HRmRead,  cdas->op1_low);
    638       s390_amode_get_reg_usage(u, cdas->op2);
    639       addHRegUse(u, HRmRead,  cdas->op3_high);
    640       addHRegUse(u, HRmRead,  cdas->op3_low);
    641       addHRegUse(u, HRmWrite, cdas->old_mem_high);
    642       addHRegUse(u, HRmWrite, cdas->old_mem_low);
    643       addHRegUse(u, HRmWrite, cdas->scratch);
    644       break;
    645    }
    646 
    647    case S390_INSN_COMPARE:
    648       addHRegUse(u, HRmRead, insn->variant.compare.src1);
    649       s390_opnd_RMI_get_reg_usage(u, insn->variant.compare.src2);
    650       break;
    651 
    652    case S390_INSN_HELPER_CALL: {
    653       UInt i;
    654 
    655       /* Assume that all volatile registers are clobbered. ABI says,
    656          volatile registers are: r0 - r5. Valgrind's register allocator
    657          does not know about r0, so we can leave that out */
    658       for (i = 1; i <= 5; ++i) {
    659          addHRegUse(u, HRmWrite, s390_hreg_gpr(i));
    660       }
    661 
    662       /* Ditto for floating point registers. f0 - f7 are volatile */
    663       for (i = 0; i <= 7; ++i) {
    664          addHRegUse(u, HRmWrite, s390_hreg_fpr(i));
    665       }
    666 
    667       /* The registers that are used for passing arguments will be read.
    668          Not all of them may, but in general we need to assume that. */
    669       for (i = 0; i < insn->variant.helper_call.details->num_args; ++i) {
    670          addHRegUse(u, HRmRead, s390_hreg_gpr(s390_gprno_from_arg_index(i)));
    671       }
    672 
    673       /* s390_insn_helper_call_emit also reads / writes the link register
    674          and stack pointer. But those registers are not visible to the
    675          register allocator. So we don't need to do anything for them. */
    676       break;
    677    }
    678 
    679    case S390_INSN_BFP_TRIOP:
    680       addHRegUse(u, HRmWrite, insn->variant.bfp_triop.dst);
    681       addHRegUse(u, HRmRead,  insn->variant.bfp_triop.dst);  /* first */
    682       addHRegUse(u, HRmRead,  insn->variant.bfp_triop.op2);  /* second */
    683       addHRegUse(u, HRmRead,  insn->variant.bfp_triop.op3);  /* third */
    684       break;
    685 
    686    case S390_INSN_BFP_BINOP:
    687       addHRegUse(u, HRmWrite, insn->variant.bfp_binop.dst_hi);
    688       addHRegUse(u, HRmRead,  insn->variant.bfp_binop.dst_hi);  /* left */
    689       addHRegUse(u, HRmRead,  insn->variant.bfp_binop.op2_hi);  /* right */
    690       if (insn->size == 16) {
    691          addHRegUse(u, HRmWrite, insn->variant.bfp_binop.dst_lo);
    692          addHRegUse(u, HRmRead,  insn->variant.bfp_binop.dst_lo);  /* left */
    693          addHRegUse(u, HRmRead,  insn->variant.bfp_binop.op2_lo);  /* right */
    694       }
    695       break;
    696 
    697    case S390_INSN_BFP_UNOP:
    698       addHRegUse(u, HRmWrite, insn->variant.bfp_unop.dst_hi);
    699       addHRegUse(u, HRmRead,  insn->variant.bfp_unop.op_hi);  /* operand */
    700       if (insn->size == 16) {
    701          addHRegUse(u, HRmWrite, insn->variant.bfp_unop.dst_lo);
    702          addHRegUse(u, HRmRead,  insn->variant.bfp_unop.op_lo);  /* operand */
    703       }
    704       break;
    705 
    706    case S390_INSN_BFP_COMPARE:
    707       addHRegUse(u, HRmWrite, insn->variant.bfp_compare.dst);
    708       addHRegUse(u, HRmRead,  insn->variant.bfp_compare.op1_hi);  /* left */
    709       addHRegUse(u, HRmRead,  insn->variant.bfp_compare.op2_hi);  /* right */
    710       if (insn->size == 16) {
    711          addHRegUse(u, HRmRead,  insn->variant.bfp_compare.op1_lo);  /* left */
    712          addHRegUse(u, HRmRead,  insn->variant.bfp_compare.op2_lo);  /* right */
    713       }
    714       break;
    715 
    716    case S390_INSN_BFP_CONVERT:
    717       addHRegUse(u, HRmWrite, insn->variant.bfp_convert.dst_hi);
    718       if (! hregIsInvalid(insn->variant.bfp_convert.dst_lo))
    719          addHRegUse(u, HRmWrite, insn->variant.bfp_convert.dst_lo);
    720       addHRegUse(u, HRmRead,  insn->variant.bfp_convert.op_hi);
    721       if (! hregIsInvalid(insn->variant.bfp_convert.op_lo))
    722          addHRegUse(u, HRmRead, insn->variant.bfp_convert.op_lo);
    723       break;
    724 
    725    case S390_INSN_DFP_BINOP: {
    726       s390_dfp_binop *dfp_binop = insn->variant.dfp_binop.details;
    727 
    728       addHRegUse(u, HRmWrite, dfp_binop->dst_hi);
    729       addHRegUse(u, HRmRead,  dfp_binop->op2_hi);  /* left */
    730       addHRegUse(u, HRmRead,  dfp_binop->op3_hi);  /* right */
    731       if (insn->size == 16) {
    732          addHRegUse(u, HRmWrite, dfp_binop->dst_lo);
    733          addHRegUse(u, HRmRead,  dfp_binop->op2_lo);  /* left */
    734          addHRegUse(u, HRmRead,  dfp_binop->op3_lo);  /* right */
    735       }
    736       break;
    737    }
    738 
    739    case S390_INSN_DFP_UNOP:
    740       addHRegUse(u, HRmWrite, insn->variant.dfp_unop.dst_hi);
    741       addHRegUse(u, HRmRead,  insn->variant.dfp_unop.op_hi);  /* operand */
    742       if (insn->size == 16) {
    743          addHRegUse(u, HRmWrite, insn->variant.dfp_unop.dst_lo);
    744          addHRegUse(u, HRmRead,  insn->variant.dfp_unop.op_lo);  /* operand */
    745       }
    746       break;
    747 
    748    case S390_INSN_DFP_INTOP:
    749       addHRegUse(u, HRmWrite, insn->variant.dfp_intop.dst_hi);
    750       addHRegUse(u, HRmRead,  insn->variant.dfp_intop.op2);
    751       addHRegUse(u, HRmRead,  insn->variant.dfp_intop.op3_hi);
    752       if (insn->size == 16) {
    753          addHRegUse(u, HRmWrite, insn->variant.dfp_intop.dst_lo);
    754          addHRegUse(u, HRmRead,  insn->variant.dfp_intop.op3_lo);
    755       }
    756       break;
    757 
    758    case S390_INSN_DFP_COMPARE:
    759       addHRegUse(u, HRmWrite, insn->variant.dfp_compare.dst);
    760       addHRegUse(u, HRmRead,  insn->variant.dfp_compare.op1_hi);  /* left */
    761       addHRegUse(u, HRmRead,  insn->variant.dfp_compare.op2_hi);  /* right */
    762       if (insn->size == 16) {
    763          addHRegUse(u, HRmRead,  insn->variant.dfp_compare.op1_lo);  /* left */
    764          addHRegUse(u, HRmRead,  insn->variant.dfp_compare.op2_lo);  /* right */
    765       }
    766       break;
    767 
    768    case S390_INSN_DFP_CONVERT:
    769       addHRegUse(u, HRmWrite, insn->variant.dfp_convert.dst_hi);
    770       if (! hregIsInvalid(insn->variant.dfp_convert.dst_lo))
    771          addHRegUse(u, HRmWrite, insn->variant.dfp_convert.dst_lo);
    772       addHRegUse(u, HRmRead,  insn->variant.dfp_convert.op_hi);  /* operand */
    773       if (! hregIsInvalid(insn->variant.dfp_convert.op_lo))
    774          addHRegUse(u, HRmRead, insn->variant.dfp_convert.op_lo); /* operand */
    775       break;
    776 
    777    case S390_INSN_DFP_REROUND:
    778       addHRegUse(u, HRmWrite, insn->variant.dfp_reround.dst_hi);
    779       addHRegUse(u, HRmRead,  insn->variant.dfp_reround.op2);     /* left */
    780       addHRegUse(u, HRmRead,  insn->variant.dfp_reround.op3_hi);  /* right */
    781       if (insn->size == 16) {
    782          addHRegUse(u, HRmWrite, insn->variant.dfp_reround.dst_lo);
    783          addHRegUse(u, HRmRead,  insn->variant.dfp_reround.op3_lo); /* right */
    784       }
    785       break;
    786 
    787    case S390_INSN_FP_CONVERT: {
    788       s390_fp_convert *fp_convert = insn->variant.fp_convert.details;
    789 
    790       addHRegUse(u, HRmWrite, fp_convert->dst_hi);
    791       if (! hregIsInvalid(fp_convert->dst_lo))
    792          addHRegUse(u, HRmWrite, fp_convert->dst_lo);
    793       addHRegUse(u, HRmRead,  fp_convert->op_hi);
    794       if (! hregIsInvalid(fp_convert->op_lo))
    795          addHRegUse(u, HRmRead, fp_convert->op_lo);
    796       addHRegUse(u, HRmWrite, fp_convert->r1);
    797       break;
    798    }
    799 
    800    case S390_INSN_MIMM:
    801       s390_amode_get_reg_usage(u, insn->variant.mimm.dst);
    802       break;
    803 
    804    case S390_INSN_MADD:
    805       s390_amode_get_reg_usage(u, insn->variant.madd.dst);
    806       break;
    807 
    808    case S390_INSN_MFENCE:
    809       break;
    810 
    811    case S390_INSN_SET_FPC_BFPRM:
    812       addHRegUse(u, HRmRead,  insn->variant.set_fpc_bfprm.mode);
    813       break;
    814 
    815    case S390_INSN_SET_FPC_DFPRM:
    816       addHRegUse(u, HRmRead,  insn->variant.set_fpc_dfprm.mode);
    817       break;
    818 
    819    case S390_INSN_EVCHECK:
    820       s390_amode_get_reg_usage(u, insn->variant.evcheck.counter);
    821       s390_amode_get_reg_usage(u, insn->variant.evcheck.fail_addr);
    822       break;
    823 
    824    case S390_INSN_PROFINC:
    825       /* Does not use any register visible to the register allocator */
    826       break;
    827 
    828    case S390_INSN_XDIRECT:
    829       s390_amode_get_reg_usage(u, insn->variant.xdirect.guest_IA);
    830       break;
    831 
    832    case S390_INSN_XINDIR:
    833       addHRegUse(u, HRmRead, insn->variant.xindir.dst);
    834       s390_amode_get_reg_usage(u, insn->variant.xindir.guest_IA);
    835       break;
    836 
    837    case S390_INSN_XASSISTED:
    838       addHRegUse(u, HRmRead, insn->variant.xassisted.dst);
    839       s390_amode_get_reg_usage(u, insn->variant.xassisted.guest_IA);
    840       break;
    841 
    842    default:
    843       vpanic("s390_insn_get_reg_usage");
    844    }
    845 }
    846 
    847 
    848 /* Helper function for s390_insn_map_regs */
    849 static void
    850 s390_opnd_RMI_map_regs(HRegRemap *m, s390_opnd_RMI *op)
    851 {
    852    switch (op->tag) {
    853    case S390_OPND_REG:
    854       op->variant.reg = lookupHRegRemap(m, op->variant.reg);
    855       break;
    856 
    857    case S390_OPND_IMMEDIATE:
    858       break;
    859 
    860    case S390_OPND_AMODE:
    861       s390_amode_map_regs(m, op->variant.am);
    862       break;
    863 
    864    default:
    865       vpanic("s390_opnd_RMI_map_regs");
    866    }
    867 }
    868 
    869 
    870 static void
    871 s390_insn_map_regs(HRegRemap *m, s390_insn *insn)
    872 {
    873    switch (insn->tag) {
    874    case S390_INSN_LOAD:
    875       insn->variant.load.dst = lookupHRegRemap(m, insn->variant.load.dst);
    876       s390_amode_map_regs(m, insn->variant.load.src);
    877       break;
    878 
    879    case S390_INSN_STORE:
    880       s390_amode_map_regs(m, insn->variant.store.dst);
    881       insn->variant.store.src = lookupHRegRemap(m, insn->variant.store.src);
    882       break;
    883 
    884    case S390_INSN_MOVE:
    885       insn->variant.move.dst = lookupHRegRemap(m, insn->variant.move.dst);
    886       insn->variant.move.src = lookupHRegRemap(m, insn->variant.move.src);
    887       break;
    888 
    889    case S390_INSN_MEMCPY:
    890       s390_amode_map_regs(m, insn->variant.memcpy.dst);
    891       s390_amode_map_regs(m, insn->variant.memcpy.src);
    892       break;
    893 
    894    case S390_INSN_COND_MOVE:
    895       insn->variant.cond_move.dst = lookupHRegRemap(m, insn->variant.cond_move.dst);
    896       s390_opnd_RMI_map_regs(m, &insn->variant.cond_move.src);
    897       break;
    898 
    899    case S390_INSN_LOAD_IMMEDIATE:
    900       insn->variant.load_immediate.dst =
    901          lookupHRegRemap(m, insn->variant.load_immediate.dst);
    902       break;
    903 
    904    case S390_INSN_ALU:
    905       insn->variant.alu.dst = lookupHRegRemap(m, insn->variant.alu.dst);
    906       s390_opnd_RMI_map_regs(m, &insn->variant.alu.op2);
    907       break;
    908 
    909    case S390_INSN_SMUL:
    910    case S390_INSN_UMUL:
    911       insn->variant.mul.dst_hi = lookupHRegRemap(m, insn->variant.mul.dst_hi);
    912       insn->variant.mul.dst_lo = lookupHRegRemap(m, insn->variant.mul.dst_lo);
    913       s390_opnd_RMI_map_regs(m, &insn->variant.mul.op2);
    914       break;
    915 
    916    case S390_INSN_SDIV:
    917    case S390_INSN_UDIV:
    918       insn->variant.div.op1_hi = lookupHRegRemap(m, insn->variant.div.op1_hi);
    919       insn->variant.div.op1_lo = lookupHRegRemap(m, insn->variant.div.op1_lo);
    920       s390_opnd_RMI_map_regs(m, &insn->variant.div.op2);
    921       break;
    922 
    923    case S390_INSN_DIVS:
    924       insn->variant.divs.op1 = lookupHRegRemap(m, insn->variant.divs.op1);
    925       insn->variant.divs.rem = lookupHRegRemap(m, insn->variant.divs.rem);
    926       s390_opnd_RMI_map_regs(m, &insn->variant.divs.op2);
    927       break;
    928 
    929    case S390_INSN_CLZ:
    930       insn->variant.clz.num_bits = lookupHRegRemap(m, insn->variant.clz.num_bits);
    931       insn->variant.clz.clobber  = lookupHRegRemap(m, insn->variant.clz.clobber);
    932       s390_opnd_RMI_map_regs(m, &insn->variant.clz.src);
    933       break;
    934 
    935    case S390_INSN_UNOP:
    936       insn->variant.unop.dst = lookupHRegRemap(m, insn->variant.unop.dst);
    937       s390_opnd_RMI_map_regs(m, &insn->variant.unop.src);
    938       break;
    939 
    940    case S390_INSN_TEST:
    941       s390_opnd_RMI_map_regs(m, &insn->variant.test.src);
    942       break;
    943 
    944    case S390_INSN_CC2BOOL:
    945       insn->variant.cc2bool.dst = lookupHRegRemap(m, insn->variant.cc2bool.dst);
    946       break;
    947 
    948    case S390_INSN_CAS:
    949       insn->variant.cas.op1 = lookupHRegRemap(m, insn->variant.cas.op1);
    950       s390_amode_map_regs(m, insn->variant.cas.op2);
    951       insn->variant.cas.op3 = lookupHRegRemap(m, insn->variant.cas.op3);
    952       insn->variant.cas.old_mem = lookupHRegRemap(m, insn->variant.cas.old_mem);
    953       break;
    954 
    955    case S390_INSN_CDAS: {
    956       s390_cdas *cdas = insn->variant.cdas.details;
    957 
    958       cdas->op1_high = lookupHRegRemap(m, cdas->op1_high);
    959       cdas->op1_low  = lookupHRegRemap(m, cdas->op1_low);
    960       s390_amode_map_regs(m, cdas->op2);
    961       cdas->op3_high = lookupHRegRemap(m, cdas->op3_high);
    962       cdas->op3_low  = lookupHRegRemap(m, cdas->op3_low);
    963       cdas->old_mem_high = lookupHRegRemap(m, cdas->old_mem_high);
    964       cdas->old_mem_low  = lookupHRegRemap(m, cdas->old_mem_low);
    965       cdas->scratch  = lookupHRegRemap(m, cdas->scratch);
    966       break;
    967    }
    968 
    969    case S390_INSN_COMPARE:
    970       insn->variant.compare.src1 = lookupHRegRemap(m, insn->variant.compare.src1);
    971       s390_opnd_RMI_map_regs(m, &insn->variant.compare.src2);
    972       break;
    973 
    974    case S390_INSN_HELPER_CALL:
    975       /* s390_insn_helper_call_emit also reads / writes the link register
    976          and stack pointer. But those registers are not visible to the
    977          register allocator. So we don't need to do anything for them.
    978          As for the arguments of the helper call -- they will be loaded into
    979          non-virtual registers. Again, we don't need to do anything for those
    980          here. */
    981       break;
    982 
    983    case S390_INSN_BFP_TRIOP:
    984       insn->variant.bfp_triop.dst =
    985          lookupHRegRemap(m, insn->variant.bfp_triop.dst);
    986       insn->variant.bfp_triop.op2 =
    987          lookupHRegRemap(m, insn->variant.bfp_triop.op2);
    988       insn->variant.bfp_triop.op3 =
    989          lookupHRegRemap(m, insn->variant.bfp_triop.op3);
    990       break;
    991 
    992    case S390_INSN_BFP_BINOP:
    993       insn->variant.bfp_binop.dst_hi =
    994          lookupHRegRemap(m, insn->variant.bfp_binop.dst_hi);
    995       insn->variant.bfp_binop.op2_hi =
    996          lookupHRegRemap(m, insn->variant.bfp_binop.op2_hi);
    997       if (insn->size == 16) {
    998          insn->variant.bfp_binop.dst_lo =
    999             lookupHRegRemap(m, insn->variant.bfp_binop.dst_lo);
   1000          insn->variant.bfp_binop.op2_lo  =
   1001             lookupHRegRemap(m, insn->variant.bfp_binop.op2_lo);
   1002       }
   1003       break;
   1004 
   1005    case S390_INSN_BFP_UNOP:
   1006       insn->variant.bfp_unop.dst_hi =
   1007          lookupHRegRemap(m, insn->variant.bfp_unop.dst_hi);
   1008       insn->variant.bfp_unop.op_hi  =
   1009          lookupHRegRemap(m, insn->variant.bfp_unop.op_hi);
   1010       if (insn->size == 16) {
   1011          insn->variant.bfp_unop.dst_lo =
   1012             lookupHRegRemap(m, insn->variant.bfp_unop.dst_lo);
   1013          insn->variant.bfp_unop.op_lo  =
   1014             lookupHRegRemap(m, insn->variant.bfp_unop.op_lo);
   1015       }
   1016       break;
   1017 
   1018    case S390_INSN_BFP_COMPARE:
   1019       insn->variant.bfp_compare.dst =
   1020          lookupHRegRemap(m, insn->variant.bfp_compare.dst);
   1021       insn->variant.bfp_compare.op1_hi =
   1022          lookupHRegRemap(m, insn->variant.bfp_compare.op1_hi);
   1023       insn->variant.bfp_compare.op2_hi =
   1024          lookupHRegRemap(m, insn->variant.bfp_compare.op2_hi);
   1025       if (insn->size == 16) {
   1026          insn->variant.bfp_compare.op1_lo =
   1027             lookupHRegRemap(m, insn->variant.bfp_compare.op1_lo);
   1028          insn->variant.bfp_compare.op2_lo =
   1029             lookupHRegRemap(m, insn->variant.bfp_compare.op2_lo);
   1030       }
   1031       break;
   1032 
   1033    case S390_INSN_BFP_CONVERT:
   1034       insn->variant.bfp_convert.dst_hi =
   1035          lookupHRegRemap(m, insn->variant.bfp_convert.dst_hi);
   1036       if (! hregIsInvalid(insn->variant.bfp_convert.dst_lo))
   1037          insn->variant.bfp_convert.dst_lo =
   1038             lookupHRegRemap(m, insn->variant.bfp_convert.dst_lo);
   1039       insn->variant.bfp_convert.op_hi =
   1040          lookupHRegRemap(m, insn->variant.bfp_convert.op_hi);
   1041       if (! hregIsInvalid(insn->variant.bfp_convert.op_lo))
   1042          insn->variant.bfp_convert.op_lo =
   1043             lookupHRegRemap(m, insn->variant.bfp_convert.op_lo);
   1044       break;
   1045 
   1046    case S390_INSN_DFP_BINOP: {
   1047       s390_dfp_binop *dfp_binop = insn->variant.dfp_binop.details;
   1048 
   1049       dfp_binop->dst_hi = lookupHRegRemap(m, dfp_binop->dst_hi);
   1050       dfp_binop->op2_hi = lookupHRegRemap(m, dfp_binop->op2_hi);
   1051       dfp_binop->op3_hi = lookupHRegRemap(m, dfp_binop->op3_hi);
   1052       if (insn->size == 16) {
   1053          dfp_binop->dst_lo = lookupHRegRemap(m, dfp_binop->dst_lo);
   1054          dfp_binop->op2_lo = lookupHRegRemap(m, dfp_binop->op2_lo);
   1055          dfp_binop->op3_lo = lookupHRegRemap(m, dfp_binop->op3_lo);
   1056       }
   1057       break;
   1058    }
   1059 
   1060    case S390_INSN_DFP_UNOP:
   1061       insn->variant.dfp_unop.dst_hi =
   1062          lookupHRegRemap(m, insn->variant.dfp_unop.dst_hi);
   1063       insn->variant.dfp_unop.op_hi  =
   1064          lookupHRegRemap(m, insn->variant.dfp_unop.op_hi);
   1065       if (insn->size == 16) {
   1066          insn->variant.dfp_unop.dst_lo =
   1067             lookupHRegRemap(m, insn->variant.dfp_unop.dst_lo);
   1068          insn->variant.dfp_unop.op_lo  =
   1069             lookupHRegRemap(m, insn->variant.dfp_unop.op_lo);
   1070       }
   1071       break;
   1072 
   1073    case S390_INSN_DFP_INTOP:
   1074       insn->variant.dfp_intop.dst_hi =
   1075          lookupHRegRemap(m, insn->variant.dfp_intop.dst_hi);
   1076       insn->variant.dfp_intop.op2    =
   1077          lookupHRegRemap(m, insn->variant.dfp_intop.op2);
   1078       insn->variant.dfp_intop.op3_hi =
   1079          lookupHRegRemap(m, insn->variant.dfp_intop.op3_hi);
   1080       if (insn->size == 16) {
   1081          insn->variant.dfp_intop.dst_lo =
   1082             lookupHRegRemap(m, insn->variant.dfp_intop.dst_lo);
   1083          insn->variant.dfp_intop.op3_lo =
   1084             lookupHRegRemap(m, insn->variant.dfp_intop.op3_lo);
   1085       }
   1086       break;
   1087 
   1088    case S390_INSN_DFP_COMPARE:
   1089       insn->variant.dfp_compare.dst =
   1090          lookupHRegRemap(m, insn->variant.dfp_compare.dst);
   1091       insn->variant.dfp_compare.op1_hi =
   1092          lookupHRegRemap(m, insn->variant.dfp_compare.op1_hi);
   1093       insn->variant.dfp_compare.op2_hi =
   1094          lookupHRegRemap(m, insn->variant.dfp_compare.op2_hi);
   1095       if (insn->size == 16) {
   1096          insn->variant.dfp_compare.op1_lo =
   1097             lookupHRegRemap(m, insn->variant.dfp_compare.op1_lo);
   1098          insn->variant.dfp_compare.op2_lo =
   1099             lookupHRegRemap(m, insn->variant.dfp_compare.op2_lo);
   1100       }
   1101       break;
   1102 
   1103    case S390_INSN_DFP_CONVERT:
   1104       insn->variant.dfp_convert.dst_hi =
   1105          lookupHRegRemap(m, insn->variant.dfp_convert.dst_hi);
   1106       if (! hregIsInvalid(insn->variant.dfp_convert.dst_lo))
   1107          insn->variant.dfp_convert.dst_lo =
   1108             lookupHRegRemap(m, insn->variant.dfp_convert.dst_lo);
   1109       insn->variant.dfp_convert.op_hi =
   1110          lookupHRegRemap(m, insn->variant.dfp_convert.op_hi);
   1111       if (! hregIsInvalid(insn->variant.dfp_convert.op_lo))
   1112          insn->variant.dfp_convert.op_lo =
   1113             lookupHRegRemap(m, insn->variant.dfp_convert.op_lo);
   1114       break;
   1115 
   1116    case S390_INSN_DFP_REROUND:
   1117       insn->variant.dfp_reround.dst_hi =
   1118          lookupHRegRemap(m, insn->variant.dfp_reround.dst_hi);
   1119       insn->variant.dfp_reround.op2    =
   1120          lookupHRegRemap(m, insn->variant.dfp_reround.op2);
   1121       insn->variant.dfp_reround.op3_hi =
   1122          lookupHRegRemap(m, insn->variant.dfp_reround.op3_hi);
   1123       if (insn->size == 16) {
   1124          insn->variant.dfp_reround.dst_lo =
   1125             lookupHRegRemap(m, insn->variant.dfp_reround.dst_lo);
   1126          insn->variant.dfp_reround.op3_lo =
   1127             lookupHRegRemap(m, insn->variant.dfp_reround.op3_lo);
   1128       }
   1129       break;
   1130 
   1131    case S390_INSN_FP_CONVERT: {
   1132       s390_fp_convert *fp_convert = insn->variant.fp_convert.details;
   1133 
   1134       fp_convert->dst_hi = lookupHRegRemap(m, fp_convert->dst_hi);
   1135       if (! hregIsInvalid(fp_convert->dst_lo))
   1136          fp_convert->dst_lo = lookupHRegRemap(m, fp_convert->dst_lo);
   1137       fp_convert->op_hi = lookupHRegRemap(m, fp_convert->op_hi);
   1138       if (! hregIsInvalid(fp_convert->op_lo))
   1139          fp_convert->op_lo = lookupHRegRemap(m, fp_convert->op_lo);
   1140       fp_convert->r1 = lookupHRegRemap(m, fp_convert->r1);
   1141       break;
   1142    }
   1143 
   1144    case S390_INSN_MIMM:
   1145       s390_amode_map_regs(m, insn->variant.mimm.dst);
   1146       break;
   1147 
   1148    case S390_INSN_MADD:
   1149       s390_amode_map_regs(m, insn->variant.madd.dst);
   1150       break;
   1151 
   1152    case S390_INSN_MFENCE:
   1153       break;
   1154 
   1155    case S390_INSN_SET_FPC_BFPRM:
   1156       insn->variant.set_fpc_bfprm.mode =
   1157          lookupHRegRemap(m, insn->variant.set_fpc_bfprm.mode);
   1158       break;
   1159 
   1160    case S390_INSN_SET_FPC_DFPRM:
   1161       insn->variant.set_fpc_dfprm.mode =
   1162          lookupHRegRemap(m, insn->variant.set_fpc_dfprm.mode);
   1163       break;
   1164 
   1165    case S390_INSN_EVCHECK:
   1166       s390_amode_map_regs(m, insn->variant.evcheck.counter);
   1167       s390_amode_map_regs(m, insn->variant.evcheck.fail_addr);
   1168       break;
   1169 
   1170    case S390_INSN_PROFINC:
   1171       /* Does not use any register visible to the register allocator */
   1172       break;
   1173 
   1174    case S390_INSN_XDIRECT:
   1175       s390_amode_map_regs(m, insn->variant.xdirect.guest_IA);
   1176       break;
   1177 
   1178    case S390_INSN_XINDIR:
   1179       s390_amode_map_regs(m, insn->variant.xindir.guest_IA);
   1180       insn->variant.xindir.dst =
   1181          lookupHRegRemap(m, insn->variant.xindir.dst);
   1182       break;
   1183 
   1184    case S390_INSN_XASSISTED:
   1185       s390_amode_map_regs(m, insn->variant.xassisted.guest_IA);
   1186       insn->variant.xassisted.dst =
   1187          lookupHRegRemap(m, insn->variant.xassisted.dst);
   1188       break;
   1189 
   1190    default:
   1191       vpanic("s390_insn_map_regs");
   1192    }
   1193 }
   1194 
   1195 
   1196 /* Return True, if INSN is a move between two registers of the same class.
   1197    In that case assign the source and destination registers to SRC and DST,
   1198    respectively. */
   1199 static Bool
   1200 s390_insn_is_reg_reg_move(const s390_insn *insn, HReg *src, HReg *dst)
   1201 {
   1202    if (insn->tag == S390_INSN_MOVE &&
   1203        hregClass(insn->variant.move.src) == hregClass(insn->variant.move.dst)) {
   1204       *src = insn->variant.move.src;
   1205       *dst = insn->variant.move.dst;
   1206       return True;
   1207    }
   1208 
   1209    return False;
   1210 }
   1211 
   1212 
   1213 /*------------------------------------------------------------*/
   1214 /*--- Functions to emit a sequence of bytes                ---*/
   1215 /*------------------------------------------------------------*/
   1216 
   1217 static __inline__ UChar *
   1218 emit_2bytes(UChar *p, ULong val)
   1219 {
   1220    return (UChar *)__builtin_memcpy(p, ((UChar *)&val) + 6, 2) + 2;
   1221 }
   1222 
   1223 
   1224 static __inline__ UChar *
   1225 emit_4bytes(UChar *p, ULong val)
   1226 {
   1227    return (UChar *)__builtin_memcpy(p, ((UChar *)&val) + 4, 4) + 4;
   1228 }
   1229 
   1230 
   1231 static __inline__ UChar *
   1232 emit_6bytes(UChar *p, ULong val)
   1233 {
   1234    return (UChar *)__builtin_memcpy(p, ((UChar *)&val) + 2, 6) + 6;
   1235 }
   1236 
   1237 
   1238 /*------------------------------------------------------------*/
   1239 /*--- Functions to emit various instruction formats        ---*/
   1240 /*------------------------------------------------------------*/
   1241 
   1242 static UChar *
   1243 emit_RI(UChar *p, UInt op, UChar r1, UShort i2)
   1244 {
   1245    ULong the_insn = op;
   1246 
   1247    the_insn |= ((ULong)r1) << 20;
   1248    the_insn |= ((ULong)i2) << 0;
   1249 
   1250    return emit_4bytes(p, the_insn);
   1251 }
   1252 
   1253 
   1254 static UChar *
   1255 emit_RIL(UChar *p, ULong op, UChar r1, UInt i2)
   1256 {
   1257    ULong the_insn = op;
   1258 
   1259    the_insn |= ((ULong)r1) << 36;
   1260    the_insn |= ((ULong)i2) << 0;
   1261 
   1262    return emit_6bytes(p, the_insn);
   1263 }
   1264 
   1265 
   1266 static UChar *
   1267 emit_RR(UChar *p, UInt op, UChar r1, UChar r2)
   1268 {
   1269    ULong the_insn = op;
   1270 
   1271    the_insn |= ((ULong)r1) << 4;
   1272    the_insn |= ((ULong)r2) << 0;
   1273 
   1274    return emit_2bytes(p, the_insn);
   1275 }
   1276 
   1277 
   1278 static UChar *
   1279 emit_RRE(UChar *p, UInt op, UChar r1, UChar r2)
   1280 {
   1281    ULong the_insn = op;
   1282 
   1283    the_insn |= ((ULong)r1) << 4;
   1284    the_insn |= ((ULong)r2) << 0;
   1285 
   1286    return emit_4bytes(p, the_insn);
   1287 }
   1288 
   1289 
   1290 static UChar *
   1291 emit_RRF(UChar *p, UInt op, UChar r1, UChar r3, UChar r2)
   1292 {
   1293    ULong the_insn = op;
   1294 
   1295    the_insn |= ((ULong)r1) << 12;
   1296    the_insn |= ((ULong)r3) << 4;
   1297    the_insn |= ((ULong)r2) << 0;
   1298 
   1299    return emit_4bytes(p, the_insn);
   1300 }
   1301 
   1302 
   1303 static UChar *
   1304 emit_RRF2(UChar *p, UInt op, UChar m3, UChar m4, UChar r1, UChar r2)
   1305 {
   1306    ULong the_insn = op;
   1307 
   1308    the_insn |= ((ULong)m3) << 12;
   1309    the_insn |= ((ULong)m4) << 8;
   1310    the_insn |= ((ULong)r1) << 4;
   1311    the_insn |= ((ULong)r2) << 0;
   1312 
   1313    return emit_4bytes(p, the_insn);
   1314 }
   1315 
   1316 
   1317 static UChar *
   1318 emit_RRF3(UChar *p, UInt op, UChar r3, UChar r1, UChar r2)
   1319 {
   1320    ULong the_insn = op;
   1321 
   1322    the_insn |= ((ULong)r3) << 12;
   1323    the_insn |= ((ULong)r1) << 4;
   1324    the_insn |= ((ULong)r2) << 0;
   1325 
   1326    return emit_4bytes(p, the_insn);
   1327 }
   1328 
   1329 
   1330 static UChar *
   1331 emit_RRF4(UChar *p, UInt op, UChar r3, UChar m4, UChar r1, UChar r2)
   1332 {
   1333    ULong the_insn = op;
   1334 
   1335    the_insn |= ((ULong)r3) << 12;
   1336    the_insn |= ((ULong)m4) << 8;
   1337    the_insn |= ((ULong)r1) << 4;
   1338    the_insn |= ((ULong)r2) << 0;
   1339 
   1340    return emit_4bytes(p, the_insn);
   1341 }
   1342 
   1343 
   1344 static UChar *
   1345 emit_RRF5(UChar *p, UInt op, UChar m4, UChar r1, UChar r2)
   1346 {
   1347    ULong the_insn = op;
   1348 
   1349    the_insn |= ((ULong)m4) << 8;
   1350    the_insn |= ((ULong)r1) << 4;
   1351    the_insn |= ((ULong)r2) << 0;
   1352 
   1353    return emit_4bytes(p, the_insn);
   1354 }
   1355 
   1356 
   1357 static UChar *
   1358 emit_RS(UChar *p, UInt op, UChar r1, UChar r3, UChar b2, UShort d2)
   1359 {
   1360    ULong the_insn = op;
   1361 
   1362    the_insn |= ((ULong)r1) << 20;
   1363    the_insn |= ((ULong)r3) << 16;
   1364    the_insn |= ((ULong)b2) << 12;
   1365    the_insn |= ((ULong)d2) << 0;
   1366 
   1367    return emit_4bytes(p, the_insn);
   1368 }
   1369 
   1370 
   1371 static UChar *
   1372 emit_RSY(UChar *p, ULong op, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
   1373 {
   1374    ULong the_insn = op;
   1375 
   1376    the_insn |= ((ULong)r1) << 36;
   1377    the_insn |= ((ULong)r3) << 32;
   1378    the_insn |= ((ULong)b2) << 28;
   1379    the_insn |= ((ULong)dl2) << 16;
   1380    the_insn |= ((ULong)dh2) << 8;
   1381 
   1382    return emit_6bytes(p, the_insn);
   1383 }
   1384 
   1385 
   1386 static UChar *
   1387 emit_RX(UChar *p, UInt op, UChar r1, UChar x2, UChar b2, UShort d2)
   1388 {
   1389    ULong the_insn = op;
   1390 
   1391    the_insn |= ((ULong)r1) << 20;
   1392    the_insn |= ((ULong)x2) << 16;
   1393    the_insn |= ((ULong)b2) << 12;
   1394    the_insn |= ((ULong)d2) << 0;
   1395 
   1396    return emit_4bytes(p, the_insn);
   1397 }
   1398 
   1399 
   1400 static UChar *
   1401 emit_RXF(UChar *p, ULong op, UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
   1402 {
   1403    ULong the_insn = op;
   1404 
   1405    the_insn |= ((ULong)r3) << 36;
   1406    the_insn |= ((ULong)x2) << 32;
   1407    the_insn |= ((ULong)b2) << 28;
   1408    the_insn |= ((ULong)d2) << 16;
   1409    the_insn |= ((ULong)r1) << 12;
   1410 
   1411    return emit_6bytes(p, the_insn);
   1412 }
   1413 
   1414 
   1415 static UChar *
   1416 emit_RXY(UChar *p, ULong op, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   1417 {
   1418    ULong the_insn = op;
   1419 
   1420    the_insn |= ((ULong)r1) << 36;
   1421    the_insn |= ((ULong)x2) << 32;
   1422    the_insn |= ((ULong)b2) << 28;
   1423    the_insn |= ((ULong)dl2) << 16;
   1424    the_insn |= ((ULong)dh2) << 8;
   1425 
   1426    return emit_6bytes(p, the_insn);
   1427 }
   1428 
   1429 
   1430 static UChar *
   1431 emit_S(UChar *p, UInt op, UChar b2, UShort d2)
   1432 {
   1433    ULong the_insn = op;
   1434 
   1435    the_insn |= ((ULong)b2) << 12;
   1436    the_insn |= ((ULong)d2) << 0;
   1437 
   1438    return emit_4bytes(p, the_insn);
   1439 }
   1440 
   1441 
   1442 static UChar *
   1443 emit_SI(UChar *p, UInt op, UChar i2, UChar b1, UShort d1)
   1444 {
   1445    ULong the_insn = op;
   1446 
   1447    the_insn |= ((ULong)i2) << 16;
   1448    the_insn |= ((ULong)b1) << 12;
   1449    the_insn |= ((ULong)d1) << 0;
   1450 
   1451    return emit_4bytes(p, the_insn);
   1452 }
   1453 
   1454 
   1455 static UChar *
   1456 emit_SIL(UChar *p, ULong op, UChar b1, UShort d1, UShort i2)
   1457 {
   1458    ULong the_insn = op;
   1459 
   1460    the_insn |= ((ULong)b1) << 28;
   1461    the_insn |= ((ULong)d1) << 16;
   1462    the_insn |= ((ULong)i2) << 0;
   1463 
   1464    return emit_6bytes(p, the_insn);
   1465 }
   1466 
   1467 
   1468 static UChar *
   1469 emit_SIY(UChar *p, ULong op, UChar i2, UChar b1, UShort dl1, UChar dh1)
   1470 {
   1471    ULong the_insn = op;
   1472 
   1473    the_insn |= ((ULong)i2) << 32;
   1474    the_insn |= ((ULong)b1) << 28;
   1475    the_insn |= ((ULong)dl1) << 16;
   1476    the_insn |= ((ULong)dh1) << 8;
   1477 
   1478    return emit_6bytes(p, the_insn);
   1479 }
   1480 
   1481 
   1482 static UChar *
   1483 emit_SSa(UChar *p, ULong op, UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
   1484 {
   1485    ULong the_insn = op;
   1486 
   1487    the_insn |= ((ULong)l)  << 32;
   1488    the_insn |= ((ULong)b1) << 28;
   1489    the_insn |= ((ULong)d1) << 16;
   1490    the_insn |= ((ULong)b2) << 12;
   1491    the_insn |= ((ULong)d2) << 0;
   1492 
   1493    return emit_6bytes(p, the_insn);
   1494 }
   1495 
   1496 
   1497 /*------------------------------------------------------------*/
   1498 /*--- Functions to emit particular instructions            ---*/
   1499 /*------------------------------------------------------------*/
   1500 
   1501 static UChar *
   1502 s390_emit_AR(UChar *p, UChar r1, UChar r2)
   1503 {
   1504    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1505       s390_disasm(ENC3(MNM, GPR, GPR), "ar", r1, r2);
   1506 
   1507    return emit_RR(p, 0x1a00, r1, r2);
   1508 }
   1509 
   1510 
   1511 static UChar *
   1512 s390_emit_AGR(UChar *p, UChar r1, UChar r2)
   1513 {
   1514    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1515       s390_disasm(ENC3(MNM, GPR, GPR), "agr", r1, r2);
   1516 
   1517    return emit_RRE(p, 0xb9080000, r1, r2);
   1518 }
   1519 
   1520 
   1521 static UChar *
   1522 s390_emit_A(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   1523 {
   1524    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1525       s390_disasm(ENC3(MNM, GPR, UDXB), "a", r1, d2, x2, b2);
   1526 
   1527    return emit_RX(p, 0x5a000000, r1, x2, b2, d2);
   1528 }
   1529 
   1530 
   1531 static UChar *
   1532 s390_emit_AY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   1533 {
   1534    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1535       s390_disasm(ENC3(MNM, GPR, SDXB), "ay", r1, dh2, dl2, x2, b2);
   1536 
   1537    return emit_RXY(p, 0xe3000000005aULL, r1, x2, b2, dl2, dh2);
   1538 }
   1539 
   1540 
   1541 static UChar *
   1542 s390_emit_AG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   1543 {
   1544    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1545       s390_disasm(ENC3(MNM, GPR, SDXB), "ag", r1, dh2, dl2, x2, b2);
   1546 
   1547    return emit_RXY(p, 0xe30000000008ULL, r1, x2, b2, dl2, dh2);
   1548 }
   1549 
   1550 
   1551 static UChar *
   1552 s390_emit_AFI(UChar *p, UChar r1, UInt i2)
   1553 {
   1554    vassert(s390_host_has_eimm);
   1555 
   1556    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1557       s390_disasm(ENC3(MNM, GPR, INT), "afi", r1, i2);
   1558 
   1559    return emit_RIL(p, 0xc20900000000ULL, r1, i2);
   1560 }
   1561 
   1562 
   1563 static UChar *
   1564 s390_emit_AGFI(UChar *p, UChar r1, UInt i2)
   1565 {
   1566    vassert(s390_host_has_eimm);
   1567 
   1568    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1569       s390_disasm(ENC3(MNM, GPR, INT), "agfi", r1, i2);
   1570 
   1571    return emit_RIL(p, 0xc20800000000ULL, r1, i2);
   1572 }
   1573 
   1574 
   1575 static UChar *
   1576 s390_emit_AH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   1577 {
   1578    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1579       s390_disasm(ENC3(MNM, GPR, UDXB), "ah", r1, d2, x2, b2);
   1580 
   1581    return emit_RX(p, 0x4a000000, r1, x2, b2, d2);
   1582 }
   1583 
   1584 
   1585 static UChar *
   1586 s390_emit_AHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   1587 {
   1588    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1589       s390_disasm(ENC3(MNM, GPR, SDXB), "ahy", r1, dh2, dl2, x2, b2);
   1590 
   1591    return emit_RXY(p, 0xe3000000007aULL, r1, x2, b2, dl2, dh2);
   1592 }
   1593 
   1594 
   1595 static UChar *
   1596 s390_emit_AHI(UChar *p, UChar r1, UShort i2)
   1597 {
   1598    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1599       s390_disasm(ENC3(MNM, GPR, INT), "ahi", r1, (Int)(Short)i2);
   1600 
   1601    return emit_RI(p, 0xa70a0000, r1, i2);
   1602 }
   1603 
   1604 
   1605 static UChar *
   1606 s390_emit_AGHI(UChar *p, UChar r1, UShort i2)
   1607 {
   1608    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1609       s390_disasm(ENC3(MNM, GPR, INT), "aghi", r1, (Int)(Short)i2);
   1610 
   1611    return emit_RI(p, 0xa70b0000, r1, i2);
   1612 }
   1613 
   1614 
   1615 static UChar *
   1616 s390_emit_AGSI(UChar *p, UChar i2, UChar b1, UShort dl1, UChar dh1)
   1617 {
   1618    vassert(s390_host_has_gie);
   1619 
   1620    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1621       s390_disasm(ENC3(MNM, SDXB, INT), "agsi", dh1, dl1, 0, b1, (Int)(Char)i2);
   1622 
   1623    return emit_SIY(p, 0xeb000000007aULL, i2, b1, dl1, dh1);
   1624 }
   1625 
   1626 
   1627 static UChar *
   1628 s390_emit_ASI(UChar *p, UChar i2, UChar b1, UShort dl1, UChar dh1)
   1629 {
   1630    vassert(s390_host_has_gie);
   1631 
   1632    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1633       s390_disasm(ENC3(MNM, SDXB, INT), "asi", dh1, dl1, 0, b1, (Int)(Char)i2);
   1634 
   1635    return emit_SIY(p, 0xeb000000006aULL, i2, b1, dl1, dh1);
   1636 }
   1637 
   1638 
   1639 static UChar *
   1640 s390_emit_NR(UChar *p, UChar r1, UChar r2)
   1641 {
   1642    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1643       s390_disasm(ENC3(MNM, GPR, GPR), "nr", r1, r2);
   1644 
   1645    return emit_RR(p, 0x1400, r1, r2);
   1646 }
   1647 
   1648 
   1649 static UChar *
   1650 s390_emit_NGR(UChar *p, UChar r1, UChar r2)
   1651 {
   1652    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1653       s390_disasm(ENC3(MNM, GPR, GPR), "ngr", r1, r2);
   1654 
   1655    return emit_RRE(p, 0xb9800000, r1, r2);
   1656 }
   1657 
   1658 
   1659 static UChar *
   1660 s390_emit_N(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   1661 {
   1662    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1663       s390_disasm(ENC3(MNM, GPR, UDXB), "n", r1, d2, x2, b2);
   1664 
   1665    return emit_RX(p, 0x54000000, r1, x2, b2, d2);
   1666 }
   1667 
   1668 
   1669 static UChar *
   1670 s390_emit_NY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   1671 {
   1672    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1673       s390_disasm(ENC3(MNM, GPR, SDXB), "ny", r1, dh2, dl2, x2, b2);
   1674 
   1675    return emit_RXY(p, 0xe30000000054ULL, r1, x2, b2, dl2, dh2);
   1676 }
   1677 
   1678 
   1679 static UChar *
   1680 s390_emit_NG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   1681 {
   1682    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1683       s390_disasm(ENC3(MNM, GPR, SDXB), "ng", r1, dh2, dl2, x2, b2);
   1684 
   1685    return emit_RXY(p, 0xe30000000080ULL, r1, x2, b2, dl2, dh2);
   1686 }
   1687 
   1688 
   1689 static UChar *
   1690 s390_emit_NIHF(UChar *p, UChar r1, UInt i2)
   1691 {
   1692    vassert(s390_host_has_eimm);
   1693 
   1694    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1695       s390_disasm(ENC3(MNM, GPR, UINT), "nihf", r1, i2);
   1696 
   1697    return emit_RIL(p, 0xc00a00000000ULL, r1, i2);
   1698 }
   1699 
   1700 
   1701 static UChar *
   1702 s390_emit_NILF(UChar *p, UChar r1, UInt i2)
   1703 {
   1704    vassert(s390_host_has_eimm);
   1705 
   1706    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1707       s390_disasm(ENC3(MNM, GPR, UINT), "nilf", r1, i2);
   1708 
   1709    return emit_RIL(p, 0xc00b00000000ULL, r1, i2);
   1710 }
   1711 
   1712 
   1713 static UChar *
   1714 s390_emit_NILL(UChar *p, UChar r1, UShort i2)
   1715 {
   1716    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1717       s390_disasm(ENC3(MNM, GPR, UINT), "nill", r1, i2);
   1718 
   1719    return emit_RI(p, 0xa5070000, r1, i2);
   1720 }
   1721 
   1722 
   1723 static UChar *
   1724 s390_emit_BASR(UChar *p, UChar r1, UChar r2)
   1725 {
   1726    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1727       s390_disasm(ENC3(MNM, GPR, GPR), "basr", r1, r2);
   1728 
   1729    return emit_RR(p, 0x0d00, r1, r2);
   1730 }
   1731 
   1732 
   1733 static UChar *
   1734 s390_emit_BCR(UChar *p, UChar r1, UChar r2)
   1735 {
   1736    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1737       s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
   1738 
   1739    return emit_RR(p, 0x0700, r1, r2);
   1740 }
   1741 
   1742 
   1743 static UChar *
   1744 s390_emit_BRC(UChar *p, UChar r1, UShort i2)
   1745 {
   1746    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1747       s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
   1748 
   1749    return emit_RI(p, 0xa7040000, r1, i2);
   1750 }
   1751 
   1752 
   1753 static UChar *
   1754 s390_emit_BRCL(UChar *p, UChar r1, ULong i2)
   1755 {
   1756    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1757       s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
   1758 
   1759    return emit_RIL(p, 0xc00400000000ULL, r1, i2);
   1760 }
   1761 
   1762 
   1763 static UChar *
   1764 s390_emit_CR(UChar *p, UChar r1, UChar r2)
   1765 {
   1766    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1767       s390_disasm(ENC3(MNM, GPR, GPR), "cr", r1, r2);
   1768 
   1769    return emit_RR(p, 0x1900, r1, r2);
   1770 }
   1771 
   1772 
   1773 static UChar *
   1774 s390_emit_CGR(UChar *p, UChar r1, UChar r2)
   1775 {
   1776    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1777       s390_disasm(ENC3(MNM, GPR, GPR), "cgr", r1, r2);
   1778 
   1779    return emit_RRE(p, 0xb9200000, r1, r2);
   1780 }
   1781 
   1782 
   1783 static UChar *
   1784 s390_emit_C(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   1785 {
   1786    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1787       s390_disasm(ENC3(MNM, GPR, UDXB), "c", r1, d2, x2, b2);
   1788 
   1789    return emit_RX(p, 0x59000000, r1, x2, b2, d2);
   1790 }
   1791 
   1792 
   1793 static UChar *
   1794 s390_emit_CY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   1795 {
   1796    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1797       s390_disasm(ENC3(MNM, GPR, SDXB), "cy", r1, dh2, dl2, x2, b2);
   1798 
   1799    return emit_RXY(p, 0xe30000000059ULL, r1, x2, b2, dl2, dh2);
   1800 }
   1801 
   1802 
   1803 static UChar *
   1804 s390_emit_CG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   1805 {
   1806    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1807       s390_disasm(ENC3(MNM, GPR, SDXB), "cg", r1, dh2, dl2, x2, b2);
   1808 
   1809    return emit_RXY(p, 0xe30000000020ULL, r1, x2, b2, dl2, dh2);
   1810 }
   1811 
   1812 
   1813 static UChar *
   1814 s390_emit_CFI(UChar *p, UChar r1, UInt i2)
   1815 {
   1816    vassert(s390_host_has_eimm);
   1817 
   1818    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1819       s390_disasm(ENC3(MNM, GPR, INT), "cfi", r1, i2);
   1820 
   1821    return emit_RIL(p, 0xc20d00000000ULL, r1, i2);
   1822 }
   1823 
   1824 
   1825 static UChar *
   1826 s390_emit_CGFI(UChar *p, UChar r1, UInt i2)
   1827 {
   1828    vassert(s390_host_has_eimm);
   1829 
   1830    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1831       s390_disasm(ENC3(MNM, GPR, INT), "cgfi", r1, i2);
   1832 
   1833    return emit_RIL(p, 0xc20c00000000ULL, r1, i2);
   1834 }
   1835 
   1836 
   1837 static UChar *
   1838 s390_emit_CS(UChar *p, UChar r1, UChar r3, UChar b2, UShort d2)
   1839 {
   1840    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1841       s390_disasm(ENC4(MNM, GPR, GPR, UDXB), "cs", r1, r3, d2, 0, b2);
   1842 
   1843    return emit_RS(p, 0xba000000, r1, r3, b2, d2);
   1844 }
   1845 
   1846 
   1847 static UChar *
   1848 s390_emit_CSY(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
   1849 {
   1850    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1851       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "csy", r1, r3, dh2, dl2, 0, b2);
   1852 
   1853    return emit_RSY(p, 0xeb0000000014ULL, r1, r3, b2, dl2, dh2);
   1854 }
   1855 
   1856 
   1857 static UChar *
   1858 s390_emit_CSG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
   1859 {
   1860    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1861       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "csg", r1, r3, dh2, dl2, 0, b2);
   1862 
   1863    return emit_RSY(p, 0xeb0000000030ULL, r1, r3, b2, dl2, dh2);
   1864 }
   1865 
   1866 
   1867 static UChar *
   1868 s390_emit_CDS(UChar *p, UChar r1, UChar r3, UChar b2, UShort d2)
   1869 {
   1870    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1871       s390_disasm(ENC4(MNM, GPR, GPR, UDXB), "cds", r1, r3, d2, 0, b2);
   1872 
   1873    return emit_RS(p, 0xbb000000, r1, r3, b2, d2);
   1874 }
   1875 
   1876 
   1877 static UChar *
   1878 s390_emit_CDSY(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
   1879 {
   1880    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1881       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "cdsy", r1, r3, dh2, dl2, 0, b2);
   1882 
   1883    return emit_RSY(p, 0xeb0000000031ULL, r1, r3, b2, dl2, dh2);
   1884 }
   1885 
   1886 
   1887 static UChar *
   1888 s390_emit_CDSG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
   1889 {
   1890    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1891       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "cdsg", r1, r3, dh2, dl2, 0, b2);
   1892 
   1893    return emit_RSY(p, 0xeb000000003eULL, r1, r3, b2, dl2, dh2);
   1894 }
   1895 
   1896 
   1897 static UChar *
   1898 s390_emit_CLR(UChar *p, UChar r1, UChar r2)
   1899 {
   1900    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1901       s390_disasm(ENC3(MNM, GPR, GPR), "clr", r1, r2);
   1902 
   1903    return emit_RR(p, 0x1500, r1, r2);
   1904 }
   1905 
   1906 
   1907 static UChar *
   1908 s390_emit_CLGR(UChar *p, UChar r1, UChar r2)
   1909 {
   1910    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1911       s390_disasm(ENC3(MNM, GPR, GPR), "clgr", r1, r2);
   1912 
   1913    return emit_RRE(p, 0xb9210000, r1, r2);
   1914 }
   1915 
   1916 
   1917 static UChar *
   1918 s390_emit_CL(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   1919 {
   1920    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1921       s390_disasm(ENC3(MNM, GPR, UDXB), "cl", r1, d2, x2, b2);
   1922 
   1923    return emit_RX(p, 0x55000000, r1, x2, b2, d2);
   1924 }
   1925 
   1926 
   1927 static UChar *
   1928 s390_emit_CLY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   1929 {
   1930    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1931       s390_disasm(ENC3(MNM, GPR, SDXB), "cly", r1, dh2, dl2, x2, b2);
   1932 
   1933    return emit_RXY(p, 0xe30000000055ULL, r1, x2, b2, dl2, dh2);
   1934 }
   1935 
   1936 
   1937 static UChar *
   1938 s390_emit_CLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   1939 {
   1940    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1941       s390_disasm(ENC3(MNM, GPR, SDXB), "clg", r1, dh2, dl2, x2, b2);
   1942 
   1943    return emit_RXY(p, 0xe30000000021ULL, r1, x2, b2, dl2, dh2);
   1944 }
   1945 
   1946 
   1947 static UChar *
   1948 s390_emit_CLFI(UChar *p, UChar r1, UInt i2)
   1949 {
   1950    vassert(s390_host_has_eimm);
   1951 
   1952    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1953       s390_disasm(ENC3(MNM, GPR, UINT), "clfi", r1, i2);
   1954 
   1955    return emit_RIL(p, 0xc20f00000000ULL, r1, i2);
   1956 }
   1957 
   1958 
   1959 static UChar *
   1960 s390_emit_CLGFI(UChar *p, UChar r1, UInt i2)
   1961 {
   1962    vassert(s390_host_has_eimm);
   1963 
   1964    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1965       s390_disasm(ENC3(MNM, GPR, UINT), "clgfi", r1, i2);
   1966 
   1967    return emit_RIL(p, 0xc20e00000000ULL, r1, i2);
   1968 }
   1969 
   1970 
   1971 static UChar *
   1972 s390_emit_DR(UChar *p, UChar r1, UChar r2)
   1973 {
   1974    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1975       s390_disasm(ENC3(MNM, GPR, GPR), "dr", r1, r2);
   1976 
   1977    return emit_RR(p, 0x1d00, r1, r2);
   1978 }
   1979 
   1980 
   1981 static UChar *
   1982 s390_emit_D(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   1983 {
   1984    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1985       s390_disasm(ENC3(MNM, GPR, UDXB), "d", r1, d2, x2, b2);
   1986 
   1987    return emit_RX(p, 0x5d000000, r1, x2, b2, d2);
   1988 }
   1989 
   1990 
   1991 static UChar *
   1992 s390_emit_DLR(UChar *p, UChar r1, UChar r2)
   1993 {
   1994    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   1995       s390_disasm(ENC3(MNM, GPR, GPR), "dlr", r1, r2);
   1996 
   1997    return emit_RRE(p, 0xb9970000, r1, r2);
   1998 }
   1999 
   2000 
   2001 static UChar *
   2002 s390_emit_DLGR(UChar *p, UChar r1, UChar r2)
   2003 {
   2004    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2005       s390_disasm(ENC3(MNM, GPR, GPR), "dlgr", r1, r2);
   2006 
   2007    return emit_RRE(p, 0xb9870000, r1, r2);
   2008 }
   2009 
   2010 
   2011 static UChar *
   2012 s390_emit_DL(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2013 {
   2014    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2015       s390_disasm(ENC3(MNM, GPR, SDXB), "dl", r1, dh2, dl2, x2, b2);
   2016 
   2017    return emit_RXY(p, 0xe30000000097ULL, r1, x2, b2, dl2, dh2);
   2018 }
   2019 
   2020 
   2021 static UChar *
   2022 s390_emit_DLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2023 {
   2024    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2025       s390_disasm(ENC3(MNM, GPR, SDXB), "dlg", r1, dh2, dl2, x2, b2);
   2026 
   2027    return emit_RXY(p, 0xe30000000087ULL, r1, x2, b2, dl2, dh2);
   2028 }
   2029 
   2030 
   2031 static UChar *
   2032 s390_emit_DSGR(UChar *p, UChar r1, UChar r2)
   2033 {
   2034    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2035       s390_disasm(ENC3(MNM, GPR, GPR), "dsgr", r1, r2);
   2036 
   2037    return emit_RRE(p, 0xb90d0000, r1, r2);
   2038 }
   2039 
   2040 
   2041 static UChar *
   2042 s390_emit_DSG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2043 {
   2044    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2045       s390_disasm(ENC3(MNM, GPR, SDXB), "dsg", r1, dh2, dl2, x2, b2);
   2046 
   2047    return emit_RXY(p, 0xe3000000000dULL, r1, x2, b2, dl2, dh2);
   2048 }
   2049 
   2050 
   2051 static UChar *
   2052 s390_emit_XR(UChar *p, UChar r1, UChar r2)
   2053 {
   2054    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2055       s390_disasm(ENC3(MNM, GPR, GPR), "xr", r1, r2);
   2056 
   2057    return emit_RR(p, 0x1700, r1, r2);
   2058 }
   2059 
   2060 
   2061 static UChar *
   2062 s390_emit_XGR(UChar *p, UChar r1, UChar r2)
   2063 {
   2064    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2065       s390_disasm(ENC3(MNM, GPR, GPR), "xgr", r1, r2);
   2066 
   2067    return emit_RRE(p, 0xb9820000, r1, r2);
   2068 }
   2069 
   2070 
   2071 static UChar *
   2072 s390_emit_X(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   2073 {
   2074    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2075       s390_disasm(ENC3(MNM, GPR, UDXB), "x", r1, d2, x2, b2);
   2076 
   2077    return emit_RX(p, 0x57000000, r1, x2, b2, d2);
   2078 }
   2079 
   2080 
   2081 static UChar *
   2082 s390_emit_XY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2083 {
   2084    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2085       s390_disasm(ENC3(MNM, GPR, SDXB), "xy", r1, dh2, dl2, x2, b2);
   2086 
   2087    return emit_RXY(p, 0xe30000000057ULL, r1, x2, b2, dl2, dh2);
   2088 }
   2089 
   2090 
   2091 static UChar *
   2092 s390_emit_XG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2093 {
   2094    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2095       s390_disasm(ENC3(MNM, GPR, SDXB), "xg", r1, dh2, dl2, x2, b2);
   2096 
   2097    return emit_RXY(p, 0xe30000000082ULL, r1, x2, b2, dl2, dh2);
   2098 }
   2099 
   2100 
   2101 static UChar *
   2102 s390_emit_XIHF(UChar *p, UChar r1, UInt i2)
   2103 {
   2104    vassert(s390_host_has_eimm);
   2105 
   2106    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2107       s390_disasm(ENC3(MNM, GPR, UINT), "xihf", r1, i2);
   2108 
   2109    return emit_RIL(p, 0xc00600000000ULL, r1, i2);
   2110 }
   2111 
   2112 
   2113 static UChar *
   2114 s390_emit_XILF(UChar *p, UChar r1, UInt i2)
   2115 {
   2116    vassert(s390_host_has_eimm);
   2117 
   2118    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2119       s390_disasm(ENC3(MNM, GPR, UINT), "xilf", r1, i2);
   2120 
   2121    return emit_RIL(p, 0xc00700000000ULL, r1, i2);
   2122 }
   2123 
   2124 
   2125 static UChar *
   2126 s390_emit_XC(UChar *p, UInt l, UChar b1, UShort d1, UChar b2, UShort d2)
   2127 {
   2128    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2129       s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d1, l, b1, d2, 0, b2);
   2130 
   2131    return emit_SSa(p, 0xd70000000000ULL, l, b1, d1, b2, d2);
   2132 }
   2133 
   2134 
   2135 static UChar *
   2136 s390_emit_FLOGR(UChar *p, UChar r1, UChar r2)
   2137 {
   2138    vassert(s390_host_has_eimm);
   2139 
   2140    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2141       s390_disasm(ENC3(MNM, GPR, GPR), "flogr", r1, r2);
   2142 
   2143    return emit_RRE(p, 0xb9830000, r1, r2);
   2144 }
   2145 
   2146 
   2147 static UChar *
   2148 s390_emit_IC(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   2149 {
   2150    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2151       s390_disasm(ENC3(MNM, GPR, UDXB), "ic", r1, d2, x2, b2);
   2152 
   2153    return emit_RX(p, 0x43000000, r1, x2, b2, d2);
   2154 }
   2155 
   2156 
   2157 static UChar *
   2158 s390_emit_ICY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2159 {
   2160    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2161       s390_disasm(ENC3(MNM, GPR, SDXB), "icy", r1, dh2, dl2, x2, b2);
   2162 
   2163    return emit_RXY(p, 0xe30000000073ULL, r1, x2, b2, dl2, dh2);
   2164 }
   2165 
   2166 
   2167 static UChar *
   2168 s390_emit_IIHF(UChar *p, UChar r1, UInt i2)
   2169 {
   2170    vassert(s390_host_has_eimm);
   2171 
   2172    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2173       s390_disasm(ENC3(MNM, GPR, UINT), "iihf", r1, i2);
   2174 
   2175    return emit_RIL(p, 0xc00800000000ULL, r1, i2);
   2176 }
   2177 
   2178 
   2179 static UChar *
   2180 s390_emit_IIHH(UChar *p, UChar r1, UShort i2)
   2181 {
   2182    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2183       s390_disasm(ENC3(MNM, GPR, UINT), "iihh", r1, i2);
   2184 
   2185    return emit_RI(p, 0xa5000000, r1, i2);
   2186 }
   2187 
   2188 
   2189 static UChar *
   2190 s390_emit_IIHL(UChar *p, UChar r1, UShort i2)
   2191 {
   2192    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2193       s390_disasm(ENC3(MNM, GPR, UINT), "iihl", r1, i2);
   2194 
   2195    return emit_RI(p, 0xa5010000, r1, i2);
   2196 }
   2197 
   2198 
   2199 static UChar *
   2200 s390_emit_IILF(UChar *p, UChar r1, UInt i2)
   2201 {
   2202    vassert(s390_host_has_eimm);
   2203 
   2204    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2205       s390_disasm(ENC3(MNM, GPR, UINT), "iilf", r1, i2);
   2206 
   2207    return emit_RIL(p, 0xc00900000000ULL, r1, i2);
   2208 }
   2209 
   2210 
   2211 static UChar *
   2212 s390_emit_IILH(UChar *p, UChar r1, UShort i2)
   2213 {
   2214    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2215       s390_disasm(ENC3(MNM, GPR, UINT), "iilh", r1, i2);
   2216 
   2217    return emit_RI(p, 0xa5020000, r1, i2);
   2218 }
   2219 
   2220 
   2221 static UChar *
   2222 s390_emit_IILL(UChar *p, UChar r1, UShort i2)
   2223 {
   2224    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2225       s390_disasm(ENC3(MNM, GPR, UINT), "iill", r1, i2);
   2226 
   2227    return emit_RI(p, 0xa5030000, r1, i2);
   2228 }
   2229 
   2230 
   2231 static UChar *
   2232 s390_emit_IPM(UChar *p, UChar r1, UChar r2)
   2233 {
   2234    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2235       s390_disasm(ENC2(MNM, GPR), "ipm", r1);
   2236 
   2237    return emit_RRE(p, 0xb2220000, r1, r2);
   2238 }
   2239 
   2240 
   2241 static UChar *
   2242 s390_emit_LR(UChar *p, UChar r1, UChar r2)
   2243 {
   2244    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2245       s390_disasm(ENC3(MNM, GPR, GPR), "lr", r1, r2);
   2246 
   2247    return emit_RR(p, 0x1800, r1, r2);
   2248 }
   2249 
   2250 
   2251 static UChar *
   2252 s390_emit_LGR(UChar *p, UChar r1, UChar r2)
   2253 {
   2254    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2255       s390_disasm(ENC3(MNM, GPR, GPR), "lgr", r1, r2);
   2256 
   2257    return emit_RRE(p, 0xb9040000, r1, r2);
   2258 }
   2259 
   2260 
   2261 static UChar *
   2262 s390_emit_LGFR(UChar *p, UChar r1, UChar r2)
   2263 {
   2264    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2265       s390_disasm(ENC3(MNM, GPR, GPR), "lgfr", r1, r2);
   2266 
   2267    return emit_RRE(p, 0xb9140000, r1, r2);
   2268 }
   2269 
   2270 
   2271 static UChar *
   2272 s390_emit_L(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   2273 {
   2274    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2275       s390_disasm(ENC3(MNM, GPR, UDXB), "l", r1, d2, x2, b2);
   2276 
   2277    return emit_RX(p, 0x58000000, r1, x2, b2, d2);
   2278 }
   2279 
   2280 
   2281 static UChar *
   2282 s390_emit_LY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2283 {
   2284    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2285       s390_disasm(ENC3(MNM, GPR, SDXB), "ly", r1, dh2, dl2, x2, b2);
   2286 
   2287    return emit_RXY(p, 0xe30000000058ULL, r1, x2, b2, dl2, dh2);
   2288 }
   2289 
   2290 
   2291 static UChar *
   2292 s390_emit_LG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2293 {
   2294    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2295       s390_disasm(ENC3(MNM, GPR, SDXB), "lg", r1, dh2, dl2, x2, b2);
   2296 
   2297    return emit_RXY(p, 0xe30000000004ULL, r1, x2, b2, dl2, dh2);
   2298 }
   2299 
   2300 
   2301 static UChar *
   2302 s390_emit_LGF(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2303 {
   2304    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2305       s390_disasm(ENC3(MNM, GPR, SDXB), "lgf", r1, dh2, dl2, x2, b2);
   2306 
   2307    return emit_RXY(p, 0xe30000000014ULL, r1, x2, b2, dl2, dh2);
   2308 }
   2309 
   2310 
   2311 static UChar *
   2312 s390_emit_LGFI(UChar *p, UChar r1, UInt i2)
   2313 {
   2314    vassert(s390_host_has_eimm);
   2315 
   2316    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2317       s390_disasm(ENC3(MNM, GPR, INT), "lgfi", r1, i2);
   2318 
   2319    return emit_RIL(p, 0xc00100000000ULL, r1, i2);
   2320 }
   2321 
   2322 
   2323 static UChar *
   2324 s390_emit_LTR(UChar *p, UChar r1, UChar r2)
   2325 {
   2326    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2327       s390_disasm(ENC3(MNM, GPR, GPR), "ltr", r1, r2);
   2328 
   2329    return emit_RR(p, 0x1200, r1, r2);
   2330 }
   2331 
   2332 
   2333 static UChar *
   2334 s390_emit_LTGR(UChar *p, UChar r1, UChar r2)
   2335 {
   2336    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2337       s390_disasm(ENC3(MNM, GPR, GPR), "ltgr", r1, r2);
   2338 
   2339    return emit_RRE(p, 0xb9020000, r1, r2);
   2340 }
   2341 
   2342 
   2343 static UChar *
   2344 s390_emit_LT(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2345 {
   2346    vassert(s390_host_has_eimm);
   2347 
   2348    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2349       s390_disasm(ENC3(MNM, GPR, SDXB), "lt", r1, dh2, dl2, x2, b2);
   2350 
   2351    return emit_RXY(p, 0xe30000000012ULL, r1, x2, b2, dl2, dh2);
   2352 }
   2353 
   2354 
   2355 static UChar *
   2356 s390_emit_LTG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2357 {
   2358    vassert(s390_host_has_eimm);
   2359 
   2360    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2361       s390_disasm(ENC3(MNM, GPR, SDXB), "ltg", r1, dh2, dl2, x2, b2);
   2362 
   2363    return emit_RXY(p, 0xe30000000002ULL, r1, x2, b2, dl2, dh2);
   2364 }
   2365 
   2366 
   2367 static UChar *
   2368 s390_emit_LBR(UChar *p, UChar r1, UChar r2)
   2369 {
   2370    vassert(s390_host_has_eimm);
   2371 
   2372    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2373       s390_disasm(ENC3(MNM, GPR, GPR), "lbr", r1, r2);
   2374 
   2375    return emit_RRE(p, 0xb9260000, r1, r2);
   2376 }
   2377 
   2378 
   2379 static UChar *
   2380 s390_emit_LGBR(UChar *p, UChar r1, UChar r2)
   2381 {
   2382    vassert(s390_host_has_eimm);
   2383 
   2384    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2385       s390_disasm(ENC3(MNM, GPR, GPR), "lgbr", r1, r2);
   2386 
   2387    return emit_RRE(p, 0xb9060000, r1, r2);
   2388 }
   2389 
   2390 
   2391 static UChar *
   2392 s390_emit_LB(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2393 {
   2394    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2395       s390_disasm(ENC3(MNM, GPR, SDXB), "lb", r1, dh2, dl2, x2, b2);
   2396 
   2397    return emit_RXY(p, 0xe30000000076ULL, r1, x2, b2, dl2, dh2);
   2398 }
   2399 
   2400 
   2401 static UChar *
   2402 s390_emit_LGB(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2403 {
   2404    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2405       s390_disasm(ENC3(MNM, GPR, SDXB), "lgb", r1, dh2, dl2, x2, b2);
   2406 
   2407    return emit_RXY(p, 0xe30000000077ULL, r1, x2, b2, dl2, dh2);
   2408 }
   2409 
   2410 
   2411 static UChar *
   2412 s390_emit_LCR(UChar *p, UChar r1, UChar r2)
   2413 {
   2414    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2415       s390_disasm(ENC3(MNM, GPR, GPR), "lcr", r1, r2);
   2416 
   2417    return emit_RR(p, 0x1300, r1, r2);
   2418 }
   2419 
   2420 
   2421 static UChar *
   2422 s390_emit_LCGR(UChar *p, UChar r1, UChar r2)
   2423 {
   2424    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2425       s390_disasm(ENC3(MNM, GPR, GPR), "lcgr", r1, r2);
   2426 
   2427    return emit_RRE(p, 0xb9030000, r1, r2);
   2428 }
   2429 
   2430 
   2431 static UChar *
   2432 s390_emit_LHR(UChar *p, UChar r1, UChar r2)
   2433 {
   2434    vassert(s390_host_has_eimm);
   2435 
   2436    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2437       s390_disasm(ENC3(MNM, GPR, GPR), "lhr", r1, r2);
   2438 
   2439    return emit_RRE(p, 0xb9270000, r1, r2);
   2440 }
   2441 
   2442 
   2443 static UChar *
   2444 s390_emit_LGHR(UChar *p, UChar r1, UChar r2)
   2445 {
   2446    vassert(s390_host_has_eimm);
   2447 
   2448    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2449       s390_disasm(ENC3(MNM, GPR, GPR), "lghr", r1, r2);
   2450 
   2451    return emit_RRE(p, 0xb9070000, r1, r2);
   2452 }
   2453 
   2454 
   2455 static UChar *
   2456 s390_emit_LH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   2457 {
   2458    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2459       s390_disasm(ENC3(MNM, GPR, UDXB), "lh", r1, d2, x2, b2);
   2460 
   2461    return emit_RX(p, 0x48000000, r1, x2, b2, d2);
   2462 }
   2463 
   2464 
   2465 static UChar *
   2466 s390_emit_LHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2467 {
   2468    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2469       s390_disasm(ENC3(MNM, GPR, SDXB), "lhy", r1, dh2, dl2, x2, b2);
   2470 
   2471    return emit_RXY(p, 0xe30000000078ULL, r1, x2, b2, dl2, dh2);
   2472 }
   2473 
   2474 
   2475 static UChar *
   2476 s390_emit_LGH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2477 {
   2478    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2479       s390_disasm(ENC3(MNM, GPR, SDXB), "lgh", r1, dh2, dl2, x2, b2);
   2480 
   2481    return emit_RXY(p, 0xe30000000015ULL, r1, x2, b2, dl2, dh2);
   2482 }
   2483 
   2484 
   2485 static UChar *
   2486 s390_emit_LHI(UChar *p, UChar r1, UShort i2)
   2487 {
   2488    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2489       s390_disasm(ENC3(MNM, GPR, INT), "lhi", r1, (Int)(Short)i2);
   2490 
   2491    return emit_RI(p, 0xa7080000, r1, i2);
   2492 }
   2493 
   2494 
   2495 static UChar *
   2496 s390_emit_LGHI(UChar *p, UChar r1, UShort i2)
   2497 {
   2498    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2499       s390_disasm(ENC3(MNM, GPR, INT), "lghi", r1, (Int)(Short)i2);
   2500 
   2501    return emit_RI(p, 0xa7090000, r1, i2);
   2502 }
   2503 
   2504 
   2505 static UChar *
   2506 s390_emit_LLGFR(UChar *p, UChar r1, UChar r2)
   2507 {
   2508    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2509       s390_disasm(ENC3(MNM, GPR, GPR), "llgfr", r1, r2);
   2510 
   2511    return emit_RRE(p, 0xb9160000, r1, r2);
   2512 }
   2513 
   2514 
   2515 static UChar *
   2516 s390_emit_LLGF(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2517 {
   2518    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2519       s390_disasm(ENC3(MNM, GPR, SDXB), "llgf", r1, dh2, dl2, x2, b2);
   2520 
   2521    return emit_RXY(p, 0xe30000000016ULL, r1, x2, b2, dl2, dh2);
   2522 }
   2523 
   2524 
   2525 static UChar *
   2526 s390_emit_LLCR(UChar *p, UChar r1, UChar r2)
   2527 {
   2528    vassert(s390_host_has_eimm);
   2529 
   2530    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2531       s390_disasm(ENC3(MNM, GPR, GPR), "llcr", r1, r2);
   2532 
   2533    return emit_RRE(p, 0xb9940000, r1, r2);
   2534 }
   2535 
   2536 
   2537 static UChar *
   2538 s390_emit_LLGCR(UChar *p, UChar r1, UChar r2)
   2539 {
   2540    vassert(s390_host_has_eimm);
   2541 
   2542    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2543       s390_disasm(ENC3(MNM, GPR, GPR), "llgcr", r1, r2);
   2544 
   2545    return emit_RRE(p, 0xb9840000, r1, r2);
   2546 }
   2547 
   2548 
   2549 static UChar *
   2550 s390_emit_LLC(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2551 {
   2552    vassert(s390_host_has_eimm);
   2553 
   2554    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2555       s390_disasm(ENC3(MNM, GPR, SDXB), "llc", r1, dh2, dl2, x2, b2);
   2556 
   2557    return emit_RXY(p, 0xe30000000094ULL, r1, x2, b2, dl2, dh2);
   2558 }
   2559 
   2560 
   2561 static UChar *
   2562 s390_emit_LLGC(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2563 {
   2564    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2565       s390_disasm(ENC3(MNM, GPR, SDXB), "llgc", r1, dh2, dl2, x2, b2);
   2566 
   2567    return emit_RXY(p, 0xe30000000090ULL, r1, x2, b2, dl2, dh2);
   2568 }
   2569 
   2570 
   2571 static UChar *
   2572 s390_emit_LLHR(UChar *p, UChar r1, UChar r2)
   2573 {
   2574    vassert(s390_host_has_eimm);
   2575 
   2576    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2577       s390_disasm(ENC3(MNM, GPR, GPR), "llhr", r1, r2);
   2578 
   2579    return emit_RRE(p, 0xb9950000, r1, r2);
   2580 }
   2581 
   2582 
   2583 static UChar *
   2584 s390_emit_LLGHR(UChar *p, UChar r1, UChar r2)
   2585 {
   2586    vassert(s390_host_has_eimm);
   2587 
   2588    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2589       s390_disasm(ENC3(MNM, GPR, GPR), "llghr", r1, r2);
   2590 
   2591    return emit_RRE(p, 0xb9850000, r1, r2);
   2592 }
   2593 
   2594 
   2595 static UChar *
   2596 s390_emit_LLH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2597 {
   2598    vassert(s390_host_has_eimm);
   2599 
   2600    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2601       s390_disasm(ENC3(MNM, GPR, SDXB), "llh", r1, dh2, dl2, x2, b2);
   2602 
   2603    return emit_RXY(p, 0xe30000000095ULL, r1, x2, b2, dl2, dh2);
   2604 }
   2605 
   2606 
   2607 static UChar *
   2608 s390_emit_LLGH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2609 {
   2610    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2611       s390_disasm(ENC3(MNM, GPR, SDXB), "llgh", r1, dh2, dl2, x2, b2);
   2612 
   2613    return emit_RXY(p, 0xe30000000091ULL, r1, x2, b2, dl2, dh2);
   2614 }
   2615 
   2616 
   2617 static UChar *
   2618 s390_emit_LLILF(UChar *p, UChar r1, UInt i2)
   2619 {
   2620    vassert(s390_host_has_eimm);
   2621 
   2622    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2623       s390_disasm(ENC3(MNM, GPR, UINT), "llilf", r1, i2);
   2624 
   2625    return emit_RIL(p, 0xc00f00000000ULL, r1, i2);
   2626 }
   2627 
   2628 
   2629 static UChar *
   2630 s390_emit_LLILH(UChar *p, UChar r1, UShort i2)
   2631 {
   2632    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2633       s390_disasm(ENC3(MNM, GPR, UINT), "llilh", r1, i2);
   2634 
   2635    return emit_RI(p, 0xa50e0000, r1, i2);
   2636 }
   2637 
   2638 
   2639 static UChar *
   2640 s390_emit_LLILL(UChar *p, UChar r1, UShort i2)
   2641 {
   2642    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2643       s390_disasm(ENC3(MNM, GPR, UINT), "llill", r1, i2);
   2644 
   2645    return emit_RI(p, 0xa50f0000, r1, i2);
   2646 }
   2647 
   2648 
   2649 static UChar *
   2650 s390_emit_MR(UChar *p, UChar r1, UChar r2)
   2651 {
   2652    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2653       s390_disasm(ENC3(MNM, GPR, GPR), "mr", r1, r2);
   2654 
   2655    return emit_RR(p, 0x1c00, r1, r2);
   2656 }
   2657 
   2658 
   2659 static UChar *
   2660 s390_emit_M(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   2661 {
   2662    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2663       s390_disasm(ENC3(MNM, GPR, UDXB), "m", r1, d2, x2, b2);
   2664 
   2665    return emit_RX(p, 0x5c000000, r1, x2, b2, d2);
   2666 }
   2667 
   2668 
   2669 static UChar *
   2670 s390_emit_MFY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2671 {
   2672    vassert(s390_host_has_gie);
   2673 
   2674    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2675       s390_disasm(ENC3(MNM, GPR, SDXB), "mfy", r1, dh2, dl2, x2, b2);
   2676 
   2677    return emit_RXY(p, 0xe3000000005cULL, r1, x2, b2, dl2, dh2);
   2678 }
   2679 
   2680 
   2681 static UChar *
   2682 s390_emit_MH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   2683 {
   2684    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2685       s390_disasm(ENC3(MNM, GPR, UDXB), "mh", r1, d2, x2, b2);
   2686 
   2687    return emit_RX(p, 0x4c000000, r1, x2, b2, d2);
   2688 }
   2689 
   2690 
   2691 static UChar *
   2692 s390_emit_MHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2693 {
   2694    vassert(s390_host_has_gie);
   2695 
   2696    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2697       s390_disasm(ENC3(MNM, GPR, SDXB), "mhy", r1, dh2, dl2, x2, b2);
   2698 
   2699    return emit_RXY(p, 0xe3000000007cULL, r1, x2, b2, dl2, dh2);
   2700 }
   2701 
   2702 
   2703 static UChar *
   2704 s390_emit_MHI(UChar *p, UChar r1, UShort i2)
   2705 {
   2706    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2707       s390_disasm(ENC3(MNM, GPR, INT), "mhi", r1, (Int)(Short)i2);
   2708 
   2709    return emit_RI(p, 0xa70c0000, r1, i2);
   2710 }
   2711 
   2712 
   2713 static UChar *
   2714 s390_emit_MLR(UChar *p, UChar r1, UChar r2)
   2715 {
   2716    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2717       s390_disasm(ENC3(MNM, GPR, GPR), "mlr", r1, r2);
   2718 
   2719    return emit_RRE(p, 0xb9960000, r1, r2);
   2720 }
   2721 
   2722 
   2723 static UChar *
   2724 s390_emit_MLGR(UChar *p, UChar r1, UChar r2)
   2725 {
   2726    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2727       s390_disasm(ENC3(MNM, GPR, GPR), "mlgr", r1, r2);
   2728 
   2729    return emit_RRE(p, 0xb9860000, r1, r2);
   2730 }
   2731 
   2732 
   2733 static UChar *
   2734 s390_emit_ML(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2735 {
   2736    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2737       s390_disasm(ENC3(MNM, GPR, SDXB), "ml", r1, dh2, dl2, x2, b2);
   2738 
   2739    return emit_RXY(p, 0xe30000000096ULL, r1, x2, b2, dl2, dh2);
   2740 }
   2741 
   2742 
   2743 static UChar *
   2744 s390_emit_MLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2745 {
   2746    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2747       s390_disasm(ENC3(MNM, GPR, SDXB), "mlg", r1, dh2, dl2, x2, b2);
   2748 
   2749    return emit_RXY(p, 0xe30000000086ULL, r1, x2, b2, dl2, dh2);
   2750 }
   2751 
   2752 
   2753 static UChar *
   2754 s390_emit_MSR(UChar *p, UChar r1, UChar r2)
   2755 {
   2756    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2757       s390_disasm(ENC3(MNM, GPR, GPR), "msr", r1, r2);
   2758 
   2759    return emit_RRE(p, 0xb2520000, r1, r2);
   2760 }
   2761 
   2762 
   2763 static UChar *
   2764 s390_emit_MSGR(UChar *p, UChar r1, UChar r2)
   2765 {
   2766    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2767       s390_disasm(ENC3(MNM, GPR, GPR), "msgr", r1, r2);
   2768 
   2769    return emit_RRE(p, 0xb90c0000, r1, r2);
   2770 }
   2771 
   2772 
   2773 static UChar *
   2774 s390_emit_MS(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   2775 {
   2776    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2777       s390_disasm(ENC3(MNM, GPR, UDXB), "ms", r1, d2, x2, b2);
   2778 
   2779    return emit_RX(p, 0x71000000, r1, x2, b2, d2);
   2780 }
   2781 
   2782 
   2783 static UChar *
   2784 s390_emit_MSY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2785 {
   2786    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2787       s390_disasm(ENC3(MNM, GPR, SDXB), "msy", r1, dh2, dl2, x2, b2);
   2788 
   2789    return emit_RXY(p, 0xe30000000051ULL, r1, x2, b2, dl2, dh2);
   2790 }
   2791 
   2792 
   2793 static UChar *
   2794 s390_emit_MSG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2795 {
   2796    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2797       s390_disasm(ENC3(MNM, GPR, SDXB), "msg", r1, dh2, dl2, x2, b2);
   2798 
   2799    return emit_RXY(p, 0xe3000000000cULL, r1, x2, b2, dl2, dh2);
   2800 }
   2801 
   2802 
   2803 static UChar *
   2804 s390_emit_MSFI(UChar *p, UChar r1, UInt i2)
   2805 {
   2806    vassert(s390_host_has_gie);
   2807 
   2808    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2809       s390_disasm(ENC3(MNM, GPR, INT), "msfi", r1, i2);
   2810 
   2811    return emit_RIL(p, 0xc20100000000ULL, r1, i2);
   2812 }
   2813 
   2814 
   2815 static UChar *
   2816 s390_emit_MSGFI(UChar *p, UChar r1, UInt i2)
   2817 {
   2818    vassert(s390_host_has_gie);
   2819 
   2820    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2821       s390_disasm(ENC3(MNM, GPR, INT), "msgfi", r1, i2);
   2822 
   2823    return emit_RIL(p, 0xc20000000000ULL, r1, i2);
   2824 }
   2825 
   2826 
   2827 static UChar *
   2828 s390_emit_MVC(UChar *p, UInt l, UChar b1, UShort d1, UChar b2, UShort d2)
   2829 {
   2830    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2831       s390_disasm(ENC3(MNM, UDLB, UDXB), "mvc", d1, l, b1, d2, 0, b2);
   2832 
   2833    return emit_SSa(p, 0xd20000000000ULL, l, b1, d1, b2, d2);
   2834 }
   2835 
   2836 
   2837 static UChar *
   2838 s390_emit_MVI(UChar *p, UChar i2, UChar b1, UShort d1)
   2839 {
   2840    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2841       s390_disasm(ENC3(MNM, UDXB, INT), "mvi", d1, 0, b1, i2);
   2842 
   2843    return emit_SI(p, 0x92000000, i2, b1, d1);
   2844 }
   2845 
   2846 
   2847 static UChar *
   2848 s390_emit_MVHHI(UChar *p, UChar b1, UShort d1, UShort i2)
   2849 {
   2850    vassert(s390_host_has_gie);
   2851 
   2852    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2853       s390_disasm(ENC3(MNM, UDXB, INT), "mvhhi", d1, 0, b1, i2);
   2854 
   2855    return emit_SIL(p, 0xe54400000000ULL, b1, d1, i2);
   2856 }
   2857 
   2858 
   2859 static UChar *
   2860 s390_emit_MVHI(UChar *p, UChar b1, UShort d1, UShort i2)
   2861 {
   2862    vassert(s390_host_has_gie);
   2863 
   2864    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2865       s390_disasm(ENC3(MNM, UDXB, INT), "mvhi", d1, 0, b1, i2);
   2866 
   2867    return emit_SIL(p, 0xe54c00000000ULL, b1, d1, i2);
   2868 }
   2869 
   2870 
   2871 static UChar *
   2872 s390_emit_MVGHI(UChar *p, UChar b1, UShort d1, UShort i2)
   2873 {
   2874    vassert(s390_host_has_gie);
   2875 
   2876    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2877       s390_disasm(ENC3(MNM, UDXB, INT), "mvghi", d1, 0, b1, i2);
   2878 
   2879    return emit_SIL(p, 0xe54800000000ULL, b1, d1, i2);
   2880 }
   2881 
   2882 
   2883 static UChar *
   2884 s390_emit_OR(UChar *p, UChar r1, UChar r2)
   2885 {
   2886    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2887       s390_disasm(ENC3(MNM, GPR, GPR), "or", r1, r2);
   2888 
   2889    return emit_RR(p, 0x1600, r1, r2);
   2890 }
   2891 
   2892 
   2893 static UChar *
   2894 s390_emit_OGR(UChar *p, UChar r1, UChar r2)
   2895 {
   2896    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2897       s390_disasm(ENC3(MNM, GPR, GPR), "ogr", r1, r2);
   2898 
   2899    return emit_RRE(p, 0xb9810000, r1, r2);
   2900 }
   2901 
   2902 
   2903 static UChar *
   2904 s390_emit_O(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   2905 {
   2906    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2907       s390_disasm(ENC3(MNM, GPR, UDXB), "o", r1, d2, x2, b2);
   2908 
   2909    return emit_RX(p, 0x56000000, r1, x2, b2, d2);
   2910 }
   2911 
   2912 
   2913 static UChar *
   2914 s390_emit_OY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2915 {
   2916    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2917       s390_disasm(ENC3(MNM, GPR, SDXB), "oy", r1, dh2, dl2, x2, b2);
   2918 
   2919    return emit_RXY(p, 0xe30000000056ULL, r1, x2, b2, dl2, dh2);
   2920 }
   2921 
   2922 
   2923 static UChar *
   2924 s390_emit_OG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   2925 {
   2926    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2927       s390_disasm(ENC3(MNM, GPR, SDXB), "og", r1, dh2, dl2, x2, b2);
   2928 
   2929    return emit_RXY(p, 0xe30000000081ULL, r1, x2, b2, dl2, dh2);
   2930 }
   2931 
   2932 
   2933 static UChar *
   2934 s390_emit_OIHF(UChar *p, UChar r1, UInt i2)
   2935 {
   2936    vassert(s390_host_has_eimm);
   2937 
   2938    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2939       s390_disasm(ENC3(MNM, GPR, UINT), "oihf", r1, i2);
   2940 
   2941    return emit_RIL(p, 0xc00c00000000ULL, r1, i2);
   2942 }
   2943 
   2944 
   2945 static UChar *
   2946 s390_emit_OILF(UChar *p, UChar r1, UInt i2)
   2947 {
   2948    vassert(s390_host_has_eimm);
   2949 
   2950    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2951       s390_disasm(ENC3(MNM, GPR, UINT), "oilf", r1, i2);
   2952 
   2953    return emit_RIL(p, 0xc00d00000000ULL, r1, i2);
   2954 }
   2955 
   2956 
   2957 static UChar *
   2958 s390_emit_OILL(UChar *p, UChar r1, UShort i2)
   2959 {
   2960    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2961       s390_disasm(ENC3(MNM, GPR, UINT), "oill", r1, i2);
   2962 
   2963    return emit_RI(p, 0xa50b0000, r1, i2);
   2964 }
   2965 
   2966 
   2967 static UChar *
   2968 s390_emit_SLL(UChar *p, UChar r1, UChar b2, UShort d2)
   2969 {
   2970    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2971       s390_disasm(ENC3(MNM, GPR, UDXB), "sll", r1, d2, 0, b2);
   2972 
   2973    return emit_RS(p, 0x89000000, r1, 0, b2, d2);
   2974 }
   2975 
   2976 
   2977 static UChar *
   2978 s390_emit_SLLG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
   2979 {
   2980    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2981       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "sllg", r1, r3, dh2, dl2, 0, b2);
   2982 
   2983    return emit_RSY(p, 0xeb000000000dULL, r1, r3, b2, dl2, dh2);
   2984 }
   2985 
   2986 
   2987 static UChar *
   2988 s390_emit_SRA(UChar *p, UChar r1, UChar b2, UShort d2)
   2989 {
   2990    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   2991       s390_disasm(ENC3(MNM, GPR, UDXB), "sra", r1, d2, 0, b2);
   2992 
   2993    return emit_RS(p, 0x8a000000, r1, 0, b2, d2);
   2994 }
   2995 
   2996 
   2997 static UChar *
   2998 s390_emit_SRAG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
   2999 {
   3000    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3001       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "srag", r1, r3, dh2, dl2, 0, b2);
   3002 
   3003    return emit_RSY(p, 0xeb000000000aULL, r1, r3, b2, dl2, dh2);
   3004 }
   3005 
   3006 
   3007 static UChar *
   3008 s390_emit_SRL(UChar *p, UChar r1, UChar b2, UShort d2)
   3009 {
   3010    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3011       s390_disasm(ENC3(MNM, GPR, UDXB), "srl", r1, d2, 0, b2);
   3012 
   3013    return emit_RS(p, 0x88000000, r1, 0, b2, d2);
   3014 }
   3015 
   3016 
   3017 static UChar *
   3018 s390_emit_SRLG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
   3019 {
   3020    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3021       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "srlg", r1, r3, dh2, dl2, 0, b2);
   3022 
   3023    return emit_RSY(p, 0xeb000000000cULL, r1, r3, b2, dl2, dh2);
   3024 }
   3025 
   3026 
   3027 static UChar *
   3028 s390_emit_ST(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   3029 {
   3030    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3031       s390_disasm(ENC3(MNM, GPR, UDXB), "st", r1, d2, x2, b2);
   3032 
   3033    return emit_RX(p, 0x50000000, r1, x2, b2, d2);
   3034 }
   3035 
   3036 
   3037 static UChar *
   3038 s390_emit_STY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   3039 {
   3040    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3041       s390_disasm(ENC3(MNM, GPR, SDXB), "sty", r1, dh2, dl2, x2, b2);
   3042 
   3043    return emit_RXY(p, 0xe30000000050ULL, r1, x2, b2, dl2, dh2);
   3044 }
   3045 
   3046 
   3047 static UChar *
   3048 s390_emit_STG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   3049 {
   3050    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3051       s390_disasm(ENC3(MNM, GPR, SDXB), "stg", r1, dh2, dl2, x2, b2);
   3052 
   3053    return emit_RXY(p, 0xe30000000024ULL, r1, x2, b2, dl2, dh2);
   3054 }
   3055 
   3056 
   3057 static UChar *
   3058 s390_emit_STC(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   3059 {
   3060    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3061       s390_disasm(ENC3(MNM, GPR, UDXB), "stc", r1, d2, x2, b2);
   3062 
   3063    return emit_RX(p, 0x42000000, r1, x2, b2, d2);
   3064 }
   3065 
   3066 
   3067 static UChar *
   3068 s390_emit_STCY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   3069 {
   3070    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3071       s390_disasm(ENC3(MNM, GPR, SDXB), "stcy", r1, dh2, dl2, x2, b2);
   3072 
   3073    return emit_RXY(p, 0xe30000000072ULL, r1, x2, b2, dl2, dh2);
   3074 }
   3075 
   3076 
   3077 static UChar *
   3078 s390_emit_STH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   3079 {
   3080    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3081       s390_disasm(ENC3(MNM, GPR, UDXB), "sth", r1, d2, x2, b2);
   3082 
   3083    return emit_RX(p, 0x40000000, r1, x2, b2, d2);
   3084 }
   3085 
   3086 
   3087 static UChar *
   3088 s390_emit_STHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   3089 {
   3090    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3091       s390_disasm(ENC3(MNM, GPR, SDXB), "sthy", r1, dh2, dl2, x2, b2);
   3092 
   3093    return emit_RXY(p, 0xe30000000070ULL, r1, x2, b2, dl2, dh2);
   3094 }
   3095 
   3096 
   3097 static UChar *
   3098 s390_emit_SR(UChar *p, UChar r1, UChar r2)
   3099 {
   3100    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3101       s390_disasm(ENC3(MNM, GPR, GPR), "sr", r1, r2);
   3102 
   3103    return emit_RR(p, 0x1b00, r1, r2);
   3104 }
   3105 
   3106 
   3107 static UChar *
   3108 s390_emit_SGR(UChar *p, UChar r1, UChar r2)
   3109 {
   3110    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3111       s390_disasm(ENC3(MNM, GPR, GPR), "sgr", r1, r2);
   3112 
   3113    return emit_RRE(p, 0xb9090000, r1, r2);
   3114 }
   3115 
   3116 
   3117 static UChar *
   3118 s390_emit_S(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   3119 {
   3120    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3121       s390_disasm(ENC3(MNM, GPR, UDXB), "s", r1, d2, x2, b2);
   3122 
   3123    return emit_RX(p, 0x5b000000, r1, x2, b2, d2);
   3124 }
   3125 
   3126 
   3127 static UChar *
   3128 s390_emit_SY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   3129 {
   3130    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3131       s390_disasm(ENC3(MNM, GPR, SDXB), "sy", r1, dh2, dl2, x2, b2);
   3132 
   3133    return emit_RXY(p, 0xe3000000005bULL, r1, x2, b2, dl2, dh2);
   3134 }
   3135 
   3136 
   3137 static UChar *
   3138 s390_emit_SG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   3139 {
   3140    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3141       s390_disasm(ENC3(MNM, GPR, SDXB), "sg", r1, dh2, dl2, x2, b2);
   3142 
   3143    return emit_RXY(p, 0xe30000000009ULL, r1, x2, b2, dl2, dh2);
   3144 }
   3145 
   3146 
   3147 static UChar *
   3148 s390_emit_SH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   3149 {
   3150    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3151       s390_disasm(ENC3(MNM, GPR, UDXB), "sh", r1, d2, x2, b2);
   3152 
   3153    return emit_RX(p, 0x4b000000, r1, x2, b2, d2);
   3154 }
   3155 
   3156 
   3157 static UChar *
   3158 s390_emit_SHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   3159 {
   3160    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3161       s390_disasm(ENC3(MNM, GPR, SDXB), "shy", r1, dh2, dl2, x2, b2);
   3162 
   3163    return emit_RXY(p, 0xe3000000007bULL, r1, x2, b2, dl2, dh2);
   3164 }
   3165 
   3166 
   3167 static UChar *
   3168 s390_emit_SLFI(UChar *p, UChar r1, UInt i2)
   3169 {
   3170    vassert(s390_host_has_eimm);
   3171 
   3172    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3173       s390_disasm(ENC3(MNM, GPR, UINT), "slfi", r1, i2);
   3174 
   3175    return emit_RIL(p, 0xc20500000000ULL, r1, i2);
   3176 }
   3177 
   3178 
   3179 static UChar *
   3180 s390_emit_SLGFI(UChar *p, UChar r1, UInt i2)
   3181 {
   3182    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3183       s390_disasm(ENC3(MNM, GPR, UINT), "slgfi", r1, i2);
   3184 
   3185    return emit_RIL(p, 0xc20400000000ULL, r1, i2);
   3186 }
   3187 
   3188 
   3189 static UChar *
   3190 s390_emit_LDR(UChar *p, UChar r1, UChar r2)
   3191 {
   3192    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3193       s390_disasm(ENC3(MNM, FPR, FPR), "ldr", r1, r2);
   3194 
   3195    return emit_RR(p, 0x2800, r1, r2);
   3196 }
   3197 
   3198 
   3199 static UChar *
   3200 s390_emit_LE(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   3201 {
   3202    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3203       s390_disasm(ENC3(MNM, FPR, UDXB), "le", r1, d2, x2, b2);
   3204 
   3205    return emit_RX(p, 0x78000000, r1, x2, b2, d2);
   3206 }
   3207 
   3208 
   3209 static UChar *
   3210 s390_emit_LD(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   3211 {
   3212    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3213       s390_disasm(ENC3(MNM, FPR, UDXB), "ld", r1, d2, x2, b2);
   3214 
   3215    return emit_RX(p, 0x68000000, r1, x2, b2, d2);
   3216 }
   3217 
   3218 
   3219 static UChar *
   3220 s390_emit_LEY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   3221 {
   3222    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3223       s390_disasm(ENC3(MNM, FPR, SDXB), "ley", r1, dh2, dl2, x2, b2);
   3224 
   3225    return emit_RXY(p, 0xed0000000064ULL, r1, x2, b2, dl2, dh2);
   3226 }
   3227 
   3228 
   3229 static UChar *
   3230 s390_emit_LDY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   3231 {
   3232    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3233       s390_disasm(ENC3(MNM, FPR, SDXB), "ldy", r1, dh2, dl2, x2, b2);
   3234 
   3235    return emit_RXY(p, 0xed0000000065ULL, r1, x2, b2, dl2, dh2);
   3236 }
   3237 
   3238 
   3239 static UChar *
   3240 s390_emit_LFPC(UChar *p, UChar b2, UShort d2)
   3241 {
   3242    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3243       s390_disasm(ENC2(MNM, UDXB), "lfpc", d2, 0, b2);
   3244 
   3245    return emit_S(p, 0xb29d0000, b2, d2);
   3246 }
   3247 
   3248 
   3249 static UChar *
   3250 s390_emit_LDGR(UChar *p, UChar r1, UChar r2)
   3251 {
   3252    vassert(s390_host_has_fgx);
   3253 
   3254    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3255       s390_disasm(ENC3(MNM, FPR, GPR), "ldgr", r1, r2);
   3256 
   3257    return emit_RRE(p, 0xb3c10000, r1, r2);
   3258 }
   3259 
   3260 
   3261 static UChar *
   3262 s390_emit_LGDR(UChar *p, UChar r1, UChar r2)
   3263 {
   3264    vassert(s390_host_has_fgx);
   3265 
   3266    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3267       s390_disasm(ENC3(MNM, GPR, FPR), "lgdr", r1, r2);
   3268 
   3269    return emit_RRE(p, 0xb3cd0000, r1, r2);
   3270 }
   3271 
   3272 
   3273 static UChar *
   3274 s390_emit_LZER(UChar *p, UChar r1, UChar r2)
   3275 {
   3276    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3277       s390_disasm(ENC2(MNM, FPR), "lzer", r1);
   3278 
   3279    return emit_RRE(p, 0xb3740000, r1, r2);
   3280 }
   3281 
   3282 
   3283 static UChar *
   3284 s390_emit_LZDR(UChar *p, UChar r1, UChar r2)
   3285 {
   3286    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3287       s390_disasm(ENC2(MNM, FPR), "lzdr", r1);
   3288 
   3289    return emit_RRE(p, 0xb3750000, r1, r2);
   3290 }
   3291 
   3292 
   3293 static UChar *
   3294 s390_emit_SFPC(UChar *p, UChar r1)
   3295 {
   3296    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3297       s390_disasm(ENC2(MNM, GPR), "sfpc", r1);
   3298 
   3299    return emit_RRE(p, 0xb3840000, r1, 0);
   3300 }
   3301 
   3302 
   3303 static UChar *
   3304 s390_emit_STE(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   3305 {
   3306    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3307       s390_disasm(ENC3(MNM, FPR, UDXB), "ste", r1, d2, x2, b2);
   3308 
   3309    return emit_RX(p, 0x70000000, r1, x2, b2, d2);
   3310 }
   3311 
   3312 
   3313 static UChar *
   3314 s390_emit_STD(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
   3315 {
   3316    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3317       s390_disasm(ENC3(MNM, FPR, UDXB), "std", r1, d2, x2, b2);
   3318 
   3319    return emit_RX(p, 0x60000000, r1, x2, b2, d2);
   3320 }
   3321 
   3322 
   3323 static UChar *
   3324 s390_emit_STEY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   3325 {
   3326    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3327       s390_disasm(ENC3(MNM, FPR, SDXB), "stey", r1, dh2, dl2, x2, b2);
   3328 
   3329    return emit_RXY(p, 0xed0000000066ULL, r1, x2, b2, dl2, dh2);
   3330 }
   3331 
   3332 
   3333 static UChar *
   3334 s390_emit_STDY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
   3335 {
   3336    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3337       s390_disasm(ENC3(MNM, FPR, SDXB), "stdy", r1, dh2, dl2, x2, b2);
   3338 
   3339    return emit_RXY(p, 0xed0000000067ULL, r1, x2, b2, dl2, dh2);
   3340 }
   3341 
   3342 
   3343 static UChar *
   3344 s390_emit_STFPC(UChar *p, UChar b2, UShort d2)
   3345 {
   3346    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3347       s390_disasm(ENC2(MNM, UDXB), "stfpc", d2, 0, b2);
   3348 
   3349    return emit_S(p, 0xb29c0000, b2, d2);
   3350 }
   3351 
   3352 
   3353 static UChar *
   3354 s390_emit_AEBR(UChar *p, UChar r1, UChar r2)
   3355 {
   3356    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3357       s390_disasm(ENC3(MNM, FPR, FPR), "aebr", r1, r2);
   3358 
   3359    return emit_RRE(p, 0xb30a0000, r1, r2);
   3360 }
   3361 
   3362 
   3363 static UChar *
   3364 s390_emit_ADBR(UChar *p, UChar r1, UChar r2)
   3365 {
   3366    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3367       s390_disasm(ENC3(MNM, FPR, FPR), "adbr", r1, r2);
   3368 
   3369    return emit_RRE(p, 0xb31a0000, r1, r2);
   3370 }
   3371 
   3372 
   3373 static UChar *
   3374 s390_emit_AXBR(UChar *p, UChar r1, UChar r2)
   3375 {
   3376    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3377       s390_disasm(ENC3(MNM, FPR, FPR), "axbr", r1, r2);
   3378 
   3379    return emit_RRE(p, 0xb34a0000, r1, r2);
   3380 }
   3381 
   3382 
   3383 static UChar *
   3384 s390_emit_CEBR(UChar *p, UChar r1, UChar r2)
   3385 {
   3386    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3387       s390_disasm(ENC3(MNM, FPR, FPR), "cebr", r1, r2);
   3388 
   3389    return emit_RRE(p, 0xb3090000, r1, r2);
   3390 }
   3391 
   3392 
   3393 static UChar *
   3394 s390_emit_CDBR(UChar *p, UChar r1, UChar r2)
   3395 {
   3396    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3397       s390_disasm(ENC3(MNM, FPR, FPR), "cdbr", r1, r2);
   3398 
   3399    return emit_RRE(p, 0xb3190000, r1, r2);
   3400 }
   3401 
   3402 
   3403 static UChar *
   3404 s390_emit_CXBR(UChar *p, UChar r1, UChar r2)
   3405 {
   3406    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3407       s390_disasm(ENC3(MNM, FPR, FPR), "cxbr", r1, r2);
   3408 
   3409    return emit_RRE(p, 0xb3490000, r1, r2);
   3410 }
   3411 
   3412 
   3413 static UChar *
   3414 s390_emit_CEFBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3415 {
   3416    vassert(m4 == 0);
   3417    vassert(m3 == 0 || s390_host_has_fpext);
   3418 
   3419    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   3420       if (m3 == 0)
   3421          s390_disasm(ENC3(MNM, FPR, GPR), "cefbr", r1, r2);
   3422       else
   3423          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT),
   3424                      "cefbra", r1, m3, r2, m4);
   3425    }
   3426 
   3427    return emit_RRF2(p, 0xb3940000, m3, m4, r1, r2);
   3428 }
   3429 
   3430 
   3431 static UChar *
   3432 s390_emit_CDFBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3433 {
   3434    vassert(m4 == 0);
   3435    vassert(m3 == 0 || s390_host_has_fpext);
   3436 
   3437    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   3438       if (m3 == 0)
   3439          s390_disasm(ENC3(MNM, FPR, GPR), "cdfbr", r1, r2);
   3440       else
   3441          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT),
   3442                      "cdfbra", r1, m3, r2, m4);
   3443    }
   3444 
   3445    return emit_RRF2(p, 0xb3950000, m3, m4, r1, r2);
   3446 }
   3447 
   3448 
   3449 static UChar *
   3450 s390_emit_CXFBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3451 {
   3452    vassert(m4 == 0);
   3453    vassert(m3 == 0 || s390_host_has_fpext);
   3454 
   3455    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   3456       if (m3 == 0)
   3457          s390_disasm(ENC3(MNM, FPR, GPR), "cxfbr", r1, r2);
   3458       else
   3459          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT),
   3460                      "cxfbra", r1, m3, r2, m4);
   3461    }
   3462 
   3463    return emit_RRF2(p, 0xb3960000, m3, m4, r1, r2);
   3464 }
   3465 
   3466 
   3467 static UChar *
   3468 s390_emit_CEGBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3469 {
   3470    vassert(m4 == 0);
   3471    vassert(m3 == 0 || s390_host_has_fpext);
   3472 
   3473    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   3474       if (m3 == 0)
   3475          s390_disasm(ENC3(MNM, FPR, GPR), "cegbr", r1, r2);
   3476       else
   3477          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT),
   3478                      "cegbra", r1, m3, r2, m4);
   3479    }
   3480 
   3481    return emit_RRF2(p, 0xb3a40000, m3, m4, r1, r2);
   3482 }
   3483 
   3484 
   3485 static UChar *
   3486 s390_emit_CDGBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3487 {
   3488    vassert(m4 == 0);
   3489    vassert(m3 == 0 || s390_host_has_fpext);
   3490 
   3491    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   3492       if (m3 == 0)
   3493          s390_disasm(ENC3(MNM, FPR, GPR), "cdgbr", r1, r2);
   3494       else
   3495          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT),
   3496                      "cdgbra", r1, m3, r2, m4);
   3497    }
   3498 
   3499    return emit_RRF2(p, 0xb3a50000, m3, m4, r1, r2);
   3500 }
   3501 
   3502 
   3503 static UChar *
   3504 s390_emit_CXGBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3505 {
   3506    vassert(m4 == 0);
   3507    vassert(m3 == 0 || s390_host_has_fpext);
   3508 
   3509    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   3510       if (m3 == 0)
   3511          s390_disasm(ENC3(MNM, FPR, GPR), "cxgbr", r1, r2);
   3512       else
   3513          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT),
   3514                      "cxgbra", r1, m3, r2, m4);
   3515    }
   3516 
   3517    return emit_RRF2(p, 0xb3a60000, m3, m4, r1, r2);
   3518 }
   3519 
   3520 
   3521 static UChar *
   3522 s390_emit_CELFBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3523 {
   3524    vassert(m4 == 0);
   3525    vassert(s390_host_has_fpext);
   3526 
   3527    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3528       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "celfbr", r1, m3, r2, m4);
   3529 
   3530    return emit_RRF2(p, 0xb3900000, m3, m4, r1, r2);
   3531 }
   3532 
   3533 
   3534 static UChar *
   3535 s390_emit_CDLFBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3536 {
   3537    vassert(m4 == 0);
   3538    vassert(s390_host_has_fpext);
   3539 
   3540    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3541       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cdlfbr", r1, m3, r2, m4);
   3542 
   3543    return emit_RRF2(p, 0xb3910000, m3, m4, r1, r2);
   3544 }
   3545 
   3546 
   3547 static UChar *
   3548 s390_emit_CXLFBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3549 {
   3550    vassert(m4 == 0);
   3551    vassert(s390_host_has_fpext);
   3552 
   3553    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3554       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cxlfbr", r1, m3, r2, m4);
   3555 
   3556    return emit_RRF2(p, 0xb3920000, m3, m4, r1, r2);
   3557 }
   3558 
   3559 
   3560 static UChar *
   3561 s390_emit_CELGBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3562 {
   3563    vassert(m4 == 0);
   3564    vassert(s390_host_has_fpext);
   3565 
   3566    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3567       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "celgbr", r1, m3, r2, m4);
   3568 
   3569    return emit_RRF2(p, 0xb3a00000, m3, m4, r1, r2);
   3570 }
   3571 
   3572 
   3573 static UChar *
   3574 s390_emit_CDLGBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3575 {
   3576    vassert(m4 == 0);
   3577    vassert(s390_host_has_fpext);
   3578 
   3579    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3580       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cdlgbr", r1, m3, r2, m4);
   3581 
   3582    return emit_RRF2(p, 0xb3a10000, m3, m4, r1, r2);
   3583 }
   3584 
   3585 
   3586 static UChar *
   3587 s390_emit_CXLGBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3588 {
   3589    vassert(m4 == 0);
   3590    vassert(s390_host_has_fpext);
   3591 
   3592    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3593       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cxlgbr", r1, m3, r2, m4);
   3594 
   3595    return emit_RRF2(p, 0xb3a20000, m3, m4, r1, r2);
   3596 }
   3597 
   3598 
   3599 static UChar *
   3600 s390_emit_CLFEBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3601 {
   3602    vassert(m4 == 0);
   3603    vassert(s390_host_has_fpext);
   3604 
   3605    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3606       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clfebr", r1, m3, r2, m4);
   3607 
   3608    return emit_RRF2(p, 0xb39c0000, m3, m4, r1, r2);
   3609 }
   3610 
   3611 
   3612 static UChar *
   3613 s390_emit_CLFDBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3614 {
   3615    vassert(m4 == 0);
   3616    vassert(s390_host_has_fpext);
   3617 
   3618    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3619       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clfdbr", r1, m3, r2, m4);
   3620 
   3621    return emit_RRF2(p, 0xb39d0000, m3, m4, r1, r2);
   3622 }
   3623 
   3624 
   3625 static UChar *
   3626 s390_emit_CLFXBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3627 {
   3628    vassert(m4 == 0);
   3629    vassert(s390_host_has_fpext);
   3630 
   3631    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3632       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clfxbr", r1, m3, r2, m4);
   3633 
   3634    return emit_RRF2(p, 0xb39e0000, m3, m4, r1, r2);
   3635 }
   3636 
   3637 
   3638 static UChar *
   3639 s390_emit_CLGEBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3640 {
   3641    vassert(m4 == 0);
   3642    vassert(s390_host_has_fpext);
   3643 
   3644    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3645       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clgebr", r1, m3, r2, m4);
   3646 
   3647    return emit_RRF2(p, 0xb3ac0000, m3, m4, r1, r2);
   3648 }
   3649 
   3650 
   3651 static UChar *
   3652 s390_emit_CLGDBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3653 {
   3654    vassert(m4 == 0);
   3655    vassert(s390_host_has_fpext);
   3656 
   3657    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3658       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clgdbr", r1, m3, r2, m4);
   3659 
   3660    return emit_RRF2(p, 0xb3ad0000, m3, m4, r1, r2);
   3661 }
   3662 
   3663 
   3664 static UChar *
   3665 s390_emit_CLGXBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3666 {
   3667    vassert(m4 == 0);
   3668    vassert(s390_host_has_fpext);
   3669 
   3670    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3671       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clgxbr", r1, m3, r2, m4);
   3672 
   3673    return emit_RRF2(p, 0xb3ae0000, m3, m4, r1, r2);
   3674 }
   3675 
   3676 
   3677 static UChar *
   3678 s390_emit_CFEBR(UChar *p, UChar r3, UChar r1, UChar r2)
   3679 {
   3680    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3681       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cfebr", r1, r3, r2);
   3682 
   3683    return emit_RRF3(p, 0xb3980000, r3, r1, r2);
   3684 }
   3685 
   3686 
   3687 static UChar *
   3688 s390_emit_CFDBR(UChar *p, UChar r3, UChar r1, UChar r2)
   3689 {
   3690    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3691       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cfdbr", r1, r3, r2);
   3692 
   3693    return emit_RRF3(p, 0xb3990000, r3, r1, r2);
   3694 }
   3695 
   3696 
   3697 static UChar *
   3698 s390_emit_CFXBR(UChar *p, UChar r3, UChar r1, UChar r2)
   3699 {
   3700    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3701       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cfxbr", r1, r3, r2);
   3702 
   3703    return emit_RRF3(p, 0xb39a0000, r3, r1, r2);
   3704 }
   3705 
   3706 
   3707 static UChar *
   3708 s390_emit_CGEBR(UChar *p, UChar r3, UChar r1, UChar r2)
   3709 {
   3710    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3711       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cgebr", r1, r3, r2);
   3712 
   3713    return emit_RRF3(p, 0xb3a80000, r3, r1, r2);
   3714 }
   3715 
   3716 
   3717 static UChar *
   3718 s390_emit_CGDBR(UChar *p, UChar r3, UChar r1, UChar r2)
   3719 {
   3720    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3721       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cgdbr", r1, r3, r2);
   3722 
   3723    return emit_RRF3(p, 0xb3a90000, r3, r1, r2);
   3724 }
   3725 
   3726 
   3727 static UChar *
   3728 s390_emit_CGXBR(UChar *p, UChar r3, UChar r1, UChar r2)
   3729 {
   3730    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3731       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cgxbr", r1, r3, r2);
   3732 
   3733    return emit_RRF3(p, 0xb3aa0000, r3, r1, r2);
   3734 }
   3735 
   3736 
   3737 static UChar *
   3738 s390_emit_DEBR(UChar *p, UChar r1, UChar r2)
   3739 {
   3740    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3741       s390_disasm(ENC3(MNM, FPR, FPR), "debr", r1, r2);
   3742 
   3743    return emit_RRE(p, 0xb30d0000, r1, r2);
   3744 }
   3745 
   3746 
   3747 static UChar *
   3748 s390_emit_DDBR(UChar *p, UChar r1, UChar r2)
   3749 {
   3750    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3751       s390_disasm(ENC3(MNM, FPR, FPR), "ddbr", r1, r2);
   3752 
   3753    return emit_RRE(p, 0xb31d0000, r1, r2);
   3754 }
   3755 
   3756 
   3757 static UChar *
   3758 s390_emit_DXBR(UChar *p, UChar r1, UChar r2)
   3759 {
   3760    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3761       s390_disasm(ENC3(MNM, FPR, FPR), "dxbr", r1, r2);
   3762 
   3763    return emit_RRE(p, 0xb34d0000, r1, r2);
   3764 }
   3765 
   3766 
   3767 static UChar *
   3768 s390_emit_LCEBR(UChar *p, UChar r1, UChar r2)
   3769 {
   3770    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3771       s390_disasm(ENC3(MNM, FPR, FPR), "lcebr", r1, r2);
   3772 
   3773    return emit_RRE(p, 0xb3030000, r1, r2);
   3774 }
   3775 
   3776 
   3777 static UChar *
   3778 s390_emit_LCDBR(UChar *p, UChar r1, UChar r2)
   3779 {
   3780    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3781       s390_disasm(ENC3(MNM, FPR, FPR), "lcdbr", r1, r2);
   3782 
   3783    return emit_RRE(p, 0xb3130000, r1, r2);
   3784 }
   3785 
   3786 
   3787 static UChar *
   3788 s390_emit_LCXBR(UChar *p, UChar r1, UChar r2)
   3789 {
   3790    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3791       s390_disasm(ENC3(MNM, FPR, FPR), "lcxbr", r1, r2);
   3792 
   3793    return emit_RRE(p, 0xb3430000, r1, r2);
   3794 }
   3795 
   3796 
   3797 static UChar *
   3798 s390_emit_LDEBR(UChar *p, UChar r1, UChar r2)
   3799 {
   3800    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3801       s390_disasm(ENC3(MNM, FPR, FPR), "ldebr", r1, r2);
   3802 
   3803    return emit_RRE(p, 0xb3040000, r1, r2);
   3804 }
   3805 
   3806 
   3807 static UChar *
   3808 s390_emit_LXDBR(UChar *p, UChar r1, UChar r2)
   3809 {
   3810    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3811       s390_disasm(ENC3(MNM, FPR, FPR), "lxdbr", r1, r2);
   3812 
   3813    return emit_RRE(p, 0xb3050000, r1, r2);
   3814 }
   3815 
   3816 
   3817 static UChar *
   3818 s390_emit_LXEBR(UChar *p, UChar r1, UChar r2)
   3819 {
   3820    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3821       s390_disasm(ENC3(MNM, FPR, FPR), "lxebr", r1, r2);
   3822 
   3823    return emit_RRE(p, 0xb3060000, r1, r2);
   3824 }
   3825 
   3826 
   3827 static UChar *
   3828 s390_emit_LNEBR(UChar *p, UChar r1, UChar r2)
   3829 {
   3830    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3831       s390_disasm(ENC3(MNM, FPR, FPR), "lnebr", r1, r2);
   3832 
   3833    return emit_RRE(p, 0xb3010000, r1, r2);
   3834 }
   3835 
   3836 
   3837 static UChar *
   3838 s390_emit_LNDBR(UChar *p, UChar r1, UChar r2)
   3839 {
   3840    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3841       s390_disasm(ENC3(MNM, FPR, FPR), "lndbr", r1, r2);
   3842 
   3843    return emit_RRE(p, 0xb3110000, r1, r2);
   3844 }
   3845 
   3846 
   3847 static UChar *
   3848 s390_emit_LNXBR(UChar *p, UChar r1, UChar r2)
   3849 {
   3850    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3851       s390_disasm(ENC3(MNM, FPR, FPR), "lnxbr", r1, r2);
   3852 
   3853    return emit_RRE(p, 0xb3410000, r1, r2);
   3854 }
   3855 
   3856 
   3857 static UChar *
   3858 s390_emit_LPEBR(UChar *p, UChar r1, UChar r2)
   3859 {
   3860    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3861       s390_disasm(ENC3(MNM, FPR, FPR), "lpebr", r1, r2);
   3862 
   3863    return emit_RRE(p, 0xb3000000, r1, r2);
   3864 }
   3865 
   3866 
   3867 static UChar *
   3868 s390_emit_LPDBR(UChar *p, UChar r1, UChar r2)
   3869 {
   3870    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3871       s390_disasm(ENC3(MNM, FPR, FPR), "lpdbr", r1, r2);
   3872 
   3873    return emit_RRE(p, 0xb3100000, r1, r2);
   3874 }
   3875 
   3876 
   3877 static UChar *
   3878 s390_emit_LPXBR(UChar *p, UChar r1, UChar r2)
   3879 {
   3880    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3881       s390_disasm(ENC3(MNM, FPR, FPR), "lpxbr", r1, r2);
   3882 
   3883    return emit_RRE(p, 0xb3400000, r1, r2);
   3884 }
   3885 
   3886 
   3887 static UChar *
   3888 s390_emit_LEDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3889 {
   3890    vassert(m4 == 0);
   3891    vassert(m3 == 0 || s390_host_has_fpext);
   3892 
   3893    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   3894       if (m3 == 0)
   3895          s390_disasm(ENC3(MNM, FPR, FPR), "ledbr", r1, r2);
   3896       else
   3897          s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
   3898                      "ledbra", r1, m3, r2, m4);
   3899    }
   3900 
   3901    return emit_RRF2(p, 0xb3440000, m3, m4, r1, r2);
   3902 }
   3903 
   3904 
   3905 static UChar *
   3906 s390_emit_LDXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3907 {
   3908    vassert(m4 == 0);
   3909    vassert(m3 == 0 || s390_host_has_fpext);
   3910 
   3911    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   3912       if (m3 == 0)
   3913          s390_disasm(ENC3(MNM, FPR, FPR), "ldxbr", r1, r2);
   3914       else
   3915          s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
   3916                      "ldxbra", r1, m3, r2, m4);
   3917    }
   3918 
   3919    return emit_RRF2(p, 0xb3450000, m3, m4, r1, r2);
   3920 }
   3921 
   3922 
   3923 static UChar *
   3924 s390_emit_LEXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3925 {
   3926    vassert(m4 == 0);
   3927    vassert(m3 == 0 || s390_host_has_fpext);
   3928 
   3929    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   3930       if (m3 == 0)
   3931          s390_disasm(ENC3(MNM, FPR, FPR), "lexbr", r1, r2);
   3932       else
   3933          s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
   3934                      "lexbra", r1, m3, r2, m4);
   3935    }
   3936 
   3937    return emit_RRF2(p, 0xb3460000, m3, m4, r1, r2);
   3938 }
   3939 
   3940 
   3941 static UChar *
   3942 s390_emit_FIEBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3943 {
   3944    vassert(m3 == 0 || s390_host_has_fpext);
   3945 
   3946    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   3947       if (m4 == 0)
   3948          s390_disasm(ENC4(MNM, FPR, UINT, FPR), "fiebr", r1, m3, r2);
   3949       else
   3950          s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
   3951                      "fiebra", r1, m3, r2, m4);
   3952    }
   3953 
   3954    return emit_RRF2(p, 0xb3570000, m3, m4, r1, r2);
   3955 }
   3956 
   3957 
   3958 static UChar *
   3959 s390_emit_FIDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3960 {
   3961    vassert(m3 == 0 || s390_host_has_fpext);
   3962 
   3963    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   3964       if (m4 == 0)
   3965          s390_disasm(ENC4(MNM, FPR, UINT, FPR), "fidbr", r1, m3, r2);
   3966       else
   3967          s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
   3968                      "fidbra", r1, m3, r2, m4);
   3969    }
   3970 
   3971    return emit_RRF2(p, 0xb35f0000, m3, m4, r1, r2);
   3972 }
   3973 
   3974 
   3975 static UChar *
   3976 s390_emit_FIXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   3977 {
   3978    vassert(m3 == 0 || s390_host_has_fpext);
   3979 
   3980    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   3981       if (m4 == 0)
   3982          s390_disasm(ENC4(MNM, FPR, UINT, FPR), "fixbr", r1, m3, r2);
   3983       else
   3984          s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
   3985                      "fixbra", r1, m3, r2, m4);
   3986    }
   3987 
   3988    return emit_RRF2(p, 0xb3470000, m3, m4, r1, r2);
   3989 }
   3990 
   3991 
   3992 static UChar *
   3993 s390_emit_MEEBR(UChar *p, UChar r1, UChar r2)
   3994 {
   3995    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   3996       s390_disasm(ENC3(MNM, FPR, FPR), "meebr", r1, r2);
   3997 
   3998    return emit_RRE(p, 0xb3170000, r1, r2);
   3999 }
   4000 
   4001 
   4002 static UChar *
   4003 s390_emit_MDBR(UChar *p, UChar r1, UChar r2)
   4004 {
   4005    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4006       s390_disasm(ENC3(MNM, FPR, FPR), "mdbr", r1, r2);
   4007 
   4008    return emit_RRE(p, 0xb31c0000, r1, r2);
   4009 }
   4010 
   4011 
   4012 static UChar *
   4013 s390_emit_MXBR(UChar *p, UChar r1, UChar r2)
   4014 {
   4015    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4016       s390_disasm(ENC3(MNM, FPR, FPR), "mxbr", r1, r2);
   4017 
   4018    return emit_RRE(p, 0xb34c0000, r1, r2);
   4019 }
   4020 
   4021 
   4022 static UChar *
   4023 s390_emit_MAEBR(UChar *p, UChar r1, UChar r3, UChar r2)
   4024 {
   4025    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4026       s390_disasm(ENC4(MNM, FPR, FPR, FPR), "maebr", r1, r3, r2);
   4027 
   4028    return emit_RRF(p, 0xb30e0000, r1, r3, r2);
   4029 }
   4030 
   4031 
   4032 static UChar *
   4033 s390_emit_MADBR(UChar *p, UChar r1, UChar r3, UChar r2)
   4034 {
   4035    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4036       s390_disasm(ENC4(MNM, FPR, FPR, FPR), "madbr", r1, r3, r2);
   4037 
   4038    return emit_RRF(p, 0xb31e0000, r1, r3, r2);
   4039 }
   4040 
   4041 
   4042 static UChar *
   4043 s390_emit_MSEBR(UChar *p, UChar r1, UChar r3, UChar r2)
   4044 {
   4045    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4046       s390_disasm(ENC4(MNM, FPR, FPR, FPR), "msebr", r1, r3, r2);
   4047 
   4048    return emit_RRF(p, 0xb30f0000, r1, r3, r2);
   4049 }
   4050 
   4051 
   4052 static UChar *
   4053 s390_emit_MSDBR(UChar *p, UChar r1, UChar r3, UChar r2)
   4054 {
   4055    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4056       s390_disasm(ENC4(MNM, FPR, FPR, FPR), "msdbr", r1, r3, r2);
   4057 
   4058    return emit_RRF(p, 0xb31f0000, r1, r3, r2);
   4059 }
   4060 
   4061 
   4062 static UChar *
   4063 s390_emit_SQEBR(UChar *p, UChar r1, UChar r2)
   4064 {
   4065    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4066       s390_disasm(ENC3(MNM, FPR, FPR), "sqebr", r1, r2);
   4067 
   4068    return emit_RRE(p, 0xb3140000, r1, r2);
   4069 }
   4070 
   4071 
   4072 static UChar *
   4073 s390_emit_SQDBR(UChar *p, UChar r1, UChar r2)
   4074 {
   4075    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4076       s390_disasm(ENC3(MNM, FPR, FPR), "sqdbr", r1, r2);
   4077 
   4078    return emit_RRE(p, 0xb3150000, r1, r2);
   4079 }
   4080 
   4081 
   4082 static UChar *
   4083 s390_emit_SQXBR(UChar *p, UChar r1, UChar r2)
   4084 {
   4085    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4086       s390_disasm(ENC3(MNM, FPR, FPR), "sqxbr", r1, r2);
   4087 
   4088    return emit_RRE(p, 0xb3160000, r1, r2);
   4089 }
   4090 
   4091 
   4092 static UChar *
   4093 s390_emit_SEBR(UChar *p, UChar r1, UChar r2)
   4094 {
   4095    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4096       s390_disasm(ENC3(MNM, FPR, FPR), "sebr", r1, r2);
   4097 
   4098    return emit_RRE(p, 0xb30b0000, r1, r2);
   4099 }
   4100 
   4101 
   4102 static UChar *
   4103 s390_emit_SDBR(UChar *p, UChar r1, UChar r2)
   4104 {
   4105    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4106       s390_disasm(ENC3(MNM, FPR, FPR), "sdbr", r1, r2);
   4107 
   4108    return emit_RRE(p, 0xb31b0000, r1, r2);
   4109 }
   4110 
   4111 
   4112 static UChar *
   4113 s390_emit_SXBR(UChar *p, UChar r1, UChar r2)
   4114 {
   4115    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4116       s390_disasm(ENC3(MNM, FPR, FPR), "sxbr", r1, r2);
   4117 
   4118    return emit_RRE(p, 0xb34b0000, r1, r2);
   4119 }
   4120 
   4121 
   4122 static UChar *
   4123 s390_emit_ADTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
   4124 {
   4125    vassert(s390_host_has_dfp);
   4126    vassert(m4 == 0 || s390_host_has_fpext);
   4127    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   4128       if (m4 == 0)
   4129          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "adtr", r1, r2, r3);
   4130       else
   4131          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "adtra", r1, r2, r3, m4);
   4132    }
   4133 
   4134    return emit_RRF4(p, 0xb3d20000, r3, m4, r1, r2);
   4135 }
   4136 
   4137 
   4138 static UChar *
   4139 s390_emit_AXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
   4140 {
   4141    vassert(s390_host_has_dfp);
   4142    vassert(m4 == 0 || s390_host_has_fpext);
   4143    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   4144       if (m4 == 0)
   4145          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "axtr", r1, r2, r3);
   4146       else
   4147          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "axtra", r1, r2, r3, m4);
   4148    }
   4149 
   4150    return emit_RRF4(p, 0xb3da0000, r3, m4, r1, r2);
   4151 }
   4152 
   4153 
   4154 static UChar *
   4155 s390_emit_CDTR(UChar *p, UChar r1, UChar r2)
   4156 {
   4157    vassert(s390_host_has_dfp);
   4158    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4159       s390_disasm(ENC3(MNM, FPR, FPR), "cdtr", r1, r2);
   4160 
   4161    return emit_RRE(p, 0xb3e40000, r1, r2);
   4162 }
   4163 
   4164 
   4165 static UChar *
   4166 s390_emit_CXTR(UChar *p, UChar r1, UChar r2)
   4167 {
   4168    vassert(s390_host_has_dfp);
   4169    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4170       s390_disasm(ENC3(MNM, FPR, FPR), "cxtr", r1, r2);
   4171 
   4172    return emit_RRE(p, 0xb3ec0000, r1, r2);
   4173 }
   4174 
   4175 
   4176 static UChar *
   4177 s390_emit_CDGTRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4178 {
   4179    vassert(s390_host_has_dfp);
   4180    vassert(m4 == 0);
   4181    vassert(m3 == 0 || s390_host_has_fpext);
   4182 
   4183    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   4184       if (m3 == 0)
   4185          s390_disasm(ENC3(MNM, FPR, GPR), "cdgtr", r1, r2);
   4186       else
   4187          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cdgtra", r1, m3, r2, m4);
   4188    }
   4189 
   4190    return emit_RRF2(p, 0xb3f10000, m3, m4, r1, r2);
   4191 }
   4192 
   4193 
   4194 static UChar *
   4195 s390_emit_CXGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4196 {
   4197    vassert(s390_host_has_dfp);
   4198    vassert(m4 == 0);
   4199    /* rounding mode m3 is not considered, as the corresponding
   4200       IRop (Iop_I64StoD128) does not take rounding mode. */
   4201    vassert(m3 == 0);
   4202 
   4203    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4204       s390_disasm(ENC3(MNM, FPR, GPR), "cxgtr", r1, r2);
   4205 
   4206    return emit_RRF2(p, 0xb3f90000, m3, m4, r1, r2);
   4207 }
   4208 
   4209 
   4210 static UChar *
   4211 s390_emit_CDFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4212 {
   4213    vassert(m4 == 0);
   4214    vassert(s390_host_has_dfp);
   4215    vassert(s390_host_has_fpext);
   4216 
   4217    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4218       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cdftr", r1, m3, r2, m4);
   4219 
   4220    return emit_RRF2(p, 0xb9510000, m3, m4, r1, r2);
   4221 }
   4222 
   4223 
   4224 static UChar *
   4225 s390_emit_CXFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4226 {
   4227    vassert(m4 == 0);
   4228    vassert(s390_host_has_dfp);
   4229    vassert(s390_host_has_fpext);
   4230 
   4231    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4232       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cxftr", r1, m3, r2, m4);
   4233 
   4234    return emit_RRF2(p, 0xb9590000, m3, m4, r1, r2);
   4235 }
   4236 
   4237 
   4238 static UChar *
   4239 s390_emit_CDLFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4240 {
   4241    vassert(m4 == 0);
   4242    vassert(s390_host_has_dfp);
   4243    vassert(s390_host_has_fpext);
   4244 
   4245    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4246       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cdlftr", r1, m3, r2, m4);
   4247 
   4248    return emit_RRF2(p, 0xb9530000, m3, m4, r1, r2);
   4249 }
   4250 
   4251 
   4252 static UChar *
   4253 s390_emit_CXLFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4254 {
   4255    vassert(m4 == 0);
   4256    vassert(s390_host_has_dfp);
   4257    vassert(s390_host_has_fpext);
   4258 
   4259    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4260       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cxlftr", r1, m3, r2, m4);
   4261 
   4262    return emit_RRF2(p, 0xb95b0000, m3, m4, r1, r2);
   4263 }
   4264 
   4265 
   4266 static UChar *
   4267 s390_emit_CDLGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4268 {
   4269    vassert(m4 == 0);
   4270    vassert(s390_host_has_dfp);
   4271    vassert(s390_host_has_fpext);
   4272 
   4273    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4274       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cdlgtr", r1, m3, r2, m4);
   4275 
   4276    return emit_RRF2(p, 0xb9520000, m3, m4, r1, r2);
   4277 }
   4278 
   4279 
   4280 static UChar *
   4281 s390_emit_CXLGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4282 {
   4283    vassert(m4 == 0);
   4284    vassert(s390_host_has_dfp);
   4285    vassert(s390_host_has_fpext);
   4286 
   4287    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4288       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cxlgtr", r1, m3, r2, m4);
   4289 
   4290    return emit_RRF2(p, 0xb95a0000, m3, m4, r1, r2);
   4291 }
   4292 
   4293 
   4294 static UChar *
   4295 s390_emit_CEDTR(UChar *p, UChar r1, UChar r2)
   4296 {
   4297    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4298       s390_disasm(ENC3(MNM, FPR, FPR), "cedtr", r1, r2);
   4299 
   4300    return emit_RRE(p, 0xb3f40000, r1, r2);
   4301 }
   4302 
   4303 
   4304 static UChar *
   4305 s390_emit_CEXTR(UChar *p, UChar r1, UChar r2)
   4306 {
   4307    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4308       s390_disasm(ENC3(MNM, FPR, FPR), "cextr", r1, r2);
   4309 
   4310    return emit_RRE(p, 0xb3fc0000, r1, r2);
   4311 }
   4312 
   4313 
   4314 static UChar *
   4315 s390_emit_CFDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4316 {
   4317    vassert(m4 == 0);
   4318    vassert(s390_host_has_dfp);
   4319    vassert(s390_host_has_fpext);
   4320 
   4321    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4322       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "cfdtr", r1, m3, r2, m4);
   4323 
   4324    return emit_RRF2(p, 0xb9410000, m3, m4, r1, r2);
   4325 }
   4326 
   4327 
   4328 static UChar *
   4329 s390_emit_CFXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4330 {
   4331    vassert(m4 == 0);
   4332    vassert(s390_host_has_dfp);
   4333    vassert(s390_host_has_fpext);
   4334 
   4335    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4336       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "cfxtr", r1, m3, r2, m4);
   4337 
   4338    return emit_RRF2(p, 0xb9490000, m3, m4, r1, r2);
   4339 }
   4340 
   4341 
   4342 static UChar *
   4343 s390_emit_CGDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4344 {
   4345    vassert(s390_host_has_dfp);
   4346    vassert(m4 == 0);
   4347    vassert(s390_host_has_fpext || m3 < 1 || m3 > 7);
   4348 
   4349    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4350       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cgdtr", r1, m3, r2);
   4351 
   4352    return emit_RRF2(p, 0xb3e10000, m3, m4, r1, r2);
   4353 }
   4354 
   4355 
   4356 static UChar *
   4357 s390_emit_CGXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4358 {
   4359    vassert(s390_host_has_dfp);
   4360    vassert(m4 == 0);
   4361    vassert(s390_host_has_fpext || m3 < 1 || m3 > 7);
   4362 
   4363    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4364       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cgxtr", r1, m3, r2);
   4365 
   4366    return emit_RRF2(p, 0xb3e90000, m3, m4, r1, r2);
   4367 }
   4368 
   4369 
   4370 static UChar *
   4371 s390_emit_CLFDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4372 {
   4373    vassert(m4 == 0);
   4374    vassert(s390_host_has_dfp);
   4375    vassert(s390_host_has_fpext);
   4376 
   4377    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4378       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clfdtr", r1, m3, r2, m4);
   4379 
   4380    return emit_RRF2(p, 0xb9430000, m3, m4, r1, r2);
   4381 }
   4382 
   4383 
   4384 static UChar *
   4385 s390_emit_CLFXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4386 {
   4387    vassert(m4 == 0);
   4388    vassert(s390_host_has_dfp);
   4389    vassert(s390_host_has_fpext);
   4390 
   4391    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4392       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clfxtr", r1, m3, r2, m4);
   4393 
   4394    return emit_RRF2(p, 0xb94b0000, m3, m4, r1, r2);
   4395 }
   4396 
   4397 
   4398 static UChar *
   4399 s390_emit_CLGDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4400 {
   4401    vassert(m4 == 0);
   4402    vassert(s390_host_has_dfp);
   4403    vassert(s390_host_has_fpext);
   4404 
   4405    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4406       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clgdtr", r1, m3, r2, m4);
   4407 
   4408    return emit_RRF2(p, 0xb9420000, m3, m4, r1, r2);
   4409 }
   4410 
   4411 
   4412 static UChar *
   4413 s390_emit_CLGXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4414 {
   4415    vassert(m4 == 0);
   4416    vassert(s390_host_has_dfp);
   4417    vassert(s390_host_has_fpext);
   4418 
   4419    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4420       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clgxtr", r1, m3, r2, m4);
   4421 
   4422    return emit_RRF2(p, 0xb94a0000, m3, m4, r1, r2);
   4423 }
   4424 
   4425 
   4426 static UChar *
   4427 s390_emit_DDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
   4428 {
   4429    vassert(s390_host_has_dfp);
   4430    vassert(m4 == 0 || s390_host_has_fpext);
   4431    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   4432       if (m4 == 0)
   4433          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "ddtr", r1, r2, r3);
   4434       else
   4435          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "ddtra", r1, r2, r3, m4);
   4436    }
   4437 
   4438    return emit_RRF4(p, 0xb3d10000, r3, m4, r1, r2);
   4439 }
   4440 
   4441 
   4442 static UChar *
   4443 s390_emit_DXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
   4444 {
   4445    vassert(s390_host_has_dfp);
   4446    vassert(m4 == 0 || s390_host_has_fpext);
   4447    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   4448       if (m4 == 0)
   4449          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "dxtr", r1, r2, r3);
   4450       else
   4451          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "dxtra", r1, r2, r3, m4);
   4452    }
   4453 
   4454    return emit_RRF4(p, 0xb3d90000, r3, m4, r1, r2);
   4455 }
   4456 
   4457 
   4458 static UChar *
   4459 s390_emit_EEDTR(UChar *p, UChar r1, UChar r2)
   4460 {
   4461    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4462       s390_disasm(ENC3(MNM, GPR, FPR), "eedtr", r1, r2);
   4463 
   4464    return emit_RRE(p, 0xb3e50000, r1, r2);
   4465 }
   4466 
   4467 
   4468 static UChar *
   4469 s390_emit_EEXTR(UChar *p, UChar r1, UChar r2)
   4470 {
   4471    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4472       s390_disasm(ENC3(MNM, GPR, FPR), "eextr", r1, r2);
   4473 
   4474    return emit_RRE(p, 0xb3ed0000, r1, r2);
   4475 }
   4476 
   4477 
   4478 static UChar *
   4479 s390_emit_ESDTR(UChar *p, UChar r1, UChar r2)
   4480 {
   4481    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4482       s390_disasm(ENC3(MNM, GPR, FPR), "esdtr", r1, r2);
   4483 
   4484    return emit_RRE(p, 0xb3e70000, r1, r2);
   4485 }
   4486 
   4487 
   4488 static UChar *
   4489 s390_emit_ESXTR(UChar *p, UChar r1, UChar r2)
   4490 {
   4491    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4492       s390_disasm(ENC3(MNM, GPR, FPR), "esxtr", r1, r2);
   4493 
   4494    return emit_RRE(p, 0xb3ef0000, r1, r2);
   4495 }
   4496 
   4497 
   4498 static UChar *
   4499 s390_emit_IEDTR(UChar *p, UChar r3, UChar r1, UChar r2)
   4500 {
   4501    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4502       s390_disasm(ENC4(MNM, FPR, FPR, GPR), "iedtr", r1, r3, r2);
   4503 
   4504    return emit_RRF(p, 0xb3f60000, r3, r1, r2);
   4505 }
   4506 
   4507 
   4508 static UChar *
   4509 s390_emit_IEXTR(UChar *p, UChar r3, UChar r1, UChar r2)
   4510 {
   4511    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4512       s390_disasm(ENC4(MNM, FPR, FPR, GPR), "iextr", r1, r3, r2);
   4513 
   4514    return emit_RRF(p, 0xb3fe0000, r3, r1, r2);
   4515 }
   4516 
   4517 
   4518 static UChar *
   4519 s390_emit_LDETR(UChar *p, UChar m4, UChar r1, UChar r2)
   4520 {
   4521    vassert(s390_host_has_dfp);
   4522    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4523       s390_disasm(ENC4(MNM, FPR, FPR, UINT), "ldetr", r1, r2, m4);
   4524 
   4525    return emit_RRF5(p, 0xb3d40000, m4, r1, r2);
   4526 }
   4527 
   4528 
   4529 static UChar *
   4530 s390_emit_LXDTR(UChar *p, UChar m4, UChar r1, UChar r2)
   4531 {
   4532    vassert(s390_host_has_dfp);
   4533    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4534       s390_disasm(ENC4(MNM, FPR, FPR, UINT), "lxdtr", r1, r2, m4);
   4535 
   4536    return emit_RRF5(p, 0xb3dc0000, m4, r1, r2);
   4537 }
   4538 
   4539 
   4540 static UChar *
   4541 s390_emit_LEDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4542 {
   4543    vassert(s390_host_has_dfp);
   4544    vassert(m4 == 0);
   4545    vassert(s390_host_has_fpext || m3 < 1 || m3 > 7);
   4546 
   4547    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4548       s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), "ledtr", r1, m3, r2, m4);
   4549 
   4550    return emit_RRF2(p, 0xb3d50000, m3, m4, r1, r2);
   4551 }
   4552 
   4553 
   4554 static UChar *
   4555 s390_emit_LDXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
   4556 {
   4557    vassert(s390_host_has_dfp);
   4558    vassert(m4 == 0);
   4559    vassert(s390_host_has_fpext || m3 < 1 || m3 > 7);
   4560 
   4561    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4562       s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), "ldxtr", r1, m3, r2, m4);
   4563 
   4564    return emit_RRF2(p, 0xb3dd0000, m3, m4, r1, r2);
   4565 }
   4566 
   4567 
   4568 static UChar *
   4569 s390_emit_MDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
   4570 {
   4571    vassert(s390_host_has_dfp);
   4572    vassert(m4 == 0 || s390_host_has_fpext);
   4573    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   4574       if (m4 == 0)
   4575          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "mdtr", r1, r2, r3);
   4576       else
   4577          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "mdtra", r1, r2, r3, m4);
   4578    }
   4579 
   4580    return emit_RRF4(p, 0xb3d00000, r3, m4, r1, r2);
   4581 }
   4582 
   4583 
   4584 static UChar *
   4585 s390_emit_MXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
   4586 {
   4587    vassert(s390_host_has_dfp);
   4588    vassert(m4 == 0 || s390_host_has_fpext);
   4589    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   4590       if (m4 == 0)
   4591          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "mxtr", r1, r2, r3);
   4592       else
   4593          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "mxtra", r1, r2, r3, m4);
   4594    }
   4595 
   4596    return emit_RRF4(p, 0xb3d80000, r3, m4, r1, r2);
   4597 }
   4598 
   4599 
   4600 static UChar *
   4601 emit_E(UChar *p, UInt op)
   4602 {
   4603    ULong the_insn = op;
   4604 
   4605    return emit_2bytes(p, the_insn);
   4606 }
   4607 
   4608 
   4609 static UChar *
   4610 s390_emit_PFPO(UChar *p)
   4611 {
   4612    vassert(s390_host_has_pfpo);
   4613    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   4614       s390_disasm(ENC1(MNM), "pfpo");
   4615    }
   4616 
   4617    return emit_E(p, 0x010a);
   4618 }
   4619 
   4620 
   4621 static UChar *
   4622 s390_emit_QADTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
   4623 {
   4624    vassert(s390_host_has_dfp);
   4625    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4626       s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "qadtr", r1, r3, r2, m4);
   4627 
   4628    return emit_RRF4(p, 0xb3f50000, r3, m4, r1, r2);
   4629 }
   4630 
   4631 
   4632 static UChar *
   4633 s390_emit_QAXTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
   4634 {
   4635    vassert(s390_host_has_dfp);
   4636    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4637       s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "qaxtr", r1, r3, r2, m4);
   4638 
   4639    return emit_RRF4(p, 0xb3fd0000, r3, m4, r1, r2);
   4640 }
   4641 
   4642 
   4643 static UChar *
   4644 s390_emit_RRDTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
   4645 {
   4646    vassert(s390_host_has_dfp);
   4647    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4648       s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), "rrdtr", r1, r3, r2, m4);
   4649 
   4650    return emit_RRF4(p, 0xb3f70000, r3, m4, r1, r2);
   4651 }
   4652 
   4653 
   4654 static UChar *
   4655 s390_emit_RRXTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
   4656 {
   4657    vassert(s390_host_has_dfp);
   4658    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4659       s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), "rrxtr", r1, r3, r2, m4);
   4660 
   4661    return emit_RRF4(p, 0xb3ff0000, r3, m4, r1, r2);
   4662 }
   4663 
   4664 
   4665 static UChar *
   4666 s390_emit_SDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
   4667 {
   4668    vassert(s390_host_has_dfp);
   4669    vassert(m4 == 0 || s390_host_has_fpext);
   4670    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   4671       if (m4 == 0)
   4672          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "sdtr", r1, r2, r3);
   4673       else
   4674          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "sdtra", r1, r2, r3, m4);
   4675    }
   4676 
   4677    return emit_RRF4(p, 0xb3d30000, r3, m4, r1, r2);
   4678 }
   4679 
   4680 
   4681 static UChar *
   4682 s390_emit_SXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
   4683 {
   4684    vassert(s390_host_has_dfp);
   4685    vassert(m4 == 0 || s390_host_has_fpext);
   4686    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
   4687       if (m4 == 0)
   4688          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "sxtr", r1, r2, r3);
   4689       else
   4690          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "sxtra", r1, r2, r3, m4);
   4691    }
   4692 
   4693    return emit_RRF4(p, 0xb3db0000, r3, m4, r1, r2);
   4694 }
   4695 
   4696 
   4697 static UChar *
   4698 s390_emit_SLDT(UChar *p, UChar r3, UChar r1, UChar r2)
   4699 {
   4700    vassert(s390_host_has_dfp);
   4701    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4702       s390_disasm(ENC4(MNM, FPR, FPR, UDXB), "sldt", r1, r3, 0, 0, r2);
   4703 
   4704    return emit_RXF(p, 0xED0000000040ULL, r3, 0, r2, 0, r1);
   4705 }
   4706 
   4707 
   4708 static UChar *
   4709 s390_emit_SLXT(UChar *p, UChar r3, UChar r1, UChar r2)
   4710 {
   4711    vassert(s390_host_has_dfp);
   4712    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4713       s390_disasm(ENC4(MNM, FPR, FPR, UDXB), "slxt", r1, r3, 0, 0, r2);
   4714 
   4715    return emit_RXF(p, 0xED0000000048ULL, r3, 0, r2, 0, r1);
   4716 }
   4717 
   4718 
   4719 static UChar *
   4720 s390_emit_SRDT(UChar *p, UChar r3, UChar r1, UChar r2)
   4721 {
   4722    vassert(s390_host_has_dfp);
   4723    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4724       s390_disasm(ENC4(MNM, FPR, FPR, UDXB), "srdt", r1, r3, 0, 0, r2);
   4725 
   4726    return emit_RXF(p, 0xED0000000041ULL, r3, 0, r2, 0, r1);
   4727 }
   4728 
   4729 
   4730 static UChar *
   4731 s390_emit_SRXT(UChar *p, UChar r3, UChar r1, UChar r2)
   4732 {
   4733    vassert(s390_host_has_dfp);
   4734    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4735       s390_disasm(ENC4(MNM, FPR, FPR, UDXB), "srxt", r1, r3, 0, 0, r2);
   4736 
   4737    return emit_RXF(p, 0xED0000000049ULL, r3, 0, r2, 0, r1);
   4738 }
   4739 
   4740 
   4741 static UChar *
   4742 s390_emit_LOCGR(UChar *p, UChar m3, UChar r1, UChar r2)
   4743 {
   4744    vassert(s390_host_has_lsc);
   4745    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4746       s390_disasm(ENC4(MNM, GPR, GPR, UINT), "locgr", r1, r2, m3);
   4747 
   4748    return emit_RRF3(p, 0xb9e20000, m3, r1, r2);
   4749 }
   4750 
   4751 
   4752 static UChar *
   4753 s390_emit_LOC(UChar *p, UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2)
   4754 {
   4755    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4756       s390_disasm(ENC4(MNM, GPR, UINT, SDXB), "loc", r1, m3, dh2, dl2, 0, b2);
   4757 
   4758    return emit_RSY(p, 0xeb00000000f2ULL, r1, m3, b2, dl2, dh2);
   4759 }
   4760 
   4761 
   4762 static UChar *
   4763 s390_emit_LOCG(UChar *p, UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2)
   4764 {
   4765    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
   4766       s390_disasm(ENC4(MNM, GPR, UINT, SDXB), "locg", r1, m3, dh2, dl2, 0, b2);
   4767 
   4768    return emit_RSY(p, 0xeb00000000e2ULL, r1, m3, b2, dl2, dh2);
   4769 }
   4770 
   4771 
   4772 /* Provide a symbolic name for register "R0" */
   4773 #define R0 0
   4774 
   4775 /* Split up a 20-bit displacement into its high and low piece
   4776    suitable for passing as function arguments */
   4777 #define DISP20(d) (((UInt)d) & 0xFFF), ((((UInt)d) >> 12) & 0xFF)
   4778 
   4779 /*---------------------------------------------------------------*/
   4780 /*--- Helper functions                                        ---*/
   4781 /*---------------------------------------------------------------*/
   4782 
   4783 static __inline__ Bool
   4784 uint_fits_signed_16bit(UInt val)
   4785 {
   4786    UInt v = val & 0xFFFFu;
   4787 
   4788    /* sign extend */
   4789    v = (Int)(v << 16) >> 16;
   4790 
   4791    return val == v;
   4792 }
   4793 
   4794 
   4795 static __inline__ Bool
   4796 ulong_fits_signed_16bit(ULong val)
   4797 {
   4798    ULong v = val & 0xFFFFu;
   4799 
   4800    /* sign extend */
   4801    v = (Long)(v << 48) >> 48;
   4802 
   4803    return val == v;
   4804 }
   4805 
   4806 
   4807 static __inline__ Bool
   4808 ulong_fits_signed_32bit(ULong val)
   4809 {
   4810    ULong v = val & 0xFFFFFFFFu;
   4811 
   4812    /* sign extend */
   4813    v = (Long)(v << 32) >> 32;
   4814 
   4815    return val == v;
   4816 }
   4817 
   4818 
   4819 static __inline__ Bool
   4820 ulong_fits_unsigned_32bit(ULong val)
   4821 {
   4822    return (val & 0xFFFFFFFFu) == val;
   4823 }
   4824 
   4825 
   4826 /* Load a 64-bit immediate VAL into register REG. */
   4827 static UChar *
   4828 s390_emit_load_64imm(UChar *p, UChar reg, ULong val)
   4829 {
   4830    if (ulong_fits_signed_16bit(val)) {
   4831       return s390_emit_LGHI(p, reg, val);
   4832    }
   4833 
   4834    if (s390_host_has_eimm) {
   4835       if (ulong_fits_unsigned_32bit(val)) {
   4836          return s390_emit_LLILF(p, reg, val);
   4837       }
   4838       if (ulong_fits_signed_32bit(val)) {
   4839          /* LGFI's sign extension will recreate the correct 64-bit value */
   4840          return s390_emit_LGFI(p, reg, val);
   4841       }
   4842       /* Do it in two steps: upper half [0:31] and lower half [32:63] */
   4843       p =  s390_emit_IIHF(p, reg, val >> 32);
   4844       return s390_emit_IILF(p, reg, val & 0xFFFFFFFF);
   4845    }
   4846 
   4847    /* Fall back */
   4848    if (ulong_fits_unsigned_32bit(val)) {
   4849       p = s390_emit_LLILH(p, reg, (val >> 16) & 0xFFFF); /* sets val[32:47]
   4850                                                             val[0:31] = 0 */
   4851       p = s390_emit_IILL(p, reg, val & 0xFFFF);          /* sets val[48:63] */
   4852       return p;
   4853    }
   4854 
   4855    p = s390_emit_IIHH(p, reg, (val >> 48) & 0xFFFF);
   4856    p = s390_emit_IIHL(p, reg, (val >> 32) & 0xFFFF);
   4857    p = s390_emit_IILH(p, reg, (val >> 16) & 0xFFFF);
   4858    p = s390_emit_IILL(p, reg, val & 0xFFFF);
   4859 
   4860    return p;
   4861 }
   4862 
   4863 /* Load a 32-bit immediate VAL into register REG. */
   4864 static UChar *
   4865 s390_emit_load_32imm(UChar *p, UChar reg, UInt val)
   4866 {
   4867    if (uint_fits_signed_16bit(val)) {
   4868       /* LHI's sign extension will recreate the correct 32-bit value */
   4869       return s390_emit_LHI(p, reg, val);
   4870    }
   4871    if (s390_host_has_eimm) {
   4872       return s390_emit_IILF(p, reg, val);
   4873    }
   4874    /* val[0:15]  --> (val >> 16) & 0xFFFF
   4875       val[16:31] --> val & 0xFFFF */
   4876    p = s390_emit_IILH(p, reg, (val >> 16) & 0xFFFF);
   4877    return s390_emit_IILL(p, reg, val & 0xFFFF);
   4878 }
   4879 
   4880 /*------------------------------------------------------------*/
   4881 /*--- Wrapper functions                                    ---*/
   4882 /*------------------------------------------------------------*/
   4883 
   4884 /* r1[32:63],r1+1[32:63] = r1+1[32:63] * memory[op2addr][0:31] */
   4885 static UChar *
   4886 s390_emit_MFYw(UChar *p, UChar r1, UChar x, UChar b,  UShort dl, UChar dh)
   4887 {
   4888    if (s390_host_has_gie) {
   4889       return s390_emit_MFY(p, r1, x, b, dl, dh);
   4890    }
   4891 
   4892    /* Load from memory into R0, then MULTIPLY with R1 */
   4893    p = s390_emit_LY(p, R0, x, b, dl, dh);
   4894    return s390_emit_MR(p, r1, R0);
   4895 }
   4896 
   4897 /* r1[32:63] = r1[32:63] * memory[op2addr][0:15] */
   4898 static UChar *
   4899 s390_emit_MHYw(UChar *p, UChar r1, UChar x, UChar b,  UShort dl, UChar dh)
   4900 {
   4901    if (s390_host_has_gie) {
   4902       return s390_emit_MHY(p, r1, x, b, dl, dh);
   4903    }
   4904 
   4905    /* Load from memory into R0, then MULTIPLY with R1 */
   4906    p = s390_emit_LHY(p, R0, x, b, dl, dh);
   4907    return s390_emit_MSR(p, r1, R0);
   4908 }
   4909 
   4910 /* r1[32:63] = r1[32:63] * i2 */
   4911 static UChar *
   4912 s390_emit_MSFIw(UChar *p, UChar r1, UInt i2)
   4913 {
   4914    if (s390_host_has_gie) {
   4915       return s390_emit_MSFI(p, r1, i2);
   4916    }
   4917 
   4918    /* Load I2 into R0; then MULTIPLY R0 with R1 */
   4919    p = s390_emit_load_32imm(p, R0, i2);
   4920    return s390_emit_MSR(p, r1, R0);
   4921 }
   4922 
   4923 
   4924 /* r1[32:63] = r1[32:63] & i2 */
   4925 static UChar *
   4926 s390_emit_NILFw(UChar *p, UChar r1, UInt i2)
   4927 {
   4928    if (s390_host_has_eimm) {
   4929       return s390_emit_NILF(p, r1, i2);
   4930    }
   4931 
   4932    /* Load I2 into R0; then AND R0 with R1 */
   4933    p = s390_emit_load_32imm(p, R0, i2);
   4934    return s390_emit_NR(p, r1, R0);
   4935 }
   4936 
   4937 
   4938 /* r1[32:63] = r1[32:63] | i2 */
   4939 static UChar *
   4940 s390_emit_OILFw(UChar *p, UChar r1, UInt i2)
   4941 {
   4942    if (s390_host_has_eimm) {
   4943       return s390_emit_OILF(p, r1, i2);
   4944    }
   4945 
   4946    /* Load I2 into R0; then AND R0 with R1 */
   4947    p = s390_emit_load_32imm(p, R0, i2);
   4948    return s390_emit_OR(p, r1, R0);
   4949 }
   4950 
   4951 
   4952 /* r1[32:63] = r1[32:63] ^ i2 */
   4953 static UChar *
   4954 s390_emit_XILFw(UChar *p, UChar r1, UInt i2)
   4955 {
   4956    if (s390_host_has_eimm) {
   4957       return s390_emit_XILF(p, r1, i2);
   4958    }
   4959 
   4960    /* Load I2 into R0; then AND R0 with R1 */
   4961    p = s390_emit_load_32imm(p, R0, i2);
   4962    return s390_emit_XR(p, r1, R0);
   4963 }
   4964 
   4965 
   4966 /*  r1[32:63] = sign_extend(r2[56:63]) */
   4967 static UChar *
   4968 s390_emit_LBRw(UChar *p, UChar r1, UChar r2)
   4969 {
   4970    if (s390_host_has_eimm) {
   4971       return s390_emit_LBR(p, r1, r2);
   4972    }
   4973 
   4974    p = s390_emit_LR(p, r1, r2);               /* r1 = r2 */
   4975    p = s390_emit_SLL(p, r1, R0, 24);          /* r1 = r1 << 24  */
   4976    return s390_emit_SRA(p, r1, R0, 24);       /* r1 = r1 >>a 24 */
   4977 }
   4978 
   4979 
   4980 /*  r1[0:63] = sign_extend(r2[56:63]) */
   4981 static UChar *
   4982 s390_emit_LGBRw(UChar *p, UChar r1, UChar r2)
   4983 {
   4984    if (s390_host_has_eimm) {
   4985       return s390_emit_LGBR(p, r1, r2);
   4986    }
   4987 
   4988    p = s390_emit_LR(p, r1, r2);                       /* r1 = r2 */
   4989    p = s390_emit_SLLG(p, r1, r1, R0, DISP20(56));     /* r1 = r1 << 56  */
   4990    return s390_emit_SRAG(p, r1, r1, R0, DISP20(56));  /* r1 = r1 >>a 56 */
   4991 }
   4992 
   4993 
   4994 /* r1[32:63] = sign_extend(r2[48:63]) */
   4995 static UChar *
   4996 s390_emit_LHRw(UChar *p, UChar r1, UChar r2)
   4997 {
   4998    if (s390_host_has_eimm) {
   4999       return s390_emit_LHR(p, r1, r2);
   5000    }
   5001 
   5002    p = s390_emit_LR(p, r1, r2);               /* r1 = r2 */
   5003    p = s390_emit_SLL(p, r1, R0, 16);          /* r1 = r1 << 16  */
   5004    return s390_emit_SRA(p, r1, R0, 16);       /* r1 = r1 >>a 16 */
   5005 }
   5006 
   5007 
   5008 /* r1[0:63] = sign_extend(r2[48:63]) */
   5009 static UChar *
   5010 s390_emit_LGHRw(UChar *p, UChar r1, UChar r2)
   5011 {
   5012    if (s390_host_has_eimm) {
   5013       return s390_emit_LGHR(p, r1, r2);
   5014    }
   5015 
   5016    p = s390_emit_LR(p, r1, r2);               /* r1 = r2 */
   5017    p = s390_emit_SLLG(p, r1, r1, R0, DISP20(48));     /* r1 = r1 << 48  */
   5018    return s390_emit_SRAG(p, r1, r1, R0, DISP20(48));  /* r1 = r1 >>a 48 */
   5019 }
   5020 
   5021 
   5022 /* r1[0:63] = sign_extend(i2) */
   5023 static UChar *
   5024 s390_emit_LGFIw(UChar *p, UChar r1, UInt i2)
   5025 {
   5026    if (s390_host_has_eimm) {
   5027       return s390_emit_LGFI(p, r1, i2);
   5028    }
   5029 
   5030    p = s390_emit_load_32imm(p, R0, i2);
   5031    return s390_emit_LGFR(p, r1, R0);
   5032 }
   5033 
   5034 
   5035 /* r1[32:63] = zero_extend($r2[56:63]) */
   5036 static UChar *
   5037 s390_emit_LLCRw(UChar *p, UChar r1, UChar r2)
   5038 {
   5039    if (s390_host_has_eimm) {
   5040       return s390_emit_LLCR(p, r1, r2);
   5041    }
   5042 
   5043    p = s390_emit_LR(p, r1, r2);
   5044    p = s390_emit_LHI(p, R0, 0xFF);
   5045    return s390_emit_NR(p, r1, R0);
   5046 }
   5047 
   5048 
   5049 /* r1[0:63] = zero_extend($r2[56:63]) */
   5050 static UChar *
   5051 s390_emit_LLGCRw(UChar *p, UChar r1, UChar r2)
   5052 {
   5053    if (s390_host_has_eimm) {
   5054       return s390_emit_LLGCR(p, r1, r2);
   5055    }
   5056 
   5057    p = s390_emit_LR(p, r1, r2);
   5058    p = s390_emit_LLILL(p, R0, 0xFF);
   5059    return s390_emit_NGR(p, r1, R0);
   5060 }
   5061 
   5062 
   5063 /* r1[32:63] = zero_extend(r2[48:63]) */
   5064 static UChar *
   5065 s390_emit_LLHRw(UChar *p, UChar r1, UChar r2)
   5066 {
   5067    if (s390_host_has_eimm) {
   5068       return s390_emit_LLHR(p, r1, r2);
   5069    }
   5070 
   5071    p = s390_emit_LR(p, r1, r2);
   5072    p = s390_emit_LLILL(p, R0, 0xFFFF);
   5073    return s390_emit_NR(p, r1, R0);
   5074 }
   5075 
   5076 
   5077 /* r1[0:63] = zero_extend(r2[48:63]) */
   5078 static UChar *
   5079 s390_emit_LLGHRw(UChar *p, UChar r1, UChar r2)
   5080 {
   5081    if (s390_host_has_eimm) {
   5082       return s390_emit_LLGHR(p, r1, r2);
   5083    }
   5084 
   5085    p = s390_emit_LR(p, r1, r2);
   5086    p = s390_emit_LLILL(p, R0, 0xFFFF);
   5087    return s390_emit_NGR(p, r1, R0);
   5088 }
   5089 
   5090 
   5091 /* r1[32:63] = zero_extend(mem[op2addr][0:7]) */
   5092 static UChar *
   5093 s390_emit_LLCw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl, UChar dh)
   5094 {
   5095    if (s390_host_has_eimm) {
   5096       return s390_emit_LLC(p, r1, x2, b2, dl, dh);
   5097    }
   5098 
   5099    if (dh == 0) {
   5100       p = s390_emit_IC(p, r1, x2, b2, dl);
   5101    } else {
   5102       p = s390_emit_ICY(p, r1, x2, b2, dl, dh);
   5103    }
   5104    p = s390_emit_LLILL(p, R0, 0xFF);
   5105    return s390_emit_NR(p, r1, R0);
   5106 }
   5107 
   5108 
   5109 /* r1[32:63] = zero_extend(mem[op2addr][0:15]) */
   5110 static UChar *
   5111 s390_emit_LLHw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl, UChar dh)
   5112 {
   5113    if (s390_host_has_eimm) {
   5114       return s390_emit_LLH(p, r1, x2, b2, dl, dh);
   5115    }
   5116 
   5117    p = s390_emit_LLGH(p, r1, x2, b2, dl, dh);
   5118    p = s390_emit_LLILL(p, R0, 0xFFFF);
   5119    return s390_emit_NR(p, r1, R0);
   5120 }
   5121 
   5122 
   5123 /* r1[0:63] = zero_extend(i2) */
   5124 static UChar *
   5125 s390_emit_LLILFw(UChar *p, UChar r1, UInt i2)
   5126 {
   5127    if (s390_host_has_eimm) {
   5128       return s390_emit_LLILF(p, r1, i2);
   5129    }
   5130 
   5131    p = s390_emit_LLILH(p, r1, (i2 >> 16) & 0xFFFF);  /* i2[0:15] */
   5132    return s390_emit_OILL(p, r1, i2 & 0xFFFF);
   5133 }
   5134 
   5135 
   5136 /* r1[32:63] = r1[32:63] + i2 */
   5137 static UChar *
   5138 s390_emit_AFIw(UChar *p, UChar r1, UInt i2)
   5139 {
   5140    if (s390_host_has_eimm) {
   5141       return s390_emit_AFI(p, r1, i2);
   5142    }
   5143    /* Load 32 bit immediate to R0 then add */
   5144    p = s390_emit_load_32imm(p, R0, i2);
   5145    return s390_emit_AR(p, r1, R0);
   5146 }
   5147 
   5148 
   5149 /* r1[32:63] = r1[32:63] - i2 */
   5150 static UChar *
   5151 s390_emit_SLFIw(UChar *p, UChar r1, UInt i2)
   5152 {
   5153    if (s390_host_has_eimm) {
   5154       return s390_emit_SLFI(p, r1, i2);
   5155    }
   5156 
   5157    /* Load 32 bit immediate to R0 then subtract */
   5158    p = s390_emit_load_32imm(p, R0, i2);
   5159    return s390_emit_SR(p, r1, R0);
   5160 }
   5161 
   5162 
   5163 /* r1[0:63] = r1[0:63] - zero_extend(i2) */
   5164 static UChar *
   5165 s390_emit_SLGFIw(UChar *p, UChar r1, UInt i2)
   5166 {
   5167    if (s390_host_has_eimm) {
   5168       return s390_emit_SLGFI(p, r1, i2);
   5169    }
   5170 
   5171    /* Load zero-extended 32 bit immediate to R0 then subtract */
   5172    p = s390_emit_load_64imm(p, R0, i2);
   5173    return s390_emit_SGR(p, r1, R0);
   5174 }
   5175 
   5176 
   5177 static UChar *
   5178 s390_emit_LTw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl, UChar dh)
   5179 {
   5180    if (s390_host_has_eimm) {
   5181       return s390_emit_LT(p, r1, x2, b2, dl, dh);
   5182    }
   5183    /* Load 32 bit from memory to R0 then compare */
   5184    if (dh == 0) {
   5185       p = s390_emit_L(p, R0, x2, b2, dl);
   5186    } else {
   5187       p = s390_emit_LY(p, R0, x2, b2, dl, dh);
   5188    }
   5189    return s390_emit_LTR(p, r1, R0);
   5190 }
   5191 
   5192 
   5193 static UChar *
   5194 s390_emit_LTGw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl, UChar dh)
   5195 {
   5196    if (s390_host_has_eimm) {
   5197       return s390_emit_LTG(p, r1, x2, b2, dl, dh);
   5198    }
   5199    /* Load 64 bit from memory to R0 then compare */
   5200    p = s390_emit_LG(p, R0, x2, b2, dl, dh);
   5201    return s390_emit_LTGR(p, r1, R0);
   5202 }
   5203 
   5204 
   5205 static UChar *
   5206 s390_emit_CFIw(UChar *p, UChar r1, UInt i2)
   5207 {
   5208    if (s390_host_has_eimm) {
   5209       return s390_emit_CFI(p, r1, i2);
   5210    }
   5211    /* Load 32 bit immediate to R0 then compare */
   5212    p = s390_emit_load_32imm(p, R0, i2);
   5213    return s390_emit_CR(p, r1, R0);
   5214 }
   5215 
   5216 
   5217 static UChar *
   5218 s390_emit_CLFIw(UChar *p, UChar r1, UInt i2)
   5219 {
   5220    if (s390_host_has_eimm) {
   5221       return s390_emit_CLFI(p, r1, i2);
   5222    }
   5223    /* Load 32 bit immediate to R0 then compare */
   5224    p = s390_emit_load_32imm(p, R0, i2);
   5225    return s390_emit_CLR(p, r1, R0);
   5226 }
   5227 
   5228 
   5229 static UChar *
   5230 s390_emit_LGDRw(UChar *p, UChar r1, UChar r2)
   5231 {
   5232    if (s390_host_has_fgx) {
   5233       return s390_emit_LGDR(p, r1, r2);
   5234    }
   5235 
   5236    /* Store the FPR at memory[sp - 8]. This is safe because SP grows towards
   5237       smaller addresses and is 8-byte aligned. Then load the GPR from that
   5238       memory location/ */
   5239    p = s390_emit_STDY(p, r2, R0, S390_REGNO_STACK_POINTER, DISP20(-8));
   5240    return s390_emit_LG(p, r1, R0, S390_REGNO_STACK_POINTER, DISP20(-8));
   5241 }
   5242 
   5243 
   5244 static UChar *
   5245 s390_emit_LDGRw(UChar *p, UChar r1, UChar r2)
   5246 {
   5247    if (s390_host_has_fgx) {
   5248       return s390_emit_LDGR(p, r1, r2);
   5249    }
   5250 
   5251    /* Store the GPR at memory[sp - 8]. This is safe because SP grows towards
   5252       smaller addresses and is 8-byte aligned. Then load the FPR from that
   5253       memory location/ */
   5254    p = s390_emit_STG(p, r2, R0, S390_REGNO_STACK_POINTER, DISP20(-8));
   5255    return s390_emit_LDY(p, r1, R0, S390_REGNO_STACK_POINTER, DISP20(-8));
   5256 }
   5257 
   5258 
   5259 /*---------------------------------------------------------------*/
   5260 /*--- Constructors for the various s390_insn kinds            ---*/
   5261 /*---------------------------------------------------------------*/
   5262 
   5263 s390_insn *
   5264 s390_insn_load(UChar size, HReg dst, s390_amode *src)
   5265 {
   5266    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5267 
   5268    insn->tag  = S390_INSN_LOAD;
   5269    insn->size = size;
   5270    insn->variant.load.src  = src;
   5271    insn->variant.load.dst  = dst;
   5272 
   5273    vassert(size == 1 || size == 2 || size == 4 || size == 8);
   5274 
   5275    return insn;
   5276 }
   5277 
   5278 
   5279 s390_insn *
   5280 s390_insn_store(UChar size, s390_amode *dst, HReg src)
   5281 {
   5282    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5283 
   5284    insn->tag  = S390_INSN_STORE;
   5285    insn->size = size;
   5286    insn->variant.store.src  = src;
   5287    insn->variant.store.dst  = dst;
   5288 
   5289    vassert(size == 1 || size == 2 || size == 4 || size == 8);
   5290 
   5291    return insn;
   5292 }
   5293 
   5294 
   5295 s390_insn *
   5296 s390_insn_move(UChar size, HReg dst, HReg src)
   5297 {
   5298    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5299 
   5300    insn->tag  = S390_INSN_MOVE;
   5301    insn->size = size;
   5302    insn->variant.move.src  = src;
   5303    insn->variant.move.dst  = dst;
   5304 
   5305    vassert(size == 1 || size == 2 || size == 4 || size == 8);
   5306 
   5307    return insn;
   5308 }
   5309 
   5310 
   5311 s390_insn *
   5312 s390_insn_memcpy(UChar size, s390_amode *dst, s390_amode *src)
   5313 {
   5314    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5315 
   5316    /* This insn will be mapped to MVC which requires base register
   5317       plus 12-bit displacement */
   5318    vassert(src->tag == S390_AMODE_B12);
   5319    vassert(dst->tag == S390_AMODE_B12);
   5320 
   5321    insn->tag  = S390_INSN_MEMCPY;
   5322    insn->size = size;
   5323    insn->variant.memcpy.src = src;
   5324    insn->variant.memcpy.dst = dst;
   5325 
   5326    vassert(size == 1 || size == 2 || size == 4 || size == 8);
   5327 
   5328    return insn;
   5329 }
   5330 
   5331 
   5332 s390_insn *
   5333 s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst, s390_opnd_RMI src)
   5334 {
   5335    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5336 
   5337    insn->tag  = S390_INSN_COND_MOVE;
   5338    insn->size = size;
   5339    insn->variant.cond_move.cond = cond;
   5340    insn->variant.cond_move.src  = src;
   5341    insn->variant.cond_move.dst  = dst;
   5342 
   5343    vassert(size == 1 || size == 2 || size == 4 || size == 8);
   5344 
   5345    return insn;
   5346 }
   5347 
   5348 
   5349 s390_insn *
   5350 s390_insn_load_immediate(UChar size, HReg dst, ULong value)
   5351 {
   5352    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5353 
   5354    insn->tag  = S390_INSN_LOAD_IMMEDIATE;
   5355    insn->size = size;
   5356    insn->variant.load_immediate.dst   = dst;
   5357    insn->variant.load_immediate.value = value;
   5358 
   5359    return insn;
   5360 }
   5361 
   5362 
   5363 s390_insn *
   5364 s390_insn_alu(UChar size, s390_alu_t tag, HReg dst, s390_opnd_RMI op2)
   5365 {
   5366    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5367 
   5368    insn->tag  = S390_INSN_ALU;
   5369    insn->size = size;
   5370    insn->variant.alu.tag = tag;
   5371    insn->variant.alu.dst = dst;
   5372    insn->variant.alu.op2 = op2;
   5373 
   5374    return insn;
   5375 }
   5376 
   5377 
   5378 s390_insn *
   5379 s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo, s390_opnd_RMI op2,
   5380               Bool signed_multiply)
   5381 {
   5382    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5383 
   5384    vassert(! hregIsVirtual(dst_hi));
   5385    vassert(! hregIsVirtual(dst_lo));
   5386 
   5387    insn->tag  = signed_multiply ? S390_INSN_SMUL : S390_INSN_UMUL;
   5388    insn->size = size;
   5389    insn->variant.mul.dst_hi = dst_hi;
   5390    insn->variant.mul.dst_lo = dst_lo;
   5391    insn->variant.mul.op2 = op2;
   5392 
   5393    return insn;
   5394 }
   5395 
   5396 
   5397 s390_insn *
   5398 s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo, s390_opnd_RMI op2,
   5399               Bool signed_divide)
   5400 {
   5401    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5402 
   5403    vassert(size == 4 || size == 8);
   5404    vassert(! hregIsVirtual(op1_hi));
   5405    vassert(! hregIsVirtual(op1_lo));
   5406 
   5407    insn->tag  = signed_divide ? S390_INSN_SDIV : S390_INSN_UDIV;
   5408    insn->size = size;
   5409    insn->variant.div.op1_hi = op1_hi;
   5410    insn->variant.div.op1_lo = op1_lo;
   5411    insn->variant.div.op2 = op2;
   5412 
   5413    return insn;
   5414 }
   5415 
   5416 
   5417 s390_insn *
   5418 s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2)
   5419 {
   5420    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5421 
   5422    vassert(size == 8);
   5423    vassert(! hregIsVirtual(op1));
   5424    vassert(! hregIsVirtual(rem));
   5425 
   5426    insn->tag  = S390_INSN_DIVS;
   5427    insn->size = size;
   5428    insn->variant.divs.rem = rem;   /* remainder */
   5429    insn->variant.divs.op1 = op1;   /* also quotient */
   5430    insn->variant.divs.op2 = op2;
   5431 
   5432    return insn;
   5433 }
   5434 
   5435 
   5436 s390_insn *
   5437 s390_insn_clz(UChar size, HReg num_bits, HReg clobber, s390_opnd_RMI src)
   5438 {
   5439    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5440 
   5441    vassert(size == 8);
   5442    vassert(! hregIsVirtual(num_bits));
   5443    vassert(! hregIsVirtual(clobber));
   5444 
   5445    insn->tag  = S390_INSN_CLZ;
   5446    insn->size = size;
   5447    insn->variant.clz.num_bits = num_bits;
   5448    insn->variant.clz.clobber  = clobber;
   5449    insn->variant.clz.src = src;
   5450 
   5451    return insn;
   5452 }
   5453 
   5454 
   5455 s390_insn *
   5456 s390_insn_unop(UChar size, s390_unop_t tag, HReg dst, s390_opnd_RMI opnd)
   5457 {
   5458    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5459 
   5460    insn->tag  = S390_INSN_UNOP;
   5461    insn->size = size;
   5462    insn->variant.unop.tag = tag;
   5463    insn->variant.unop.dst = dst;
   5464    insn->variant.unop.src = opnd;
   5465 
   5466    return insn;
   5467 }
   5468 
   5469 
   5470 s390_insn *
   5471 s390_insn_test(UChar size, s390_opnd_RMI src)
   5472 {
   5473    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5474 
   5475    vassert(size == 4 || size == 8);
   5476 
   5477    insn->tag  = S390_INSN_TEST;
   5478    insn->size = size;
   5479    insn->variant.test.src = src;
   5480 
   5481    return insn;
   5482 }
   5483 
   5484 
   5485 s390_insn *
   5486 s390_insn_cc2bool(HReg dst, s390_cc_t cond)
   5487 {
   5488    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5489 
   5490    insn->tag  = S390_INSN_CC2BOOL;
   5491    insn->size = 0;   /* does not matter */
   5492    insn->variant.cc2bool.cond = cond;
   5493    insn->variant.cc2bool.dst  = dst;
   5494 
   5495    return insn;
   5496 }
   5497 
   5498 
   5499 s390_insn *
   5500 s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3, HReg old_mem)
   5501 {
   5502    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5503 
   5504    vassert(size == 4 || size == 8);
   5505    vassert(hregNumber(op2->x) == 0);
   5506    vassert(op2->tag == S390_AMODE_B12 || op2->tag == S390_AMODE_B20);
   5507 
   5508    insn->tag  = S390_INSN_CAS;
   5509    insn->size = size;
   5510    insn->variant.cas.op1 = op1;
   5511    insn->variant.cas.op2 = op2;
   5512    insn->variant.cas.op3 = op3;
   5513    insn->variant.cas.old_mem = old_mem;
   5514 
   5515    return insn;
   5516 }
   5517 
   5518 
   5519 s390_insn *
   5520 s390_insn_cdas(UChar size, HReg op1_high, HReg op1_low, s390_amode *op2,
   5521                HReg op3_high, HReg op3_low, HReg old_mem_high, HReg old_mem_low,
   5522                HReg scratch)
   5523 {
   5524    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5525    s390_cdas *cdas = LibVEX_Alloc_inline(sizeof(s390_cdas));
   5526 
   5527    vassert(size == 4 || size == 8);
   5528    vassert(hregNumber(op2->x) == 0);
   5529    vassert(hregNumber(scratch) == 1);  /* r0,r1 used as scratch reg pair */
   5530    vassert(op2->tag == S390_AMODE_B12 || op2->tag == S390_AMODE_B20);
   5531 
   5532    insn->tag  = S390_INSN_CDAS;
   5533    insn->size = size;
   5534    insn->variant.cdas.details = cdas;
   5535 
   5536    cdas->op1_high = op1_high;
   5537    cdas->op1_low  = op1_low;
   5538    cdas->op2 = op2;
   5539    cdas->op3_high = op3_high;
   5540    cdas->op3_low  = op3_low;
   5541    cdas->old_mem_high = old_mem_high;
   5542    cdas->old_mem_low  = old_mem_low;
   5543    cdas->scratch = scratch;
   5544 
   5545    return insn;
   5546 }
   5547 
   5548 
   5549 s390_insn *
   5550 s390_insn_compare(UChar size, HReg src1, s390_opnd_RMI src2,
   5551                   Bool signed_comparison)
   5552 {
   5553    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5554 
   5555    vassert(size == 4 || size == 8);
   5556 
   5557    insn->tag  = S390_INSN_COMPARE;
   5558    insn->size = size;
   5559    insn->variant.compare.src1 = src1;
   5560    insn->variant.compare.src2 = src2;
   5561    insn->variant.compare.signed_comparison = signed_comparison;
   5562 
   5563    return insn;
   5564 }
   5565 
   5566 
   5567 s390_insn *
   5568 s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args,
   5569                       const HChar *name, RetLoc rloc)
   5570 {
   5571    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5572    s390_helper_call *helper_call = LibVEX_Alloc_inline(sizeof(s390_helper_call));
   5573 
   5574    insn->tag  = S390_INSN_HELPER_CALL;
   5575    insn->size = 0;  /* does not matter */
   5576    insn->variant.helper_call.details = helper_call;
   5577 
   5578    helper_call->cond = cond;
   5579    helper_call->target = target;
   5580    helper_call->num_args = num_args;
   5581    helper_call->name = name;
   5582    helper_call->rloc = rloc;
   5583 
   5584    vassert(is_sane_RetLoc(rloc));
   5585 
   5586    return insn;
   5587 }
   5588 
   5589 
   5590 s390_insn *
   5591 s390_insn_bfp_triop(UChar size, s390_bfp_triop_t tag, HReg dst, HReg op2,
   5592                     HReg op3)
   5593 {
   5594    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5595 
   5596    vassert(size == 4 || size == 8);
   5597 
   5598    insn->tag  = S390_INSN_BFP_TRIOP;
   5599    insn->size = size;
   5600    insn->variant.bfp_triop.tag = tag;
   5601    insn->variant.bfp_triop.dst = dst;
   5602    insn->variant.bfp_triop.op2 = op2;
   5603    insn->variant.bfp_triop.op3 = op3;
   5604 
   5605    return insn;
   5606 }
   5607 
   5608 
   5609 s390_insn *
   5610 s390_insn_bfp_binop(UChar size, s390_bfp_binop_t tag, HReg dst, HReg op2)
   5611 {
   5612    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5613 
   5614    vassert(size == 4 || size == 8);
   5615 
   5616    insn->tag  = S390_INSN_BFP_BINOP;
   5617    insn->size = size;
   5618    insn->variant.bfp_binop.tag = tag;
   5619    insn->variant.bfp_binop.dst_hi = dst;
   5620    insn->variant.bfp_binop.op2_hi = op2;
   5621    insn->variant.bfp_binop.dst_lo = INVALID_HREG;
   5622    insn->variant.bfp_binop.op2_lo = INVALID_HREG;
   5623 
   5624    return insn;
   5625 }
   5626 
   5627 
   5628 s390_insn *
   5629 s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst, HReg op)
   5630 {
   5631    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5632 
   5633    vassert(size == 4 || size == 8);
   5634 
   5635    insn->tag  = S390_INSN_BFP_UNOP;
   5636    insn->size = size;
   5637    insn->variant.bfp_unop.tag = tag;
   5638    insn->variant.bfp_unop.dst_hi = dst;
   5639    insn->variant.bfp_unop.op_hi  = op;
   5640    insn->variant.bfp_unop.dst_lo = INVALID_HREG;
   5641    insn->variant.bfp_unop.op_lo  = INVALID_HREG;
   5642 
   5643    return insn;
   5644 }
   5645 
   5646 
   5647 s390_insn *
   5648 s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2)
   5649 {
   5650    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5651 
   5652    vassert(size == 4 || size == 8);
   5653 
   5654    insn->tag  = S390_INSN_BFP_COMPARE;
   5655    insn->size = size;
   5656    insn->variant.bfp_compare.dst = dst;
   5657    insn->variant.bfp_compare.op1_hi = op1;
   5658    insn->variant.bfp_compare.op2_hi = op2;
   5659    insn->variant.bfp_compare.op1_lo = INVALID_HREG;
   5660    insn->variant.bfp_compare.op2_lo = INVALID_HREG;
   5661 
   5662    return insn;
   5663 }
   5664 
   5665 
   5666 s390_insn *
   5667 s390_insn_bfp_convert(UChar size, s390_bfp_conv_t tag, HReg dst, HReg op,
   5668                       s390_bfp_round_t rounding_mode)
   5669 {
   5670    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5671 
   5672    vassert(size == 4 || size == 8);
   5673 
   5674    insn->tag  = S390_INSN_BFP_CONVERT;
   5675    insn->size = size;
   5676    insn->variant.bfp_convert.tag = tag;
   5677    insn->variant.bfp_convert.dst_hi = dst;
   5678    insn->variant.bfp_convert.op_hi  = op;
   5679    insn->variant.bfp_convert.dst_lo = INVALID_HREG;
   5680    insn->variant.bfp_convert.op_lo  = INVALID_HREG;
   5681    insn->variant.bfp_convert.rounding_mode = rounding_mode;
   5682 
   5683    return insn;
   5684 }
   5685 
   5686 
   5687 /* Check validity of a register pair for 128-bit FP. Valid register
   5688    pairs are (0,2), (1,3), (4, 6), (5, 7), (8, 10), (9, 11), (12, 14),
   5689    and (13, 15). */
   5690 static Bool
   5691 is_valid_fp128_regpair(HReg hi, HReg lo)
   5692 {
   5693    UInt hi_regno = hregNumber(hi);
   5694    UInt lo_regno = hregNumber(lo);
   5695 
   5696    if (lo_regno != hi_regno + 2) return False;
   5697    if ((hi_regno & 0x2) != 0) return False;
   5698 
   5699    return True;
   5700 }
   5701 
   5702 s390_insn *
   5703 s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t tag, HReg dst_hi,
   5704                        HReg dst_lo, HReg op2_hi, HReg op2_lo)
   5705 {
   5706    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5707 
   5708    vassert(size == 16);
   5709    vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
   5710    vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
   5711 
   5712    insn->tag  = S390_INSN_BFP_BINOP;
   5713    insn->size = size;
   5714    insn->variant.bfp_binop.tag = tag;
   5715    insn->variant.bfp_binop.dst_hi = dst_hi;
   5716    insn->variant.bfp_binop.dst_lo = dst_lo;
   5717    insn->variant.bfp_binop.op2_hi = op2_hi;
   5718    insn->variant.bfp_binop.op2_lo = op2_lo;
   5719 
   5720    return insn;
   5721 }
   5722 
   5723 
   5724 s390_insn *
   5725 s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t tag, HReg dst_hi,
   5726                       HReg dst_lo, HReg op_hi, HReg op_lo)
   5727 {
   5728    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5729 
   5730    vassert(size == 16);
   5731    vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
   5732    vassert(is_valid_fp128_regpair(op_hi, op_lo));
   5733 
   5734    insn->tag  = S390_INSN_BFP_UNOP;
   5735    insn->size = size;
   5736    insn->variant.bfp_unop.tag = tag;
   5737    insn->variant.bfp_unop.dst_hi = dst_hi;
   5738    insn->variant.bfp_unop.dst_lo = dst_lo;
   5739    insn->variant.bfp_unop.op_hi = op_hi;
   5740    insn->variant.bfp_unop.op_lo = op_lo;
   5741 
   5742    return insn;
   5743 }
   5744 
   5745 
   5746 s390_insn *
   5747 s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi, HReg op1_lo,
   5748                          HReg op2_hi, HReg op2_lo)
   5749 {
   5750    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5751 
   5752    vassert(size == 16);
   5753    vassert(is_valid_fp128_regpair(op1_hi, op1_lo));
   5754    vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
   5755 
   5756    insn->tag  = S390_INSN_BFP_COMPARE;
   5757    insn->size = size;
   5758    insn->variant.bfp_compare.dst = dst;
   5759    insn->variant.bfp_compare.op1_hi = op1_hi;
   5760    insn->variant.bfp_compare.op1_lo = op1_lo;
   5761    insn->variant.bfp_compare.op2_hi = op2_hi;
   5762    insn->variant.bfp_compare.op2_lo = op2_lo;
   5763 
   5764    return insn;
   5765 }
   5766 
   5767 
   5768 s390_insn *
   5769 s390_insn_bfp128_convert(UChar size, s390_bfp_conv_t tag, HReg dst_hi,
   5770                          HReg dst_lo, HReg op_hi, HReg op_lo,
   5771                          s390_bfp_round_t rounding_mode)
   5772 {
   5773    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5774 
   5775    if (size == 16) {
   5776       /* From smaller or equal size to 16 bytes */
   5777       vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
   5778       vassert(hregIsInvalid(op_lo)
   5779               || is_valid_fp128_regpair(op_hi, op_lo));
   5780    } else {
   5781       /* From 16 bytes to smaller size */
   5782       vassert(is_valid_fp128_regpair(op_hi, op_lo));
   5783    }
   5784 
   5785    insn->tag  = S390_INSN_BFP_CONVERT;
   5786    insn->size = size;
   5787    insn->variant.bfp_convert.tag = tag;
   5788    insn->variant.bfp_convert.dst_hi = dst_hi;
   5789    insn->variant.bfp_convert.dst_lo = dst_lo;
   5790    insn->variant.bfp_convert.op_hi = op_hi;
   5791    insn->variant.bfp_convert.op_lo = op_lo;
   5792    insn->variant.bfp_convert.rounding_mode = rounding_mode;
   5793 
   5794    return insn;
   5795 }
   5796 
   5797 
   5798 s390_insn *
   5799 s390_insn_bfp128_convert_to(UChar size, s390_bfp_conv_t tag, HReg dst_hi,
   5800                             HReg dst_lo, HReg op)
   5801 {
   5802    /* Conversion to bfp128 never requires a rounding mode. Provide default
   5803       rounding mode. It will not be used when emitting insns. */
   5804    s390_bfp_round_t rounding_mode = S390_BFP_ROUND_NEAREST_EVEN;
   5805 
   5806    return s390_insn_bfp128_convert(size, tag, dst_hi, dst_lo, op,
   5807                                    INVALID_HREG, rounding_mode);
   5808 }
   5809 
   5810 
   5811 s390_insn *
   5812 s390_insn_bfp128_convert_from(UChar size, s390_bfp_conv_t tag, HReg dst_hi,
   5813                               HReg dst_lo, HReg op_hi, HReg op_lo,
   5814                               s390_bfp_round_t rounding_mode)
   5815 {
   5816    return s390_insn_bfp128_convert(size, tag, dst_hi, dst_lo, op_hi, op_lo,
   5817                                    rounding_mode);
   5818 }
   5819 
   5820 
   5821 s390_insn *
   5822 s390_insn_dfp_binop(UChar size, s390_dfp_binop_t tag, HReg dst, HReg op2,
   5823                     HReg op3, s390_dfp_round_t rounding_mode)
   5824 {
   5825    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5826    s390_dfp_binop *dfp_binop = LibVEX_Alloc_inline(sizeof(s390_dfp_binop));
   5827 
   5828    vassert(size == 8);
   5829 
   5830    insn->tag  = S390_INSN_DFP_BINOP;
   5831    insn->size = size;
   5832    insn->variant.dfp_binop.details = dfp_binop;
   5833 
   5834    dfp_binop->tag = tag;
   5835    dfp_binop->dst_hi = dst;
   5836    dfp_binop->op2_hi = op2;
   5837    dfp_binop->op3_hi = op3;
   5838    dfp_binop->dst_lo = INVALID_HREG;
   5839    dfp_binop->op2_lo = INVALID_HREG;
   5840    dfp_binop->op3_lo = INVALID_HREG;
   5841    dfp_binop->rounding_mode = rounding_mode;
   5842 
   5843    return insn;
   5844 }
   5845 
   5846 
   5847 s390_insn *
   5848 s390_insn_dfp_unop(UChar size, s390_dfp_unop_t tag, HReg dst, HReg op)
   5849 {
   5850    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5851 
   5852    vassert(size == 8);
   5853 
   5854    insn->tag  = S390_INSN_DFP_UNOP;
   5855    insn->size = size;
   5856    insn->variant.dfp_unop.tag = tag;
   5857    insn->variant.dfp_unop.dst_hi = dst;
   5858    insn->variant.dfp_unop.op_hi  = op;
   5859    insn->variant.dfp_unop.dst_lo = INVALID_HREG;
   5860    insn->variant.dfp_unop.op_lo  = INVALID_HREG;
   5861 
   5862    return insn;
   5863 }
   5864 
   5865 
   5866 s390_insn *
   5867 s390_insn_dfp_intop(UChar size, s390_dfp_intop_t tag, HReg dst, HReg op2,
   5868                     HReg op3)
   5869 {
   5870    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5871 
   5872    vassert(size == 8);
   5873 
   5874    insn->tag  = S390_INSN_DFP_INTOP;
   5875    insn->size = size;
   5876    insn->variant.dfp_intop.tag = tag;
   5877    insn->variant.dfp_intop.dst_hi = dst;
   5878    insn->variant.dfp_intop.op2    = op2;
   5879    insn->variant.dfp_intop.op3_hi = op3;
   5880    insn->variant.dfp_intop.dst_lo = INVALID_HREG;
   5881    insn->variant.dfp_intop.op3_lo = INVALID_HREG;
   5882 
   5883    return insn;
   5884 }
   5885 
   5886 
   5887 s390_insn *
   5888 s390_insn_dfp_compare(UChar size, s390_dfp_cmp_t tag, HReg dst,
   5889                       HReg op1, HReg op2)
   5890 {
   5891    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5892 
   5893    vassert(size == 8);
   5894 
   5895    insn->tag  = S390_INSN_DFP_COMPARE;
   5896    insn->size = size;
   5897    insn->variant.dfp_compare.tag = tag;
   5898    insn->variant.dfp_compare.dst = dst;
   5899    insn->variant.dfp_compare.op1_hi = op1;
   5900    insn->variant.dfp_compare.op2_hi = op2;
   5901    insn->variant.dfp_compare.op1_lo = INVALID_HREG;
   5902    insn->variant.dfp_compare.op2_lo = INVALID_HREG;
   5903 
   5904    return insn;
   5905 }
   5906 
   5907 
   5908 s390_insn *
   5909 s390_insn_dfp_convert(UChar size, s390_dfp_conv_t tag, HReg dst, HReg op,
   5910                       s390_dfp_round_t rounding_mode)
   5911 {
   5912    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5913 
   5914    vassert(size == 4 || size == 8);
   5915 
   5916    insn->tag  = S390_INSN_DFP_CONVERT;
   5917    insn->size = size;
   5918    insn->variant.dfp_convert.tag = tag;
   5919    insn->variant.dfp_convert.dst_hi = dst;
   5920    insn->variant.dfp_convert.op_hi  = op;
   5921    insn->variant.dfp_convert.dst_lo = INVALID_HREG;
   5922    insn->variant.dfp_convert.op_lo  = INVALID_HREG;
   5923    insn->variant.dfp_convert.rounding_mode = rounding_mode;
   5924 
   5925    return insn;
   5926 }
   5927 
   5928 
   5929 s390_insn *
   5930 s390_insn_dfp_reround(UChar size, HReg dst, HReg op2, HReg op3,
   5931                       s390_dfp_round_t rounding_mode)
   5932 {
   5933    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5934 
   5935    vassert(size == 8);
   5936 
   5937    insn->tag  = S390_INSN_DFP_REROUND;
   5938    insn->size = size;
   5939    insn->variant.dfp_reround.dst_hi = dst;
   5940    insn->variant.dfp_reround.op2 = op2;
   5941    insn->variant.dfp_reround.op3_hi = op3;
   5942    insn->variant.dfp_reround.dst_lo = INVALID_HREG;
   5943    insn->variant.dfp_reround.op3_lo = INVALID_HREG;
   5944    insn->variant.dfp_reround.rounding_mode = rounding_mode;
   5945 
   5946    return insn;
   5947 }
   5948 
   5949 
   5950 s390_insn *
   5951 s390_insn_fp_convert(UChar size, s390_fp_conv_t tag, HReg dst, HReg op,
   5952                      HReg r1, s390_dfp_round_t rounding_mode)
   5953 {
   5954    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5955    s390_fp_convert *fp_convert = LibVEX_Alloc_inline(sizeof(s390_fp_convert));
   5956 
   5957    vassert(size == 4 || size == 8);
   5958 
   5959    insn->tag  = S390_INSN_FP_CONVERT;
   5960    insn->size = size;
   5961    insn->variant.fp_convert.details = fp_convert;
   5962 
   5963    fp_convert->tag = tag;
   5964    fp_convert->dst_hi = dst;
   5965    fp_convert->op_hi  = op;
   5966    fp_convert->r1 = r1;
   5967    fp_convert->dst_lo = INVALID_HREG;
   5968    fp_convert->op_lo  = INVALID_HREG;
   5969    fp_convert->rounding_mode = rounding_mode;
   5970 
   5971    return insn;
   5972 }
   5973 
   5974 
   5975 s390_insn *
   5976 s390_insn_fp128_convert(UChar size, s390_fp_conv_t tag, HReg dst_hi,
   5977                         HReg dst_lo, HReg op_hi, HReg op_lo, HReg r1,
   5978                         s390_dfp_round_t rounding_mode)
   5979 {
   5980    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   5981    s390_fp_convert *fp_convert = LibVEX_Alloc_inline(sizeof(s390_fp_convert));
   5982 
   5983    vassert(size == 16);
   5984 
   5985    insn->tag  = S390_INSN_FP_CONVERT;
   5986    insn->size = size;
   5987    insn->variant.fp_convert.details = fp_convert;
   5988 
   5989    fp_convert->tag = tag;
   5990    fp_convert->dst_hi = dst_hi;
   5991    fp_convert->dst_lo = dst_lo;
   5992    fp_convert->op_hi  = op_hi;
   5993    fp_convert->r1 = r1;
   5994    fp_convert->op_lo  = op_lo;
   5995    fp_convert->rounding_mode = rounding_mode;
   5996 
   5997    return insn;
   5998 }
   5999 
   6000 
   6001 s390_insn *
   6002 s390_insn_dfp128_binop(UChar size, s390_dfp_binop_t tag, HReg dst_hi,
   6003                        HReg dst_lo, HReg op2_hi, HReg op2_lo, HReg op3_hi,
   6004                        HReg op3_lo, s390_dfp_round_t rounding_mode)
   6005 {
   6006    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6007    s390_dfp_binop *dfp_binop = LibVEX_Alloc_inline(sizeof(s390_dfp_binop));
   6008 
   6009    vassert(size == 16);
   6010    vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
   6011    vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
   6012    vassert(is_valid_fp128_regpair(op3_hi, op3_lo));
   6013 
   6014    insn->tag  = S390_INSN_DFP_BINOP;
   6015    insn->size = size;
   6016    insn->variant.dfp_binop.details = dfp_binop;
   6017 
   6018    dfp_binop->tag = tag;
   6019    dfp_binop->dst_hi = dst_hi;
   6020    dfp_binop->dst_lo = dst_lo;
   6021    dfp_binop->op2_hi = op2_hi;
   6022    dfp_binop->op2_lo = op2_lo;
   6023    dfp_binop->op3_hi = op3_hi;
   6024    dfp_binop->op3_lo = op3_lo;
   6025    dfp_binop->rounding_mode = rounding_mode;
   6026 
   6027    return insn;
   6028 }
   6029 
   6030 
   6031 s390_insn *
   6032 s390_insn_dfp128_unop(UChar size, s390_dfp_unop_t tag, HReg dst,
   6033                       HReg op_hi, HReg op_lo)
   6034 {
   6035    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6036 
   6037    /* destination is an 8 byte integer value */
   6038    vassert(size == 8);
   6039    vassert(is_valid_fp128_regpair(op_hi, op_lo));
   6040 
   6041    insn->tag  = S390_INSN_DFP_UNOP;
   6042    insn->size = size;
   6043    insn->variant.dfp_unop.tag = tag;
   6044    insn->variant.dfp_unop.dst_hi = dst;
   6045    insn->variant.dfp_unop.dst_lo = INVALID_HREG;
   6046    insn->variant.dfp_unop.op_hi = op_hi;
   6047    insn->variant.dfp_unop.op_lo = op_lo;
   6048 
   6049    return insn;
   6050 }
   6051 
   6052 
   6053 s390_insn *
   6054 s390_insn_dfp128_intop(UChar size, s390_dfp_intop_t tag, HReg dst_hi,
   6055                        HReg dst_lo, HReg op2, HReg op3_hi, HReg op3_lo)
   6056 {
   6057    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6058 
   6059    vassert(size == 16);
   6060    vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
   6061    vassert(is_valid_fp128_regpair(op3_hi, op3_lo));
   6062 
   6063    insn->tag  = S390_INSN_DFP_INTOP;
   6064    insn->size = size;
   6065    insn->variant.dfp_intop.tag = tag;
   6066    insn->variant.dfp_intop.dst_hi = dst_hi;
   6067    insn->variant.dfp_intop.dst_lo = dst_lo;
   6068    insn->variant.dfp_intop.op2    = op2;
   6069    insn->variant.dfp_intop.op3_hi = op3_hi;
   6070    insn->variant.dfp_intop.op3_lo = op3_lo;
   6071 
   6072    return insn;
   6073 }
   6074 
   6075 
   6076 s390_insn *
   6077 s390_insn_dfp128_compare(UChar size, s390_dfp_cmp_t tag, HReg dst, HReg op1_hi,
   6078                          HReg op1_lo, HReg op2_hi, HReg op2_lo)
   6079 {
   6080    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6081 
   6082    vassert(size == 16);
   6083    vassert(is_valid_fp128_regpair(op1_hi, op1_lo));
   6084    vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
   6085 
   6086    insn->tag  = S390_INSN_DFP_COMPARE;
   6087    insn->size = size;
   6088    insn->variant.dfp_compare.tag = tag;
   6089    insn->variant.dfp_compare.dst = dst;
   6090    insn->variant.dfp_compare.op1_hi = op1_hi;
   6091    insn->variant.dfp_compare.op1_lo = op1_lo;
   6092    insn->variant.dfp_compare.op2_hi = op2_hi;
   6093    insn->variant.dfp_compare.op2_lo = op2_lo;
   6094 
   6095    return insn;
   6096 }
   6097 
   6098 
   6099 static s390_insn *
   6100 s390_insn_dfp128_convert(UChar size, s390_dfp_conv_t tag, HReg dst_hi,
   6101                          HReg dst_lo, HReg op_hi, HReg op_lo,
   6102                          s390_dfp_round_t rounding_mode)
   6103 {
   6104    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6105 
   6106    if (size == 16) {
   6107       /* From smaller size to 16 bytes */
   6108       vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
   6109       vassert(hregIsInvalid(op_lo));
   6110    } else {
   6111       /* From 16 bytes to smaller size */
   6112       vassert(is_valid_fp128_regpair(op_hi, op_lo));
   6113    }
   6114 
   6115    insn->tag  = S390_INSN_DFP_CONVERT;
   6116    insn->size = size;
   6117    insn->variant.dfp_convert.tag = tag;
   6118    insn->variant.dfp_convert.dst_hi = dst_hi;
   6119    insn->variant.dfp_convert.dst_lo = dst_lo;
   6120    insn->variant.dfp_convert.op_hi = op_hi;
   6121    insn->variant.dfp_convert.op_lo = op_lo;
   6122    insn->variant.dfp_convert.rounding_mode = rounding_mode;
   6123 
   6124    return insn;
   6125 }
   6126 
   6127 
   6128 s390_insn *
   6129 s390_insn_dfp128_convert_to(UChar size, s390_dfp_conv_t tag, HReg dst_hi,
   6130                             HReg dst_lo, HReg op)
   6131 {
   6132    /* Conversion to dfp128 never requires a rounding mode. Provide default
   6133       rounding mode. It will not be used when emitting insns. */
   6134    s390_dfp_round_t rounding_mode = S390_DFP_ROUND_NEAREST_EVEN_4;
   6135 
   6136    return s390_insn_dfp128_convert(size, tag, dst_hi, dst_lo, op,
   6137                                    INVALID_HREG, rounding_mode);
   6138 }
   6139 
   6140 
   6141 s390_insn *
   6142 s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t tag, HReg dst_hi,
   6143                               HReg dst_lo, HReg op_hi, HReg op_lo,
   6144                               s390_dfp_round_t rounding_mode)
   6145 {
   6146    return s390_insn_dfp128_convert(size, tag, dst_hi, dst_lo, op_hi, op_lo,
   6147                                    rounding_mode);
   6148 }
   6149 
   6150 
   6151 s390_insn *
   6152 s390_insn_dfp128_reround(UChar size, HReg dst_hi, HReg dst_lo, HReg op2,
   6153                          HReg op3_hi, HReg op3_lo,
   6154                          s390_dfp_round_t rounding_mode)
   6155 {
   6156    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6157 
   6158    vassert(size == 16);
   6159    vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
   6160    vassert(is_valid_fp128_regpair(op3_hi, op3_lo));
   6161 
   6162    insn->tag  = S390_INSN_DFP_REROUND;
   6163    insn->size = size;
   6164    insn->variant.dfp_reround.dst_hi = dst_hi;
   6165    insn->variant.dfp_reround.dst_lo = dst_lo;
   6166    insn->variant.dfp_reround.op2    = op2;
   6167    insn->variant.dfp_reround.op3_hi = op3_hi;
   6168    insn->variant.dfp_reround.op3_lo = op3_lo;
   6169    insn->variant.dfp_reround.rounding_mode = rounding_mode;
   6170 
   6171    return insn;
   6172 }
   6173 
   6174 
   6175 s390_insn *
   6176 s390_insn_mfence(void)
   6177 {
   6178    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6179 
   6180    insn->tag  = S390_INSN_MFENCE;
   6181    insn->size = 0;   /* not needed */
   6182 
   6183    return insn;
   6184 }
   6185 
   6186 
   6187 s390_insn *
   6188 s390_insn_mimm(UChar size, s390_amode *dst, ULong value)
   6189 {
   6190    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6191 
   6192    /* This insn will be mapped to insns that require base register
   6193       plus 12-bit displacement */
   6194    vassert(dst->tag == S390_AMODE_B12);
   6195 
   6196    insn->tag  = S390_INSN_MIMM;
   6197    insn->size = size;
   6198    insn->variant.mimm.dst = dst;
   6199    insn->variant.mimm.value = value;
   6200 
   6201    return insn;
   6202 }
   6203 
   6204 
   6205 s390_insn *
   6206 s390_insn_madd(UChar size, s390_amode *dst, UChar delta, ULong value)
   6207 {
   6208    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6209 
   6210    vassert(size == 4 || size == 8);
   6211 
   6212    /* This insn will be mapped to an ASI or AGSI so we can only allow base
   6213       register plus 12-bit / 20-bit displacement. */
   6214    vassert(dst->tag == S390_AMODE_B12 || dst->tag == S390_AMODE_B20);
   6215    /* ASI and AGSI require the GIE facility */
   6216    vassert(s390_host_has_gie);
   6217 
   6218    insn->tag  = S390_INSN_MADD;
   6219    insn->size = size;
   6220    insn->variant.madd.dst   = dst;
   6221    insn->variant.madd.delta = delta;
   6222    insn->variant.madd.value = value;
   6223 
   6224    return insn;
   6225 }
   6226 
   6227 
   6228 s390_insn *
   6229 s390_insn_set_fpc_bfprm(UChar size, HReg mode)
   6230 {
   6231    vassert(size == 4);
   6232 
   6233    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6234 
   6235    insn->tag  = S390_INSN_SET_FPC_BFPRM;
   6236    insn->size = size;
   6237    insn->variant.set_fpc_bfprm.mode = mode;
   6238 
   6239    return insn;
   6240 }
   6241 
   6242 
   6243 s390_insn *
   6244 s390_insn_set_fpc_dfprm(UChar size, HReg mode)
   6245 {
   6246    vassert(size == 4);
   6247 
   6248    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6249 
   6250    insn->tag  = S390_INSN_SET_FPC_DFPRM;
   6251    insn->size = size;
   6252    insn->variant.set_fpc_dfprm.mode = mode;
   6253 
   6254    return insn;
   6255 }
   6256 
   6257 
   6258 s390_insn *
   6259 s390_insn_xdirect(s390_cc_t cond, Addr64 dst, s390_amode *guest_IA,
   6260                   Bool to_fast_entry)
   6261 {
   6262    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6263 
   6264    vassert(guest_IA->tag == S390_AMODE_B12);
   6265 
   6266    insn->tag  = S390_INSN_XDIRECT;
   6267    insn->size = 0;   /* does not matter */
   6268 
   6269    insn->variant.xdirect.cond = cond;
   6270    insn->variant.xdirect.dst = dst;
   6271    insn->variant.xdirect.guest_IA = guest_IA;
   6272    insn->variant.xdirect.to_fast_entry = to_fast_entry;
   6273 
   6274    return insn;
   6275 }
   6276 
   6277 
   6278 s390_insn *
   6279 s390_insn_xindir(s390_cc_t cond, HReg dst, s390_amode *guest_IA)
   6280 {
   6281    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6282 
   6283    vassert(guest_IA->tag == S390_AMODE_B12);
   6284 
   6285    insn->tag  = S390_INSN_XINDIR;
   6286    insn->size = 0;   /* does not matter */
   6287 
   6288    insn->variant.xindir.cond = cond;
   6289    insn->variant.xindir.dst = dst;
   6290    insn->variant.xindir.guest_IA = guest_IA;
   6291 
   6292    return insn;
   6293 }
   6294 
   6295 
   6296 s390_insn *
   6297 s390_insn_xassisted(s390_cc_t cond, HReg dst, s390_amode *guest_IA,
   6298                     IRJumpKind kind)
   6299 {
   6300    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6301 
   6302    vassert(guest_IA->tag == S390_AMODE_B12);
   6303 
   6304    insn->tag  = S390_INSN_XASSISTED;
   6305    insn->size = 0;   /* does not matter */
   6306 
   6307    insn->variant.xassisted.cond = cond;
   6308    insn->variant.xassisted.dst = dst;
   6309    insn->variant.xassisted.guest_IA = guest_IA;
   6310    insn->variant.xassisted.kind = kind;
   6311 
   6312    return insn;
   6313 }
   6314 
   6315 
   6316 s390_insn *
   6317 s390_insn_evcheck(s390_amode *counter, s390_amode *fail_addr)
   6318 {
   6319    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6320 
   6321    vassert(counter->tag   == S390_AMODE_B12);
   6322    vassert(fail_addr->tag == S390_AMODE_B12);
   6323 
   6324    insn->tag  = S390_INSN_EVCHECK;
   6325    insn->size = 0;   /* does not matter */
   6326 
   6327    insn->variant.evcheck.counter = counter;
   6328    insn->variant.evcheck.fail_addr = fail_addr;
   6329 
   6330    return insn;
   6331 }
   6332 
   6333 
   6334 s390_insn *
   6335 s390_insn_profinc(void)
   6336 {
   6337    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
   6338 
   6339    insn->tag  = S390_INSN_PROFINC;
   6340    insn->size = 0;   /* does not matter */
   6341 
   6342    return insn;
   6343 }
   6344 
   6345 
   6346 /*---------------------------------------------------------------*/
   6347 /*--- Debug print                                             ---*/
   6348 /*---------------------------------------------------------------*/
   6349 
   6350 static const HChar *
   6351 s390_cc_as_string(s390_cc_t cc)
   6352 {
   6353    switch (cc) {
   6354    case S390_CC_NEVER:  return "never";
   6355    case S390_CC_OVFL:   return "overflow";
   6356    case S390_CC_H:      return "greater than";     /* A > B ; high */
   6357    case S390_CC_NLE:    return "not low or equal";
   6358    case S390_CC_L:      return "less than";        /* A < B ; low */
   6359    case S390_CC_NHE:    return "not high or equal";
   6360    case S390_CC_LH:     return "low or high";
   6361    case S390_CC_NE:     return "not equal";        /* A != B ; not zero */
   6362    case S390_CC_E:      return "equal";            /* A == B ; zero */
   6363    case S390_CC_NLH:    return "not low or high";
   6364    case S390_CC_HE:     return "greater or equal"; /* A >= B ; high or equal*/
   6365    case S390_CC_NL:     return "not low";          /* not low */
   6366    case S390_CC_LE:     return "less or equal";    /* A <= B ; low or equal */
   6367    case S390_CC_NH:     return "not high";
   6368    case S390_CC_NO:     return "not overflow";
   6369    case S390_CC_ALWAYS: return "always";
   6370    default:
   6371       vpanic("s390_cc_as_string");
   6372    }
   6373 }
   6374 
   6375 
   6376 static const HChar *
   6377 s390_jump_kind_as_string(IRJumpKind kind)
   6378 {
   6379    switch (kind) {
   6380    case Ijk_Boring:      return "Boring";
   6381    case Ijk_Call:        return "Call";
   6382    case Ijk_Ret:         return "Return";
   6383    case Ijk_ClientReq:   return "ClientReq";
   6384    case Ijk_Yield:       return "Yield";
   6385    case Ijk_EmWarn:      return "EmWarn";
   6386    case Ijk_EmFail:      return "EmFail";
   6387    case Ijk_NoDecode:    return "NoDecode";
   6388    case Ijk_MapFail:     return "MapFail";
   6389    case Ijk_InvalICache: return "Invalidate";
   6390    case Ijk_NoRedir:     return "NoRedir";
   6391    case Ijk_SigTRAP:     return "SigTRAP";
   6392    case Ijk_SigSEGV:     return "SigSEGV";
   6393    case Ijk_SigBUS:      return "SigBUS";
   6394    case Ijk_Sys_syscall: return "Sys_syscall";
   6395    default:
   6396       vpanic("s390_jump_kind_as_string");
   6397    }
   6398 }
   6399 
   6400 
   6401 /* Helper function for writing out a V insn */
   6402 static void
   6403 s390_sprintf(HChar *buf, const HChar *fmt, ...)
   6404 {
   6405    HChar *p;
   6406    ULong value;
   6407    va_list args;
   6408    va_start(args, fmt);
   6409 
   6410    p = buf;
   6411    for ( ; *fmt; ++fmt) {
   6412       Int c = *fmt;
   6413 
   6414       if (c != '%') {
   6415          *p++ = c;
   6416          continue;
   6417       }
   6418 
   6419       c = *++fmt;  /* next char */
   6420       switch (c) {
   6421       case '%':
   6422          *p++ = c;   /* %% */
   6423          continue;
   6424 
   6425       case 's':     /* %s */
   6426          p += vex_sprintf(p, "%s", va_arg(args, HChar *));
   6427          continue;
   6428 
   6429       case 'M':     /* %M = mnemonic */
   6430          p += vex_sprintf(p, "%-8s", va_arg(args, HChar *));
   6431          continue;
   6432 
   6433       case 'R':     /* %R = register */
   6434          p += vex_sprintf(p, "%s", s390_hreg_as_string(va_arg(args, HReg)));
   6435          continue;
   6436 
   6437       case 'A':     /* %A = amode */
   6438          p += vex_sprintf(p, "%s",
   6439                           s390_amode_as_string(va_arg(args, s390_amode *)));
   6440          continue;
   6441 
   6442       case 'G':     /* %G = guest state @ offset */
   6443          p += vex_sprintf(p, "guest[%u]", va_arg(args, UInt));
   6444          continue;
   6445 
   6446       case 'C':     /* %C = condition code */
   6447          p += vex_sprintf(p, "%s", s390_cc_as_string(va_arg(args, s390_cc_t)));
   6448          continue;
   6449 
   6450       case 'J':     /* &J = jump kind */
   6451          p += vex_sprintf(p, "%s",
   6452                           s390_jump_kind_as_string(va_arg(args, IRJumpKind)));
   6453          continue;
   6454 
   6455       case 'L': {   /* %L = argument list in helper call*/
   6456          UInt i, num_args;
   6457 
   6458          num_args = va_arg(args, UInt);
   6459 
   6460          for (i = 0; i < num_args; ++i) {
   6461             if (i != 0) p += vex_sprintf(p, ", ");
   6462             p += vex_sprintf(p, "r%u", s390_gprno_from_arg_index(i));
   6463          }
   6464          continue;
   6465       }
   6466 
   6467       case 'O': {   /* %O = RMI operand */
   6468          s390_opnd_RMI *op = va_arg(args, s390_opnd_RMI *);
   6469 
   6470          switch (op->tag) {
   6471          case S390_OPND_REG:
   6472             p += vex_sprintf(p, "%s", s390_hreg_as_string(op->variant.reg));
   6473             continue;
   6474 
   6475          case S390_OPND_AMODE:
   6476             p += vex_sprintf(p, "%s", s390_amode_as_string(op->variant.am));
   6477             continue;
   6478 
   6479          case S390_OPND_IMMEDIATE:
   6480             value = op->variant.imm;
   6481             goto print_value;
   6482 
   6483          default:
   6484             goto fail;
   6485          }
   6486       }
   6487 
   6488       case 'I':     /* %I = immediate value */
   6489          value = va_arg(args, ULong);
   6490          goto print_value;
   6491 
   6492       print_value:
   6493          if ((Long)value < 0)
   6494             p += vex_sprintf(p, "%lld", (Long)value);
   6495          else if (value < 100)
   6496             p += vex_sprintf(p, "%llu", value);
   6497          else
   6498             p += vex_sprintf(p, "0x%llx", value);
   6499          continue;
   6500 
   6501       default:
   6502          goto fail;
   6503       }
   6504    }
   6505    *p = '\0';
   6506    va_end(args);
   6507 
   6508    return;
   6509 
   6510  fail: vpanic("s390_printf");
   6511 }
   6512 
   6513 
   6514 /* Decompile the given insn into a static buffer and return it */
   6515 const HChar *
   6516 s390_insn_as_string(const s390_insn *insn)
   6517 {
   6518    static HChar buf[300];  // large enough
   6519    const HChar *op;
   6520    HChar *p;
   6521 
   6522    buf[0] = '\0';
   6523 
   6524    switch (insn->tag) {
   6525    case S390_INSN_LOAD:
   6526       s390_sprintf(buf, "%M %R,%A", "v-load", insn->variant.load.dst,
   6527                    insn->variant.load.src);
   6528       break;
   6529 
   6530    case S390_INSN_STORE:
   6531       s390_sprintf(buf, "%M %R,%A", "v-store", insn->variant.store.src,
   6532                    insn->variant.store.dst);
   6533       break;
   6534 
   6535    case S390_INSN_MOVE:
   6536       s390_sprintf(buf, "%M %R,%R", "v-move", insn->variant.move.dst,
   6537                    insn->variant.move.src);
   6538       break;
   6539 
   6540    case S390_INSN_MEMCPY:
   6541       s390_sprintf(buf, "%M %A,%A", "v-memcpy", insn->variant.memcpy.dst,
   6542                    insn->variant.memcpy.src);
   6543       break;
   6544 
   6545    case S390_INSN_COND_MOVE:
   6546       s390_sprintf(buf, "%M if (%C) %R,%O", "v-move",
   6547                    insn->variant.cond_move.cond, insn->variant.cond_move.dst,
   6548                    &insn->variant.cond_move.src);
   6549       break;
   6550 
   6551    case S390_INSN_LOAD_IMMEDIATE:
   6552       s390_sprintf(buf, "%M %R,%I", "v-loadi", insn->variant.load_immediate.dst,
   6553                    insn->variant.load_immediate.value);
   6554       break;
   6555 
   6556    case S390_INSN_ALU:
   6557       switch (insn->variant.alu.tag) {
   6558       case S390_ALU_ADD:  op = "v-add";  break;
   6559       case S390_ALU_SUB:  op = "v-sub";  break;
   6560       case S390_ALU_MUL:  op = "v-mul";  break;
   6561       case S390_ALU_AND:  op = "v-and";  break;
   6562       case S390_ALU_OR:   op = "v-or";   break;
   6563       case S390_ALU_XOR:  op = "v-xor";  break;
   6564       case S390_ALU_LSH:  op = "v-lsh";  break;
   6565       case S390_ALU_RSH:  op = "v-rsh";  break;
   6566       case S390_ALU_RSHA: op = "v-rsha"; break;
   6567       default: goto fail;
   6568       }
   6569       s390_sprintf(buf, "%M %R,%O", op, insn->variant.alu.dst, /* also op1 */
   6570                    &insn->variant.alu.op2);
   6571       break;
   6572 
   6573    case S390_INSN_SMUL:
   6574    case S390_INSN_UMUL:
   6575       if (insn->tag == S390_INSN_SMUL) {
   6576          op = "v-muls";
   6577       } else {
   6578          op = "v-mulu";
   6579       }
   6580       s390_sprintf(buf, "%M %R,%O", op, insn->variant.mul.dst_hi,
   6581                    &insn->variant.mul.op2);
   6582       break;
   6583 
   6584    case S390_INSN_SDIV:
   6585    case S390_INSN_UDIV:
   6586       if (insn->tag == S390_INSN_SDIV) {
   6587          op = "v-divs";
   6588       } else {
   6589          op = "v-divu";
   6590       }
   6591       s390_sprintf(buf, "%M %R,%O", op, insn->variant.div.op1_hi,
   6592                    &insn->variant.div.op2);
   6593       break;
   6594 
   6595    case S390_INSN_DIVS:
   6596       s390_sprintf(buf, "%M %R,%O", "v-divsi", insn->variant.divs.op1,
   6597                    &insn->variant.divs.op2);
   6598       break;
   6599 
   6600    case S390_INSN_CLZ:
   6601       s390_sprintf(buf, "%M %R,%O", "v-clz", insn->variant.clz.num_bits,
   6602                    &insn->variant.clz.src);
   6603       break;
   6604 
   6605    case S390_INSN_UNOP:
   6606       switch (insn->variant.unop.tag) {
   6607       case S390_ZERO_EXTEND_8:
   6608       case S390_ZERO_EXTEND_16:
   6609       case S390_ZERO_EXTEND_32:
   6610          op = "v-zerox";
   6611          break;
   6612 
   6613       case S390_SIGN_EXTEND_8:
   6614       case S390_SIGN_EXTEND_16:
   6615       case S390_SIGN_EXTEND_32:
   6616          op = "v-signx";
   6617          break;
   6618 
   6619       case S390_NEGATE:
   6620          op = "v-neg";
   6621          break;
   6622 
   6623       default:
   6624          goto fail;
   6625       }
   6626       s390_sprintf(buf, "%M %R,%O", op, insn->variant.unop.dst,
   6627                    &insn->variant.unop.src);
   6628       break;
   6629 
   6630    case S390_INSN_TEST:
   6631       s390_sprintf(buf, "%M %O", "v-test", &insn->variant.test.src);
   6632       break;
   6633 
   6634    case S390_INSN_CC2BOOL:
   6635       s390_sprintf(buf, "%M %R,%C", "v-cc2b", insn->variant.cc2bool.dst,
   6636                    insn->variant.cc2bool.cond);
   6637       break;
   6638 
   6639    case S390_INSN_CAS:
   6640       s390_sprintf(buf, "%M %R,%A,%R,%R", "v-cas", insn->variant.cas.op1,
   6641                    insn->variant.cas.op2, insn->variant.cas.op3,
   6642                    insn->variant.cas.old_mem);
   6643       break;
   6644 
   6645    case S390_INSN_CDAS: {
   6646       s390_cdas *cdas = insn->variant.cdas.details;
   6647 
   6648       s390_sprintf(buf, "%M %R,%R,%A,%R,%R,%R,%R", "v-cdas",
   6649                    cdas->op1_high, cdas->op1_low, cdas->op2, cdas->op3_high,
   6650                    cdas->op3_low, cdas->old_mem_high, cdas->old_mem_low);
   6651       break;
   6652    }
   6653 
   6654    case S390_INSN_COMPARE:
   6655       if (insn->variant.compare.signed_comparison) {
   6656          op = "v-cmps";
   6657       } else {
   6658          op = "v-cmpu";
   6659       }
   6660       s390_sprintf(buf, "%M %R,%O", op, insn->variant.compare.src1,
   6661                    &insn->variant.compare.src2);
   6662       break;
   6663 
   6664    case S390_INSN_HELPER_CALL: {
   6665       s390_helper_call *helper_call = insn->variant.helper_call.details;
   6666       s390_sprintf(buf, "%M if (%C) %s{%I}(%L)", "v-call",
   6667                    helper_call->cond,
   6668                    helper_call->name,
   6669                    helper_call->target,
   6670                    helper_call->num_args);
   6671       return buf;   /* avoid printing "size = ..." which is meaningless */
   6672    }
   6673 
   6674    case S390_INSN_BFP_TRIOP:
   6675       switch (insn->variant.bfp_triop.tag) {
   6676       case S390_BFP_MADD:  op = "v-fmadd";  break;
   6677       case S390_BFP_MSUB:  op = "v-fmsub";  break;
   6678       default: goto fail;
   6679       }
   6680       s390_sprintf(buf, "%M %R,%R,%R", op,
   6681                    insn->variant.bfp_triop.dst  /* op1 same as dst */,
   6682                    insn->variant.bfp_triop.op2, insn->variant.bfp_triop.op3);
   6683       break;
   6684 
   6685    case S390_INSN_BFP_BINOP:
   6686       switch (insn->variant.bfp_binop.tag) {
   6687       case S390_BFP_ADD:      op = "v-fadd";  break;
   6688       case S390_BFP_SUB:      op = "v-fsub";  break;
   6689       case S390_BFP_MUL:      op = "v-fmul";  break;
   6690       case S390_BFP_DIV:      op = "v-fdiv";  break;
   6691       default: goto fail;
   6692       }
   6693       s390_sprintf(buf, "%M %R,%R", op,
   6694                    insn->variant.bfp_binop.dst_hi  /* op1 same as dst */,
   6695                    insn->variant.bfp_binop.op2_hi);
   6696       break;
   6697 
   6698    case S390_INSN_BFP_COMPARE:
   6699       s390_sprintf(buf, "%M %R,%R,%R", "v-fcmp", insn->variant.bfp_compare.dst,
   6700                    insn->variant.bfp_compare.op1_hi,
   6701                    insn->variant.bfp_compare.op2_hi);
   6702       break;
   6703 
   6704    case S390_INSN_BFP_UNOP:
   6705       switch (insn->variant.bfp_unop.tag) {
   6706       case S390_BFP_ABS:         op = "v-fabs";  break;
   6707       case S390_BFP_NABS:        op = "v-fnabs"; break;
   6708       case S390_BFP_NEG:         op = "v-fneg";  break;
   6709       case S390_BFP_SQRT:        op = "v-fsqrt"; break;
   6710       default: goto fail;
   6711       }
   6712       s390_sprintf(buf, "%M %R,%R", op, insn->variant.bfp_unop.dst_hi,
   6713                    insn->variant.bfp_unop.op_hi);
   6714       break;
   6715 
   6716    case S390_INSN_BFP_CONVERT:
   6717       switch (insn->variant.bfp_convert.tag) {
   6718       case S390_BFP_I32_TO_F32:
   6719       case S390_BFP_I32_TO_F64:
   6720       case S390_BFP_I32_TO_F128:
   6721       case S390_BFP_I64_TO_F32:
   6722       case S390_BFP_I64_TO_F64:
   6723       case S390_BFP_I64_TO_F128: op = "v-i2f"; break;
   6724       case S390_BFP_U32_TO_F32:
   6725       case S390_BFP_U32_TO_F64:
   6726       case S390_BFP_U32_TO_F128:
   6727       case S390_BFP_U64_TO_F32:
   6728       case S390_BFP_U64_TO_F64:
   6729       case S390_BFP_U64_TO_F128: op = "v-u2f"; break;
   6730       case S390_BFP_F32_TO_I32:
   6731       case S390_BFP_F32_TO_I64:
   6732       case S390_BFP_F64_TO_I32:
   6733       case S390_BFP_F64_TO_I64:
   6734       case S390_BFP_F128_TO_I32:
   6735       case S390_BFP_F128_TO_I64: op = "v-f2i"; break;
   6736       case S390_BFP_F32_TO_U32:
   6737       case S390_BFP_F32_TO_U64:
   6738       case S390_BFP_F64_TO_U32:
   6739       case S390_BFP_F64_TO_U64:
   6740       case S390_BFP_F128_TO_U32:
   6741       case S390_BFP_F128_TO_U64: op = "v-f2u"; break;
   6742       case S390_BFP_F32_TO_F64:
   6743       case S390_BFP_F32_TO_F128:
   6744       case S390_BFP_F64_TO_F32:
   6745       case S390_BFP_F64_TO_F128:
   6746       case S390_BFP_F128_TO_F32:
   6747       case S390_BFP_F128_TO_F64: op = "v-f2f"; break;
   6748       case S390_BFP_F32_TO_F32I:
   6749       case S390_BFP_F64_TO_F64I:
   6750       case S390_BFP_F128_TO_F128I: op = "v-f2fi"; break;
   6751       default: goto fail;
   6752       }
   6753       s390_sprintf(buf, "%M %R,%R", op, insn->variant.bfp_convert.dst_hi,
   6754                    insn->variant.bfp_convert.op_hi);
   6755       break;
   6756 
   6757    case S390_INSN_DFP_BINOP: {
   6758       s390_dfp_binop *dfp_binop = insn->variant.dfp_binop.details;
   6759 
   6760       switch (dfp_binop->tag) {
   6761       case S390_DFP_ADD:  op = "v-dadd";  break;
   6762       case S390_DFP_SUB:  op = "v-dsub";  break;
   6763       case S390_DFP_MUL:  op = "v-dmul";  break;
   6764       case S390_DFP_DIV:  op = "v-ddiv";  break;
   6765       case S390_DFP_QUANTIZE:  op = "v-dqua";  break;
   6766       default: goto fail;
   6767       }
   6768       s390_sprintf(buf, "%M %R,%R,%R", op, dfp_binop->dst_hi,
   6769                    dfp_binop->op2_hi, dfp_binop->op3_hi);
   6770       break;
   6771    }
   6772 
   6773    case S390_INSN_DFP_UNOP:
   6774       switch (insn->variant.dfp_unop.tag) {
   6775       case S390_DFP_EXTRACT_EXP_D64:
   6776       case S390_DFP_EXTRACT_EXP_D128:  op = "v-d2exp";  break;
   6777       case S390_DFP_EXTRACT_SIG_D64:
   6778       case S390_DFP_EXTRACT_SIG_D128:  op = "v-d2sig";  break;
   6779       default: goto fail;
   6780       }
   6781       s390_sprintf(buf, "%M %R,%R", op, insn->variant.dfp_unop.dst_hi,
   6782                    insn->variant.dfp_unop.op_hi);
   6783       break;
   6784 
   6785    case S390_INSN_DFP_INTOP:
   6786       switch (insn->variant.dfp_intop.tag) {
   6787       case S390_DFP_SHIFT_LEFT:  op = "v-dshl"; break;
   6788       case S390_DFP_SHIFT_RIGHT: op = "v-dshr"; break;
   6789       case S390_DFP_INSERT_EXP:  op = "v-diexp"; break;
   6790       default: goto fail;
   6791       }
   6792       s390_sprintf(buf, "%M %R,%R,%R", op, insn->variant.dfp_intop.dst_hi,
   6793                    insn->variant.dfp_intop.op2,
   6794                    insn->variant.dfp_intop.op3_hi);
   6795       break;
   6796 
   6797    case S390_INSN_DFP_COMPARE:
   6798       switch (insn->variant.dfp_compare.tag) {
   6799       case S390_DFP_COMPARE:     op = "v-dcmp"; break;
   6800       case S390_DFP_COMPARE_EXP: op = "v-dcmpexp"; break;
   6801       default: goto fail;
   6802       }
   6803       s390_sprintf(buf, "%M %R,%R,%R", op, insn->variant.dfp_compare.dst,
   6804                    insn->variant.dfp_compare.op1_hi,
   6805                    insn->variant.dfp_compare.op2_hi);
   6806       break;
   6807 
   6808    case S390_INSN_DFP_CONVERT:
   6809       switch (insn->variant.dfp_convert.tag) {
   6810       case S390_DFP_D32_TO_D64:
   6811       case S390_DFP_D64_TO_D32:
   6812       case S390_DFP_D64_TO_D128:
   6813       case S390_DFP_D128_TO_D64: op = "v-d2d"; break;
   6814       case S390_DFP_I32_TO_D64:
   6815       case S390_DFP_I32_TO_D128:
   6816       case S390_DFP_I64_TO_D64:
   6817       case S390_DFP_I64_TO_D128: op = "v-i2d"; break;
   6818       case S390_DFP_U32_TO_D64:
   6819       case S390_DFP_U32_TO_D128:
   6820       case S390_DFP_U64_TO_D64:
   6821       case S390_DFP_U64_TO_D128: op = "v-u2d"; break;
   6822       case S390_DFP_D64_TO_I32:
   6823       case S390_DFP_D128_TO_I32:
   6824       case S390_DFP_D64_TO_I64:
   6825       case S390_DFP_D128_TO_I64: op = "v-d2i"; break;
   6826       case S390_DFP_D64_TO_U32:
   6827       case S390_DFP_D64_TO_U64:
   6828       case S390_DFP_D128_TO_U32:
   6829       case S390_DFP_D128_TO_U64: op = "v-d2u"; break;
   6830       default: goto fail;
   6831       }
   6832       s390_sprintf(buf, "%M %R,%R", op, insn->variant.dfp_convert.dst_hi,
   6833                    insn->variant.dfp_convert.op_hi);
   6834       break;
   6835 
   6836    case S390_INSN_DFP_REROUND:
   6837       s390_sprintf(buf, "%M %R,%R,%R", "v-drrnd",
   6838                    insn->variant.dfp_reround.dst_hi,
   6839                    insn->variant.dfp_reround.op2,
   6840                    insn->variant.dfp_reround.op3_hi);
   6841       break;
   6842 
   6843    case S390_INSN_FP_CONVERT: {
   6844       s390_fp_convert *fp_convert = insn->variant.fp_convert.details;
   6845 
   6846       switch (fp_convert->tag) {
   6847       case S390_FP_F32_TO_D32:
   6848       case S390_FP_F32_TO_D64:
   6849       case S390_FP_F32_TO_D128:
   6850       case S390_FP_F64_TO_D32:
   6851       case S390_FP_F64_TO_D64:
   6852       case S390_FP_F64_TO_D128:
   6853       case S390_FP_F128_TO_D32:
   6854       case S390_FP_F128_TO_D64:
   6855       case S390_FP_F128_TO_D128: op = "v-f2d"; break;
   6856       case S390_FP_D32_TO_F32:
   6857       case S390_FP_D32_TO_F64:
   6858       case S390_FP_D32_TO_F128:
   6859       case S390_FP_D64_TO_F32:
   6860       case S390_FP_D64_TO_F64:
   6861       case S390_FP_D64_TO_F128:
   6862       case S390_FP_D128_TO_F32:
   6863       case S390_FP_D128_TO_F64:
   6864       case S390_FP_D128_TO_F128: op = "v-d2f"; break;
   6865       default: goto fail;
   6866       }
   6867       s390_sprintf(buf, "%M %R,%R", op, fp_convert->dst_hi,
   6868                    fp_convert->op_hi);
   6869       break;
   6870    }
   6871 
   6872    case S390_INSN_MFENCE:
   6873       s390_sprintf(buf, "%M", "v-mfence");
   6874       return buf;   /* avoid printing "size = ..." which is meaningless */
   6875 
   6876    case S390_INSN_MIMM:
   6877       s390_sprintf(buf, "%M %A,%I", "v-mimm", insn->variant.mimm.dst,
   6878                    insn->variant.mimm.value);
   6879       break;
   6880 
   6881    case S390_INSN_MADD:
   6882       s390_sprintf(buf, "%M %A += %I  (= %I)", "v-madd",
   6883                    insn->variant.madd.dst,
   6884                    (Long)(Char)insn->variant.madd.delta,
   6885                    insn->variant.madd.value);
   6886       break;
   6887 
   6888    case S390_INSN_SET_FPC_BFPRM:
   6889       s390_sprintf(buf, "%M %R", "v-set-fpc-bfprm",
   6890                    insn->variant.set_fpc_bfprm.mode);
   6891       break;
   6892 
   6893    case S390_INSN_SET_FPC_DFPRM:
   6894       s390_sprintf(buf, "%M %R", "v-set-fpc-dfprm",
   6895                    insn->variant.set_fpc_dfprm.mode);
   6896       break;
   6897 
   6898    case S390_INSN_EVCHECK:
   6899       s390_sprintf(buf, "%M counter = %A, fail-addr = %A", "v-evcheck",
   6900                    insn->variant.evcheck.counter,
   6901                    insn->variant.evcheck.fail_addr);
   6902       return buf;   /* avoid printing "size = ..." which is meaningless */
   6903 
   6904    case S390_INSN_PROFINC:
   6905       s390_sprintf(buf, "%M", "v-profinc");
   6906       return buf;   /* avoid printing "size = ..." which is meaningless */
   6907 
   6908    case S390_INSN_XDIRECT:
   6909       s390_sprintf(buf, "%M if (%C) %A = %I  %s", "v-xdirect",
   6910                    insn->variant.xdirect.cond,
   6911                    insn->variant.xdirect.guest_IA,
   6912                    insn->variant.xdirect.dst,
   6913                    insn->variant.xdirect.to_fast_entry ? "fast" : "slow");
   6914       return buf;   /* avoid printing "size = ..." which is meaningless */
   6915 
   6916    case S390_INSN_XINDIR:
   6917       s390_sprintf(buf, "%M if (%C) %A = %R", "v-xindir",
   6918                    insn->variant.xindir.cond,
   6919                    insn->variant.xindir.guest_IA,
   6920                    insn->variant.xindir.dst);
   6921       return buf;   /* avoid printing "size = ..." which is meaningless */
   6922 
   6923    case S390_INSN_XASSISTED:
   6924       s390_sprintf(buf, "%M if (%C) %J %A = %R", "v-xassisted",
   6925                    insn->variant.xassisted.cond,
   6926                    insn->variant.xassisted.kind,
   6927                    insn->variant.xassisted.guest_IA,
   6928                    insn->variant.xassisted.dst);
   6929       return buf;   /* avoid printing "size = ..." which is meaningless */
   6930 
   6931    default: goto fail;
   6932    }
   6933 
   6934    /* Write out how many bytes are involved in the operation */
   6935 
   6936    {
   6937       UInt len, i;
   6938 
   6939       for (p = buf; *p; ++p)
   6940          continue;
   6941 
   6942       len = p - buf;
   6943 
   6944       if (len < 32) {
   6945          for (i = len; i < 32; ++i)
   6946             p += vex_sprintf(p, " ");
   6947       } else {
   6948          p += vex_sprintf(p, "\t");
   6949       }
   6950    }
   6951 
   6952    /* Special cases first */
   6953    switch (insn->tag) {
   6954    case S390_INSN_UNOP:
   6955       switch (insn->variant.unop.tag) {
   6956       case S390_SIGN_EXTEND_8:
   6957       case S390_ZERO_EXTEND_8:  p += vex_sprintf(p, "1 -> "); goto common;
   6958       case S390_SIGN_EXTEND_16:
   6959       case S390_ZERO_EXTEND_16: p += vex_sprintf(p, "2 -> "); goto common;
   6960       case S390_SIGN_EXTEND_32:
   6961       case S390_ZERO_EXTEND_32: p += vex_sprintf(p, "4 -> "); goto common;
   6962       default:
   6963          goto common;
   6964       }
   6965 
   6966    case S390_INSN_BFP_CONVERT:
   6967       switch (insn->variant.bfp_convert.tag) {
   6968       case S390_BFP_I32_TO_F32:
   6969       case S390_BFP_I32_TO_F64:
   6970       case S390_BFP_I32_TO_F128:
   6971       case S390_BFP_U32_TO_F32:
   6972       case S390_BFP_U32_TO_F64:
   6973       case S390_BFP_U32_TO_F128:
   6974       case S390_BFP_F32_TO_I32:
   6975       case S390_BFP_F32_TO_I64:
   6976       case S390_BFP_F32_TO_U32:
   6977       case S390_BFP_F32_TO_U64:
   6978       case S390_BFP_F32_TO_F64:
   6979       case S390_BFP_F32_TO_F128: p += vex_sprintf(p, "4 -> "); goto common;
   6980       case S390_BFP_I64_TO_F32:
   6981       case S390_BFP_I64_TO_F64:
   6982       case S390_BFP_I64_TO_F128:
   6983       case S390_BFP_U64_TO_F32:
   6984       case S390_BFP_U64_TO_F64:
   6985       case S390_BFP_U64_TO_F128:
   6986       case S390_BFP_F64_TO_I32:
   6987       case S390_BFP_F64_TO_I64:
   6988       case S390_BFP_F64_TO_U32:
   6989       case S390_BFP_F64_TO_U64:
   6990       case S390_BFP_F64_TO_F32:
   6991       case S390_BFP_F64_TO_F128: p += vex_sprintf(p, "8 -> "); goto common;
   6992       case S390_BFP_F128_TO_I32:
   6993       case S390_BFP_F128_TO_I64:
   6994       case S390_BFP_F128_TO_U32:
   6995       case S390_BFP_F128_TO_U64:
   6996       case S390_BFP_F128_TO_F32:
   6997       case S390_BFP_F128_TO_F64: p += vex_sprintf(p, "16 -> "); goto common;
   6998       default:
   6999          goto common;
   7000       }
   7001 
   7002    case S390_INSN_DFP_CONVERT:
   7003       switch (insn->variant.dfp_convert.tag) {
   7004       case S390_DFP_D32_TO_D64:
   7005       case S390_DFP_I32_TO_D64:
   7006       case S390_DFP_I32_TO_D128:
   7007       case S390_DFP_U32_TO_D64:
   7008       case S390_DFP_U32_TO_D128: p += vex_sprintf(p, "4 -> "); goto common;
   7009       case S390_DFP_D64_TO_D32:
   7010       case S390_DFP_D64_TO_D128:
   7011       case S390_DFP_I64_TO_D64:
   7012       case S390_DFP_I64_TO_D128:
   7013       case S390_DFP_U64_TO_D64:
   7014       case S390_DFP_U64_TO_D128:
   7015       case S390_DFP_D64_TO_I32:
   7016       case S390_DFP_D64_TO_I64:
   7017       case S390_DFP_D64_TO_U32:
   7018       case S390_DFP_D64_TO_U64:  p += vex_sprintf(p, "8 -> "); goto common;
   7019       case S390_DFP_D128_TO_D64:
   7020       case S390_DFP_D128_TO_I32:
   7021       case S390_DFP_D128_TO_I64:
   7022       case S390_DFP_D128_TO_U32:
   7023       case S390_DFP_D128_TO_U64: p += vex_sprintf(p, "16 -> "); goto common;
   7024       default:
   7025          goto common;
   7026       }
   7027 
   7028    case S390_INSN_FP_CONVERT: {
   7029       s390_fp_convert *fp_convert = insn->variant.fp_convert.details;
   7030 
   7031       switch (fp_convert->tag) {
   7032       case S390_FP_F32_TO_D32:
   7033       case S390_FP_F32_TO_D64:
   7034       case S390_FP_F32_TO_D128:
   7035       case S390_FP_D32_TO_F32:
   7036       case S390_FP_D32_TO_F64:
   7037       case S390_FP_D32_TO_F128:  p += vex_sprintf(p, "4 -> "); goto common;
   7038       case S390_FP_F64_TO_D32:
   7039       case S390_FP_F64_TO_D64:
   7040       case S390_FP_F64_TO_D128:
   7041       case S390_FP_D64_TO_F32:
   7042       case S390_FP_D64_TO_F64:
   7043       case S390_FP_D64_TO_F128:  p += vex_sprintf(p, "8 -> "); goto common;
   7044       case S390_FP_F128_TO_D32:
   7045       case S390_FP_F128_TO_D64:
   7046       case S390_FP_F128_TO_D128:
   7047       case S390_FP_D128_TO_F32:
   7048       case S390_FP_D128_TO_F64:
   7049       case S390_FP_D128_TO_F128: p += vex_sprintf(p, "16 -> "); goto common;
   7050       default:
   7051          goto common;
   7052       }
   7053    }
   7054 
   7055    default:
   7056       goto common;
   7057    }
   7058 
   7059    /* Common case */
   7060  common:
   7061    vex_sprintf(p, "%u bytes", (UInt)insn->size);
   7062 
   7063    return buf;
   7064 
   7065  fail: vpanic("s390_insn_as_string");
   7066 }
   7067 
   7068 
   7069 
   7070 /* Load NUM bytes from memory into register REG using addressing mode AM. */
   7071 static UChar *
   7072 s390_emit_load_mem(UChar *p, UInt num, UChar reg, const s390_amode *am)
   7073 {
   7074    UInt b = hregNumber(am->b);
   7075    UInt x = hregNumber(am->x);  /* 0 for B12 and B20 */
   7076    UInt d = am->d;
   7077 
   7078    switch (am->tag) {
   7079    case S390_AMODE_B12:
   7080    case S390_AMODE_BX12:
   7081       switch (num) {
   7082       case 1: return s390_emit_IC(p, reg, x, b, d);
   7083       case 2: return s390_emit_LH(p, reg, x, b, d);
   7084       case 4: return s390_emit_L(p, reg, x, b, d);
   7085       case 8: return s390_emit_LG(p, reg, x, b, DISP20(d));
   7086       default: goto fail;
   7087       }
   7088       break;
   7089 
   7090    case S390_AMODE_B20:
   7091    case S390_AMODE_BX20:
   7092       switch (num) {
   7093       case 1: return s390_emit_ICY(p, reg, x, b, DISP20(d));
   7094       case 2: return s390_emit_LHY(p, reg, x, b, DISP20(d));
   7095       case 4: return s390_emit_LY(p, reg, x, b, DISP20(d));
   7096       case 8: return s390_emit_LG(p, reg, x, b, DISP20(d));
   7097       default: goto fail;
   7098       }
   7099       break;
   7100 
   7101    default: goto fail;
   7102    }
   7103 
   7104  fail:
   7105    vpanic("s390_emit_load_mem");
   7106 }
   7107 
   7108 
   7109 /* Load condition code into register REG */
   7110 static UChar *
   7111 s390_emit_load_cc(UChar *p, UChar reg)
   7112 {
   7113    p = s390_emit_LGHI(p, reg, 0);  /* Clear out, cc not affected */
   7114    p = s390_emit_IPM(p, reg, reg);
   7115    /* Shift 28 bits to the right --> [0,1,2,3] */
   7116    return s390_emit_SRL(p, reg, 0, 28); /* REG = cc */
   7117 }
   7118 
   7119 
   7120 /*---------------------------------------------------------------*/
   7121 /*--- Code generation                                         ---*/
   7122 /*---------------------------------------------------------------*/
   7123 
   7124 /* Do not load more bytes than requested. */
   7125 static UChar *
   7126 s390_insn_load_emit(UChar *buf, const s390_insn *insn)
   7127 {
   7128    UInt r, x, b, d;
   7129    const s390_amode *src;
   7130 
   7131    src = insn->variant.load.src;
   7132 
   7133    r = hregNumber(insn->variant.load.dst);
   7134 
   7135    if (hregClass(insn->variant.load.dst) == HRcFlt64) {
   7136       b = hregNumber(src->b);
   7137       x = hregNumber(src->x);  /* 0 for B12 and B20 */
   7138       d = src->d;
   7139 
   7140       switch (insn->size) {
   7141 
   7142       case 4:
   7143          switch (src->tag) {
   7144          case S390_AMODE_B12:
   7145          case S390_AMODE_BX12:
   7146             return s390_emit_LE(buf, r, x, b, d);
   7147 
   7148          case S390_AMODE_B20:
   7149          case S390_AMODE_BX20:
   7150             return s390_emit_LEY(buf, r, x, b, DISP20(d));
   7151          }
   7152          break;
   7153 
   7154       case 8:
   7155          switch (src->tag) {
   7156          case S390_AMODE_B12:
   7157          case S390_AMODE_BX12:
   7158             return s390_emit_LD(buf, r, x, b, d);
   7159 
   7160          case S390_AMODE_B20:
   7161          case S390_AMODE_BX20:
   7162             return s390_emit_LDY(buf, r, x, b, DISP20(d));
   7163          }
   7164          break;
   7165       }
   7166       vpanic("s390_insn_load_emit");
   7167    }
   7168 
   7169    /* Integer stuff */
   7170    return s390_emit_load_mem(buf, insn->size, r, src);
   7171 }
   7172 
   7173 
   7174 static UChar *
   7175 s390_insn_store_emit(UChar *buf, const s390_insn *insn)
   7176 {
   7177    UInt r, x, b, d;
   7178    const s390_amode *dst;
   7179 
   7180    dst = insn->variant.store.dst;
   7181 
   7182    r = hregNumber(insn->variant.store.src);
   7183    b = hregNumber(dst->b);
   7184    x = hregNumber(dst->x);  /* 0 for B12 and B20 */
   7185    d = dst->d;
   7186 
   7187    if (hregClass(insn->variant.store.src) == HRcFlt64) {
   7188       switch (insn->size) {
   7189 
   7190       case 4:
   7191          switch (dst->tag) {
   7192          case S390_AMODE_B12:
   7193          case S390_AMODE_BX12:
   7194             return s390_emit_STE(buf, r, x, b, d);
   7195 
   7196          case S390_AMODE_B20:
   7197          case S390_AMODE_BX20:
   7198             return s390_emit_STEY(buf, r, x, b, DISP20(d));
   7199          }
   7200          break;
   7201 
   7202       case 8:
   7203          switch (dst->tag) {
   7204          case S390_AMODE_B12:
   7205          case S390_AMODE_BX12:
   7206             return s390_emit_STD(buf, r, x, b, d);
   7207 
   7208          case S390_AMODE_B20:
   7209          case S390_AMODE_BX20:
   7210             return s390_emit_STDY(buf, r, x, b, DISP20(d));
   7211          }
   7212          break;
   7213       }
   7214       vpanic("s390_insn_store_emit");
   7215    }
   7216 
   7217    /* Integer stuff */
   7218    switch (insn->size) {
   7219    case 1:
   7220       switch (dst->tag) {
   7221       case S390_AMODE_B12:
   7222       case S390_AMODE_BX12:
   7223          return s390_emit_STC(buf, r, x, b, d);
   7224 
   7225       case S390_AMODE_B20:
   7226       case S390_AMODE_BX20:
   7227          return s390_emit_STCY(buf, r, x, b, DISP20(d));
   7228       }
   7229       break;
   7230 
   7231    case 2:
   7232       switch (dst->tag) {
   7233       case S390_AMODE_B12:
   7234       case S390_AMODE_BX12:
   7235          return s390_emit_STH(buf, r, x, b, d);
   7236 
   7237       case S390_AMODE_B20:
   7238       case S390_AMODE_BX20:
   7239          return s390_emit_STHY(buf, r, x, b, DISP20(d));
   7240       }
   7241       break;
   7242 
   7243    case 4:
   7244       switch (dst->tag) {
   7245       case S390_AMODE_B12:
   7246       case S390_AMODE_BX12:
   7247          return s390_emit_ST(buf, r, x, b, d);
   7248 
   7249       case S390_AMODE_B20:
   7250       case S390_AMODE_BX20:
   7251          return s390_emit_STY(buf, r, x, b, DISP20(d));
   7252       }
   7253       break;
   7254 
   7255    case 8:
   7256       return s390_emit_STG(buf, r, x, b, DISP20(d));
   7257 
   7258    default:
   7259       break;
   7260    }
   7261 
   7262    vpanic("s390_insn_store_emit");
   7263 }
   7264 
   7265 
   7266 static UChar *
   7267 s390_insn_move_emit(UChar *buf, const s390_insn *insn)
   7268 {
   7269    UInt dst, src;
   7270    HRegClass dst_class, src_class;
   7271 
   7272    dst = hregNumber(insn->variant.move.dst);
   7273    src = hregNumber(insn->variant.move.src);
   7274 
   7275    dst_class = hregClass(insn->variant.move.dst);
   7276    src_class = hregClass(insn->variant.move.src);
   7277 
   7278    if (dst_class == src_class) {
   7279       if (dst_class == HRcInt64)
   7280          return s390_emit_LGR(buf, dst, src);
   7281       if (dst_class == HRcFlt64)
   7282          return s390_emit_LDR(buf, dst, src);
   7283    } else {
   7284       if (dst_class == HRcFlt64 && src_class == HRcInt64) {
   7285          if (insn->size == 4) {
   7286             buf = s390_emit_SLLG(buf, R0, src, 0, DISP20(32)); /* r0 = src << 32 */
   7287             return s390_emit_LDGRw(buf, dst, R0);
   7288          } else {
   7289             return s390_emit_LDGRw(buf, dst, src);
   7290          }
   7291       }
   7292       if (dst_class == HRcInt64 && src_class == HRcFlt64) {
   7293          if (insn->size == 4) {
   7294             buf = s390_emit_LGDRw(buf, dst, src);
   7295             return s390_emit_SRLG(buf, dst, dst, 0, DISP20(32)); /* dst >>= 32 */
   7296          } else {
   7297             return s390_emit_LGDRw(buf, dst, src);
   7298          }
   7299       }
   7300       /* A move between floating point registers and general purpose
   7301          registers of different size should never occur and indicates
   7302          an error elsewhere. */
   7303    }
   7304 
   7305    vpanic("s390_insn_move_emit");
   7306 }
   7307 
   7308 
   7309 static UChar *
   7310 s390_insn_memcpy_emit(UChar *buf, const s390_insn *insn)
   7311 {
   7312    s390_amode *dst = insn->variant.memcpy.dst;
   7313    s390_amode *src = insn->variant.memcpy.src;
   7314 
   7315    return s390_emit_MVC(buf, insn->size - 1, hregNumber(dst->b), dst->d,
   7316                         hregNumber(src->b), src->d);
   7317 }
   7318 
   7319 
   7320 static UChar *
   7321 s390_insn_load_immediate_emit(UChar *buf, const s390_insn *insn)
   7322 {
   7323    UInt  r;
   7324    ULong value = insn->variant.load_immediate.value;
   7325 
   7326    r = hregNumber(insn->variant.load_immediate.dst);
   7327 
   7328    if (hregClass(insn->variant.load_immediate.dst) == HRcFlt64) {
   7329       vassert(value == 0);
   7330       switch (insn->size) {
   7331       case 4: return s390_emit_LZER(buf, r, value);
   7332       case 8: return s390_emit_LZDR(buf, r, value);
   7333       }
   7334       vpanic("s390_insn_load_immediate_emit");
   7335    }
   7336 
   7337    switch (insn->size) {
   7338    case 1:
   7339    case 2:
   7340       /* Load the immediate values as a 4 byte value. That does not hurt as
   7341          those extra bytes will not be looked at. Fall through .... */
   7342    case 4:
   7343       return s390_emit_load_32imm(buf, r, value);
   7344 
   7345    case 8:
   7346       return s390_emit_load_64imm(buf, r, value);
   7347    }
   7348 
   7349    vpanic("s390_insn_load_immediate_emit");
   7350 }
   7351 
   7352 
   7353 /* There is no easy way to do ALU operations on 1-byte or 2-byte operands.
   7354    So we simply perform a 4-byte operation. Doing so uses possibly undefined
   7355    bits and produces an undefined result in those extra bit positions. But
   7356    upstream does not look at those positions, so this is OK. */
   7357 static UChar *