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