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