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-2017
12    Copyright (C) 2012-2017  Florian Krohm   (britzel@acm.org)
13 
14    This program is free software; you can redistribute it and/or
15    modify it under the terms of the GNU General Public License as
16    published by the Free Software Foundation; either version 2 of the
17    License, or (at your option) any later version.
18 
19    This program is distributed in the hope that it will be useful, but
20    WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22    General Public License for more details.
23 
24    You should have received a copy of the GNU General Public License
25    along with this program; if not, write to the Free Software
26    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27    02110-1301, USA.
28 
29    The GNU General Public License is contained in the file COPYING.
30 */
31 
32 /* Contributed by Florian Krohm */
33 
34 #include "libvex_basictypes.h"
35 #include "libvex.h"
36 #include "libvex_trc_values.h"
37 #include "libvex_s390x_common.h"
38 
39 #include "main_util.h"
40 #include "main_globals.h"
41 #include "host_generic_regs.h"
42 #include "host_s390_defs.h"
43 #include "s390_disasm.h"
44 #include "guest_s390_defs.h"    /* S390X_GUEST_OFFSET */
45 #include <stdarg.h>
46 
47 /*------------------------------------------------------------*/
48 /*--- Forward declarations                                 ---*/
49 /*------------------------------------------------------------*/
50 
51 static void s390_insn_map_regs(HRegRemap *, s390_insn *);
52 static void s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *);
53 static UInt s390_tchain_load64_len(void);
54 
55 
56 /*------------------------------------------------------------*/
57 /*--- Registers                                            ---*/
58 /*------------------------------------------------------------*/
59 
60 /* A mapping from register number to register index */
61 static Int gpr_index[16];  // GPR regno -> register index
62 static Int vr_index[32];   // VR regno -> register index
63 
64 HReg
s390_hreg_gpr(UInt regno)65 s390_hreg_gpr(UInt regno)
66 {
67    Int ix = gpr_index[regno];
68    vassert(ix >= 0);
69    return mkHReg(/*virtual*/False, HRcInt64, regno, ix);
70 }
71 
72 HReg
s390_hreg_fpr(UInt regno)73 s390_hreg_fpr(UInt regno)
74 {
75    Int ix = vr_index[regno];
76    vassert(ix >= 0);
77    return mkHReg(/*virtual*/False, HRcFlt64, regno, ix);
78 }
79 
80 HReg
s390_hreg_vr(UInt regno)81 s390_hreg_vr(UInt regno)
82 {
83    Int ix = vr_index[regno];
84    vassert(ix >= 0);
85    return mkHReg(/*virtual*/False, HRcVec128, regno, ix);
86 }
87 
88 static __inline__ UInt
hregNumber(HReg reg)89 hregNumber(HReg reg)
90 {
91    return hregEncoding(reg);
92 }
93 
94 /* Decompile the given register into a static buffer and return it */
95 const HChar *
s390_hreg_as_string(HReg reg)96 s390_hreg_as_string(HReg reg)
97 {
98    static HChar buf[10];
99 
100    static const HChar ireg_names[16][5] = {
101       "%r0",  "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",
102       "%r8",  "%r9",  "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
103    };
104 
105    static const HChar freg_names[16][5] = {
106       "%f0",  "%f1",  "%f2",  "%f3",  "%f4",  "%f5",  "%f6",  "%f7",
107       "%f8",  "%f9",  "%f10", "%f11", "%f12", "%f13", "%f14", "%f15"
108    };
109 
110    static const HChar vreg_names[32][5] = {
111       "%v0",  "%v1",  "%v2",  "%v3",  "%v4",  "%v5",  "%v6",  "%v7",
112       "%v8",  "%v9",  "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
113       "%v16",  "%v17",  "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
114       "%v24",  "%v25",  "%v26", "%v27", "%v28", "%v29", "%v30", "%v31"
115    };
116 
117    UInt r;  /* hregNumber() returns an UInt */
118 
119    r = hregNumber(reg);
120 
121    /* Be generic for all virtual regs. */
122    if (hregIsVirtual(reg)) {
123       buf[0] = '\0';
124       switch (hregClass(reg)) {
125       case HRcInt64: vex_sprintf(buf, "%%vR%u", r); break;
126       case HRcFlt64: vex_sprintf(buf, "%%vF%u", r); break;
127       case HRcVec128: vex_sprintf(buf, "%%vV%u", r); break;
128       default:       goto fail;
129       }
130       return buf;
131    }
132 
133    /* But specific for real regs. */
134    switch (hregClass(reg)) {
135    case HRcInt64:  vassert(r < 16); return ireg_names[r];
136    case HRcFlt64:  vassert(r < 16); return freg_names[r];
137    case HRcVec128: vassert(r < 32); return vreg_names[r];
138    default:        goto fail;
139    }
140 
141  fail: vpanic("s390_hreg_as_string");
142 }
143 
144 
145 /* Return the real register that holds the guest state pointer */
146 HReg
s390_hreg_guest_state_pointer(void)147 s390_hreg_guest_state_pointer(void)
148 {
149    return s390_hreg_gpr(S390_REGNO_GUEST_STATE_POINTER);
150 }
151 
152 /* Return the real register that holds the stack pointer */
153 HReg
s390_hreg_stack_pointer(void)154 s390_hreg_stack_pointer(void)
155 {
156    return s390_hreg_gpr(S390_REGNO_STACK_POINTER);
157 }
158 
159 
160 /* Is VALUE within the domain of a 20-bit signed integer. */
161 static __inline__ Bool
fits_signed_20bit(Int value)162 fits_signed_20bit(Int value)
163 {
164    UInt uval = value;
165    return ((Int)(uval << 12) >> 12) == value;
166 }
167 
168 
169 /* Is VALUE within the domain of a 12-bit unsigned integer. */
170 static __inline__ Bool
fits_unsigned_12bit(Int value)171 fits_unsigned_12bit(Int value)
172 {
173    return (value & 0xFFF) == value;
174 }
175 
176 /*------------------------------------------------------------*/
177 /*--- Addressing modes (amodes)                            ---*/
178 /*------------------------------------------------------------*/
179 
180 /* Construct a b12 amode. */
181 s390_amode *
s390_amode_b12(Int d,HReg b)182 s390_amode_b12(Int d, HReg b)
183 {
184    s390_amode *am = LibVEX_Alloc_inline(sizeof(s390_amode));
185 
186    vassert(fits_unsigned_12bit(d));
187 
188    am->tag = S390_AMODE_B12;
189    am->d = d;
190    am->b = b;
191    am->x = s390_hreg_gpr(0);  /* hregNumber(am->x) == 0 */
192 
193    return am;
194 }
195 
196 
197 /* Construct a b20 amode. */
198 s390_amode *
s390_amode_b20(Int d,HReg b)199 s390_amode_b20(Int d, HReg b)
200 {
201    s390_amode *am = LibVEX_Alloc_inline(sizeof(s390_amode));
202 
203    vassert(fits_signed_20bit(d));
204 
205    am->tag = S390_AMODE_B20;
206    am->d = d;
207    am->b = b;
208    am->x = s390_hreg_gpr(0);  /* hregNumber(am->x) == 0 */
209 
210    return am;
211 }
212 
213 
214 /* Construct a bx12 amode. */
215 s390_amode *
s390_amode_bx12(Int d,HReg b,HReg x)216 s390_amode_bx12(Int d, HReg b, HReg x)
217 {
218    s390_amode *am = LibVEX_Alloc_inline(sizeof(s390_amode));
219 
220    vassert(fits_unsigned_12bit(d));
221    vassert(hregNumber(b) != 0);
222    vassert(hregNumber(x) != 0);
223 
224    am->tag = S390_AMODE_BX12;
225    am->d = d;
226    am->b = b;
227    am->x = x;
228 
229    return am;
230 }
231 
232 
233 /* Construct a bx20 amode. */
234 s390_amode *
s390_amode_bx20(Int d,HReg b,HReg x)235 s390_amode_bx20(Int d, HReg b, HReg x)
236 {
237    s390_amode *am = LibVEX_Alloc_inline(sizeof(s390_amode));
238 
239    vassert(fits_signed_20bit(d));
240    vassert(hregNumber(b) != 0);
241    vassert(hregNumber(x) != 0);
242 
243    am->tag = S390_AMODE_BX20;
244    am->d = d;
245    am->b = b;
246    am->x = x;
247 
248    return am;
249 }
250 
251 
252 /* Construct an AMODE for accessing the guest state at OFFSET.
253    OFFSET can be at most 3 * sizeof(VexGuestS390XState) + LibVEX_N_SPILL_BYTES
254    which may be too large for a B12 addressing mode.
255    Use a B20 amode as a fallback which will be safe for any offset.
256 */
257 s390_amode *
s390_amode_for_guest_state(Int offset)258 s390_amode_for_guest_state(Int offset)
259 {
260    if (fits_unsigned_12bit(offset))
261       return s390_amode_b12(offset, s390_hreg_guest_state_pointer());
262 
263    if (fits_signed_20bit(offset))
264       return s390_amode_b20(offset, s390_hreg_guest_state_pointer());
265 
266    vpanic("invalid guest state offset");
267 }
268 
269 
270 /* Construct an AMODE for accessing stack pointer at OFFSET.
271    OFFSET can be at most 3 * sizeof(VexGuestS390XState) + LibVEX_N_SPILL_BYTES
272    which may be too large for a B12 addressing mode.
273    Use a B20 amode as a fallback which will be safe for any offset.
274 */
275 s390_amode *
s390_amode_for_stack_pointer(Int offset)276 s390_amode_for_stack_pointer(Int offset)
277 {
278    if (fits_unsigned_12bit(offset))
279       return s390_amode_b12(offset, s390_hreg_stack_pointer());
280 
281    if (fits_signed_20bit(offset))
282       return s390_amode_b20(offset, s390_hreg_stack_pointer());
283 
284    vpanic("invalid stack pointer offset");
285 }
286 
287 
288 /* Decompile the given amode into a static buffer and return it. */
289 const HChar *
s390_amode_as_string(const s390_amode * am)290 s390_amode_as_string(const s390_amode *am)
291 {
292    static HChar buf[30];
293    HChar *p;
294 
295    buf[0] = '\0';
296    p = buf;
297 
298    switch (am->tag) {
299    case S390_AMODE_B12:
300    case S390_AMODE_B20:
301       vex_sprintf(p, "%d(%s)", am->d, s390_hreg_as_string(am->b));
302       break;
303 
304    case S390_AMODE_BX12:
305    case S390_AMODE_BX20:
306       /* s390_hreg_as_string returns pointer to local buffer. Need to
307          split this into two printfs */
308       p += vex_sprintf(p, "%d(%s,", am->d, s390_hreg_as_string(am->x));
309       vex_sprintf(p, "%s)", s390_hreg_as_string(am->b));
310       break;
311 
312    default:
313       vpanic("s390_amode_as_string");
314    }
315 
316    return buf;
317 }
318 
319 
320 /* Helper function for s390_amode_is_sane */
321 static __inline__ Bool
is_virtual_gpr(HReg reg)322 is_virtual_gpr(HReg reg)
323 {
324    return hregIsVirtual(reg) && hregClass(reg) == HRcInt64;
325 }
326 
327 /* Helper function for all vector operations */
328 static UChar
s390_getM_from_size(const UChar size)329 s390_getM_from_size(const UChar size) {
330    switch(size) {
331    case 1:
332       return 0;
333    case 2:
334       return 1;
335    case 4:
336       return 2;
337    case 8:
338       return 3;
339    case 16:
340       return 4;
341    default:
342       vex_printf("size=%d\n", size);
343       vpanic("s390_getM_from_size: unknown size");
344    }
345 }
346 
347 /* Helper for generating RXB field in vector instructions */
348 static UChar
s390_update_rxb(const UChar rxb,const UChar index,UChar * vr)349 s390_update_rxb(const UChar rxb, const UChar index, UChar* vr) {
350    vassert((index >= 1) && (index <= 4));
351    UChar result = rxb;
352    if(vr != NULL) {
353       if(*vr >= 16) {
354          result |= 1 << (4 - index);
355          *vr -= 16;
356       }
357    }
358    return result;
359 }
360 
361 /* Sanity check for an amode */
362 Bool
s390_amode_is_sane(const s390_amode * am)363 s390_amode_is_sane(const s390_amode *am)
364 {
365    switch (am->tag) {
366    case S390_AMODE_B12:
367       return is_virtual_gpr(am->b) && fits_unsigned_12bit(am->d);
368 
369    case S390_AMODE_B20:
370       return is_virtual_gpr(am->b) && fits_signed_20bit(am->d);
371 
372    case S390_AMODE_BX12:
373       return is_virtual_gpr(am->b) && is_virtual_gpr(am->x) &&
374              fits_unsigned_12bit(am->d);
375 
376    case S390_AMODE_BX20:
377       return is_virtual_gpr(am->b) && is_virtual_gpr(am->x) &&
378              fits_signed_20bit(am->d);
379 
380    default:
381       vpanic("s390_amode_is_sane");
382    }
383 }
384 
385 
386 /* Record the register use of an amode */
387 static void
s390_amode_get_reg_usage(HRegUsage * u,const s390_amode * am)388 s390_amode_get_reg_usage(HRegUsage *u, const s390_amode *am)
389 {
390    switch (am->tag) {
391    case S390_AMODE_B12:
392    case S390_AMODE_B20:
393       addHRegUse(u, HRmRead, am->b);
394       return;
395 
396    case S390_AMODE_BX12:
397    case S390_AMODE_BX20:
398       addHRegUse(u, HRmRead, am->b);
399       addHRegUse(u, HRmRead, am->x);
400       return;
401 
402    default:
403       vpanic("s390_amode_get_reg_usage");
404    }
405 }
406 
407 
408 static void
s390_amode_map_regs(HRegRemap * m,s390_amode * am)409 s390_amode_map_regs(HRegRemap *m, s390_amode *am)
410 {
411    switch (am->tag) {
412    case S390_AMODE_B12:
413    case S390_AMODE_B20:
414       am->b = lookupHRegRemap(m, am->b);
415       return;
416 
417    case S390_AMODE_BX12:
418    case S390_AMODE_BX20:
419       am->b = lookupHRegRemap(m, am->b);
420       am->x = lookupHRegRemap(m, am->x);
421       return;
422 
423    default:
424       vpanic("s390_amode_map_regs");
425    }
426 }
427 
428 
429 void
ppS390AMode(const s390_amode * am)430 ppS390AMode(const s390_amode *am)
431 {
432    vex_printf("%s", s390_amode_as_string(am));
433 }
434 
435 void
ppS390Instr(const s390_insn * insn,Bool mode64)436 ppS390Instr(const s390_insn *insn, Bool mode64)
437 {
438    vex_printf("%s", s390_insn_as_string(insn));
439 }
440 
441 UInt
ppHRegS390(HReg reg)442 ppHRegS390(HReg reg)
443 {
444    return vex_printf("%s", s390_hreg_as_string(reg));
445 }
446 
447 /*------------------------------------------------------------*/
448 /*--- Helpers for register allocation                      ---*/
449 /*------------------------------------------------------------*/
450 
451 /* Initialise and return the "register universe", i.e. a list of
452    all hardware registers. Called once. */
453 const RRegUniverse *
getRRegUniverse_S390(void)454 getRRegUniverse_S390(void)
455 {
456    static RRegUniverse all_regs;
457    static Bool initialised = False;
458    RRegUniverse *ru = &all_regs;
459 
460    if (LIKELY(initialised))
461       return ru;
462 
463    RRegUniverse__init(ru);
464 
465    /* Assign invalid values to the gpr/vr_index */
466    for (UInt i = 0; i < sizeof gpr_index / sizeof gpr_index[0]; ++i)
467       gpr_index[i] = -1;
468    for (UInt i = 0; i < sizeof vr_index / sizeof vr_index[0]; ++i)
469       vr_index[i] = -1;
470 
471 
472    /* Add the registers that are available to the register allocator.
473       GPRs:  registers 6..11 are callee saved, list them first
474              registers 1..5 are caller saved, list them after
475       FPRs:  registers 8..15 are callee saved, list them first
476              registers 0..7 are caller saved, list them after
477              FPR12 - FPR15 are also used as register pairs for 128-bit
478              floating point operations
479       VRs:   registers 0..31 are available
480    */
481    ru->allocable_start[HRcInt64] = ru->size;
482    for (UInt regno = 6; regno <= 11; ++regno) {
483       gpr_index[regno] = ru->size;
484       ru->regs[ru->size++] = s390_hreg_gpr(regno);
485    }
486    for (UInt regno = 1; regno <= 5; ++regno) {
487       gpr_index[regno] = ru->size;
488       ru->regs[ru->size++] = s390_hreg_gpr(regno);
489    }
490    ru->allocable_end[HRcInt64] = ru->size - 1;
491 
492    ru->allocable_start[HRcFlt64] = ru->size;
493    for (UInt regno = 8; regno <= 15; ++regno) {
494       vr_index[regno] = ru->size;
495       ru->regs[ru->size++] = s390_hreg_fpr(regno);
496    }
497    for (UInt regno = 0; regno <= 7; ++regno) {
498       vr_index[regno] = ru->size;
499       ru->regs[ru->size++] = s390_hreg_fpr(regno);
500    }
501    ru->allocable_end[HRcFlt64] = ru->size - 1;
502 
503    ru->allocable_start[HRcVec128] = ru->size;
504    for (UInt regno = 16; regno <= 31; ++regno) {
505       vr_index[regno] = ru->size;
506       ru->regs[ru->size++] = s390_hreg_vr(regno);
507    }
508    ru->allocable_end[HRcVec128] = ru->size - 1;
509    ru->allocable = ru->size;
510 
511    /* Add the registers that are not available for allocation.
512       r0  -- cannot be used as a base or index register
513       r12 -- scratch register for translation chaining support
514       r13 -- guest state pointer
515       r14 -- link register
516       r15 -- stack pointer
517    */
518    UInt other[] = { 0, 12, 13, 14, 15 };
519    for (UInt i = 0; i < sizeof other / sizeof other[0]; ++i) {
520       gpr_index[other[i]] = ru->size;
521       ru->regs[ru->size++] = s390_hreg_gpr(other[i]);
522    }
523 
524    /* Sanity checking */
525    for (UInt i = 0; i < sizeof gpr_index / sizeof gpr_index[0]; ++i)
526       vassert(gpr_index[i] >= 0);
527    for (UInt i = 0; i < sizeof vr_index / sizeof vr_index[0]; ++i)
528       vassert(vr_index[i] >= 0);
529 
530    initialised = True;
531 
532    RRegUniverse__check_is_sane(ru);
533    return ru;
534 }
535 
536 /* Tell the register allocator how the given instruction uses the registers
537    it refers to. */
538 void
getRegUsage_S390Instr(HRegUsage * u,const s390_insn * insn,Bool mode64)539 getRegUsage_S390Instr(HRegUsage *u, const s390_insn *insn, Bool mode64)
540 {
541    s390_insn_get_reg_usage(u, insn);
542 }
543 
544 
545 /* Map the registers of the given instruction */
546 void
mapRegs_S390Instr(HRegRemap * m,s390_insn * insn,Bool mode64)547 mapRegs_S390Instr(HRegRemap *m, s390_insn *insn, Bool mode64)
548 {
549    s390_insn_map_regs(m, insn);
550 }
551 
552 
553 /* Generate s390 spill/reload instructions under the direction of the
554    register allocator.  Note it's critical these don't write the
555    condition codes. This is like an Ist_Put */
556 void
genSpill_S390(HInstr ** i1,HInstr ** i2,HReg rreg,Int offsetB,Bool mode64)557 genSpill_S390(HInstr **i1, HInstr **i2, HReg rreg, Int offsetB, Bool mode64)
558 {
559    s390_amode *am;
560 
561    vassert(offsetB >= 0);
562    vassert(!hregIsVirtual(rreg));
563 
564    *i1 = *i2 = NULL;
565 
566    am = s390_amode_for_guest_state(offsetB);
567 
568    switch (hregClass(rreg)) {
569    case HRcInt64:
570    case HRcFlt64:
571       *i1 = s390_insn_store(8, am, rreg);
572       return;
573    case HRcVec128:
574       *i1 = s390_insn_store(16, am, rreg);
575       return;
576    default:
577       ppHRegClass(hregClass(rreg));
578       vpanic("genSpill_S390: unimplemented regclass");
579    }
580 }
581 
582 
583 /* This is like an Iex_Get */
584 void
genReload_S390(HInstr ** i1,HInstr ** i2,HReg rreg,Int offsetB,Bool mode64)585 genReload_S390(HInstr **i1, HInstr **i2, HReg rreg, Int offsetB, Bool mode64)
586 {
587    s390_amode *am;
588 
589    vassert(offsetB >= 0);
590    vassert(!hregIsVirtual(rreg));
591 
592    *i1 = *i2 = NULL;
593 
594    am = s390_amode_for_guest_state(offsetB);
595 
596    switch (hregClass(rreg)) {
597    case HRcInt64:
598    case HRcFlt64:
599       *i1 = s390_insn_load(8, rreg, am);
600       return;
601    case HRcVec128:
602       *i1 = s390_insn_load(16, rreg, am);
603       return;
604    default:
605       ppHRegClass(hregClass(rreg));
606       vpanic("genReload_S390: unimplemented regclass");
607    }
608 }
609 
genMove_S390(HReg from,HReg to,Bool mode64)610 s390_insn* genMove_S390(HReg from, HReg to, Bool mode64)
611 {
612    switch (hregClass(from)) {
613    case HRcInt64:
614       return s390_insn_move(sizeofIRType(Ity_I64), to, from);
615    case HRcVec128:
616       return s390_insn_move(sizeofIRType(Ity_V128), to, from);
617    default:
618       ppHRegClass(hregClass(from));
619       vpanic("genMove_S390: unimplemented regclass");
620    }
621 }
622 
623 /* Helper function for s390_insn_get_reg_usage */
624 static void
s390_opnd_RMI_get_reg_usage(HRegUsage * u,s390_opnd_RMI op)625 s390_opnd_RMI_get_reg_usage(HRegUsage *u, s390_opnd_RMI op)
626 {
627    switch (op.tag) {
628    case S390_OPND_REG:
629       addHRegUse(u, HRmRead, op.variant.reg);
630       break;
631 
632    case S390_OPND_AMODE:
633       s390_amode_get_reg_usage(u, op.variant.am);
634       break;
635 
636    case S390_OPND_IMMEDIATE:
637       break;
638 
639    default:
640       vpanic("s390_opnd_RMI_get_reg_usage");
641    }
642 }
643 
644 
645 /* Tell the register allocator how the given insn uses the registers */
646 static void
s390_insn_get_reg_usage(HRegUsage * u,const s390_insn * insn)647 s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *insn)
648 {
649    initHRegUsage(u);
650 
651    switch (insn->tag) {
652    case S390_INSN_LOAD:
653       addHRegUse(u, HRmWrite, insn->variant.load.dst);
654       s390_amode_get_reg_usage(u, insn->variant.load.src);
655       break;
656 
657    case S390_INSN_LOAD_IMMEDIATE:
658       addHRegUse(u, HRmWrite, insn->variant.load_immediate.dst);
659       break;
660 
661    case S390_INSN_STORE:
662       addHRegUse(u, HRmRead, insn->variant.store.src);
663       s390_amode_get_reg_usage(u, insn->variant.store.dst);
664       break;
665 
666    case S390_INSN_MOVE:
667       addHRegUse(u, HRmRead,  insn->variant.move.src);
668       addHRegUse(u, HRmWrite, insn->variant.move.dst);
669 
670       if (hregClass(insn->variant.move.src) == hregClass(insn->variant.move.dst)) {
671          u->isRegRegMove = True;
672          u->regMoveSrc   = insn->variant.move.src;
673          u->regMoveDst   = insn->variant.move.dst;
674       }
675       break;
676 
677    case S390_INSN_MEMCPY:
678       s390_amode_get_reg_usage(u, insn->variant.memcpy.src);
679       s390_amode_get_reg_usage(u, insn->variant.memcpy.dst);
680       break;
681 
682    case S390_INSN_COND_MOVE:
683       s390_opnd_RMI_get_reg_usage(u, insn->variant.cond_move.src);
684       addHRegUse(u, HRmWrite, insn->variant.cond_move.dst);
685       break;
686 
687    case S390_INSN_ALU:
688       addHRegUse(u, HRmWrite, insn->variant.alu.dst);
689       addHRegUse(u, HRmRead,  insn->variant.alu.dst);  /* op1 */
690       s390_opnd_RMI_get_reg_usage(u, insn->variant.alu.op2);
691       break;
692 
693    case S390_INSN_SMUL:
694    case S390_INSN_UMUL:
695       addHRegUse(u, HRmRead,  insn->variant.mul.dst_lo);  /* op1 */
696       addHRegUse(u, HRmWrite, insn->variant.mul.dst_lo);
697       addHRegUse(u, HRmWrite, insn->variant.mul.dst_hi);
698       s390_opnd_RMI_get_reg_usage(u, insn->variant.mul.op2);
699       break;
700 
701    case S390_INSN_SDIV:
702    case S390_INSN_UDIV:
703       addHRegUse(u, HRmRead,  insn->variant.div.op1_lo);
704       addHRegUse(u, HRmRead,  insn->variant.div.op1_hi);
705       addHRegUse(u, HRmWrite, insn->variant.div.op1_lo);
706       addHRegUse(u, HRmWrite, insn->variant.div.op1_hi);
707       s390_opnd_RMI_get_reg_usage(u, insn->variant.div.op2);
708       break;
709 
710    case S390_INSN_DIVS:
711       addHRegUse(u, HRmRead,  insn->variant.divs.op1);
712       addHRegUse(u, HRmWrite, insn->variant.divs.op1); /* quotient */
713       addHRegUse(u, HRmWrite, insn->variant.divs.rem); /* remainder */
714       s390_opnd_RMI_get_reg_usage(u, insn->variant.divs.op2);
715       break;
716 
717    case S390_INSN_CLZ:
718       addHRegUse(u, HRmWrite, insn->variant.clz.num_bits);
719       addHRegUse(u, HRmWrite, insn->variant.clz.clobber);
720       s390_opnd_RMI_get_reg_usage(u, insn->variant.clz.src);
721       break;
722 
723    case S390_INSN_UNOP:
724       addHRegUse(u, HRmWrite, insn->variant.unop.dst);
725       s390_opnd_RMI_get_reg_usage(u, insn->variant.unop.src);
726       break;
727 
728    case S390_INSN_TEST:
729       s390_opnd_RMI_get_reg_usage(u, insn->variant.test.src);
730       break;
731 
732    case S390_INSN_CC2BOOL:
733       addHRegUse(u, HRmWrite, insn->variant.cc2bool.dst);
734       break;
735 
736    case S390_INSN_CAS:
737       addHRegUse(u, HRmRead,  insn->variant.cas.op1);
738       s390_amode_get_reg_usage(u, insn->variant.cas.op2);
739       addHRegUse(u, HRmRead,  insn->variant.cas.op3);
740       addHRegUse(u, HRmWrite,  insn->variant.cas.old_mem);
741       break;
742 
743    case S390_INSN_CDAS: {
744       s390_cdas *cdas = insn->variant.cdas.details;
745 
746       addHRegUse(u, HRmRead,  cdas->op1_high);
747       addHRegUse(u, HRmRead,  cdas->op1_low);
748       s390_amode_get_reg_usage(u, cdas->op2);
749       addHRegUse(u, HRmRead,  cdas->op3_high);
750       addHRegUse(u, HRmRead,  cdas->op3_low);
751       addHRegUse(u, HRmWrite, cdas->old_mem_high);
752       addHRegUse(u, HRmWrite, cdas->old_mem_low);
753       addHRegUse(u, HRmWrite, cdas->scratch);
754       break;
755    }
756 
757    case S390_INSN_COMPARE:
758       addHRegUse(u, HRmRead, insn->variant.compare.src1);
759       s390_opnd_RMI_get_reg_usage(u, insn->variant.compare.src2);
760       break;
761 
762    case S390_INSN_HELPER_CALL: {
763       UInt i;
764 
765       /* Assume that all volatile registers are clobbered. ABI says,
766          volatile registers are: r0 - r5. Valgrind's register allocator
767          does not know about r0, so we can leave that out */
768       for (i = 1; i <= 5; ++i) {
769          addHRegUse(u, HRmWrite, s390_hreg_gpr(i));
770       }
771 
772       /* Ditto for floating point registers. f0 - f7 are volatile */
773       for (i = 0; i <= 7; ++i) {
774          addHRegUse(u, HRmWrite, s390_hreg_fpr(i));
775       }
776 
777       /* The registers that are used for passing arguments will be read.
778          Not all of them may, but in general we need to assume that. */
779       for (i = 0; i < insn->variant.helper_call.details->num_args; ++i) {
780          addHRegUse(u, HRmRead, s390_hreg_gpr(s390_gprno_from_arg_index(i)));
781       }
782 
783       /* s390_insn_helper_call_emit also reads / writes the link register
784          and stack pointer. But those registers are not visible to the
785          register allocator. So we don't need to do anything for them. */
786       break;
787    }
788 
789    case S390_INSN_BFP_TRIOP:
790       addHRegUse(u, HRmWrite, insn->variant.bfp_triop.dst);
791       addHRegUse(u, HRmRead,  insn->variant.bfp_triop.dst);  /* first */
792       addHRegUse(u, HRmRead,  insn->variant.bfp_triop.op2);  /* second */
793       addHRegUse(u, HRmRead,  insn->variant.bfp_triop.op3);  /* third */
794       break;
795 
796    case S390_INSN_BFP_BINOP:
797       addHRegUse(u, HRmWrite, insn->variant.bfp_binop.dst_hi);
798       addHRegUse(u, HRmRead,  insn->variant.bfp_binop.dst_hi);  /* left */
799       addHRegUse(u, HRmRead,  insn->variant.bfp_binop.op2_hi);  /* right */
800       if (insn->size == 16) {
801          addHRegUse(u, HRmWrite, insn->variant.bfp_binop.dst_lo);
802          addHRegUse(u, HRmRead,  insn->variant.bfp_binop.dst_lo);  /* left */
803          addHRegUse(u, HRmRead,  insn->variant.bfp_binop.op2_lo);  /* right */
804       }
805       break;
806 
807    case S390_INSN_BFP_UNOP:
808       addHRegUse(u, HRmWrite, insn->variant.bfp_unop.dst_hi);
809       addHRegUse(u, HRmRead,  insn->variant.bfp_unop.op_hi);  /* operand */
810       if (insn->size == 16) {
811          addHRegUse(u, HRmWrite, insn->variant.bfp_unop.dst_lo);
812          addHRegUse(u, HRmRead,  insn->variant.bfp_unop.op_lo);  /* operand */
813       }
814       break;
815 
816    case S390_INSN_BFP_COMPARE:
817       addHRegUse(u, HRmWrite, insn->variant.bfp_compare.dst);
818       addHRegUse(u, HRmRead,  insn->variant.bfp_compare.op1_hi);  /* left */
819       addHRegUse(u, HRmRead,  insn->variant.bfp_compare.op2_hi);  /* right */
820       if (insn->size == 16) {
821          addHRegUse(u, HRmRead,  insn->variant.bfp_compare.op1_lo);  /* left */
822          addHRegUse(u, HRmRead,  insn->variant.bfp_compare.op2_lo);  /* right */
823       }
824       break;
825 
826    case S390_INSN_BFP_CONVERT:
827       addHRegUse(u, HRmWrite, insn->variant.bfp_convert.dst_hi);
828       if (! hregIsInvalid(insn->variant.bfp_convert.dst_lo))
829          addHRegUse(u, HRmWrite, insn->variant.bfp_convert.dst_lo);
830       addHRegUse(u, HRmRead,  insn->variant.bfp_convert.op_hi);
831       if (! hregIsInvalid(insn->variant.bfp_convert.op_lo))
832          addHRegUse(u, HRmRead, insn->variant.bfp_convert.op_lo);
833       break;
834 
835    case S390_INSN_DFP_BINOP: {
836       s390_dfp_binop *dfp_binop = insn->variant.dfp_binop.details;
837 
838       addHRegUse(u, HRmWrite, dfp_binop->dst_hi);
839       addHRegUse(u, HRmRead,  dfp_binop->op2_hi);  /* left */
840       addHRegUse(u, HRmRead,  dfp_binop->op3_hi);  /* right */
841       if (insn->size == 16) {
842          addHRegUse(u, HRmWrite, dfp_binop->dst_lo);
843          addHRegUse(u, HRmRead,  dfp_binop->op2_lo);  /* left */
844          addHRegUse(u, HRmRead,  dfp_binop->op3_lo);  /* right */
845       }
846       break;
847    }
848 
849    case S390_INSN_DFP_UNOP:
850       addHRegUse(u, HRmWrite, insn->variant.dfp_unop.dst_hi);
851       addHRegUse(u, HRmRead,  insn->variant.dfp_unop.op_hi);  /* operand */
852       if (insn->size == 16) {
853          addHRegUse(u, HRmWrite, insn->variant.dfp_unop.dst_lo);
854          addHRegUse(u, HRmRead,  insn->variant.dfp_unop.op_lo);  /* operand */
855       }
856       break;
857 
858    case S390_INSN_DFP_INTOP:
859       addHRegUse(u, HRmWrite, insn->variant.dfp_intop.dst_hi);
860       addHRegUse(u, HRmRead,  insn->variant.dfp_intop.op2);
861       addHRegUse(u, HRmRead,  insn->variant.dfp_intop.op3_hi);
862       if (insn->size == 16) {
863          addHRegUse(u, HRmWrite, insn->variant.dfp_intop.dst_lo);
864          addHRegUse(u, HRmRead,  insn->variant.dfp_intop.op3_lo);
865       }
866       break;
867 
868    case S390_INSN_DFP_COMPARE:
869       addHRegUse(u, HRmWrite, insn->variant.dfp_compare.dst);
870       addHRegUse(u, HRmRead,  insn->variant.dfp_compare.op1_hi);  /* left */
871       addHRegUse(u, HRmRead,  insn->variant.dfp_compare.op2_hi);  /* right */
872       if (insn->size == 16) {
873          addHRegUse(u, HRmRead,  insn->variant.dfp_compare.op1_lo);  /* left */
874          addHRegUse(u, HRmRead,  insn->variant.dfp_compare.op2_lo);  /* right */
875       }
876       break;
877 
878    case S390_INSN_DFP_CONVERT:
879       addHRegUse(u, HRmWrite, insn->variant.dfp_convert.dst_hi);
880       if (! hregIsInvalid(insn->variant.dfp_convert.dst_lo))
881          addHRegUse(u, HRmWrite, insn->variant.dfp_convert.dst_lo);
882       addHRegUse(u, HRmRead,  insn->variant.dfp_convert.op_hi);  /* operand */
883       if (! hregIsInvalid(insn->variant.dfp_convert.op_lo))
884          addHRegUse(u, HRmRead, insn->variant.dfp_convert.op_lo); /* operand */
885       break;
886 
887    case S390_INSN_DFP_REROUND:
888       addHRegUse(u, HRmWrite, insn->variant.dfp_reround.dst_hi);
889       addHRegUse(u, HRmRead,  insn->variant.dfp_reround.op2);     /* left */
890       addHRegUse(u, HRmRead,  insn->variant.dfp_reround.op3_hi);  /* right */
891       if (insn->size == 16) {
892          addHRegUse(u, HRmWrite, insn->variant.dfp_reround.dst_lo);
893          addHRegUse(u, HRmRead,  insn->variant.dfp_reround.op3_lo); /* right */
894       }
895       break;
896 
897    case S390_INSN_FP_CONVERT: {
898       s390_fp_convert *fp_convert = insn->variant.fp_convert.details;
899 
900       addHRegUse(u, HRmWrite, fp_convert->dst_hi);
901       if (! hregIsInvalid(fp_convert->dst_lo))
902          addHRegUse(u, HRmWrite, fp_convert->dst_lo);
903       addHRegUse(u, HRmRead,  fp_convert->op_hi);
904       if (! hregIsInvalid(fp_convert->op_lo))
905          addHRegUse(u, HRmRead, fp_convert->op_lo);
906       addHRegUse(u, HRmWrite, fp_convert->r1);
907       break;
908    }
909 
910    case S390_INSN_MIMM:
911       s390_amode_get_reg_usage(u, insn->variant.mimm.dst);
912       break;
913 
914    case S390_INSN_MADD:
915       s390_amode_get_reg_usage(u, insn->variant.madd.dst);
916       break;
917 
918    case S390_INSN_MFENCE:
919       break;
920 
921    case S390_INSN_SET_FPC_BFPRM:
922       addHRegUse(u, HRmRead,  insn->variant.set_fpc_bfprm.mode);
923       break;
924 
925    case S390_INSN_SET_FPC_DFPRM:
926       addHRegUse(u, HRmRead,  insn->variant.set_fpc_dfprm.mode);
927       break;
928 
929    case S390_INSN_EVCHECK:
930       s390_amode_get_reg_usage(u, insn->variant.evcheck.counter);
931       s390_amode_get_reg_usage(u, insn->variant.evcheck.fail_addr);
932       break;
933 
934    case S390_INSN_PROFINC:
935       /* Does not use any register visible to the register allocator */
936       break;
937 
938    case S390_INSN_XDIRECT:
939       s390_amode_get_reg_usage(u, insn->variant.xdirect.guest_IA);
940       break;
941 
942    case S390_INSN_XINDIR:
943       addHRegUse(u, HRmRead, insn->variant.xindir.dst);
944       s390_amode_get_reg_usage(u, insn->variant.xindir.guest_IA);
945       break;
946 
947    case S390_INSN_XASSISTED:
948       addHRegUse(u, HRmRead, insn->variant.xassisted.dst);
949       s390_amode_get_reg_usage(u, insn->variant.xassisted.guest_IA);
950       break;
951 
952    case S390_INSN_VEC_AMODEOP:
953       addHRegUse(u, HRmWrite, insn->variant.vec_amodeop.dst);
954       addHRegUse(u, HRmRead, insn->variant.vec_amodeop.op1);
955       s390_amode_get_reg_usage(u, insn->variant.vec_amodeop.op2);
956       break;
957 
958    case S390_INSN_VEC_AMODEINTOP:
959       addHRegUse(u, HRmRead, insn->variant.vec_amodeintop.dst);
960       addHRegUse(u, HRmWrite, insn->variant.vec_amodeintop.dst);
961       s390_amode_get_reg_usage(u, insn->variant.vec_amodeintop.op2);
962       addHRegUse(u, HRmRead, insn->variant.vec_amodeintop.op3);
963       break;
964 
965    case S390_INSN_VEC_BINOP:
966       addHRegUse(u, HRmWrite, insn->variant.vec_binop.dst);
967       addHRegUse(u, HRmRead, insn->variant.vec_binop.op1);
968       addHRegUse(u, HRmRead, insn->variant.vec_binop.op2);
969       break;
970 
971    case S390_INSN_VEC_TRIOP:
972       addHRegUse(u, HRmWrite, insn->variant.vec_triop.dst);
973       addHRegUse(u, HRmRead, insn->variant.vec_triop.op1);
974       addHRegUse(u, HRmRead, insn->variant.vec_triop.op2);
975       addHRegUse(u, HRmRead, insn->variant.vec_triop.op3);
976       break;
977 
978    default:
979       vpanic("s390_insn_get_reg_usage");
980    }
981 }
982 
983 
984 /* Helper function for s390_insn_map_regs */
985 static void
s390_opnd_RMI_map_regs(HRegRemap * m,s390_opnd_RMI * op)986 s390_opnd_RMI_map_regs(HRegRemap *m, s390_opnd_RMI *op)
987 {
988    switch (op->tag) {
989    case S390_OPND_REG:
990       op->variant.reg = lookupHRegRemap(m, op->variant.reg);
991       break;
992 
993    case S390_OPND_IMMEDIATE:
994       break;
995 
996    case S390_OPND_AMODE:
997       s390_amode_map_regs(m, op->variant.am);
998       break;
999 
1000    default:
1001       vpanic("s390_opnd_RMI_map_regs");
1002    }
1003 }
1004 
1005 
1006 static void
s390_insn_map_regs(HRegRemap * m,s390_insn * insn)1007 s390_insn_map_regs(HRegRemap *m, s390_insn *insn)
1008 {
1009    switch (insn->tag) {
1010    case S390_INSN_LOAD:
1011       insn->variant.load.dst = lookupHRegRemap(m, insn->variant.load.dst);
1012       s390_amode_map_regs(m, insn->variant.load.src);
1013       break;
1014 
1015    case S390_INSN_STORE:
1016       s390_amode_map_regs(m, insn->variant.store.dst);
1017       insn->variant.store.src = lookupHRegRemap(m, insn->variant.store.src);
1018       break;
1019 
1020    case S390_INSN_MOVE:
1021       insn->variant.move.dst = lookupHRegRemap(m, insn->variant.move.dst);
1022       insn->variant.move.src = lookupHRegRemap(m, insn->variant.move.src);
1023       break;
1024 
1025    case S390_INSN_MEMCPY:
1026       s390_amode_map_regs(m, insn->variant.memcpy.dst);
1027       s390_amode_map_regs(m, insn->variant.memcpy.src);
1028       break;
1029 
1030    case S390_INSN_COND_MOVE:
1031       insn->variant.cond_move.dst = lookupHRegRemap(m, insn->variant.cond_move.dst);
1032       s390_opnd_RMI_map_regs(m, &insn->variant.cond_move.src);
1033       break;
1034 
1035    case S390_INSN_LOAD_IMMEDIATE:
1036       insn->variant.load_immediate.dst =
1037          lookupHRegRemap(m, insn->variant.load_immediate.dst);
1038       break;
1039 
1040    case S390_INSN_ALU:
1041       insn->variant.alu.dst = lookupHRegRemap(m, insn->variant.alu.dst);
1042       s390_opnd_RMI_map_regs(m, &insn->variant.alu.op2);
1043       break;
1044 
1045    case S390_INSN_SMUL:
1046    case S390_INSN_UMUL:
1047       insn->variant.mul.dst_hi = lookupHRegRemap(m, insn->variant.mul.dst_hi);
1048       insn->variant.mul.dst_lo = lookupHRegRemap(m, insn->variant.mul.dst_lo);
1049       s390_opnd_RMI_map_regs(m, &insn->variant.mul.op2);
1050       break;
1051 
1052    case S390_INSN_SDIV:
1053    case S390_INSN_UDIV:
1054       insn->variant.div.op1_hi = lookupHRegRemap(m, insn->variant.div.op1_hi);
1055       insn->variant.div.op1_lo = lookupHRegRemap(m, insn->variant.div.op1_lo);
1056       s390_opnd_RMI_map_regs(m, &insn->variant.div.op2);
1057       break;
1058 
1059    case S390_INSN_DIVS:
1060       insn->variant.divs.op1 = lookupHRegRemap(m, insn->variant.divs.op1);
1061       insn->variant.divs.rem = lookupHRegRemap(m, insn->variant.divs.rem);
1062       s390_opnd_RMI_map_regs(m, &insn->variant.divs.op2);
1063       break;
1064 
1065    case S390_INSN_CLZ:
1066       insn->variant.clz.num_bits = lookupHRegRemap(m, insn->variant.clz.num_bits);
1067       insn->variant.clz.clobber  = lookupHRegRemap(m, insn->variant.clz.clobber);
1068       s390_opnd_RMI_map_regs(m, &insn->variant.clz.src);
1069       break;
1070 
1071    case S390_INSN_UNOP:
1072       insn->variant.unop.dst = lookupHRegRemap(m, insn->variant.unop.dst);
1073       s390_opnd_RMI_map_regs(m, &insn->variant.unop.src);
1074       break;
1075 
1076    case S390_INSN_TEST:
1077       s390_opnd_RMI_map_regs(m, &insn->variant.test.src);
1078       break;
1079 
1080    case S390_INSN_CC2BOOL:
1081       insn->variant.cc2bool.dst = lookupHRegRemap(m, insn->variant.cc2bool.dst);
1082       break;
1083 
1084    case S390_INSN_CAS:
1085       insn->variant.cas.op1 = lookupHRegRemap(m, insn->variant.cas.op1);
1086       s390_amode_map_regs(m, insn->variant.cas.op2);
1087       insn->variant.cas.op3 = lookupHRegRemap(m, insn->variant.cas.op3);
1088       insn->variant.cas.old_mem = lookupHRegRemap(m, insn->variant.cas.old_mem);
1089       break;
1090 
1091    case S390_INSN_CDAS: {
1092       s390_cdas *cdas = insn->variant.cdas.details;
1093 
1094       cdas->op1_high = lookupHRegRemap(m, cdas->op1_high);
1095       cdas->op1_low  = lookupHRegRemap(m, cdas->op1_low);
1096       s390_amode_map_regs(m, cdas->op2);
1097       cdas->op3_high = lookupHRegRemap(m, cdas->op3_high);
1098       cdas->op3_low  = lookupHRegRemap(m, cdas->op3_low);
1099       cdas->old_mem_high = lookupHRegRemap(m, cdas->old_mem_high);
1100       cdas->old_mem_low  = lookupHRegRemap(m, cdas->old_mem_low);
1101       cdas->scratch  = lookupHRegRemap(m, cdas->scratch);
1102       break;
1103    }
1104 
1105    case S390_INSN_COMPARE:
1106       insn->variant.compare.src1 = lookupHRegRemap(m, insn->variant.compare.src1);
1107       s390_opnd_RMI_map_regs(m, &insn->variant.compare.src2);
1108       break;
1109 
1110    case S390_INSN_HELPER_CALL:
1111       /* s390_insn_helper_call_emit also reads / writes the link register
1112          and stack pointer. But those registers are not visible to the
1113          register allocator. So we don't need to do anything for them.
1114          As for the arguments of the helper call -- they will be loaded into
1115          non-virtual registers. Again, we don't need to do anything for those
1116          here. */
1117       break;
1118 
1119    case S390_INSN_BFP_TRIOP:
1120       insn->variant.bfp_triop.dst =
1121          lookupHRegRemap(m, insn->variant.bfp_triop.dst);
1122       insn->variant.bfp_triop.op2 =
1123          lookupHRegRemap(m, insn->variant.bfp_triop.op2);
1124       insn->variant.bfp_triop.op3 =
1125          lookupHRegRemap(m, insn->variant.bfp_triop.op3);
1126       break;
1127 
1128    case S390_INSN_BFP_BINOP:
1129       insn->variant.bfp_binop.dst_hi =
1130          lookupHRegRemap(m, insn->variant.bfp_binop.dst_hi);
1131       insn->variant.bfp_binop.op2_hi =
1132          lookupHRegRemap(m, insn->variant.bfp_binop.op2_hi);
1133       if (insn->size == 16) {
1134          insn->variant.bfp_binop.dst_lo =
1135             lookupHRegRemap(m, insn->variant.bfp_binop.dst_lo);
1136          insn->variant.bfp_binop.op2_lo  =
1137             lookupHRegRemap(m, insn->variant.bfp_binop.op2_lo);
1138       }
1139       break;
1140 
1141    case S390_INSN_BFP_UNOP:
1142       insn->variant.bfp_unop.dst_hi =
1143          lookupHRegRemap(m, insn->variant.bfp_unop.dst_hi);
1144       insn->variant.bfp_unop.op_hi  =
1145          lookupHRegRemap(m, insn->variant.bfp_unop.op_hi);
1146       if (insn->size == 16) {
1147          insn->variant.bfp_unop.dst_lo =
1148             lookupHRegRemap(m, insn->variant.bfp_unop.dst_lo);
1149          insn->variant.bfp_unop.op_lo  =
1150             lookupHRegRemap(m, insn->variant.bfp_unop.op_lo);
1151       }
1152       break;
1153 
1154    case S390_INSN_BFP_COMPARE:
1155       insn->variant.bfp_compare.dst =
1156          lookupHRegRemap(m, insn->variant.bfp_compare.dst);
1157       insn->variant.bfp_compare.op1_hi =
1158          lookupHRegRemap(m, insn->variant.bfp_compare.op1_hi);
1159       insn->variant.bfp_compare.op2_hi =
1160          lookupHRegRemap(m, insn->variant.bfp_compare.op2_hi);
1161       if (insn->size == 16) {
1162          insn->variant.bfp_compare.op1_lo =
1163             lookupHRegRemap(m, insn->variant.bfp_compare.op1_lo);
1164          insn->variant.bfp_compare.op2_lo =
1165             lookupHRegRemap(m, insn->variant.bfp_compare.op2_lo);
1166       }
1167       break;
1168 
1169    case S390_INSN_BFP_CONVERT:
1170       insn->variant.bfp_convert.dst_hi =
1171          lookupHRegRemap(m, insn->variant.bfp_convert.dst_hi);
1172       if (! hregIsInvalid(insn->variant.bfp_convert.dst_lo))
1173          insn->variant.bfp_convert.dst_lo =
1174             lookupHRegRemap(m, insn->variant.bfp_convert.dst_lo);
1175       insn->variant.bfp_convert.op_hi =
1176          lookupHRegRemap(m, insn->variant.bfp_convert.op_hi);
1177       if (! hregIsInvalid(insn->variant.bfp_convert.op_lo))
1178          insn->variant.bfp_convert.op_lo =
1179             lookupHRegRemap(m, insn->variant.bfp_convert.op_lo);
1180       break;
1181 
1182    case S390_INSN_DFP_BINOP: {
1183       s390_dfp_binop *dfp_binop = insn->variant.dfp_binop.details;
1184 
1185       dfp_binop->dst_hi = lookupHRegRemap(m, dfp_binop->dst_hi);
1186       dfp_binop->op2_hi = lookupHRegRemap(m, dfp_binop->op2_hi);
1187       dfp_binop->op3_hi = lookupHRegRemap(m, dfp_binop->op3_hi);
1188       if (insn->size == 16) {
1189          dfp_binop->dst_lo = lookupHRegRemap(m, dfp_binop->dst_lo);
1190          dfp_binop->op2_lo = lookupHRegRemap(m, dfp_binop->op2_lo);
1191          dfp_binop->op3_lo = lookupHRegRemap(m, dfp_binop->op3_lo);
1192       }
1193       break;
1194    }
1195 
1196    case S390_INSN_DFP_UNOP:
1197       insn->variant.dfp_unop.dst_hi =
1198          lookupHRegRemap(m, insn->variant.dfp_unop.dst_hi);
1199       insn->variant.dfp_unop.op_hi  =
1200          lookupHRegRemap(m, insn->variant.dfp_unop.op_hi);
1201       if (insn->size == 16) {
1202          insn->variant.dfp_unop.dst_lo =
1203             lookupHRegRemap(m, insn->variant.dfp_unop.dst_lo);
1204          insn->variant.dfp_unop.op_lo  =
1205             lookupHRegRemap(m, insn->variant.dfp_unop.op_lo);
1206       }
1207       break;
1208 
1209    case S390_INSN_DFP_INTOP:
1210       insn->variant.dfp_intop.dst_hi =
1211          lookupHRegRemap(m, insn->variant.dfp_intop.dst_hi);
1212       insn->variant.dfp_intop.op2    =
1213          lookupHRegRemap(m, insn->variant.dfp_intop.op2);
1214       insn->variant.dfp_intop.op3_hi =
1215          lookupHRegRemap(m, insn->variant.dfp_intop.op3_hi);
1216       if (insn->size == 16) {
1217          insn->variant.dfp_intop.dst_lo =
1218             lookupHRegRemap(m, insn->variant.dfp_intop.dst_lo);
1219          insn->variant.dfp_intop.op3_lo =
1220             lookupHRegRemap(m, insn->variant.dfp_intop.op3_lo);
1221       }
1222       break;
1223 
1224    case S390_INSN_DFP_COMPARE:
1225       insn->variant.dfp_compare.dst =
1226          lookupHRegRemap(m, insn->variant.dfp_compare.dst);
1227       insn->variant.dfp_compare.op1_hi =
1228          lookupHRegRemap(m, insn->variant.dfp_compare.op1_hi);
1229       insn->variant.dfp_compare.op2_hi =
1230          lookupHRegRemap(m, insn->variant.dfp_compare.op2_hi);
1231       if (insn->size == 16) {
1232          insn->variant.dfp_compare.op1_lo =
1233             lookupHRegRemap(m, insn->variant.dfp_compare.op1_lo);
1234          insn->variant.dfp_compare.op2_lo =
1235             lookupHRegRemap(m, insn->variant.dfp_compare.op2_lo);
1236       }
1237       break;
1238 
1239    case S390_INSN_DFP_CONVERT:
1240       insn->variant.dfp_convert.dst_hi =
1241          lookupHRegRemap(m, insn->variant.dfp_convert.dst_hi);
1242       if (! hregIsInvalid(insn->variant.dfp_convert.dst_lo))
1243          insn->variant.dfp_convert.dst_lo =
1244             lookupHRegRemap(m, insn->variant.dfp_convert.dst_lo);
1245       insn->variant.dfp_convert.op_hi =
1246          lookupHRegRemap(m, insn->variant.dfp_convert.op_hi);
1247       if (! hregIsInvalid(insn->variant.dfp_convert.op_lo))
1248          insn->variant.dfp_convert.op_lo =
1249             lookupHRegRemap(m, insn->variant.dfp_convert.op_lo);
1250       break;
1251 
1252    case S390_INSN_DFP_REROUND:
1253       insn->variant.dfp_reround.dst_hi =
1254          lookupHRegRemap(m, insn->variant.dfp_reround.dst_hi);
1255       insn->variant.dfp_reround.op2    =
1256          lookupHRegRemap(m, insn->variant.dfp_reround.op2);
1257       insn->variant.dfp_reround.op3_hi =
1258          lookupHRegRemap(m, insn->variant.dfp_reround.op3_hi);
1259       if (insn->size == 16) {
1260          insn->variant.dfp_reround.dst_lo =
1261             lookupHRegRemap(m, insn->variant.dfp_reround.dst_lo);
1262          insn->variant.dfp_reround.op3_lo =
1263             lookupHRegRemap(m, insn->variant.dfp_reround.op3_lo);
1264       }
1265       break;
1266 
1267    case S390_INSN_FP_CONVERT: {
1268       s390_fp_convert *fp_convert = insn->variant.fp_convert.details;
1269 
1270       fp_convert->dst_hi = lookupHRegRemap(m, fp_convert->dst_hi);
1271       if (! hregIsInvalid(fp_convert->dst_lo))
1272          fp_convert->dst_lo = lookupHRegRemap(m, fp_convert->dst_lo);
1273       fp_convert->op_hi = lookupHRegRemap(m, fp_convert->op_hi);
1274       if (! hregIsInvalid(fp_convert->op_lo))
1275          fp_convert->op_lo = lookupHRegRemap(m, fp_convert->op_lo);
1276       fp_convert->r1 = lookupHRegRemap(m, fp_convert->r1);
1277       break;
1278    }
1279 
1280    case S390_INSN_MIMM:
1281       s390_amode_map_regs(m, insn->variant.mimm.dst);
1282       break;
1283 
1284    case S390_INSN_MADD:
1285       s390_amode_map_regs(m, insn->variant.madd.dst);
1286       break;
1287 
1288    case S390_INSN_MFENCE:
1289       break;
1290 
1291    case S390_INSN_SET_FPC_BFPRM:
1292       insn->variant.set_fpc_bfprm.mode =
1293          lookupHRegRemap(m, insn->variant.set_fpc_bfprm.mode);
1294       break;
1295 
1296    case S390_INSN_SET_FPC_DFPRM:
1297       insn->variant.set_fpc_dfprm.mode =
1298          lookupHRegRemap(m, insn->variant.set_fpc_dfprm.mode);
1299       break;
1300 
1301    case S390_INSN_EVCHECK:
1302       s390_amode_map_regs(m, insn->variant.evcheck.counter);
1303       s390_amode_map_regs(m, insn->variant.evcheck.fail_addr);
1304       break;
1305 
1306    case S390_INSN_PROFINC:
1307       /* Does not use any register visible to the register allocator */
1308       break;
1309 
1310    case S390_INSN_XDIRECT:
1311       s390_amode_map_regs(m, insn->variant.xdirect.guest_IA);
1312       break;
1313 
1314    case S390_INSN_XINDIR:
1315       s390_amode_map_regs(m, insn->variant.xindir.guest_IA);
1316       insn->variant.xindir.dst =
1317          lookupHRegRemap(m, insn->variant.xindir.dst);
1318       break;
1319 
1320    case S390_INSN_XASSISTED:
1321       s390_amode_map_regs(m, insn->variant.xassisted.guest_IA);
1322       insn->variant.xassisted.dst =
1323          lookupHRegRemap(m, insn->variant.xassisted.dst);
1324       break;
1325 
1326    case S390_INSN_VEC_AMODEOP:
1327       insn->variant.vec_amodeop.dst =
1328          lookupHRegRemap(m, insn->variant.vec_amodeop.dst);
1329       insn->variant.vec_amodeop.op1 =
1330          lookupHRegRemap(m, insn->variant.vec_amodeop.op1);
1331       s390_amode_map_regs(m, insn->variant.vec_amodeop.op2);
1332       break;
1333 
1334    case S390_INSN_VEC_AMODEINTOP:
1335       insn->variant.vec_amodeintop.dst =
1336          lookupHRegRemap(m, insn->variant.vec_amodeintop.dst);
1337       s390_amode_map_regs(m, insn->variant.vec_amodeintop.op2);
1338       insn->variant.vec_amodeintop.op3 =
1339          lookupHRegRemap(m, insn->variant.vec_amodeintop.op3);
1340       break;
1341 
1342    case S390_INSN_VEC_BINOP:
1343       insn->variant.vec_binop.dst =
1344          lookupHRegRemap(m, insn->variant.vec_binop.dst);
1345       insn->variant.vec_binop.op1 =
1346          lookupHRegRemap(m, insn->variant.vec_binop.op1);
1347       insn->variant.vec_binop.op2 =
1348          lookupHRegRemap(m, insn->variant.vec_binop.op2);
1349       break;
1350 
1351    case S390_INSN_VEC_TRIOP:
1352       insn->variant.vec_triop.dst =
1353          lookupHRegRemap(m, insn->variant.vec_triop.dst);
1354       insn->variant.vec_triop.op1 =
1355          lookupHRegRemap(m, insn->variant.vec_triop.op1);
1356       insn->variant.vec_triop.op2 =
1357          lookupHRegRemap(m, insn->variant.vec_triop.op2);
1358       insn->variant.vec_triop.op3 =
1359          lookupHRegRemap(m, insn->variant.vec_triop.op3);
1360       break;
1361    default:
1362       vpanic("s390_insn_map_regs");
1363    }
1364 }
1365 
1366 
1367 /*------------------------------------------------------------*/
1368 /*--- Functions to emit a sequence of bytes                ---*/
1369 /*------------------------------------------------------------*/
1370 
1371 static __inline__ UChar *
emit_2bytes(UChar * p,ULong val)1372 emit_2bytes(UChar *p, ULong val)
1373 {
1374    return (UChar *)__builtin_memcpy(p, ((UChar *)&val) + 6, 2) + 2;
1375 }
1376 
1377 
1378 static __inline__ UChar *
emit_4bytes(UChar * p,ULong val)1379 emit_4bytes(UChar *p, ULong val)
1380 {
1381    return (UChar *)__builtin_memcpy(p, ((UChar *)&val) + 4, 4) + 4;
1382 }
1383 
1384 
1385 static __inline__ UChar *
emit_6bytes(UChar * p,ULong val)1386 emit_6bytes(UChar *p, ULong val)
1387 {
1388    return (UChar *)__builtin_memcpy(p, ((UChar *)&val) + 2, 6) + 6;
1389 }
1390 
1391 
1392 /*------------------------------------------------------------*/
1393 /*--- Functions to emit various instruction formats        ---*/
1394 /*------------------------------------------------------------*/
1395 
1396 static UChar *
emit_RI(UChar * p,UInt op,UChar r1,UShort i2)1397 emit_RI(UChar *p, UInt op, UChar r1, UShort i2)
1398 {
1399    ULong the_insn = op;
1400 
1401    the_insn |= ((ULong)r1) << 20;
1402    the_insn |= ((ULong)i2) << 0;
1403 
1404    return emit_4bytes(p, the_insn);
1405 }
1406 
1407 
1408 static UChar *
emit_RIL(UChar * p,ULong op,UChar r1,UInt i2)1409 emit_RIL(UChar *p, ULong op, UChar r1, UInt i2)
1410 {
1411    ULong the_insn = op;
1412 
1413    the_insn |= ((ULong)r1) << 36;
1414    the_insn |= ((ULong)i2) << 0;
1415 
1416    return emit_6bytes(p, the_insn);
1417 }
1418 
1419 
1420 static UChar *
emit_RR(UChar * p,UInt op,UChar r1,UChar r2)1421 emit_RR(UChar *p, UInt op, UChar r1, UChar r2)
1422 {
1423    ULong the_insn = op;
1424 
1425    the_insn |= ((ULong)r1) << 4;
1426    the_insn |= ((ULong)r2) << 0;
1427 
1428    return emit_2bytes(p, the_insn);
1429 }
1430 
1431 
1432 static UChar *
emit_RRE(UChar * p,UInt op,UChar r1,UChar r2)1433 emit_RRE(UChar *p, UInt op, UChar r1, UChar r2)
1434 {
1435    ULong the_insn = op;
1436 
1437    the_insn |= ((ULong)r1) << 4;
1438    the_insn |= ((ULong)r2) << 0;
1439 
1440    return emit_4bytes(p, the_insn);
1441 }
1442 
1443 
1444 static UChar *
emit_RRF(UChar * p,UInt op,UChar r1,UChar r3,UChar r2)1445 emit_RRF(UChar *p, UInt op, UChar r1, UChar r3, UChar r2)
1446 {
1447    ULong the_insn = op;
1448 
1449    the_insn |= ((ULong)r1) << 12;
1450    the_insn |= ((ULong)r3) << 4;
1451    the_insn |= ((ULong)r2) << 0;
1452 
1453    return emit_4bytes(p, the_insn);
1454 }
1455 
1456 
1457 static UChar *
emit_RRF2(UChar * p,UInt op,UChar m3,UChar m4,UChar r1,UChar r2)1458 emit_RRF2(UChar *p, UInt op, UChar m3, UChar m4, UChar r1, UChar r2)
1459 {
1460    ULong the_insn = op;
1461 
1462    the_insn |= ((ULong)m3) << 12;
1463    the_insn |= ((ULong)m4) << 8;
1464    the_insn |= ((ULong)r1) << 4;
1465    the_insn |= ((ULong)r2) << 0;
1466 
1467    return emit_4bytes(p, the_insn);
1468 }
1469 
1470 
1471 static UChar *
emit_RRF3(UChar * p,UInt op,UChar r3,UChar r1,UChar r2)1472 emit_RRF3(UChar *p, UInt op, UChar r3, UChar r1, UChar r2)
1473 {
1474    ULong the_insn = op;
1475 
1476    the_insn |= ((ULong)r3) << 12;
1477    the_insn |= ((ULong)r1) << 4;
1478    the_insn |= ((ULong)r2) << 0;
1479 
1480    return emit_4bytes(p, the_insn);
1481 }
1482 
1483 
1484 static UChar *
emit_RRF4(UChar * p,UInt op,UChar r3,UChar m4,UChar r1,UChar r2)1485 emit_RRF4(UChar *p, UInt op, UChar r3, UChar m4, UChar r1, UChar r2)
1486 {
1487    ULong the_insn = op;
1488 
1489    the_insn |= ((ULong)r3) << 12;
1490    the_insn |= ((ULong)m4) << 8;
1491    the_insn |= ((ULong)r1) << 4;
1492    the_insn |= ((ULong)r2) << 0;
1493 
1494    return emit_4bytes(p, the_insn);
1495 }
1496 
1497 
1498 static UChar *
emit_RRF5(UChar * p,UInt op,UChar m4,UChar r1,UChar r2)1499 emit_RRF5(UChar *p, UInt op, UChar m4, UChar r1, UChar r2)
1500 {
1501    ULong the_insn = op;
1502 
1503    the_insn |= ((ULong)m4) << 8;
1504    the_insn |= ((ULong)r1) << 4;
1505    the_insn |= ((ULong)r2) << 0;
1506 
1507    return emit_4bytes(p, the_insn);
1508 }
1509 
1510 
1511 static UChar *
emit_RS(UChar * p,UInt op,UChar r1,UChar r3,UChar b2,UShort d2)1512 emit_RS(UChar *p, UInt op, UChar r1, UChar r3, UChar b2, UShort d2)
1513 {
1514    ULong the_insn = op;
1515 
1516    the_insn |= ((ULong)r1) << 20;
1517    the_insn |= ((ULong)r3) << 16;
1518    the_insn |= ((ULong)b2) << 12;
1519    the_insn |= ((ULong)d2) << 0;
1520 
1521    return emit_4bytes(p, the_insn);
1522 }
1523 
1524 
1525 static UChar *
emit_RSY(UChar * p,ULong op,UChar r1,UChar r3,UChar b2,UShort dl2,UChar dh2)1526 emit_RSY(UChar *p, ULong op, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1527 {
1528    ULong the_insn = op;
1529 
1530    the_insn |= ((ULong)r1) << 36;
1531    the_insn |= ((ULong)r3) << 32;
1532    the_insn |= ((ULong)b2) << 28;
1533    the_insn |= ((ULong)dl2) << 16;
1534    the_insn |= ((ULong)dh2) << 8;
1535 
1536    return emit_6bytes(p, the_insn);
1537 }
1538 
1539 
1540 static UChar *
emit_RX(UChar * p,UInt op,UChar r1,UChar x2,UChar b2,UShort d2)1541 emit_RX(UChar *p, UInt op, UChar r1, UChar x2, UChar b2, UShort d2)
1542 {
1543    ULong the_insn = op;
1544 
1545    the_insn |= ((ULong)r1) << 20;
1546    the_insn |= ((ULong)x2) << 16;
1547    the_insn |= ((ULong)b2) << 12;
1548    the_insn |= ((ULong)d2) << 0;
1549 
1550    return emit_4bytes(p, the_insn);
1551 }
1552 
1553 
1554 static UChar *
emit_RXF(UChar * p,ULong op,UChar r3,UChar x2,UChar b2,UShort d2,UChar r1)1555 emit_RXF(UChar *p, ULong op, UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
1556 {
1557    ULong the_insn = op;
1558 
1559    the_insn |= ((ULong)r3) << 36;
1560    the_insn |= ((ULong)x2) << 32;
1561    the_insn |= ((ULong)b2) << 28;
1562    the_insn |= ((ULong)d2) << 16;
1563    the_insn |= ((ULong)r1) << 12;
1564 
1565    return emit_6bytes(p, the_insn);
1566 }
1567 
1568 
1569 static UChar *
emit_RXY(UChar * p,ULong op,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)1570 emit_RXY(UChar *p, ULong op, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
1571 {
1572    ULong the_insn = op;
1573 
1574    the_insn |= ((ULong)r1) << 36;
1575    the_insn |= ((ULong)x2) << 32;
1576    the_insn |= ((ULong)b2) << 28;
1577    the_insn |= ((ULong)dl2) << 16;
1578    the_insn |= ((ULong)dh2) << 8;
1579 
1580    return emit_6bytes(p, the_insn);
1581 }
1582 
1583 
1584 static UChar *
emit_S(UChar * p,UInt op,UChar b2,UShort d2)1585 emit_S(UChar *p, UInt op, UChar b2, UShort d2)
1586 {
1587    ULong the_insn = op;
1588 
1589    the_insn |= ((ULong)b2) << 12;
1590    the_insn |= ((ULong)d2) << 0;
1591 
1592    return emit_4bytes(p, the_insn);
1593 }
1594 
1595 
1596 static UChar *
emit_SI(UChar * p,UInt op,UChar i2,UChar b1,UShort d1)1597 emit_SI(UChar *p, UInt op, UChar i2, UChar b1, UShort d1)
1598 {
1599    ULong the_insn = op;
1600 
1601    the_insn |= ((ULong)i2) << 16;
1602    the_insn |= ((ULong)b1) << 12;
1603    the_insn |= ((ULong)d1) << 0;
1604 
1605    return emit_4bytes(p, the_insn);
1606 }
1607 
1608 
1609 static UChar *
emit_SIL(UChar * p,ULong op,UChar b1,UShort d1,UShort i2)1610 emit_SIL(UChar *p, ULong op, UChar b1, UShort d1, UShort i2)
1611 {
1612    ULong the_insn = op;
1613 
1614    the_insn |= ((ULong)b1) << 28;
1615    the_insn |= ((ULong)d1) << 16;
1616    the_insn |= ((ULong)i2) << 0;
1617 
1618    return emit_6bytes(p, the_insn);
1619 }
1620 
1621 
1622 static UChar *
emit_SIY(UChar * p,ULong op,UChar i2,UChar b1,UShort dl1,UChar dh1)1623 emit_SIY(UChar *p, ULong op, UChar i2, UChar b1, UShort dl1, UChar dh1)
1624 {
1625    ULong the_insn = op;
1626 
1627    the_insn |= ((ULong)i2) << 32;
1628    the_insn |= ((ULong)b1) << 28;
1629    the_insn |= ((ULong)dl1) << 16;
1630    the_insn |= ((ULong)dh1) << 8;
1631 
1632    return emit_6bytes(p, the_insn);
1633 }
1634 
1635 
1636 static UChar *
emit_SSa(UChar * p,ULong op,UChar l,UChar b1,UShort d1,UChar b2,UShort d2)1637 emit_SSa(UChar *p, ULong op, UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
1638 {
1639    ULong the_insn = op;
1640 
1641    the_insn |= ((ULong)l)  << 32;
1642    the_insn |= ((ULong)b1) << 28;
1643    the_insn |= ((ULong)d1) << 16;
1644    the_insn |= ((ULong)b2) << 12;
1645    the_insn |= ((ULong)d2) << 0;
1646 
1647    return emit_6bytes(p, the_insn);
1648 }
1649 
1650 
1651 static UChar *
emit_VRI_VI(UChar * p,ULong op,UChar v1,UShort i2)1652 emit_VRI_VI(UChar *p, ULong op, UChar v1, UShort i2)
1653 {
1654    ULong the_insn = op;
1655    ULong rxb = s390_update_rxb(0, 1, &v1);
1656 
1657    the_insn |= ((ULong)v1) << 36;
1658    the_insn |= ((ULong)i2) << 16;
1659    the_insn |= ((ULong)rxb)<< 8;
1660 
1661    return emit_6bytes(p, the_insn);
1662 }
1663 
1664 
1665 static UChar *
emit_VRX(UChar * p,ULong op,UChar v1,UChar x2,UChar b2,UShort d2)1666 emit_VRX(UChar *p, ULong op, UChar v1, UChar x2, UChar b2, UShort d2)
1667 {
1668    ULong the_insn = op;
1669    ULong rxb = s390_update_rxb(0, 1, &v1);
1670 
1671    the_insn |= ((ULong)v1) << 36;
1672    the_insn |= ((ULong)x2) << 32;
1673    the_insn |= ((ULong)b2) << 28;
1674    the_insn |= ((ULong)d2) << 16;
1675    the_insn |= ((ULong)rxb)<< 8;
1676 
1677    return emit_6bytes(p, the_insn);
1678 }
1679 
1680 
1681 static UChar *
emit_VRS(UChar * p,ULong op,UChar reg1,UChar b2,UShort d2,UChar reg3,UChar m4)1682 emit_VRS(UChar *p, ULong op, UChar reg1, UChar b2, UShort d2, UChar reg3, UChar m4)
1683 {
1684    ULong the_insn = op;
1685    ULong rxb = s390_update_rxb(0, 1, &reg1);
1686    rxb = s390_update_rxb(rxb, 2, &reg3);
1687 
1688    the_insn |= ((ULong)reg1) << 36;
1689    the_insn |= ((ULong)reg3) << 32;
1690    the_insn |= ((ULong)b2)   << 28;
1691    the_insn |= ((ULong)d2)   << 16;
1692    the_insn |= ((ULong)m4)   << 12;
1693    the_insn |= ((ULong)rxb)  << 8;
1694 
1695    return emit_6bytes(p, the_insn);
1696 }
1697 
1698 
1699 static UChar *
emit_VRR_VVM(UChar * p,ULong op,UChar v1,UChar v2,UChar m4)1700 emit_VRR_VVM(UChar *p, ULong op, UChar v1, UChar v2, UChar m4)
1701 {
1702    ULong the_insn = op;
1703    ULong rxb = s390_update_rxb(0, 1, &v1);
1704    rxb = s390_update_rxb(rxb, 2, &v2);
1705 
1706    the_insn |= ((ULong)v1) << 36;
1707    the_insn |= ((ULong)v2) << 32;
1708    the_insn |= ((ULong)m4) << 12;
1709    the_insn |= ((ULong)rxb)<< 8;
1710 
1711    return emit_6bytes(p, the_insn);
1712 }
1713 
1714 static UChar *
emit_VRR_VVMMM(UChar * p,ULong op,UChar v1,UChar v2,UChar m3,UChar m4,UChar m5)1715 emit_VRR_VVMMM(UChar *p, ULong op, UChar v1, UChar v2, UChar m3, UChar m4,
1716                UChar m5)
1717 {
1718    ULong the_insn = op;
1719    ULong rxb = s390_update_rxb(0, 1, &v1);
1720    rxb = s390_update_rxb(rxb, 2, &v2);
1721 
1722    the_insn |= ((ULong)v1) << 36;
1723    the_insn |= ((ULong)v2) << 32;
1724    the_insn |= ((ULong)m5) << 20;
1725    the_insn |= ((ULong)m4) << 16;
1726    the_insn |= ((ULong)m3) << 12;
1727    the_insn |= ((ULong)rxb) << 8;
1728 
1729    return emit_6bytes(p, the_insn);
1730 }
1731 
1732 static UChar *
emit_VRR_VVVM(UChar * p,ULong op,UChar v1,UChar v2,UChar v3,UChar m4)1733 emit_VRR_VVVM(UChar *p, ULong op, UChar v1, UChar v2, UChar v3, UChar m4)
1734 {
1735    ULong the_insn = op;
1736    ULong rxb = s390_update_rxb(0, 1, &v1);
1737    rxb = s390_update_rxb(rxb, 2, &v2);
1738    rxb = s390_update_rxb(rxb, 3, &v3);
1739 
1740    the_insn |= ((ULong)v1) << 36;
1741    the_insn |= ((ULong)v2) << 32;
1742    the_insn |= ((ULong)v3) << 28;
1743    the_insn |= ((ULong)m4) << 12;
1744    the_insn |= ((ULong)rxb)<< 8;
1745 
1746    return emit_6bytes(p, the_insn);
1747 }
1748 
1749 
1750 static UChar *
emit_VRR_VVV(UChar * p,ULong op,UChar v1,UChar v2,UChar v3)1751 emit_VRR_VVV(UChar *p, ULong op, UChar v1, UChar v2, UChar v3)
1752 {
1753    return emit_VRR_VVVM(p, op, v1, v2, v3, 0);
1754 }
1755 
1756 
1757 static UChar *
emit_VRR_VV(UChar * p,ULong op,UChar v1,UChar v2)1758 emit_VRR_VV(UChar *p, ULong op, UChar v1, UChar v2)
1759 {
1760    return emit_VRR_VVM(p, op, v1, v2, 0);
1761 }
1762 
1763 
1764 static UChar *
emit_VRR_VVVV(UChar * p,ULong op,UChar v1,UChar v2,UChar v3,UChar v4)1765 emit_VRR_VVVV(UChar *p, ULong op, UChar v1, UChar v2, UChar v3, UChar v4)
1766 {
1767    ULong the_insn = op;
1768    ULong rxb = s390_update_rxb(0, 1, &v1);
1769    rxb = s390_update_rxb(rxb, 2, &v2);
1770    rxb = s390_update_rxb(rxb, 3, &v3);
1771    rxb = s390_update_rxb(rxb, 4, &v4);
1772 
1773    the_insn |= ((ULong)v1) << 36;
1774    the_insn |= ((ULong)v2) << 32;
1775    the_insn |= ((ULong)v3) << 28;
1776    the_insn |= ((ULong)v4) << 12;
1777    the_insn |= ((ULong)rxb)<< 8;
1778 
1779    return emit_6bytes(p, the_insn);
1780 }
1781 
1782 static UChar *
emit_VRRe_VVVVMM(UChar * p,ULong op,UChar v1,UChar v2,UChar v3,UChar v4,UChar m5,UChar m6)1783 emit_VRRe_VVVVMM(UChar *p, ULong op, UChar v1, UChar v2, UChar v3, UChar v4,
1784                  UChar m5, UChar m6)
1785 {
1786    ULong the_insn = op;
1787    ULong rxb = s390_update_rxb(0, 1, &v1);
1788    rxb = s390_update_rxb(rxb, 2, &v2);
1789    rxb = s390_update_rxb(rxb, 3, &v3);
1790    rxb = s390_update_rxb(rxb, 4, &v4);
1791 
1792    the_insn |= ((ULong)v1) << 36;
1793    the_insn |= ((ULong)v2) << 32;
1794    the_insn |= ((ULong)v3) << 28;
1795    the_insn |= ((ULong)m6) << 24;
1796    the_insn |= ((ULong)m5) << 16;
1797    the_insn |= ((ULong)v4) << 12;
1798    the_insn |= ((ULong)rxb) << 8;
1799 
1800    return emit_6bytes(p, the_insn);
1801 }
1802 
1803 static UChar *
emit_VRR_VRR(UChar * p,ULong op,UChar v1,UChar r2,UChar r3)1804 emit_VRR_VRR(UChar *p, ULong op, UChar v1, UChar r2, UChar r3)
1805 {
1806    ULong the_insn = op;
1807    ULong rxb = s390_update_rxb(0, 1, &v1);
1808 
1809    the_insn |= ((ULong)v1) << 36;
1810    the_insn |= ((ULong)r2) << 32;
1811    the_insn |= ((ULong)r3) << 28;
1812    the_insn |= ((ULong)rxb)<< 8;
1813 
1814    return emit_6bytes(p, the_insn);
1815 }
1816 
1817 static UChar *
emit_VRR_VVVMMM(UChar * p,ULong op,UChar v1,UChar v2,UChar v3,UChar m4,UChar m5,UChar m6)1818 emit_VRR_VVVMMM(UChar *p, ULong op, UChar v1, UChar v2, UChar v3, UChar m4,
1819                 UChar m5, UChar m6)
1820 {
1821    ULong the_insn = op;
1822    ULong rxb = s390_update_rxb(0, 1, &v1);
1823    rxb = s390_update_rxb(rxb, 2, &v2);
1824    rxb = s390_update_rxb(rxb, 3, &v3);
1825 
1826    the_insn |= ((ULong)v1) << 36;
1827    the_insn |= ((ULong)v2) << 32;
1828    the_insn |= ((ULong)v3) << 28;
1829    the_insn |= ((ULong)m6) << 20;
1830    the_insn |= ((ULong)m5) << 16;
1831    the_insn |= ((ULong)m4) << 12;
1832    the_insn |= ((ULong)rxb) << 8;
1833 
1834    return emit_6bytes(p, the_insn);
1835 }
1836 
1837 static UChar*
emit_VRR_VVVMM(UChar * p,ULong op,UChar v1,UChar v2,UChar v3,UChar m4,UChar m5)1838 emit_VRR_VVVMM(UChar *p, ULong op, UChar v1, UChar v2, UChar v3, UChar m4,
1839                UChar m5)
1840 {
1841    return emit_VRR_VVVMMM(p, op, v1, v2, v3, m4, m5, 0);
1842 }
1843 
1844 /*------------------------------------------------------------*/
1845 /*--- Functions to emit particular instructions            ---*/
1846 /*------------------------------------------------------------*/
1847 
1848 static UChar *
s390_emit_AR(UChar * p,UChar r1,UChar r2)1849 s390_emit_AR(UChar *p, UChar r1, UChar r2)
1850 {
1851    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1852       s390_disasm(ENC3(MNM, GPR, GPR), "ar", r1, r2);
1853 
1854    return emit_RR(p, 0x1a00, r1, r2);
1855 }
1856 
1857 
1858 static UChar *
s390_emit_AGR(UChar * p,UChar r1,UChar r2)1859 s390_emit_AGR(UChar *p, UChar r1, UChar r2)
1860 {
1861    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1862       s390_disasm(ENC3(MNM, GPR, GPR), "agr", r1, r2);
1863 
1864    return emit_RRE(p, 0xb9080000, r1, r2);
1865 }
1866 
1867 
1868 static UChar *
s390_emit_A(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)1869 s390_emit_A(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
1870 {
1871    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1872       s390_disasm(ENC3(MNM, GPR, UDXB), "a", r1, d2, x2, b2);
1873 
1874    return emit_RX(p, 0x5a000000, r1, x2, b2, d2);
1875 }
1876 
1877 
1878 static UChar *
s390_emit_AY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)1879 s390_emit_AY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
1880 {
1881    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1882       s390_disasm(ENC3(MNM, GPR, SDXB), "ay", r1, dh2, dl2, x2, b2);
1883 
1884    return emit_RXY(p, 0xe3000000005aULL, r1, x2, b2, dl2, dh2);
1885 }
1886 
1887 
1888 static UChar *
s390_emit_AG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)1889 s390_emit_AG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
1890 {
1891    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1892       s390_disasm(ENC3(MNM, GPR, SDXB), "ag", r1, dh2, dl2, x2, b2);
1893 
1894    return emit_RXY(p, 0xe30000000008ULL, r1, x2, b2, dl2, dh2);
1895 }
1896 
1897 
1898 static UChar *
s390_emit_AFI(UChar * p,UChar r1,UInt i2)1899 s390_emit_AFI(UChar *p, UChar r1, UInt i2)
1900 {
1901    vassert(s390_host_has_eimm);
1902 
1903    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1904       s390_disasm(ENC3(MNM, GPR, INT), "afi", r1, i2);
1905 
1906    return emit_RIL(p, 0xc20900000000ULL, r1, i2);
1907 }
1908 
1909 
1910 static UChar *
s390_emit_AGFI(UChar * p,UChar r1,UInt i2)1911 s390_emit_AGFI(UChar *p, UChar r1, UInt i2)
1912 {
1913    vassert(s390_host_has_eimm);
1914 
1915    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1916       s390_disasm(ENC3(MNM, GPR, INT), "agfi", r1, i2);
1917 
1918    return emit_RIL(p, 0xc20800000000ULL, r1, i2);
1919 }
1920 
1921 
1922 static UChar *
s390_emit_AH(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)1923 s390_emit_AH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
1924 {
1925    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1926       s390_disasm(ENC3(MNM, GPR, UDXB), "ah", r1, d2, x2, b2);
1927 
1928    return emit_RX(p, 0x4a000000, r1, x2, b2, d2);
1929 }
1930 
1931 
1932 static UChar *
s390_emit_AHY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)1933 s390_emit_AHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
1934 {
1935    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1936       s390_disasm(ENC3(MNM, GPR, SDXB), "ahy", r1, dh2, dl2, x2, b2);
1937 
1938    return emit_RXY(p, 0xe3000000007aULL, r1, x2, b2, dl2, dh2);
1939 }
1940 
1941 
1942 static UChar *
s390_emit_AHI(UChar * p,UChar r1,UShort i2)1943 s390_emit_AHI(UChar *p, UChar r1, UShort i2)
1944 {
1945    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1946       s390_disasm(ENC3(MNM, GPR, INT), "ahi", r1, (Int)(Short)i2);
1947 
1948    return emit_RI(p, 0xa70a0000, r1, i2);
1949 }
1950 
1951 
1952 static UChar *
s390_emit_AGHI(UChar * p,UChar r1,UShort i2)1953 s390_emit_AGHI(UChar *p, UChar r1, UShort i2)
1954 {
1955    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1956       s390_disasm(ENC3(MNM, GPR, INT), "aghi", r1, (Int)(Short)i2);
1957 
1958    return emit_RI(p, 0xa70b0000, r1, i2);
1959 }
1960 
1961 
1962 static UChar *
s390_emit_AGSI(UChar * p,UChar i2,UChar b1,UShort dl1,UChar dh1)1963 s390_emit_AGSI(UChar *p, UChar i2, UChar b1, UShort dl1, UChar dh1)
1964 {
1965    vassert(s390_host_has_gie);
1966 
1967    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1968       s390_disasm(ENC3(MNM, SDXB, INT), "agsi", dh1, dl1, 0, b1, (Int)(Char)i2);
1969 
1970    return emit_SIY(p, 0xeb000000007aULL, i2, b1, dl1, dh1);
1971 }
1972 
1973 
1974 static UChar *
s390_emit_ASI(UChar * p,UChar i2,UChar b1,UShort dl1,UChar dh1)1975 s390_emit_ASI(UChar *p, UChar i2, UChar b1, UShort dl1, UChar dh1)
1976 {
1977    vassert(s390_host_has_gie);
1978 
1979    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1980       s390_disasm(ENC3(MNM, SDXB, INT), "asi", dh1, dl1, 0, b1, (Int)(Char)i2);
1981 
1982    return emit_SIY(p, 0xeb000000006aULL, i2, b1, dl1, dh1);
1983 }
1984 
1985 
1986 static UChar *
s390_emit_NR(UChar * p,UChar r1,UChar r2)1987 s390_emit_NR(UChar *p, UChar r1, UChar r2)
1988 {
1989    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
1990       s390_disasm(ENC3(MNM, GPR, GPR), "nr", r1, r2);
1991 
1992    return emit_RR(p, 0x1400, r1, r2);
1993 }
1994 
1995 
1996 static UChar *
s390_emit_NGR(UChar * p,UChar r1,UChar r2)1997 s390_emit_NGR(UChar *p, UChar r1, UChar r2)
1998 {
1999    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2000       s390_disasm(ENC3(MNM, GPR, GPR), "ngr", r1, r2);
2001 
2002    return emit_RRE(p, 0xb9800000, r1, r2);
2003 }
2004 
2005 
2006 static UChar *
s390_emit_N(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)2007 s390_emit_N(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
2008 {
2009    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2010       s390_disasm(ENC3(MNM, GPR, UDXB), "n", r1, d2, x2, b2);
2011 
2012    return emit_RX(p, 0x54000000, r1, x2, b2, d2);
2013 }
2014 
2015 
2016 static UChar *
s390_emit_NY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2017 s390_emit_NY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2018 {
2019    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2020       s390_disasm(ENC3(MNM, GPR, SDXB), "ny", r1, dh2, dl2, x2, b2);
2021 
2022    return emit_RXY(p, 0xe30000000054ULL, r1, x2, b2, dl2, dh2);
2023 }
2024 
2025 
2026 static UChar *
s390_emit_NG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2027 s390_emit_NG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2028 {
2029    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2030       s390_disasm(ENC3(MNM, GPR, SDXB), "ng", r1, dh2, dl2, x2, b2);
2031 
2032    return emit_RXY(p, 0xe30000000080ULL, r1, x2, b2, dl2, dh2);
2033 }
2034 
2035 
2036 static UChar *
s390_emit_NIHF(UChar * p,UChar r1,UInt i2)2037 s390_emit_NIHF(UChar *p, UChar r1, UInt i2)
2038 {
2039    vassert(s390_host_has_eimm);
2040 
2041    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2042       s390_disasm(ENC3(MNM, GPR, UINT), "nihf", r1, i2);
2043 
2044    return emit_RIL(p, 0xc00a00000000ULL, r1, i2);
2045 }
2046 
2047 
2048 static UChar *
s390_emit_NILF(UChar * p,UChar r1,UInt i2)2049 s390_emit_NILF(UChar *p, UChar r1, UInt i2)
2050 {
2051    vassert(s390_host_has_eimm);
2052 
2053    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2054       s390_disasm(ENC3(MNM, GPR, UINT), "nilf", r1, i2);
2055 
2056    return emit_RIL(p, 0xc00b00000000ULL, r1, i2);
2057 }
2058 
2059 
2060 static UChar *
s390_emit_NILL(UChar * p,UChar r1,UShort i2)2061 s390_emit_NILL(UChar *p, UChar r1, UShort i2)
2062 {
2063    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2064       s390_disasm(ENC3(MNM, GPR, UINT), "nill", r1, i2);
2065 
2066    return emit_RI(p, 0xa5070000, r1, i2);
2067 }
2068 
2069 
2070 static UChar *
s390_emit_BASR(UChar * p,UChar r1,UChar r2)2071 s390_emit_BASR(UChar *p, UChar r1, UChar r2)
2072 {
2073    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2074       s390_disasm(ENC3(MNM, GPR, GPR), "basr", r1, r2);
2075 
2076    return emit_RR(p, 0x0d00, r1, r2);
2077 }
2078 
2079 
2080 static UChar *
s390_emit_BCR(UChar * p,UChar r1,UChar r2)2081 s390_emit_BCR(UChar *p, UChar r1, UChar r2)
2082 {
2083    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2084       s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
2085 
2086    return emit_RR(p, 0x0700, r1, r2);
2087 }
2088 
2089 
2090 static UChar *
s390_emit_BRC(UChar * p,UChar r1,UShort i2)2091 s390_emit_BRC(UChar *p, UChar r1, UShort i2)
2092 {
2093    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2094       s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
2095 
2096    return emit_RI(p, 0xa7040000, r1, i2);
2097 }
2098 
2099 
2100 static UChar *
s390_emit_BRCL(UChar * p,UChar r1,ULong i2)2101 s390_emit_BRCL(UChar *p, UChar r1, ULong i2)
2102 {
2103    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2104       s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
2105 
2106    return emit_RIL(p, 0xc00400000000ULL, r1, i2);
2107 }
2108 
2109 
2110 static UChar *
s390_emit_CR(UChar * p,UChar r1,UChar r2)2111 s390_emit_CR(UChar *p, UChar r1, UChar r2)
2112 {
2113    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2114       s390_disasm(ENC3(MNM, GPR, GPR), "cr", r1, r2);
2115 
2116    return emit_RR(p, 0x1900, r1, r2);
2117 }
2118 
2119 
2120 static UChar *
s390_emit_CGR(UChar * p,UChar r1,UChar r2)2121 s390_emit_CGR(UChar *p, UChar r1, UChar r2)
2122 {
2123    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2124       s390_disasm(ENC3(MNM, GPR, GPR), "cgr", r1, r2);
2125 
2126    return emit_RRE(p, 0xb9200000, r1, r2);
2127 }
2128 
2129 
2130 static UChar *
s390_emit_C(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)2131 s390_emit_C(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
2132 {
2133    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2134       s390_disasm(ENC3(MNM, GPR, UDXB), "c", r1, d2, x2, b2);
2135 
2136    return emit_RX(p, 0x59000000, r1, x2, b2, d2);
2137 }
2138 
2139 
2140 static UChar *
s390_emit_CY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2141 s390_emit_CY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2142 {
2143    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2144       s390_disasm(ENC3(MNM, GPR, SDXB), "cy", r1, dh2, dl2, x2, b2);
2145 
2146    return emit_RXY(p, 0xe30000000059ULL, r1, x2, b2, dl2, dh2);
2147 }
2148 
2149 
2150 static UChar *
s390_emit_CG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2151 s390_emit_CG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2152 {
2153    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2154       s390_disasm(ENC3(MNM, GPR, SDXB), "cg", r1, dh2, dl2, x2, b2);
2155 
2156    return emit_RXY(p, 0xe30000000020ULL, r1, x2, b2, dl2, dh2);
2157 }
2158 
2159 
2160 static UChar *
s390_emit_CFI(UChar * p,UChar r1,UInt i2)2161 s390_emit_CFI(UChar *p, UChar r1, UInt i2)
2162 {
2163    vassert(s390_host_has_eimm);
2164 
2165    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2166       s390_disasm(ENC3(MNM, GPR, INT), "cfi", r1, i2);
2167 
2168    return emit_RIL(p, 0xc20d00000000ULL, r1, i2);
2169 }
2170 
2171 
2172 static UChar *
s390_emit_CGFI(UChar * p,UChar r1,UInt i2)2173 s390_emit_CGFI(UChar *p, UChar r1, UInt i2)
2174 {
2175    vassert(s390_host_has_eimm);
2176 
2177    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2178       s390_disasm(ENC3(MNM, GPR, INT), "cgfi", r1, i2);
2179 
2180    return emit_RIL(p, 0xc20c00000000ULL, r1, i2);
2181 }
2182 
2183 
2184 static UChar *
s390_emit_CS(UChar * p,UChar r1,UChar r3,UChar b2,UShort d2)2185 s390_emit_CS(UChar *p, UChar r1, UChar r3, UChar b2, UShort d2)
2186 {
2187    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2188       s390_disasm(ENC4(MNM, GPR, GPR, UDXB), "cs", r1, r3, d2, 0, b2);
2189 
2190    return emit_RS(p, 0xba000000, r1, r3, b2, d2);
2191 }
2192 
2193 
2194 static UChar *
s390_emit_CSY(UChar * p,UChar r1,UChar r3,UChar b2,UShort dl2,UChar dh2)2195 s390_emit_CSY(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2196 {
2197    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2198       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "csy", r1, r3, dh2, dl2, 0, b2);
2199 
2200    return emit_RSY(p, 0xeb0000000014ULL, r1, r3, b2, dl2, dh2);
2201 }
2202 
2203 
2204 static UChar *
s390_emit_CSG(UChar * p,UChar r1,UChar r3,UChar b2,UShort dl2,UChar dh2)2205 s390_emit_CSG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2206 {
2207    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2208       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "csg", r1, r3, dh2, dl2, 0, b2);
2209 
2210    return emit_RSY(p, 0xeb0000000030ULL, r1, r3, b2, dl2, dh2);
2211 }
2212 
2213 
2214 static UChar *
s390_emit_CDS(UChar * p,UChar r1,UChar r3,UChar b2,UShort d2)2215 s390_emit_CDS(UChar *p, UChar r1, UChar r3, UChar b2, UShort d2)
2216 {
2217    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2218       s390_disasm(ENC4(MNM, GPR, GPR, UDXB), "cds", r1, r3, d2, 0, b2);
2219 
2220    return emit_RS(p, 0xbb000000, r1, r3, b2, d2);
2221 }
2222 
2223 
2224 static UChar *
s390_emit_CDSY(UChar * p,UChar r1,UChar r3,UChar b2,UShort dl2,UChar dh2)2225 s390_emit_CDSY(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2226 {
2227    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2228       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "cdsy", r1, r3, dh2, dl2, 0, b2);
2229 
2230    return emit_RSY(p, 0xeb0000000031ULL, r1, r3, b2, dl2, dh2);
2231 }
2232 
2233 
2234 static UChar *
s390_emit_CDSG(UChar * p,UChar r1,UChar r3,UChar b2,UShort dl2,UChar dh2)2235 s390_emit_CDSG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2236 {
2237    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2238       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "cdsg", r1, r3, dh2, dl2, 0, b2);
2239 
2240    return emit_RSY(p, 0xeb000000003eULL, r1, r3, b2, dl2, dh2);
2241 }
2242 
2243 
2244 static UChar *
s390_emit_CLR(UChar * p,UChar r1,UChar r2)2245 s390_emit_CLR(UChar *p, UChar r1, UChar r2)
2246 {
2247    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2248       s390_disasm(ENC3(MNM, GPR, GPR), "clr", r1, r2);
2249 
2250    return emit_RR(p, 0x1500, r1, r2);
2251 }
2252 
2253 
2254 static UChar *
s390_emit_CLGR(UChar * p,UChar r1,UChar r2)2255 s390_emit_CLGR(UChar *p, UChar r1, UChar r2)
2256 {
2257    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2258       s390_disasm(ENC3(MNM, GPR, GPR), "clgr", r1, r2);
2259 
2260    return emit_RRE(p, 0xb9210000, r1, r2);
2261 }
2262 
2263 
2264 static UChar *
s390_emit_CL(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)2265 s390_emit_CL(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
2266 {
2267    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2268       s390_disasm(ENC3(MNM, GPR, UDXB), "cl", r1, d2, x2, b2);
2269 
2270    return emit_RX(p, 0x55000000, r1, x2, b2, d2);
2271 }
2272 
2273 
2274 static UChar *
s390_emit_CLY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2275 s390_emit_CLY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2276 {
2277    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2278       s390_disasm(ENC3(MNM, GPR, SDXB), "cly", r1, dh2, dl2, x2, b2);
2279 
2280    return emit_RXY(p, 0xe30000000055ULL, r1, x2, b2, dl2, dh2);
2281 }
2282 
2283 
2284 static UChar *
s390_emit_CLG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2285 s390_emit_CLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2286 {
2287    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2288       s390_disasm(ENC3(MNM, GPR, SDXB), "clg", r1, dh2, dl2, x2, b2);
2289 
2290    return emit_RXY(p, 0xe30000000021ULL, r1, x2, b2, dl2, dh2);
2291 }
2292 
2293 
2294 static UChar *
s390_emit_CLFI(UChar * p,UChar r1,UInt i2)2295 s390_emit_CLFI(UChar *p, UChar r1, UInt i2)
2296 {
2297    vassert(s390_host_has_eimm);
2298 
2299    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2300       s390_disasm(ENC3(MNM, GPR, UINT), "clfi", r1, i2);
2301 
2302    return emit_RIL(p, 0xc20f00000000ULL, r1, i2);
2303 }
2304 
2305 
2306 static UChar *
s390_emit_CLGFI(UChar * p,UChar r1,UInt i2)2307 s390_emit_CLGFI(UChar *p, UChar r1, UInt i2)
2308 {
2309    vassert(s390_host_has_eimm);
2310 
2311    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2312       s390_disasm(ENC3(MNM, GPR, UINT), "clgfi", r1, i2);
2313 
2314    return emit_RIL(p, 0xc20e00000000ULL, r1, i2);
2315 }
2316 
2317 
2318 static UChar *
s390_emit_DR(UChar * p,UChar r1,UChar r2)2319 s390_emit_DR(UChar *p, UChar r1, UChar r2)
2320 {
2321    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2322       s390_disasm(ENC3(MNM, GPR, GPR), "dr", r1, r2);
2323 
2324    return emit_RR(p, 0x1d00, r1, r2);
2325 }
2326 
2327 
2328 static UChar *
s390_emit_D(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)2329 s390_emit_D(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
2330 {
2331    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2332       s390_disasm(ENC3(MNM, GPR, UDXB), "d", r1, d2, x2, b2);
2333 
2334    return emit_RX(p, 0x5d000000, r1, x2, b2, d2);
2335 }
2336 
2337 
2338 static UChar *
s390_emit_DLR(UChar * p,UChar r1,UChar r2)2339 s390_emit_DLR(UChar *p, UChar r1, UChar r2)
2340 {
2341    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2342       s390_disasm(ENC3(MNM, GPR, GPR), "dlr", r1, r2);
2343 
2344    return emit_RRE(p, 0xb9970000, r1, r2);
2345 }
2346 
2347 
2348 static UChar *
s390_emit_DLGR(UChar * p,UChar r1,UChar r2)2349 s390_emit_DLGR(UChar *p, UChar r1, UChar r2)
2350 {
2351    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2352       s390_disasm(ENC3(MNM, GPR, GPR), "dlgr", r1, r2);
2353 
2354    return emit_RRE(p, 0xb9870000, r1, r2);
2355 }
2356 
2357 
2358 static UChar *
s390_emit_DL(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2359 s390_emit_DL(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2360 {
2361    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2362       s390_disasm(ENC3(MNM, GPR, SDXB), "dl", r1, dh2, dl2, x2, b2);
2363 
2364    return emit_RXY(p, 0xe30000000097ULL, r1, x2, b2, dl2, dh2);
2365 }
2366 
2367 
2368 static UChar *
s390_emit_DLG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2369 s390_emit_DLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2370 {
2371    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2372       s390_disasm(ENC3(MNM, GPR, SDXB), "dlg", r1, dh2, dl2, x2, b2);
2373 
2374    return emit_RXY(p, 0xe30000000087ULL, r1, x2, b2, dl2, dh2);
2375 }
2376 
2377 
2378 static UChar *
s390_emit_DSGR(UChar * p,UChar r1,UChar r2)2379 s390_emit_DSGR(UChar *p, UChar r1, UChar r2)
2380 {
2381    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2382       s390_disasm(ENC3(MNM, GPR, GPR), "dsgr", r1, r2);
2383 
2384    return emit_RRE(p, 0xb90d0000, r1, r2);
2385 }
2386 
2387 
2388 static UChar *
s390_emit_DSG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2389 s390_emit_DSG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2390 {
2391    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2392       s390_disasm(ENC3(MNM, GPR, SDXB), "dsg", r1, dh2, dl2, x2, b2);
2393 
2394    return emit_RXY(p, 0xe3000000000dULL, r1, x2, b2, dl2, dh2);
2395 }
2396 
2397 
2398 static UChar *
s390_emit_XR(UChar * p,UChar r1,UChar r2)2399 s390_emit_XR(UChar *p, UChar r1, UChar r2)
2400 {
2401    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2402       s390_disasm(ENC3(MNM, GPR, GPR), "xr", r1, r2);
2403 
2404    return emit_RR(p, 0x1700, r1, r2);
2405 }
2406 
2407 
2408 static UChar *
s390_emit_XGR(UChar * p,UChar r1,UChar r2)2409 s390_emit_XGR(UChar *p, UChar r1, UChar r2)
2410 {
2411    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2412       s390_disasm(ENC3(MNM, GPR, GPR), "xgr", r1, r2);
2413 
2414    return emit_RRE(p, 0xb9820000, r1, r2);
2415 }
2416 
2417 
2418 static UChar *
s390_emit_X(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)2419 s390_emit_X(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
2420 {
2421    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2422       s390_disasm(ENC3(MNM, GPR, UDXB), "x", r1, d2, x2, b2);
2423 
2424    return emit_RX(p, 0x57000000, r1, x2, b2, d2);
2425 }
2426 
2427 
2428 static UChar *
s390_emit_XY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2429 s390_emit_XY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2430 {
2431    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2432       s390_disasm(ENC3(MNM, GPR, SDXB), "xy", r1, dh2, dl2, x2, b2);
2433 
2434    return emit_RXY(p, 0xe30000000057ULL, r1, x2, b2, dl2, dh2);
2435 }
2436 
2437 
2438 static UChar *
s390_emit_XG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2439 s390_emit_XG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2440 {
2441    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2442       s390_disasm(ENC3(MNM, GPR, SDXB), "xg", r1, dh2, dl2, x2, b2);
2443 
2444    return emit_RXY(p, 0xe30000000082ULL, r1, x2, b2, dl2, dh2);
2445 }
2446 
2447 
2448 static UChar *
s390_emit_XIHF(UChar * p,UChar r1,UInt i2)2449 s390_emit_XIHF(UChar *p, UChar r1, UInt i2)
2450 {
2451    vassert(s390_host_has_eimm);
2452 
2453    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2454       s390_disasm(ENC3(MNM, GPR, UINT), "xihf", r1, i2);
2455 
2456    return emit_RIL(p, 0xc00600000000ULL, r1, i2);
2457 }
2458 
2459 
2460 static UChar *
s390_emit_XILF(UChar * p,UChar r1,UInt i2)2461 s390_emit_XILF(UChar *p, UChar r1, UInt i2)
2462 {
2463    vassert(s390_host_has_eimm);
2464 
2465    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2466       s390_disasm(ENC3(MNM, GPR, UINT), "xilf", r1, i2);
2467 
2468    return emit_RIL(p, 0xc00700000000ULL, r1, i2);
2469 }
2470 
2471 
2472 static UChar *
s390_emit_XC(UChar * p,UInt l,UChar b1,UShort d1,UChar b2,UShort d2)2473 s390_emit_XC(UChar *p, UInt l, UChar b1, UShort d1, UChar b2, UShort d2)
2474 {
2475    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2476       s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d1, l, b1, d2, 0, b2);
2477 
2478    return emit_SSa(p, 0xd70000000000ULL, l, b1, d1, b2, d2);
2479 }
2480 
2481 
2482 static UChar *
s390_emit_FLOGR(UChar * p,UChar r1,UChar r2)2483 s390_emit_FLOGR(UChar *p, UChar r1, UChar r2)
2484 {
2485    vassert(s390_host_has_eimm);
2486 
2487    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2488       s390_disasm(ENC3(MNM, GPR, GPR), "flogr", r1, r2);
2489 
2490    return emit_RRE(p, 0xb9830000, r1, r2);
2491 }
2492 
2493 
2494 static UChar *
s390_emit_IC(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)2495 s390_emit_IC(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
2496 {
2497    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2498       s390_disasm(ENC3(MNM, GPR, UDXB), "ic", r1, d2, x2, b2);
2499 
2500    return emit_RX(p, 0x43000000, r1, x2, b2, d2);
2501 }
2502 
2503 
2504 static UChar *
s390_emit_ICY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2505 s390_emit_ICY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2506 {
2507    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2508       s390_disasm(ENC3(MNM, GPR, SDXB), "icy", r1, dh2, dl2, x2, b2);
2509 
2510    return emit_RXY(p, 0xe30000000073ULL, r1, x2, b2, dl2, dh2);
2511 }
2512 
2513 
2514 static UChar *
s390_emit_IIHF(UChar * p,UChar r1,UInt i2)2515 s390_emit_IIHF(UChar *p, UChar r1, UInt i2)
2516 {
2517    vassert(s390_host_has_eimm);
2518 
2519    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2520       s390_disasm(ENC3(MNM, GPR, UINT), "iihf", r1, i2);
2521 
2522    return emit_RIL(p, 0xc00800000000ULL, r1, i2);
2523 }
2524 
2525 
2526 static UChar *
s390_emit_IIHH(UChar * p,UChar r1,UShort i2)2527 s390_emit_IIHH(UChar *p, UChar r1, UShort i2)
2528 {
2529    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2530       s390_disasm(ENC3(MNM, GPR, UINT), "iihh", r1, i2);
2531 
2532    return emit_RI(p, 0xa5000000, r1, i2);
2533 }
2534 
2535 
2536 static UChar *
s390_emit_IIHL(UChar * p,UChar r1,UShort i2)2537 s390_emit_IIHL(UChar *p, UChar r1, UShort i2)
2538 {
2539    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2540       s390_disasm(ENC3(MNM, GPR, UINT), "iihl", r1, i2);
2541 
2542    return emit_RI(p, 0xa5010000, r1, i2);
2543 }
2544 
2545 
2546 static UChar *
s390_emit_IILF(UChar * p,UChar r1,UInt i2)2547 s390_emit_IILF(UChar *p, UChar r1, UInt i2)
2548 {
2549    vassert(s390_host_has_eimm);
2550 
2551    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2552       s390_disasm(ENC3(MNM, GPR, UINT), "iilf", r1, i2);
2553 
2554    return emit_RIL(p, 0xc00900000000ULL, r1, i2);
2555 }
2556 
2557 
2558 static UChar *
s390_emit_IILH(UChar * p,UChar r1,UShort i2)2559 s390_emit_IILH(UChar *p, UChar r1, UShort i2)
2560 {
2561    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2562       s390_disasm(ENC3(MNM, GPR, UINT), "iilh", r1, i2);
2563 
2564    return emit_RI(p, 0xa5020000, r1, i2);
2565 }
2566 
2567 
2568 static UChar *
s390_emit_IILL(UChar * p,UChar r1,UShort i2)2569 s390_emit_IILL(UChar *p, UChar r1, UShort i2)
2570 {
2571    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2572       s390_disasm(ENC3(MNM, GPR, UINT), "iill", r1, i2);
2573 
2574    return emit_RI(p, 0xa5030000, r1, i2);
2575 }
2576 
2577 
2578 static UChar *
s390_emit_IPM(UChar * p,UChar r1,UChar r2)2579 s390_emit_IPM(UChar *p, UChar r1, UChar r2)
2580 {
2581    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2582       s390_disasm(ENC2(MNM, GPR), "ipm", r1);
2583 
2584    return emit_RRE(p, 0xb2220000, r1, r2);
2585 }
2586 
2587 
2588 static UChar *
s390_emit_LR(UChar * p,UChar r1,UChar r2)2589 s390_emit_LR(UChar *p, UChar r1, UChar r2)
2590 {
2591    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2592       s390_disasm(ENC3(MNM, GPR, GPR), "lr", r1, r2);
2593 
2594    return emit_RR(p, 0x1800, r1, r2);
2595 }
2596 
2597 
2598 static UChar *
s390_emit_LGR(UChar * p,UChar r1,UChar r2)2599 s390_emit_LGR(UChar *p, UChar r1, UChar r2)
2600 {
2601    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2602       s390_disasm(ENC3(MNM, GPR, GPR), "lgr", r1, r2);
2603 
2604    return emit_RRE(p, 0xb9040000, r1, r2);
2605 }
2606 
2607 
2608 static UChar *
s390_emit_LGFR(UChar * p,UChar r1,UChar r2)2609 s390_emit_LGFR(UChar *p, UChar r1, UChar r2)
2610 {
2611    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2612       s390_disasm(ENC3(MNM, GPR, GPR), "lgfr", r1, r2);
2613 
2614    return emit_RRE(p, 0xb9140000, r1, r2);
2615 }
2616 
2617 
2618 static UChar *
s390_emit_L(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)2619 s390_emit_L(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
2620 {
2621    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2622       s390_disasm(ENC3(MNM, GPR, UDXB), "l", r1, d2, x2, b2);
2623 
2624    return emit_RX(p, 0x58000000, r1, x2, b2, d2);
2625 }
2626 
2627 
2628 static UChar *
s390_emit_LY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2629 s390_emit_LY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2630 {
2631    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2632       s390_disasm(ENC3(MNM, GPR, SDXB), "ly", r1, dh2, dl2, x2, b2);
2633 
2634    return emit_RXY(p, 0xe30000000058ULL, r1, x2, b2, dl2, dh2);
2635 }
2636 
2637 
2638 static UChar *
s390_emit_LG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2639 s390_emit_LG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2640 {
2641    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2642       s390_disasm(ENC3(MNM, GPR, SDXB), "lg", r1, dh2, dl2, x2, b2);
2643 
2644    return emit_RXY(p, 0xe30000000004ULL, r1, x2, b2, dl2, dh2);
2645 }
2646 
2647 
2648 static UChar *
s390_emit_LGF(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2649 s390_emit_LGF(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2650 {
2651    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2652       s390_disasm(ENC3(MNM, GPR, SDXB), "lgf", r1, dh2, dl2, x2, b2);
2653 
2654    return emit_RXY(p, 0xe30000000014ULL, r1, x2, b2, dl2, dh2);
2655 }
2656 
2657 
2658 static UChar *
s390_emit_LGFI(UChar * p,UChar r1,UInt i2)2659 s390_emit_LGFI(UChar *p, UChar r1, UInt i2)
2660 {
2661    vassert(s390_host_has_eimm);
2662 
2663    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2664       s390_disasm(ENC3(MNM, GPR, INT), "lgfi", r1, i2);
2665 
2666    return emit_RIL(p, 0xc00100000000ULL, r1, i2);
2667 }
2668 
2669 
2670 static UChar *
s390_emit_LTR(UChar * p,UChar r1,UChar r2)2671 s390_emit_LTR(UChar *p, UChar r1, UChar r2)
2672 {
2673    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2674       s390_disasm(ENC3(MNM, GPR, GPR), "ltr", r1, r2);
2675 
2676    return emit_RR(p, 0x1200, r1, r2);
2677 }
2678 
2679 
2680 static UChar *
s390_emit_LTGR(UChar * p,UChar r1,UChar r2)2681 s390_emit_LTGR(UChar *p, UChar r1, UChar r2)
2682 {
2683    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2684       s390_disasm(ENC3(MNM, GPR, GPR), "ltgr", r1, r2);
2685 
2686    return emit_RRE(p, 0xb9020000, r1, r2);
2687 }
2688 
2689 
2690 static UChar *
s390_emit_LT(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2691 s390_emit_LT(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2692 {
2693    vassert(s390_host_has_eimm);
2694 
2695    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2696       s390_disasm(ENC3(MNM, GPR, SDXB), "lt", r1, dh2, dl2, x2, b2);
2697 
2698    return emit_RXY(p, 0xe30000000012ULL, r1, x2, b2, dl2, dh2);
2699 }
2700 
2701 
2702 static UChar *
s390_emit_LTG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2703 s390_emit_LTG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2704 {
2705    vassert(s390_host_has_eimm);
2706 
2707    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2708       s390_disasm(ENC3(MNM, GPR, SDXB), "ltg", r1, dh2, dl2, x2, b2);
2709 
2710    return emit_RXY(p, 0xe30000000002ULL, r1, x2, b2, dl2, dh2);
2711 }
2712 
2713 
2714 static UChar *
s390_emit_LBR(UChar * p,UChar r1,UChar r2)2715 s390_emit_LBR(UChar *p, UChar r1, UChar r2)
2716 {
2717    vassert(s390_host_has_eimm);
2718 
2719    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2720       s390_disasm(ENC3(MNM, GPR, GPR), "lbr", r1, r2);
2721 
2722    return emit_RRE(p, 0xb9260000, r1, r2);
2723 }
2724 
2725 
2726 static UChar *
s390_emit_LGBR(UChar * p,UChar r1,UChar r2)2727 s390_emit_LGBR(UChar *p, UChar r1, UChar r2)
2728 {
2729    vassert(s390_host_has_eimm);
2730 
2731    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2732       s390_disasm(ENC3(MNM, GPR, GPR), "lgbr", r1, r2);
2733 
2734    return emit_RRE(p, 0xb9060000, r1, r2);
2735 }
2736 
2737 
2738 static UChar *
s390_emit_LB(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2739 s390_emit_LB(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2740 {
2741    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2742       s390_disasm(ENC3(MNM, GPR, SDXB), "lb", r1, dh2, dl2, x2, b2);
2743 
2744    return emit_RXY(p, 0xe30000000076ULL, r1, x2, b2, dl2, dh2);
2745 }
2746 
2747 
2748 static UChar *
s390_emit_LGB(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2749 s390_emit_LGB(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2750 {
2751    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2752       s390_disasm(ENC3(MNM, GPR, SDXB), "lgb", r1, dh2, dl2, x2, b2);
2753 
2754    return emit_RXY(p, 0xe30000000077ULL, r1, x2, b2, dl2, dh2);
2755 }
2756 
2757 
2758 static UChar *
s390_emit_LCR(UChar * p,UChar r1,UChar r2)2759 s390_emit_LCR(UChar *p, UChar r1, UChar r2)
2760 {
2761    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2762       s390_disasm(ENC3(MNM, GPR, GPR), "lcr", r1, r2);
2763 
2764    return emit_RR(p, 0x1300, r1, r2);
2765 }
2766 
2767 
2768 static UChar *
s390_emit_LCGR(UChar * p,UChar r1,UChar r2)2769 s390_emit_LCGR(UChar *p, UChar r1, UChar r2)
2770 {
2771    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2772       s390_disasm(ENC3(MNM, GPR, GPR), "lcgr", r1, r2);
2773 
2774    return emit_RRE(p, 0xb9030000, r1, r2);
2775 }
2776 
2777 
2778 static UChar *
s390_emit_LHR(UChar * p,UChar r1,UChar r2)2779 s390_emit_LHR(UChar *p, UChar r1, UChar r2)
2780 {
2781    vassert(s390_host_has_eimm);
2782 
2783    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2784       s390_disasm(ENC3(MNM, GPR, GPR), "lhr", r1, r2);
2785 
2786    return emit_RRE(p, 0xb9270000, r1, r2);
2787 }
2788 
2789 
2790 static UChar *
s390_emit_LGHR(UChar * p,UChar r1,UChar r2)2791 s390_emit_LGHR(UChar *p, UChar r1, UChar r2)
2792 {
2793    vassert(s390_host_has_eimm);
2794 
2795    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2796       s390_disasm(ENC3(MNM, GPR, GPR), "lghr", r1, r2);
2797 
2798    return emit_RRE(p, 0xb9070000, r1, r2);
2799 }
2800 
2801 
2802 static UChar *
s390_emit_LH(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)2803 s390_emit_LH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
2804 {
2805    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2806       s390_disasm(ENC3(MNM, GPR, UDXB), "lh", r1, d2, x2, b2);
2807 
2808    return emit_RX(p, 0x48000000, r1, x2, b2, d2);
2809 }
2810 
2811 
2812 static UChar *
s390_emit_LHY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2813 s390_emit_LHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2814 {
2815    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2816       s390_disasm(ENC3(MNM, GPR, SDXB), "lhy", r1, dh2, dl2, x2, b2);
2817 
2818    return emit_RXY(p, 0xe30000000078ULL, r1, x2, b2, dl2, dh2);
2819 }
2820 
2821 
2822 static UChar *
s390_emit_LGH(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2823 s390_emit_LGH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2824 {
2825    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2826       s390_disasm(ENC3(MNM, GPR, SDXB), "lgh", r1, dh2, dl2, x2, b2);
2827 
2828    return emit_RXY(p, 0xe30000000015ULL, r1, x2, b2, dl2, dh2);
2829 }
2830 
2831 
2832 static UChar *
s390_emit_LHI(UChar * p,UChar r1,UShort i2)2833 s390_emit_LHI(UChar *p, UChar r1, UShort i2)
2834 {
2835    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2836       s390_disasm(ENC3(MNM, GPR, INT), "lhi", r1, (Int)(Short)i2);
2837 
2838    return emit_RI(p, 0xa7080000, r1, i2);
2839 }
2840 
2841 
2842 static UChar *
s390_emit_LGHI(UChar * p,UChar r1,UShort i2)2843 s390_emit_LGHI(UChar *p, UChar r1, UShort i2)
2844 {
2845    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2846       s390_disasm(ENC3(MNM, GPR, INT), "lghi", r1, (Int)(Short)i2);
2847 
2848    return emit_RI(p, 0xa7090000, r1, i2);
2849 }
2850 
2851 
2852 static UChar *
s390_emit_LLGFR(UChar * p,UChar r1,UChar r2)2853 s390_emit_LLGFR(UChar *p, UChar r1, UChar r2)
2854 {
2855    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2856       s390_disasm(ENC3(MNM, GPR, GPR), "llgfr", r1, r2);
2857 
2858    return emit_RRE(p, 0xb9160000, r1, r2);
2859 }
2860 
2861 
2862 static UChar *
s390_emit_LLGF(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2863 s390_emit_LLGF(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2864 {
2865    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2866       s390_disasm(ENC3(MNM, GPR, SDXB), "llgf", r1, dh2, dl2, x2, b2);
2867 
2868    return emit_RXY(p, 0xe30000000016ULL, r1, x2, b2, dl2, dh2);
2869 }
2870 
2871 
2872 static UChar *
s390_emit_LLCR(UChar * p,UChar r1,UChar r2)2873 s390_emit_LLCR(UChar *p, UChar r1, UChar r2)
2874 {
2875    vassert(s390_host_has_eimm);
2876 
2877    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2878       s390_disasm(ENC3(MNM, GPR, GPR), "llcr", r1, r2);
2879 
2880    return emit_RRE(p, 0xb9940000, r1, r2);
2881 }
2882 
2883 
2884 static UChar *
s390_emit_LLGCR(UChar * p,UChar r1,UChar r2)2885 s390_emit_LLGCR(UChar *p, UChar r1, UChar r2)
2886 {
2887    vassert(s390_host_has_eimm);
2888 
2889    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2890       s390_disasm(ENC3(MNM, GPR, GPR), "llgcr", r1, r2);
2891 
2892    return emit_RRE(p, 0xb9840000, r1, r2);
2893 }
2894 
2895 
2896 static UChar *
s390_emit_LLC(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2897 s390_emit_LLC(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2898 {
2899    vassert(s390_host_has_eimm);
2900 
2901    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2902       s390_disasm(ENC3(MNM, GPR, SDXB), "llc", r1, dh2, dl2, x2, b2);
2903 
2904    return emit_RXY(p, 0xe30000000094ULL, r1, x2, b2, dl2, dh2);
2905 }
2906 
2907 
2908 static UChar *
s390_emit_LLGC(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2909 s390_emit_LLGC(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2910 {
2911    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2912       s390_disasm(ENC3(MNM, GPR, SDXB), "llgc", r1, dh2, dl2, x2, b2);
2913 
2914    return emit_RXY(p, 0xe30000000090ULL, r1, x2, b2, dl2, dh2);
2915 }
2916 
2917 
2918 static UChar *
s390_emit_LLHR(UChar * p,UChar r1,UChar r2)2919 s390_emit_LLHR(UChar *p, UChar r1, UChar r2)
2920 {
2921    vassert(s390_host_has_eimm);
2922 
2923    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2924       s390_disasm(ENC3(MNM, GPR, GPR), "llhr", r1, r2);
2925 
2926    return emit_RRE(p, 0xb9950000, r1, r2);
2927 }
2928 
2929 
2930 static UChar *
s390_emit_LLGHR(UChar * p,UChar r1,UChar r2)2931 s390_emit_LLGHR(UChar *p, UChar r1, UChar r2)
2932 {
2933    vassert(s390_host_has_eimm);
2934 
2935    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2936       s390_disasm(ENC3(MNM, GPR, GPR), "llghr", r1, r2);
2937 
2938    return emit_RRE(p, 0xb9850000, r1, r2);
2939 }
2940 
2941 
2942 static UChar *
s390_emit_LLH(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2943 s390_emit_LLH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2944 {
2945    vassert(s390_host_has_eimm);
2946 
2947    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2948       s390_disasm(ENC3(MNM, GPR, SDXB), "llh", r1, dh2, dl2, x2, b2);
2949 
2950    return emit_RXY(p, 0xe30000000095ULL, r1, x2, b2, dl2, dh2);
2951 }
2952 
2953 
2954 static UChar *
s390_emit_LLGH(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2955 s390_emit_LLGH(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2956 {
2957    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2958       s390_disasm(ENC3(MNM, GPR, SDXB), "llgh", r1, dh2, dl2, x2, b2);
2959 
2960    return emit_RXY(p, 0xe30000000091ULL, r1, x2, b2, dl2, dh2);
2961 }
2962 
2963 
2964 static UChar *
s390_emit_LLILF(UChar * p,UChar r1,UInt i2)2965 s390_emit_LLILF(UChar *p, UChar r1, UInt i2)
2966 {
2967    vassert(s390_host_has_eimm);
2968 
2969    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2970       s390_disasm(ENC3(MNM, GPR, UINT), "llilf", r1, i2);
2971 
2972    return emit_RIL(p, 0xc00f00000000ULL, r1, i2);
2973 }
2974 
2975 
2976 static UChar *
s390_emit_LLILH(UChar * p,UChar r1,UShort i2)2977 s390_emit_LLILH(UChar *p, UChar r1, UShort i2)
2978 {
2979    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2980       s390_disasm(ENC3(MNM, GPR, UINT), "llilh", r1, i2);
2981 
2982    return emit_RI(p, 0xa50e0000, r1, i2);
2983 }
2984 
2985 
2986 static UChar *
s390_emit_LLILL(UChar * p,UChar r1,UShort i2)2987 s390_emit_LLILL(UChar *p, UChar r1, UShort i2)
2988 {
2989    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
2990       s390_disasm(ENC3(MNM, GPR, UINT), "llill", r1, i2);
2991 
2992    return emit_RI(p, 0xa50f0000, r1, i2);
2993 }
2994 
2995 
2996 static UChar *
s390_emit_MR(UChar * p,UChar r1,UChar r2)2997 s390_emit_MR(UChar *p, UChar r1, UChar r2)
2998 {
2999    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3000       s390_disasm(ENC3(MNM, GPR, GPR), "mr", r1, r2);
3001 
3002    return emit_RR(p, 0x1c00, r1, r2);
3003 }
3004 
3005 
3006 static UChar *
s390_emit_M(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3007 s390_emit_M(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3008 {
3009    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3010       s390_disasm(ENC3(MNM, GPR, UDXB), "m", r1, d2, x2, b2);
3011 
3012    return emit_RX(p, 0x5c000000, r1, x2, b2, d2);
3013 }
3014 
3015 
3016 static UChar *
s390_emit_MFY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3017 s390_emit_MFY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3018 {
3019    vassert(s390_host_has_gie);
3020 
3021    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3022       s390_disasm(ENC3(MNM, GPR, SDXB), "mfy", r1, dh2, dl2, x2, b2);
3023 
3024    return emit_RXY(p, 0xe3000000005cULL, r1, x2, b2, dl2, dh2);
3025 }
3026 
3027 
3028 static UChar *
s390_emit_MH(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3029 s390_emit_MH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3030 {
3031    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3032       s390_disasm(ENC3(MNM, GPR, UDXB), "mh", r1, d2, x2, b2);
3033 
3034    return emit_RX(p, 0x4c000000, r1, x2, b2, d2);
3035 }
3036 
3037 
3038 static UChar *
s390_emit_MHY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3039 s390_emit_MHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3040 {
3041    vassert(s390_host_has_gie);
3042 
3043    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3044       s390_disasm(ENC3(MNM, GPR, SDXB), "mhy", r1, dh2, dl2, x2, b2);
3045 
3046    return emit_RXY(p, 0xe3000000007cULL, r1, x2, b2, dl2, dh2);
3047 }
3048 
3049 
3050 static UChar *
s390_emit_MHI(UChar * p,UChar r1,UShort i2)3051 s390_emit_MHI(UChar *p, UChar r1, UShort i2)
3052 {
3053    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3054       s390_disasm(ENC3(MNM, GPR, INT), "mhi", r1, (Int)(Short)i2);
3055 
3056    return emit_RI(p, 0xa70c0000, r1, i2);
3057 }
3058 
3059 
3060 static UChar *
s390_emit_MLR(UChar * p,UChar r1,UChar r2)3061 s390_emit_MLR(UChar *p, UChar r1, UChar r2)
3062 {
3063    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3064       s390_disasm(ENC3(MNM, GPR, GPR), "mlr", r1, r2);
3065 
3066    return emit_RRE(p, 0xb9960000, r1, r2);
3067 }
3068 
3069 
3070 static UChar *
s390_emit_MLGR(UChar * p,UChar r1,UChar r2)3071 s390_emit_MLGR(UChar *p, UChar r1, UChar r2)
3072 {
3073    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3074       s390_disasm(ENC3(MNM, GPR, GPR), "mlgr", r1, r2);
3075 
3076    return emit_RRE(p, 0xb9860000, r1, r2);
3077 }
3078 
3079 
3080 static UChar *
s390_emit_ML(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3081 s390_emit_ML(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3082 {
3083    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3084       s390_disasm(ENC3(MNM, GPR, SDXB), "ml", r1, dh2, dl2, x2, b2);
3085 
3086    return emit_RXY(p, 0xe30000000096ULL, r1, x2, b2, dl2, dh2);
3087 }
3088 
3089 
3090 static UChar *
s390_emit_MLG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3091 s390_emit_MLG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3092 {
3093    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3094       s390_disasm(ENC3(MNM, GPR, SDXB), "mlg", r1, dh2, dl2, x2, b2);
3095 
3096    return emit_RXY(p, 0xe30000000086ULL, r1, x2, b2, dl2, dh2);
3097 }
3098 
3099 
3100 static UChar *
s390_emit_MSR(UChar * p,UChar r1,UChar r2)3101 s390_emit_MSR(UChar *p, UChar r1, UChar r2)
3102 {
3103    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3104       s390_disasm(ENC3(MNM, GPR, GPR), "msr", r1, r2);
3105 
3106    return emit_RRE(p, 0xb2520000, r1, r2);
3107 }
3108 
3109 
3110 static UChar *
s390_emit_MSGR(UChar * p,UChar r1,UChar r2)3111 s390_emit_MSGR(UChar *p, UChar r1, UChar r2)
3112 {
3113    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3114       s390_disasm(ENC3(MNM, GPR, GPR), "msgr", r1, r2);
3115 
3116    return emit_RRE(p, 0xb90c0000, r1, r2);
3117 }
3118 
3119 
3120 static UChar *
s390_emit_MS(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3121 s390_emit_MS(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3122 {
3123    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3124       s390_disasm(ENC3(MNM, GPR, UDXB), "ms", r1, d2, x2, b2);
3125 
3126    return emit_RX(p, 0x71000000, r1, x2, b2, d2);
3127 }
3128 
3129 
3130 static UChar *
s390_emit_MSY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3131 s390_emit_MSY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3132 {
3133    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3134       s390_disasm(ENC3(MNM, GPR, SDXB), "msy", r1, dh2, dl2, x2, b2);
3135 
3136    return emit_RXY(p, 0xe30000000051ULL, r1, x2, b2, dl2, dh2);
3137 }
3138 
3139 
3140 static UChar *
s390_emit_MSG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3141 s390_emit_MSG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3142 {
3143    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3144       s390_disasm(ENC3(MNM, GPR, SDXB), "msg", r1, dh2, dl2, x2, b2);
3145 
3146    return emit_RXY(p, 0xe3000000000cULL, r1, x2, b2, dl2, dh2);
3147 }
3148 
3149 
3150 static UChar *
s390_emit_MSFI(UChar * p,UChar r1,UInt i2)3151 s390_emit_MSFI(UChar *p, UChar r1, UInt i2)
3152 {
3153    vassert(s390_host_has_gie);
3154 
3155    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3156       s390_disasm(ENC3(MNM, GPR, INT), "msfi", r1, i2);
3157 
3158    return emit_RIL(p, 0xc20100000000ULL, r1, i2);
3159 }
3160 
3161 
3162 static UChar *
s390_emit_MSGFI(UChar * p,UChar r1,UInt i2)3163 s390_emit_MSGFI(UChar *p, UChar r1, UInt i2)
3164 {
3165    vassert(s390_host_has_gie);
3166 
3167    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3168       s390_disasm(ENC3(MNM, GPR, INT), "msgfi", r1, i2);
3169 
3170    return emit_RIL(p, 0xc20000000000ULL, r1, i2);
3171 }
3172 
3173 
3174 static UChar *
s390_emit_MVC(UChar * p,UInt l,UChar b1,UShort d1,UChar b2,UShort d2)3175 s390_emit_MVC(UChar *p, UInt l, UChar b1, UShort d1, UChar b2, UShort d2)
3176 {
3177    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3178       s390_disasm(ENC3(MNM, UDLB, UDXB), "mvc", d1, l, b1, d2, 0, b2);
3179 
3180    return emit_SSa(p, 0xd20000000000ULL, l, b1, d1, b2, d2);
3181 }
3182 
3183 
3184 static UChar *
s390_emit_MVI(UChar * p,UChar i2,UChar b1,UShort d1)3185 s390_emit_MVI(UChar *p, UChar i2, UChar b1, UShort d1)
3186 {
3187    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3188       s390_disasm(ENC3(MNM, UDXB, INT), "mvi", d1, 0, b1, i2);
3189 
3190    return emit_SI(p, 0x92000000, i2, b1, d1);
3191 }
3192 
3193 
3194 static UChar *
s390_emit_MVHHI(UChar * p,UChar b1,UShort d1,UShort i2)3195 s390_emit_MVHHI(UChar *p, UChar b1, UShort d1, UShort i2)
3196 {
3197    vassert(s390_host_has_gie);
3198 
3199    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3200       s390_disasm(ENC3(MNM, UDXB, INT), "mvhhi", d1, 0, b1, i2);
3201 
3202    return emit_SIL(p, 0xe54400000000ULL, b1, d1, i2);
3203 }
3204 
3205 
3206 static UChar *
s390_emit_MVHI(UChar * p,UChar b1,UShort d1,UShort i2)3207 s390_emit_MVHI(UChar *p, UChar b1, UShort d1, UShort i2)
3208 {
3209    vassert(s390_host_has_gie);
3210 
3211    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3212       s390_disasm(ENC3(MNM, UDXB, INT), "mvhi", d1, 0, b1, i2);
3213 
3214    return emit_SIL(p, 0xe54c00000000ULL, b1, d1, i2);
3215 }
3216 
3217 
3218 static UChar *
s390_emit_MVGHI(UChar * p,UChar b1,UShort d1,UShort i2)3219 s390_emit_MVGHI(UChar *p, UChar b1, UShort d1, UShort i2)
3220 {
3221    vassert(s390_host_has_gie);
3222 
3223    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3224       s390_disasm(ENC3(MNM, UDXB, INT), "mvghi", d1, 0, b1, i2);
3225 
3226    return emit_SIL(p, 0xe54800000000ULL, b1, d1, i2);
3227 }
3228 
3229 
3230 static UChar *
s390_emit_OR(UChar * p,UChar r1,UChar r2)3231 s390_emit_OR(UChar *p, UChar r1, UChar r2)
3232 {
3233    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3234       s390_disasm(ENC3(MNM, GPR, GPR), "or", r1, r2);
3235 
3236    return emit_RR(p, 0x1600, r1, r2);
3237 }
3238 
3239 
3240 static UChar *
s390_emit_OGR(UChar * p,UChar r1,UChar r2)3241 s390_emit_OGR(UChar *p, UChar r1, UChar r2)
3242 {
3243    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3244       s390_disasm(ENC3(MNM, GPR, GPR), "ogr", r1, r2);
3245 
3246    return emit_RRE(p, 0xb9810000, r1, r2);
3247 }
3248 
3249 
3250 static UChar *
s390_emit_O(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3251 s390_emit_O(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3252 {
3253    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3254       s390_disasm(ENC3(MNM, GPR, UDXB), "o", r1, d2, x2, b2);
3255 
3256    return emit_RX(p, 0x56000000, r1, x2, b2, d2);
3257 }
3258 
3259 
3260 static UChar *
s390_emit_OY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3261 s390_emit_OY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3262 {
3263    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3264       s390_disasm(ENC3(MNM, GPR, SDXB), "oy", r1, dh2, dl2, x2, b2);
3265 
3266    return emit_RXY(p, 0xe30000000056ULL, r1, x2, b2, dl2, dh2);
3267 }
3268 
3269 
3270 static UChar *
s390_emit_OG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3271 s390_emit_OG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3272 {
3273    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3274       s390_disasm(ENC3(MNM, GPR, SDXB), "og", r1, dh2, dl2, x2, b2);
3275 
3276    return emit_RXY(p, 0xe30000000081ULL, r1, x2, b2, dl2, dh2);
3277 }
3278 
3279 
3280 static UChar *
s390_emit_OIHF(UChar * p,UChar r1,UInt i2)3281 s390_emit_OIHF(UChar *p, UChar r1, UInt i2)
3282 {
3283    vassert(s390_host_has_eimm);
3284 
3285    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3286       s390_disasm(ENC3(MNM, GPR, UINT), "oihf", r1, i2);
3287 
3288    return emit_RIL(p, 0xc00c00000000ULL, r1, i2);
3289 }
3290 
3291 
3292 static UChar *
s390_emit_OILF(UChar * p,UChar r1,UInt i2)3293 s390_emit_OILF(UChar *p, UChar r1, UInt i2)
3294 {
3295    vassert(s390_host_has_eimm);
3296 
3297    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3298       s390_disasm(ENC3(MNM, GPR, UINT), "oilf", r1, i2);
3299 
3300    return emit_RIL(p, 0xc00d00000000ULL, r1, i2);
3301 }
3302 
3303 
3304 static UChar *
s390_emit_OILL(UChar * p,UChar r1,UShort i2)3305 s390_emit_OILL(UChar *p, UChar r1, UShort i2)
3306 {
3307    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3308       s390_disasm(ENC3(MNM, GPR, UINT), "oill", r1, i2);
3309 
3310    return emit_RI(p, 0xa50b0000, r1, i2);
3311 }
3312 
3313 
3314 static UChar *
s390_emit_SLL(UChar * p,UChar r1,UChar b2,UShort d2)3315 s390_emit_SLL(UChar *p, UChar r1, UChar b2, UShort d2)
3316 {
3317    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3318       s390_disasm(ENC3(MNM, GPR, UDXB), "sll", r1, d2, 0, b2);
3319 
3320    return emit_RS(p, 0x89000000, r1, 0, b2, d2);
3321 }
3322 
3323 
3324 static UChar *
s390_emit_SLLG(UChar * p,UChar r1,UChar r3,UChar b2,UShort dl2,UChar dh2)3325 s390_emit_SLLG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
3326 {
3327    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3328       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "sllg", r1, r3, dh2, dl2, 0, b2);
3329 
3330    return emit_RSY(p, 0xeb000000000dULL, r1, r3, b2, dl2, dh2);
3331 }
3332 
3333 
3334 static UChar *
s390_emit_SRA(UChar * p,UChar r1,UChar b2,UShort d2)3335 s390_emit_SRA(UChar *p, UChar r1, UChar b2, UShort d2)
3336 {
3337    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3338       s390_disasm(ENC3(MNM, GPR, UDXB), "sra", r1, d2, 0, b2);
3339 
3340    return emit_RS(p, 0x8a000000, r1, 0, b2, d2);
3341 }
3342 
3343 
3344 static UChar *
s390_emit_SRAG(UChar * p,UChar r1,UChar r3,UChar b2,UShort dl2,UChar dh2)3345 s390_emit_SRAG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
3346 {
3347    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3348       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "srag", r1, r3, dh2, dl2, 0, b2);
3349 
3350    return emit_RSY(p, 0xeb000000000aULL, r1, r3, b2, dl2, dh2);
3351 }
3352 
3353 
3354 static UChar *
s390_emit_SRL(UChar * p,UChar r1,UChar b2,UShort d2)3355 s390_emit_SRL(UChar *p, UChar r1, UChar b2, UShort d2)
3356 {
3357    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3358       s390_disasm(ENC3(MNM, GPR, UDXB), "srl", r1, d2, 0, b2);
3359 
3360    return emit_RS(p, 0x88000000, r1, 0, b2, d2);
3361 }
3362 
3363 
3364 static UChar *
s390_emit_SRLG(UChar * p,UChar r1,UChar r3,UChar b2,UShort dl2,UChar dh2)3365 s390_emit_SRLG(UChar *p, UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
3366 {
3367    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3368       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), "srlg", r1, r3, dh2, dl2, 0, b2);
3369 
3370    return emit_RSY(p, 0xeb000000000cULL, r1, r3, b2, dl2, dh2);
3371 }
3372 
3373 
3374 static UChar *
s390_emit_ST(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3375 s390_emit_ST(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3376 {
3377    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3378       s390_disasm(ENC3(MNM, GPR, UDXB), "st", r1, d2, x2, b2);
3379 
3380    return emit_RX(p, 0x50000000, r1, x2, b2, d2);
3381 }
3382 
3383 
3384 static UChar *
s390_emit_STY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3385 s390_emit_STY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3386 {
3387    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3388       s390_disasm(ENC3(MNM, GPR, SDXB), "sty", r1, dh2, dl2, x2, b2);
3389 
3390    return emit_RXY(p, 0xe30000000050ULL, r1, x2, b2, dl2, dh2);
3391 }
3392 
3393 
3394 static UChar *
s390_emit_STG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3395 s390_emit_STG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3396 {
3397    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3398       s390_disasm(ENC3(MNM, GPR, SDXB), "stg", r1, dh2, dl2, x2, b2);
3399 
3400    return emit_RXY(p, 0xe30000000024ULL, r1, x2, b2, dl2, dh2);
3401 }
3402 
3403 
3404 static UChar *
s390_emit_STC(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3405 s390_emit_STC(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3406 {
3407    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3408       s390_disasm(ENC3(MNM, GPR, UDXB), "stc", r1, d2, x2, b2);
3409 
3410    return emit_RX(p, 0x42000000, r1, x2, b2, d2);
3411 }
3412 
3413 
3414 static UChar *
s390_emit_STCY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3415 s390_emit_STCY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3416 {
3417    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3418       s390_disasm(ENC3(MNM, GPR, SDXB), "stcy", r1, dh2, dl2, x2, b2);
3419 
3420    return emit_RXY(p, 0xe30000000072ULL, r1, x2, b2, dl2, dh2);
3421 }
3422 
3423 
3424 static UChar *
s390_emit_STH(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3425 s390_emit_STH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3426 {
3427    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3428       s390_disasm(ENC3(MNM, GPR, UDXB), "sth", r1, d2, x2, b2);
3429 
3430    return emit_RX(p, 0x40000000, r1, x2, b2, d2);
3431 }
3432 
3433 
3434 static UChar *
s390_emit_STHY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3435 s390_emit_STHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3436 {
3437    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3438       s390_disasm(ENC3(MNM, GPR, SDXB), "sthy", r1, dh2, dl2, x2, b2);
3439 
3440    return emit_RXY(p, 0xe30000000070ULL, r1, x2, b2, dl2, dh2);
3441 }
3442 
3443 
3444 static UChar *
s390_emit_SR(UChar * p,UChar r1,UChar r2)3445 s390_emit_SR(UChar *p, UChar r1, UChar r2)
3446 {
3447    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3448       s390_disasm(ENC3(MNM, GPR, GPR), "sr", r1, r2);
3449 
3450    return emit_RR(p, 0x1b00, r1, r2);
3451 }
3452 
3453 
3454 static UChar *
s390_emit_SGR(UChar * p,UChar r1,UChar r2)3455 s390_emit_SGR(UChar *p, UChar r1, UChar r2)
3456 {
3457    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3458       s390_disasm(ENC3(MNM, GPR, GPR), "sgr", r1, r2);
3459 
3460    return emit_RRE(p, 0xb9090000, r1, r2);
3461 }
3462 
3463 
3464 static UChar *
s390_emit_S(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3465 s390_emit_S(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3466 {
3467    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3468       s390_disasm(ENC3(MNM, GPR, UDXB), "s", r1, d2, x2, b2);
3469 
3470    return emit_RX(p, 0x5b000000, r1, x2, b2, d2);
3471 }
3472 
3473 
3474 static UChar *
s390_emit_SY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3475 s390_emit_SY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3476 {
3477    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3478       s390_disasm(ENC3(MNM, GPR, SDXB), "sy", r1, dh2, dl2, x2, b2);
3479 
3480    return emit_RXY(p, 0xe3000000005bULL, r1, x2, b2, dl2, dh2);
3481 }
3482 
3483 
3484 static UChar *
s390_emit_SG(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3485 s390_emit_SG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3486 {
3487    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3488       s390_disasm(ENC3(MNM, GPR, SDXB), "sg", r1, dh2, dl2, x2, b2);
3489 
3490    return emit_RXY(p, 0xe30000000009ULL, r1, x2, b2, dl2, dh2);
3491 }
3492 
3493 
3494 static UChar *
s390_emit_SH(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3495 s390_emit_SH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3496 {
3497    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3498       s390_disasm(ENC3(MNM, GPR, UDXB), "sh", r1, d2, x2, b2);
3499 
3500    return emit_RX(p, 0x4b000000, r1, x2, b2, d2);
3501 }
3502 
3503 
3504 static UChar *
s390_emit_SHY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3505 s390_emit_SHY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3506 {
3507    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3508       s390_disasm(ENC3(MNM, GPR, SDXB), "shy", r1, dh2, dl2, x2, b2);
3509 
3510    return emit_RXY(p, 0xe3000000007bULL, r1, x2, b2, dl2, dh2);
3511 }
3512 
3513 
3514 static UChar *
s390_emit_SLFI(UChar * p,UChar r1,UInt i2)3515 s390_emit_SLFI(UChar *p, UChar r1, UInt i2)
3516 {
3517    vassert(s390_host_has_eimm);
3518 
3519    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3520       s390_disasm(ENC3(MNM, GPR, UINT), "slfi", r1, i2);
3521 
3522    return emit_RIL(p, 0xc20500000000ULL, r1, i2);
3523 }
3524 
3525 
3526 static UChar *
s390_emit_SLGFI(UChar * p,UChar r1,UInt i2)3527 s390_emit_SLGFI(UChar *p, UChar r1, UInt i2)
3528 {
3529    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3530       s390_disasm(ENC3(MNM, GPR, UINT), "slgfi", r1, i2);
3531 
3532    return emit_RIL(p, 0xc20400000000ULL, r1, i2);
3533 }
3534 
3535 
3536 static UChar *
s390_emit_LDR(UChar * p,UChar r1,UChar r2)3537 s390_emit_LDR(UChar *p, UChar r1, UChar r2)
3538 {
3539    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3540       s390_disasm(ENC3(MNM, FPR, FPR), "ldr", r1, r2);
3541 
3542    return emit_RR(p, 0x2800, r1, r2);
3543 }
3544 
3545 
3546 static UChar *
s390_emit_LE(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3547 s390_emit_LE(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3548 {
3549    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3550       s390_disasm(ENC3(MNM, FPR, UDXB), "le", r1, d2, x2, b2);
3551 
3552    return emit_RX(p, 0x78000000, r1, x2, b2, d2);
3553 }
3554 
3555 
3556 static UChar *
s390_emit_LD(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3557 s390_emit_LD(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3558 {
3559    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3560       s390_disasm(ENC3(MNM, FPR, UDXB), "ld", r1, d2, x2, b2);
3561 
3562    return emit_RX(p, 0x68000000, r1, x2, b2, d2);
3563 }
3564 
3565 
3566 static UChar *
s390_emit_LEY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3567 s390_emit_LEY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3568 {
3569    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3570       s390_disasm(ENC3(MNM, FPR, SDXB), "ley", r1, dh2, dl2, x2, b2);
3571 
3572    return emit_RXY(p, 0xed0000000064ULL, r1, x2, b2, dl2, dh2);
3573 }
3574 
3575 
3576 static UChar *
s390_emit_LDY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3577 s390_emit_LDY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3578 {
3579    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3580       s390_disasm(ENC3(MNM, FPR, SDXB), "ldy", r1, dh2, dl2, x2, b2);
3581 
3582    return emit_RXY(p, 0xed0000000065ULL, r1, x2, b2, dl2, dh2);
3583 }
3584 
3585 
3586 static UChar *
s390_emit_LFPC(UChar * p,UChar b2,UShort d2)3587 s390_emit_LFPC(UChar *p, UChar b2, UShort d2)
3588 {
3589    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3590       s390_disasm(ENC2(MNM, UDXB), "lfpc", d2, 0, b2);
3591 
3592    return emit_S(p, 0xb29d0000, b2, d2);
3593 }
3594 
3595 
3596 static UChar *
s390_emit_LDGR(UChar * p,UChar r1,UChar r2)3597 s390_emit_LDGR(UChar *p, UChar r1, UChar r2)
3598 {
3599    vassert(s390_host_has_fgx);
3600 
3601    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3602       s390_disasm(ENC3(MNM, FPR, GPR), "ldgr", r1, r2);
3603 
3604    return emit_RRE(p, 0xb3c10000, r1, r2);
3605 }
3606 
3607 
3608 static UChar *
s390_emit_LGDR(UChar * p,UChar r1,UChar r2)3609 s390_emit_LGDR(UChar *p, UChar r1, UChar r2)
3610 {
3611    vassert(s390_host_has_fgx);
3612 
3613    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3614       s390_disasm(ENC3(MNM, GPR, FPR), "lgdr", r1, r2);
3615 
3616    return emit_RRE(p, 0xb3cd0000, r1, r2);
3617 }
3618 
3619 
3620 static UChar *
s390_emit_LZER(UChar * p,UChar r1,UChar r2)3621 s390_emit_LZER(UChar *p, UChar r1, UChar r2)
3622 {
3623    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3624       s390_disasm(ENC2(MNM, FPR), "lzer", r1);
3625 
3626    return emit_RRE(p, 0xb3740000, r1, r2);
3627 }
3628 
3629 
3630 static UChar *
s390_emit_LZDR(UChar * p,UChar r1,UChar r2)3631 s390_emit_LZDR(UChar *p, UChar r1, UChar r2)
3632 {
3633    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3634       s390_disasm(ENC2(MNM, FPR), "lzdr", r1);
3635 
3636    return emit_RRE(p, 0xb3750000, r1, r2);
3637 }
3638 
3639 
3640 static UChar *
s390_emit_SFPC(UChar * p,UChar r1)3641 s390_emit_SFPC(UChar *p, UChar r1)
3642 {
3643    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3644       s390_disasm(ENC2(MNM, GPR), "sfpc", r1);
3645 
3646    return emit_RRE(p, 0xb3840000, r1, 0);
3647 }
3648 
3649 
3650 static UChar *
s390_emit_STE(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3651 s390_emit_STE(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3652 {
3653    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3654       s390_disasm(ENC3(MNM, FPR, UDXB), "ste", r1, d2, x2, b2);
3655 
3656    return emit_RX(p, 0x70000000, r1, x2, b2, d2);
3657 }
3658 
3659 
3660 static UChar *
s390_emit_STD(UChar * p,UChar r1,UChar x2,UChar b2,UShort d2)3661 s390_emit_STD(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
3662 {
3663    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3664       s390_disasm(ENC3(MNM, FPR, UDXB), "std", r1, d2, x2, b2);
3665 
3666    return emit_RX(p, 0x60000000, r1, x2, b2, d2);
3667 }
3668 
3669 
3670 static UChar *
s390_emit_STEY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3671 s390_emit_STEY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3672 {
3673    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3674       s390_disasm(ENC3(MNM, FPR, SDXB), "stey", r1, dh2, dl2, x2, b2);
3675 
3676    return emit_RXY(p, 0xed0000000066ULL, r1, x2, b2, dl2, dh2);
3677 }
3678 
3679 
3680 static UChar *
s390_emit_STDY(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)3681 s390_emit_STDY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3682 {
3683    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3684       s390_disasm(ENC3(MNM, FPR, SDXB), "stdy", r1, dh2, dl2, x2, b2);
3685 
3686    return emit_RXY(p, 0xed0000000067ULL, r1, x2, b2, dl2, dh2);
3687 }
3688 
3689 
3690 static UChar *
s390_emit_STFPC(UChar * p,UChar b2,UShort d2)3691 s390_emit_STFPC(UChar *p, UChar b2, UShort d2)
3692 {
3693    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3694       s390_disasm(ENC2(MNM, UDXB), "stfpc", d2, 0, b2);
3695 
3696    return emit_S(p, 0xb29c0000, b2, d2);
3697 }
3698 
3699 
3700 static UChar *
s390_emit_AEBR(UChar * p,UChar r1,UChar r2)3701 s390_emit_AEBR(UChar *p, UChar r1, UChar r2)
3702 {
3703    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3704       s390_disasm(ENC3(MNM, FPR, FPR), "aebr", r1, r2);
3705 
3706    return emit_RRE(p, 0xb30a0000, r1, r2);
3707 }
3708 
3709 
3710 static UChar *
s390_emit_ADBR(UChar * p,UChar r1,UChar r2)3711 s390_emit_ADBR(UChar *p, UChar r1, UChar r2)
3712 {
3713    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3714       s390_disasm(ENC3(MNM, FPR, FPR), "adbr", r1, r2);
3715 
3716    return emit_RRE(p, 0xb31a0000, r1, r2);
3717 }
3718 
3719 
3720 static UChar *
s390_emit_AXBR(UChar * p,UChar r1,UChar r2)3721 s390_emit_AXBR(UChar *p, UChar r1, UChar r2)
3722 {
3723    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3724       s390_disasm(ENC3(MNM, FPR, FPR), "axbr", r1, r2);
3725 
3726    return emit_RRE(p, 0xb34a0000, r1, r2);
3727 }
3728 
3729 
3730 static UChar *
s390_emit_CEBR(UChar * p,UChar r1,UChar r2)3731 s390_emit_CEBR(UChar *p, UChar r1, UChar r2)
3732 {
3733    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3734       s390_disasm(ENC3(MNM, FPR, FPR), "cebr", r1, r2);
3735 
3736    return emit_RRE(p, 0xb3090000, r1, r2);
3737 }
3738 
3739 
3740 static UChar *
s390_emit_CDBR(UChar * p,UChar r1,UChar r2)3741 s390_emit_CDBR(UChar *p, UChar r1, UChar r2)
3742 {
3743    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3744       s390_disasm(ENC3(MNM, FPR, FPR), "cdbr", r1, r2);
3745 
3746    return emit_RRE(p, 0xb3190000, r1, r2);
3747 }
3748 
3749 
3750 static UChar *
s390_emit_CXBR(UChar * p,UChar r1,UChar r2)3751 s390_emit_CXBR(UChar *p, UChar r1, UChar r2)
3752 {
3753    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3754       s390_disasm(ENC3(MNM, FPR, FPR), "cxbr", r1, r2);
3755 
3756    return emit_RRE(p, 0xb3490000, r1, r2);
3757 }
3758 
3759 
3760 static UChar *
s390_emit_CEFBRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3761 s390_emit_CEFBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3762 {
3763    vassert(m4 == 0);
3764    vassert(m3 == 0 || s390_host_has_fpext);
3765 
3766    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
3767       if (m3 == 0)
3768          s390_disasm(ENC3(MNM, FPR, GPR), "cefbr", r1, r2);
3769       else
3770          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT),
3771                      "cefbra", r1, m3, r2, m4);
3772    }
3773 
3774    return emit_RRF2(p, 0xb3940000, m3, m4, r1, r2);
3775 }
3776 
3777 
3778 static UChar *
s390_emit_CDFBRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3779 s390_emit_CDFBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3780 {
3781    vassert(m4 == 0);
3782    vassert(m3 == 0 || s390_host_has_fpext);
3783 
3784    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
3785       if (m3 == 0)
3786          s390_disasm(ENC3(MNM, FPR, GPR), "cdfbr", r1, r2);
3787       else
3788          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT),
3789                      "cdfbra", r1, m3, r2, m4);
3790    }
3791 
3792    return emit_RRF2(p, 0xb3950000, m3, m4, r1, r2);
3793 }
3794 
3795 
3796 static UChar *
s390_emit_CXFBRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3797 s390_emit_CXFBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3798 {
3799    vassert(m4 == 0);
3800    vassert(m3 == 0 || s390_host_has_fpext);
3801 
3802    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
3803       if (m3 == 0)
3804          s390_disasm(ENC3(MNM, FPR, GPR), "cxfbr", r1, r2);
3805       else
3806          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT),
3807                      "cxfbra", r1, m3, r2, m4);
3808    }
3809 
3810    return emit_RRF2(p, 0xb3960000, m3, m4, r1, r2);
3811 }
3812 
3813 
3814 static UChar *
s390_emit_CEGBRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3815 s390_emit_CEGBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3816 {
3817    vassert(m4 == 0);
3818    vassert(m3 == 0 || s390_host_has_fpext);
3819 
3820    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
3821       if (m3 == 0)
3822          s390_disasm(ENC3(MNM, FPR, GPR), "cegbr", r1, r2);
3823       else
3824          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT),
3825                      "cegbra", r1, m3, r2, m4);
3826    }
3827 
3828    return emit_RRF2(p, 0xb3a40000, m3, m4, r1, r2);
3829 }
3830 
3831 
3832 static UChar *
s390_emit_CDGBRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3833 s390_emit_CDGBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3834 {
3835    vassert(m4 == 0);
3836    vassert(m3 == 0 || s390_host_has_fpext);
3837 
3838    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
3839       if (m3 == 0)
3840          s390_disasm(ENC3(MNM, FPR, GPR), "cdgbr", r1, r2);
3841       else
3842          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT),
3843                      "cdgbra", r1, m3, r2, m4);
3844    }
3845 
3846    return emit_RRF2(p, 0xb3a50000, m3, m4, r1, r2);
3847 }
3848 
3849 
3850 static UChar *
s390_emit_CXGBRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3851 s390_emit_CXGBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3852 {
3853    vassert(m4 == 0);
3854    vassert(m3 == 0 || s390_host_has_fpext);
3855 
3856    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
3857       if (m3 == 0)
3858          s390_disasm(ENC3(MNM, FPR, GPR), "cxgbr", r1, r2);
3859       else
3860          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT),
3861                      "cxgbra", r1, m3, r2, m4);
3862    }
3863 
3864    return emit_RRF2(p, 0xb3a60000, m3, m4, r1, r2);
3865 }
3866 
3867 
3868 static UChar *
s390_emit_CELFBR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3869 s390_emit_CELFBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3870 {
3871    vassert(m4 == 0);
3872    vassert(s390_host_has_fpext);
3873 
3874    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3875       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "celfbr", r1, m3, r2, m4);
3876 
3877    return emit_RRF2(p, 0xb3900000, m3, m4, r1, r2);
3878 }
3879 
3880 
3881 static UChar *
s390_emit_CDLFBR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3882 s390_emit_CDLFBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3883 {
3884    vassert(m4 == 0);
3885    vassert(s390_host_has_fpext);
3886 
3887    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3888       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cdlfbr", r1, m3, r2, m4);
3889 
3890    return emit_RRF2(p, 0xb3910000, m3, m4, r1, r2);
3891 }
3892 
3893 
3894 static UChar *
s390_emit_CXLFBR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3895 s390_emit_CXLFBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3896 {
3897    vassert(m4 == 0);
3898    vassert(s390_host_has_fpext);
3899 
3900    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3901       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cxlfbr", r1, m3, r2, m4);
3902 
3903    return emit_RRF2(p, 0xb3920000, m3, m4, r1, r2);
3904 }
3905 
3906 
3907 static UChar *
s390_emit_CELGBR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3908 s390_emit_CELGBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3909 {
3910    vassert(m4 == 0);
3911    vassert(s390_host_has_fpext);
3912 
3913    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3914       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "celgbr", r1, m3, r2, m4);
3915 
3916    return emit_RRF2(p, 0xb3a00000, m3, m4, r1, r2);
3917 }
3918 
3919 
3920 static UChar *
s390_emit_CDLGBR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3921 s390_emit_CDLGBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3922 {
3923    vassert(m4 == 0);
3924    vassert(s390_host_has_fpext);
3925 
3926    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3927       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cdlgbr", r1, m3, r2, m4);
3928 
3929    return emit_RRF2(p, 0xb3a10000, m3, m4, r1, r2);
3930 }
3931 
3932 
3933 static UChar *
s390_emit_CXLGBR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3934 s390_emit_CXLGBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3935 {
3936    vassert(m4 == 0);
3937    vassert(s390_host_has_fpext);
3938 
3939    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3940       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cxlgbr", r1, m3, r2, m4);
3941 
3942    return emit_RRF2(p, 0xb3a20000, m3, m4, r1, r2);
3943 }
3944 
3945 
3946 static UChar *
s390_emit_CLFEBR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3947 s390_emit_CLFEBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3948 {
3949    vassert(m4 == 0);
3950    vassert(s390_host_has_fpext);
3951 
3952    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3953       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clfebr", r1, m3, r2, m4);
3954 
3955    return emit_RRF2(p, 0xb39c0000, m3, m4, r1, r2);
3956 }
3957 
3958 
3959 static UChar *
s390_emit_CLFDBR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3960 s390_emit_CLFDBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3961 {
3962    vassert(m4 == 0);
3963    vassert(s390_host_has_fpext);
3964 
3965    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3966       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clfdbr", r1, m3, r2, m4);
3967 
3968    return emit_RRF2(p, 0xb39d0000, m3, m4, r1, r2);
3969 }
3970 
3971 
3972 static UChar *
s390_emit_CLFXBR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3973 s390_emit_CLFXBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3974 {
3975    vassert(m4 == 0);
3976    vassert(s390_host_has_fpext);
3977 
3978    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3979       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clfxbr", r1, m3, r2, m4);
3980 
3981    return emit_RRF2(p, 0xb39e0000, m3, m4, r1, r2);
3982 }
3983 
3984 
3985 static UChar *
s390_emit_CLGEBR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3986 s390_emit_CLGEBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
3987 {
3988    vassert(m4 == 0);
3989    vassert(s390_host_has_fpext);
3990 
3991    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
3992       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clgebr", r1, m3, r2, m4);
3993 
3994    return emit_RRF2(p, 0xb3ac0000, m3, m4, r1, r2);
3995 }
3996 
3997 
3998 static UChar *
s390_emit_CLGDBR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)3999 s390_emit_CLGDBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4000 {
4001    vassert(m4 == 0);
4002    vassert(s390_host_has_fpext);
4003 
4004    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4005       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clgdbr", r1, m3, r2, m4);
4006 
4007    return emit_RRF2(p, 0xb3ad0000, m3, m4, r1, r2);
4008 }
4009 
4010 
4011 static UChar *
s390_emit_CLGXBR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4012 s390_emit_CLGXBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4013 {
4014    vassert(m4 == 0);
4015    vassert(s390_host_has_fpext);
4016 
4017    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4018       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clgxbr", r1, m3, r2, m4);
4019 
4020    return emit_RRF2(p, 0xb3ae0000, m3, m4, r1, r2);
4021 }
4022 
4023 
4024 static UChar *
s390_emit_CFEBR(UChar * p,UChar r3,UChar r1,UChar r2)4025 s390_emit_CFEBR(UChar *p, UChar r3, UChar r1, UChar r2)
4026 {
4027    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4028       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cfebr", r1, r3, r2);
4029 
4030    return emit_RRF3(p, 0xb3980000, r3, r1, r2);
4031 }
4032 
4033 
4034 static UChar *
s390_emit_CFDBR(UChar * p,UChar r3,UChar r1,UChar r2)4035 s390_emit_CFDBR(UChar *p, UChar r3, UChar r1, UChar r2)
4036 {
4037    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4038       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cfdbr", r1, r3, r2);
4039 
4040    return emit_RRF3(p, 0xb3990000, r3, r1, r2);
4041 }
4042 
4043 
4044 static UChar *
s390_emit_CFXBR(UChar * p,UChar r3,UChar r1,UChar r2)4045 s390_emit_CFXBR(UChar *p, UChar r3, UChar r1, UChar r2)
4046 {
4047    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4048       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cfxbr", r1, r3, r2);
4049 
4050    return emit_RRF3(p, 0xb39a0000, r3, r1, r2);
4051 }
4052 
4053 
4054 static UChar *
s390_emit_CGEBR(UChar * p,UChar r3,UChar r1,UChar r2)4055 s390_emit_CGEBR(UChar *p, UChar r3, UChar r1, UChar r2)
4056 {
4057    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4058       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cgebr", r1, r3, r2);
4059 
4060    return emit_RRF3(p, 0xb3a80000, r3, r1, r2);
4061 }
4062 
4063 
4064 static UChar *
s390_emit_CGDBR(UChar * p,UChar r3,UChar r1,UChar r2)4065 s390_emit_CGDBR(UChar *p, UChar r3, UChar r1, UChar r2)
4066 {
4067    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4068       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cgdbr", r1, r3, r2);
4069 
4070    return emit_RRF3(p, 0xb3a90000, r3, r1, r2);
4071 }
4072 
4073 
4074 static UChar *
s390_emit_CGXBR(UChar * p,UChar r3,UChar r1,UChar r2)4075 s390_emit_CGXBR(UChar *p, UChar r3, UChar r1, UChar r2)
4076 {
4077    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4078       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cgxbr", r1, r3, r2);
4079 
4080    return emit_RRF3(p, 0xb3aa0000, r3, r1, r2);
4081 }
4082 
4083 
4084 static UChar *
s390_emit_DEBR(UChar * p,UChar r1,UChar r2)4085 s390_emit_DEBR(UChar *p, UChar r1, UChar r2)
4086 {
4087    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4088       s390_disasm(ENC3(MNM, FPR, FPR), "debr", r1, r2);
4089 
4090    return emit_RRE(p, 0xb30d0000, r1, r2);
4091 }
4092 
4093 
4094 static UChar *
s390_emit_DDBR(UChar * p,UChar r1,UChar r2)4095 s390_emit_DDBR(UChar *p, UChar r1, UChar r2)
4096 {
4097    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4098       s390_disasm(ENC3(MNM, FPR, FPR), "ddbr", r1, r2);
4099 
4100    return emit_RRE(p, 0xb31d0000, r1, r2);
4101 }
4102 
4103 
4104 static UChar *
s390_emit_DXBR(UChar * p,UChar r1,UChar r2)4105 s390_emit_DXBR(UChar *p, UChar r1, UChar r2)
4106 {
4107    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4108       s390_disasm(ENC3(MNM, FPR, FPR), "dxbr", r1, r2);
4109 
4110    return emit_RRE(p, 0xb34d0000, r1, r2);
4111 }
4112 
4113 
4114 static UChar *
s390_emit_LCEBR(UChar * p,UChar r1,UChar r2)4115 s390_emit_LCEBR(UChar *p, UChar r1, UChar r2)
4116 {
4117    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4118       s390_disasm(ENC3(MNM, FPR, FPR), "lcebr", r1, r2);
4119 
4120    return emit_RRE(p, 0xb3030000, r1, r2);
4121 }
4122 
4123 
4124 static UChar *
s390_emit_LCDBR(UChar * p,UChar r1,UChar r2)4125 s390_emit_LCDBR(UChar *p, UChar r1, UChar r2)
4126 {
4127    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4128       s390_disasm(ENC3(MNM, FPR, FPR), "lcdbr", r1, r2);
4129 
4130    return emit_RRE(p, 0xb3130000, r1, r2);
4131 }
4132 
4133 
4134 static UChar *
s390_emit_LCXBR(UChar * p,UChar r1,UChar r2)4135 s390_emit_LCXBR(UChar *p, UChar r1, UChar r2)
4136 {
4137    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4138       s390_disasm(ENC3(MNM, FPR, FPR), "lcxbr", r1, r2);
4139 
4140    return emit_RRE(p, 0xb3430000, r1, r2);
4141 }
4142 
4143 
4144 static UChar *
s390_emit_LDEBR(UChar * p,UChar r1,UChar r2)4145 s390_emit_LDEBR(UChar *p, UChar r1, UChar r2)
4146 {
4147    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4148       s390_disasm(ENC3(MNM, FPR, FPR), "ldebr", r1, r2);
4149 
4150    return emit_RRE(p, 0xb3040000, r1, r2);
4151 }
4152 
4153 
4154 static UChar *
s390_emit_LXDBR(UChar * p,UChar r1,UChar r2)4155 s390_emit_LXDBR(UChar *p, UChar r1, UChar r2)
4156 {
4157    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4158       s390_disasm(ENC3(MNM, FPR, FPR), "lxdbr", r1, r2);
4159 
4160    return emit_RRE(p, 0xb3050000, r1, r2);
4161 }
4162 
4163 
4164 static UChar *
s390_emit_LXEBR(UChar * p,UChar r1,UChar r2)4165 s390_emit_LXEBR(UChar *p, UChar r1, UChar r2)
4166 {
4167    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4168       s390_disasm(ENC3(MNM, FPR, FPR), "lxebr", r1, r2);
4169 
4170    return emit_RRE(p, 0xb3060000, r1, r2);
4171 }
4172 
4173 
4174 static UChar *
s390_emit_LNEBR(UChar * p,UChar r1,UChar r2)4175 s390_emit_LNEBR(UChar *p, UChar r1, UChar r2)
4176 {
4177    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4178       s390_disasm(ENC3(MNM, FPR, FPR), "lnebr", r1, r2);
4179 
4180    return emit_RRE(p, 0xb3010000, r1, r2);
4181 }
4182 
4183 
4184 static UChar *
s390_emit_LNDBR(UChar * p,UChar r1,UChar r2)4185 s390_emit_LNDBR(UChar *p, UChar r1, UChar r2)
4186 {
4187    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4188       s390_disasm(ENC3(MNM, FPR, FPR), "lndbr", r1, r2);
4189 
4190    return emit_RRE(p, 0xb3110000, r1, r2);
4191 }
4192 
4193 
4194 static UChar *
s390_emit_LNXBR(UChar * p,UChar r1,UChar r2)4195 s390_emit_LNXBR(UChar *p, UChar r1, UChar r2)
4196 {
4197    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4198       s390_disasm(ENC3(MNM, FPR, FPR), "lnxbr", r1, r2);
4199 
4200    return emit_RRE(p, 0xb3410000, r1, r2);
4201 }
4202 
4203 
4204 static UChar *
s390_emit_LPEBR(UChar * p,UChar r1,UChar r2)4205 s390_emit_LPEBR(UChar *p, UChar r1, UChar r2)
4206 {
4207    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4208       s390_disasm(ENC3(MNM, FPR, FPR), "lpebr", r1, r2);
4209 
4210    return emit_RRE(p, 0xb3000000, r1, r2);
4211 }
4212 
4213 
4214 static UChar *
s390_emit_LPDBR(UChar * p,UChar r1,UChar r2)4215 s390_emit_LPDBR(UChar *p, UChar r1, UChar r2)
4216 {
4217    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4218       s390_disasm(ENC3(MNM, FPR, FPR), "lpdbr", r1, r2);
4219 
4220    return emit_RRE(p, 0xb3100000, r1, r2);
4221 }
4222 
4223 
4224 static UChar *
s390_emit_LPXBR(UChar * p,UChar r1,UChar r2)4225 s390_emit_LPXBR(UChar *p, UChar r1, UChar r2)
4226 {
4227    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4228       s390_disasm(ENC3(MNM, FPR, FPR), "lpxbr", r1, r2);
4229 
4230    return emit_RRE(p, 0xb3400000, r1, r2);
4231 }
4232 
4233 
4234 static UChar *
s390_emit_LEDBRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4235 s390_emit_LEDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4236 {
4237    vassert(m4 == 0);
4238    vassert(m3 == 0 || s390_host_has_fpext);
4239 
4240    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4241       if (m3 == 0)
4242          s390_disasm(ENC3(MNM, FPR, FPR), "ledbr", r1, r2);
4243       else
4244          s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
4245                      "ledbra", r1, m3, r2, m4);
4246    }
4247 
4248    return emit_RRF2(p, 0xb3440000, m3, m4, r1, r2);
4249 }
4250 
4251 
4252 static UChar *
s390_emit_LDXBRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4253 s390_emit_LDXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4254 {
4255    vassert(m4 == 0);
4256    vassert(m3 == 0 || s390_host_has_fpext);
4257 
4258    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4259       if (m3 == 0)
4260          s390_disasm(ENC3(MNM, FPR, FPR), "ldxbr", r1, r2);
4261       else
4262          s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
4263                      "ldxbra", r1, m3, r2, m4);
4264    }
4265 
4266    return emit_RRF2(p, 0xb3450000, m3, m4, r1, r2);
4267 }
4268 
4269 
4270 static UChar *
s390_emit_LEXBRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4271 s390_emit_LEXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4272 {
4273    vassert(m4 == 0);
4274    vassert(m3 == 0 || s390_host_has_fpext);
4275 
4276    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4277       if (m3 == 0)
4278          s390_disasm(ENC3(MNM, FPR, FPR), "lexbr", r1, r2);
4279       else
4280          s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
4281                      "lexbra", r1, m3, r2, m4);
4282    }
4283 
4284    return emit_RRF2(p, 0xb3460000, m3, m4, r1, r2);
4285 }
4286 
4287 
4288 static UChar *
s390_emit_FIEBRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4289 s390_emit_FIEBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4290 {
4291    vassert(m3 == 0 || s390_host_has_fpext);
4292 
4293    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4294       if (m4 == 0)
4295          s390_disasm(ENC4(MNM, FPR, UINT, FPR), "fiebr", r1, m3, r2);
4296       else
4297          s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
4298                      "fiebra", r1, m3, r2, m4);
4299    }
4300 
4301    return emit_RRF2(p, 0xb3570000, m3, m4, r1, r2);
4302 }
4303 
4304 
4305 static UChar *
s390_emit_FIDBRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4306 s390_emit_FIDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4307 {
4308    vassert(m3 == 0 || s390_host_has_fpext);
4309 
4310    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4311       if (m4 == 0)
4312          s390_disasm(ENC4(MNM, FPR, UINT, FPR), "fidbr", r1, m3, r2);
4313       else
4314          s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
4315                      "fidbra", r1, m3, r2, m4);
4316    }
4317 
4318    return emit_RRF2(p, 0xb35f0000, m3, m4, r1, r2);
4319 }
4320 
4321 
4322 static UChar *
s390_emit_FIXBRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4323 s390_emit_FIXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4324 {
4325    vassert(m3 == 0 || s390_host_has_fpext);
4326 
4327    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4328       if (m4 == 0)
4329          s390_disasm(ENC4(MNM, FPR, UINT, FPR), "fixbr", r1, m3, r2);
4330       else
4331          s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT),
4332                      "fixbra", r1, m3, r2, m4);
4333    }
4334 
4335    return emit_RRF2(p, 0xb3470000, m3, m4, r1, r2);
4336 }
4337 
4338 
4339 static UChar *
s390_emit_MEEBR(UChar * p,UChar r1,UChar r2)4340 s390_emit_MEEBR(UChar *p, UChar r1, UChar r2)
4341 {
4342    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4343       s390_disasm(ENC3(MNM, FPR, FPR), "meebr", r1, r2);
4344 
4345    return emit_RRE(p, 0xb3170000, r1, r2);
4346 }
4347 
4348 
4349 static UChar *
s390_emit_MDBR(UChar * p,UChar r1,UChar r2)4350 s390_emit_MDBR(UChar *p, UChar r1, UChar r2)
4351 {
4352    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4353       s390_disasm(ENC3(MNM, FPR, FPR), "mdbr", r1, r2);
4354 
4355    return emit_RRE(p, 0xb31c0000, r1, r2);
4356 }
4357 
4358 
4359 static UChar *
s390_emit_MXBR(UChar * p,UChar r1,UChar r2)4360 s390_emit_MXBR(UChar *p, UChar r1, UChar r2)
4361 {
4362    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4363       s390_disasm(ENC3(MNM, FPR, FPR), "mxbr", r1, r2);
4364 
4365    return emit_RRE(p, 0xb34c0000, r1, r2);
4366 }
4367 
4368 
4369 static UChar *
s390_emit_MAEBR(UChar * p,UChar r1,UChar r3,UChar r2)4370 s390_emit_MAEBR(UChar *p, UChar r1, UChar r3, UChar r2)
4371 {
4372    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4373       s390_disasm(ENC4(MNM, FPR, FPR, FPR), "maebr", r1, r3, r2);
4374 
4375    return emit_RRF(p, 0xb30e0000, r1, r3, r2);
4376 }
4377 
4378 
4379 static UChar *
s390_emit_MADBR(UChar * p,UChar r1,UChar r3,UChar r2)4380 s390_emit_MADBR(UChar *p, UChar r1, UChar r3, UChar r2)
4381 {
4382    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4383       s390_disasm(ENC4(MNM, FPR, FPR, FPR), "madbr", r1, r3, r2);
4384 
4385    return emit_RRF(p, 0xb31e0000, r1, r3, r2);
4386 }
4387 
4388 
4389 static UChar *
s390_emit_MSEBR(UChar * p,UChar r1,UChar r3,UChar r2)4390 s390_emit_MSEBR(UChar *p, UChar r1, UChar r3, UChar r2)
4391 {
4392    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4393       s390_disasm(ENC4(MNM, FPR, FPR, FPR), "msebr", r1, r3, r2);
4394 
4395    return emit_RRF(p, 0xb30f0000, r1, r3, r2);
4396 }
4397 
4398 
4399 static UChar *
s390_emit_MSDBR(UChar * p,UChar r1,UChar r3,UChar r2)4400 s390_emit_MSDBR(UChar *p, UChar r1, UChar r3, UChar r2)
4401 {
4402    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4403       s390_disasm(ENC4(MNM, FPR, FPR, FPR), "msdbr", r1, r3, r2);
4404 
4405    return emit_RRF(p, 0xb31f0000, r1, r3, r2);
4406 }
4407 
4408 
4409 static UChar *
s390_emit_SQEBR(UChar * p,UChar r1,UChar r2)4410 s390_emit_SQEBR(UChar *p, UChar r1, UChar r2)
4411 {
4412    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4413       s390_disasm(ENC3(MNM, FPR, FPR), "sqebr", r1, r2);
4414 
4415    return emit_RRE(p, 0xb3140000, r1, r2);
4416 }
4417 
4418 
4419 static UChar *
s390_emit_SQDBR(UChar * p,UChar r1,UChar r2)4420 s390_emit_SQDBR(UChar *p, UChar r1, UChar r2)
4421 {
4422    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4423       s390_disasm(ENC3(MNM, FPR, FPR), "sqdbr", r1, r2);
4424 
4425    return emit_RRE(p, 0xb3150000, r1, r2);
4426 }
4427 
4428 
4429 static UChar *
s390_emit_SQXBR(UChar * p,UChar r1,UChar r2)4430 s390_emit_SQXBR(UChar *p, UChar r1, UChar r2)
4431 {
4432    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4433       s390_disasm(ENC3(MNM, FPR, FPR), "sqxbr", r1, r2);
4434 
4435    return emit_RRE(p, 0xb3160000, r1, r2);
4436 }
4437 
4438 
4439 static UChar *
s390_emit_SEBR(UChar * p,UChar r1,UChar r2)4440 s390_emit_SEBR(UChar *p, UChar r1, UChar r2)
4441 {
4442    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4443       s390_disasm(ENC3(MNM, FPR, FPR), "sebr", r1, r2);
4444 
4445    return emit_RRE(p, 0xb30b0000, r1, r2);
4446 }
4447 
4448 
4449 static UChar *
s390_emit_SDBR(UChar * p,UChar r1,UChar r2)4450 s390_emit_SDBR(UChar *p, UChar r1, UChar r2)
4451 {
4452    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4453       s390_disasm(ENC3(MNM, FPR, FPR), "sdbr", r1, r2);
4454 
4455    return emit_RRE(p, 0xb31b0000, r1, r2);
4456 }
4457 
4458 
4459 static UChar *
s390_emit_SXBR(UChar * p,UChar r1,UChar r2)4460 s390_emit_SXBR(UChar *p, UChar r1, UChar r2)
4461 {
4462    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4463       s390_disasm(ENC3(MNM, FPR, FPR), "sxbr", r1, r2);
4464 
4465    return emit_RRE(p, 0xb34b0000, r1, r2);
4466 }
4467 
4468 
4469 static UChar *
s390_emit_ADTRA(UChar * p,UChar r3,UChar m4,UChar r1,UChar r2)4470 s390_emit_ADTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
4471 {
4472    vassert(s390_host_has_dfp);
4473    vassert(m4 == 0 || s390_host_has_fpext);
4474    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4475       if (m4 == 0)
4476          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "adtr", r1, r2, r3);
4477       else
4478          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "adtra", r1, r2, r3, m4);
4479    }
4480 
4481    return emit_RRF4(p, 0xb3d20000, r3, m4, r1, r2);
4482 }
4483 
4484 
4485 static UChar *
s390_emit_AXTRA(UChar * p,UChar r3,UChar m4,UChar r1,UChar r2)4486 s390_emit_AXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
4487 {
4488    vassert(s390_host_has_dfp);
4489    vassert(m4 == 0 || s390_host_has_fpext);
4490    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4491       if (m4 == 0)
4492          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "axtr", r1, r2, r3);
4493       else
4494          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "axtra", r1, r2, r3, m4);
4495    }
4496 
4497    return emit_RRF4(p, 0xb3da0000, r3, m4, r1, r2);
4498 }
4499 
4500 
4501 static UChar *
s390_emit_CDTR(UChar * p,UChar r1,UChar r2)4502 s390_emit_CDTR(UChar *p, UChar r1, UChar r2)
4503 {
4504    vassert(s390_host_has_dfp);
4505    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4506       s390_disasm(ENC3(MNM, FPR, FPR), "cdtr", r1, r2);
4507 
4508    return emit_RRE(p, 0xb3e40000, r1, r2);
4509 }
4510 
4511 
4512 static UChar *
s390_emit_CXTR(UChar * p,UChar r1,UChar r2)4513 s390_emit_CXTR(UChar *p, UChar r1, UChar r2)
4514 {
4515    vassert(s390_host_has_dfp);
4516    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4517       s390_disasm(ENC3(MNM, FPR, FPR), "cxtr", r1, r2);
4518 
4519    return emit_RRE(p, 0xb3ec0000, r1, r2);
4520 }
4521 
4522 
4523 static UChar *
s390_emit_CDGTRA(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4524 s390_emit_CDGTRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4525 {
4526    vassert(s390_host_has_dfp);
4527    vassert(m4 == 0);
4528    vassert(m3 == 0 || s390_host_has_fpext);
4529 
4530    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4531       if (m3 == 0)
4532          s390_disasm(ENC3(MNM, FPR, GPR), "cdgtr", r1, r2);
4533       else
4534          s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cdgtra", r1, m3, r2, m4);
4535    }
4536 
4537    return emit_RRF2(p, 0xb3f10000, m3, m4, r1, r2);
4538 }
4539 
4540 
4541 static UChar *
s390_emit_CXGTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4542 s390_emit_CXGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4543 {
4544    vassert(s390_host_has_dfp);
4545    vassert(m4 == 0);
4546    /* rounding mode m3 is not considered, as the corresponding
4547       IRop (Iop_I64StoD128) does not take rounding mode. */
4548    vassert(m3 == 0);
4549 
4550    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4551       s390_disasm(ENC3(MNM, FPR, GPR), "cxgtr", r1, r2);
4552 
4553    return emit_RRF2(p, 0xb3f90000, m3, m4, r1, r2);
4554 }
4555 
4556 
4557 static UChar *
s390_emit_CDFTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4558 s390_emit_CDFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4559 {
4560    vassert(m4 == 0);
4561    vassert(s390_host_has_dfp);
4562    vassert(s390_host_has_fpext);
4563 
4564    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4565       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cdftr", r1, m3, r2, m4);
4566 
4567    return emit_RRF2(p, 0xb9510000, m3, m4, r1, r2);
4568 }
4569 
4570 
4571 static UChar *
s390_emit_CXFTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4572 s390_emit_CXFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4573 {
4574    vassert(m4 == 0);
4575    vassert(s390_host_has_dfp);
4576    vassert(s390_host_has_fpext);
4577 
4578    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4579       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cxftr", r1, m3, r2, m4);
4580 
4581    return emit_RRF2(p, 0xb9590000, m3, m4, r1, r2);
4582 }
4583 
4584 
4585 static UChar *
s390_emit_CDLFTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4586 s390_emit_CDLFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4587 {
4588    vassert(m4 == 0);
4589    vassert(s390_host_has_dfp);
4590    vassert(s390_host_has_fpext);
4591 
4592    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4593       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cdlftr", r1, m3, r2, m4);
4594 
4595    return emit_RRF2(p, 0xb9530000, m3, m4, r1, r2);
4596 }
4597 
4598 
4599 static UChar *
s390_emit_CXLFTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4600 s390_emit_CXLFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4601 {
4602    vassert(m4 == 0);
4603    vassert(s390_host_has_dfp);
4604    vassert(s390_host_has_fpext);
4605 
4606    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4607       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cxlftr", r1, m3, r2, m4);
4608 
4609    return emit_RRF2(p, 0xb95b0000, m3, m4, r1, r2);
4610 }
4611 
4612 
4613 static UChar *
s390_emit_CDLGTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4614 s390_emit_CDLGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4615 {
4616    vassert(m4 == 0);
4617    vassert(s390_host_has_dfp);
4618    vassert(s390_host_has_fpext);
4619 
4620    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4621       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cdlgtr", r1, m3, r2, m4);
4622 
4623    return emit_RRF2(p, 0xb9520000, m3, m4, r1, r2);
4624 }
4625 
4626 
4627 static UChar *
s390_emit_CXLGTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4628 s390_emit_CXLGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4629 {
4630    vassert(m4 == 0);
4631    vassert(s390_host_has_dfp);
4632    vassert(s390_host_has_fpext);
4633 
4634    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4635       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), "cxlgtr", r1, m3, r2, m4);
4636 
4637    return emit_RRF2(p, 0xb95a0000, m3, m4, r1, r2);
4638 }
4639 
4640 
4641 static UChar *
s390_emit_CEDTR(UChar * p,UChar r1,UChar r2)4642 s390_emit_CEDTR(UChar *p, UChar r1, UChar r2)
4643 {
4644    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4645       s390_disasm(ENC3(MNM, FPR, FPR), "cedtr", r1, r2);
4646 
4647    return emit_RRE(p, 0xb3f40000, r1, r2);
4648 }
4649 
4650 
4651 static UChar *
s390_emit_CEXTR(UChar * p,UChar r1,UChar r2)4652 s390_emit_CEXTR(UChar *p, UChar r1, UChar r2)
4653 {
4654    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4655       s390_disasm(ENC3(MNM, FPR, FPR), "cextr", r1, r2);
4656 
4657    return emit_RRE(p, 0xb3fc0000, r1, r2);
4658 }
4659 
4660 
4661 static UChar *
s390_emit_CFDTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4662 s390_emit_CFDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4663 {
4664    vassert(m4 == 0);
4665    vassert(s390_host_has_dfp);
4666    vassert(s390_host_has_fpext);
4667 
4668    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4669       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "cfdtr", r1, m3, r2, m4);
4670 
4671    return emit_RRF2(p, 0xb9410000, m3, m4, r1, r2);
4672 }
4673 
4674 
4675 static UChar *
s390_emit_CFXTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4676 s390_emit_CFXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4677 {
4678    vassert(m4 == 0);
4679    vassert(s390_host_has_dfp);
4680    vassert(s390_host_has_fpext);
4681 
4682    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4683       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "cfxtr", r1, m3, r2, m4);
4684 
4685    return emit_RRF2(p, 0xb9490000, m3, m4, r1, r2);
4686 }
4687 
4688 
4689 static UChar *
s390_emit_CGDTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4690 s390_emit_CGDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4691 {
4692    vassert(s390_host_has_dfp);
4693    vassert(m4 == 0);
4694    vassert(s390_host_has_fpext || m3 < 1 || m3 > 7);
4695 
4696    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4697       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cgdtr", r1, m3, r2);
4698 
4699    return emit_RRF2(p, 0xb3e10000, m3, m4, r1, r2);
4700 }
4701 
4702 
4703 static UChar *
s390_emit_CGXTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4704 s390_emit_CGXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4705 {
4706    vassert(s390_host_has_dfp);
4707    vassert(m4 == 0);
4708    vassert(s390_host_has_fpext || m3 < 1 || m3 > 7);
4709 
4710    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4711       s390_disasm(ENC4(MNM, GPR, UINT, FPR), "cgxtr", r1, m3, r2);
4712 
4713    return emit_RRF2(p, 0xb3e90000, m3, m4, r1, r2);
4714 }
4715 
4716 
4717 static UChar *
s390_emit_CLFDTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4718 s390_emit_CLFDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4719 {
4720    vassert(m4 == 0);
4721    vassert(s390_host_has_dfp);
4722    vassert(s390_host_has_fpext);
4723 
4724    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4725       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clfdtr", r1, m3, r2, m4);
4726 
4727    return emit_RRF2(p, 0xb9430000, m3, m4, r1, r2);
4728 }
4729 
4730 
4731 static UChar *
s390_emit_CLFXTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4732 s390_emit_CLFXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4733 {
4734    vassert(m4 == 0);
4735    vassert(s390_host_has_dfp);
4736    vassert(s390_host_has_fpext);
4737 
4738    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4739       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clfxtr", r1, m3, r2, m4);
4740 
4741    return emit_RRF2(p, 0xb94b0000, m3, m4, r1, r2);
4742 }
4743 
4744 
4745 static UChar *
s390_emit_CLGDTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4746 s390_emit_CLGDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4747 {
4748    vassert(m4 == 0);
4749    vassert(s390_host_has_dfp);
4750    vassert(s390_host_has_fpext);
4751 
4752    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4753       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clgdtr", r1, m3, r2, m4);
4754 
4755    return emit_RRF2(p, 0xb9420000, m3, m4, r1, r2);
4756 }
4757 
4758 
4759 static UChar *
s390_emit_CLGXTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4760 s390_emit_CLGXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4761 {
4762    vassert(m4 == 0);
4763    vassert(s390_host_has_dfp);
4764    vassert(s390_host_has_fpext);
4765 
4766    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4767       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), "clgxtr", r1, m3, r2, m4);
4768 
4769    return emit_RRF2(p, 0xb94a0000, m3, m4, r1, r2);
4770 }
4771 
4772 
4773 static UChar *
s390_emit_DDTRA(UChar * p,UChar r3,UChar m4,UChar r1,UChar r2)4774 s390_emit_DDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
4775 {
4776    vassert(s390_host_has_dfp);
4777    vassert(m4 == 0 || s390_host_has_fpext);
4778    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4779       if (m4 == 0)
4780          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "ddtr", r1, r2, r3);
4781       else
4782          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "ddtra", r1, r2, r3, m4);
4783    }
4784 
4785    return emit_RRF4(p, 0xb3d10000, r3, m4, r1, r2);
4786 }
4787 
4788 
4789 static UChar *
s390_emit_DXTRA(UChar * p,UChar r3,UChar m4,UChar r1,UChar r2)4790 s390_emit_DXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
4791 {
4792    vassert(s390_host_has_dfp);
4793    vassert(m4 == 0 || s390_host_has_fpext);
4794    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4795       if (m4 == 0)
4796          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "dxtr", r1, r2, r3);
4797       else
4798          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "dxtra", r1, r2, r3, m4);
4799    }
4800 
4801    return emit_RRF4(p, 0xb3d90000, r3, m4, r1, r2);
4802 }
4803 
4804 
4805 static UChar *
s390_emit_EEDTR(UChar * p,UChar r1,UChar r2)4806 s390_emit_EEDTR(UChar *p, UChar r1, UChar r2)
4807 {
4808    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4809       s390_disasm(ENC3(MNM, GPR, FPR), "eedtr", r1, r2);
4810 
4811    return emit_RRE(p, 0xb3e50000, r1, r2);
4812 }
4813 
4814 
4815 static UChar *
s390_emit_EEXTR(UChar * p,UChar r1,UChar r2)4816 s390_emit_EEXTR(UChar *p, UChar r1, UChar r2)
4817 {
4818    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4819       s390_disasm(ENC3(MNM, GPR, FPR), "eextr", r1, r2);
4820 
4821    return emit_RRE(p, 0xb3ed0000, r1, r2);
4822 }
4823 
4824 
4825 static UChar *
s390_emit_ESDTR(UChar * p,UChar r1,UChar r2)4826 s390_emit_ESDTR(UChar *p, UChar r1, UChar r2)
4827 {
4828    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4829       s390_disasm(ENC3(MNM, GPR, FPR), "esdtr", r1, r2);
4830 
4831    return emit_RRE(p, 0xb3e70000, r1, r2);
4832 }
4833 
4834 
4835 static UChar *
s390_emit_ESXTR(UChar * p,UChar r1,UChar r2)4836 s390_emit_ESXTR(UChar *p, UChar r1, UChar r2)
4837 {
4838    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4839       s390_disasm(ENC3(MNM, GPR, FPR), "esxtr", r1, r2);
4840 
4841    return emit_RRE(p, 0xb3ef0000, r1, r2);
4842 }
4843 
4844 
4845 static UChar *
s390_emit_IEDTR(UChar * p,UChar r3,UChar r1,UChar r2)4846 s390_emit_IEDTR(UChar *p, UChar r3, UChar r1, UChar r2)
4847 {
4848    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4849       s390_disasm(ENC4(MNM, FPR, FPR, GPR), "iedtr", r1, r3, r2);
4850 
4851    return emit_RRF(p, 0xb3f60000, r3, r1, r2);
4852 }
4853 
4854 
4855 static UChar *
s390_emit_IEXTR(UChar * p,UChar r3,UChar r1,UChar r2)4856 s390_emit_IEXTR(UChar *p, UChar r3, UChar r1, UChar r2)
4857 {
4858    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4859       s390_disasm(ENC4(MNM, FPR, FPR, GPR), "iextr", r1, r3, r2);
4860 
4861    return emit_RRF(p, 0xb3fe0000, r3, r1, r2);
4862 }
4863 
4864 
4865 static UChar *
s390_emit_LDETR(UChar * p,UChar m4,UChar r1,UChar r2)4866 s390_emit_LDETR(UChar *p, UChar m4, UChar r1, UChar r2)
4867 {
4868    vassert(s390_host_has_dfp);
4869    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4870       s390_disasm(ENC4(MNM, FPR, FPR, UINT), "ldetr", r1, r2, m4);
4871 
4872    return emit_RRF5(p, 0xb3d40000, m4, r1, r2);
4873 }
4874 
4875 
4876 static UChar *
s390_emit_LXDTR(UChar * p,UChar m4,UChar r1,UChar r2)4877 s390_emit_LXDTR(UChar *p, UChar m4, UChar r1, UChar r2)
4878 {
4879    vassert(s390_host_has_dfp);
4880    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4881       s390_disasm(ENC4(MNM, FPR, FPR, UINT), "lxdtr", r1, r2, m4);
4882 
4883    return emit_RRF5(p, 0xb3dc0000, m4, r1, r2);
4884 }
4885 
4886 
4887 static UChar *
s390_emit_LEDTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4888 s390_emit_LEDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4889 {
4890    vassert(s390_host_has_dfp);
4891    vassert(m4 == 0);
4892    vassert(s390_host_has_fpext || m3 < 1 || m3 > 7);
4893 
4894    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4895       s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), "ledtr", r1, m3, r2, m4);
4896 
4897    return emit_RRF2(p, 0xb3d50000, m3, m4, r1, r2);
4898 }
4899 
4900 
4901 static UChar *
s390_emit_LDXTR(UChar * p,UChar m3,UChar m4,UChar r1,UChar r2)4902 s390_emit_LDXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
4903 {
4904    vassert(s390_host_has_dfp);
4905    vassert(m4 == 0);
4906    vassert(s390_host_has_fpext || m3 < 1 || m3 > 7);
4907 
4908    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4909       s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), "ldxtr", r1, m3, r2, m4);
4910 
4911    return emit_RRF2(p, 0xb3dd0000, m3, m4, r1, r2);
4912 }
4913 
4914 
4915 static UChar *
s390_emit_MDTRA(UChar * p,UChar r3,UChar m4,UChar r1,UChar r2)4916 s390_emit_MDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
4917 {
4918    vassert(s390_host_has_dfp);
4919    vassert(m4 == 0 || s390_host_has_fpext);
4920    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4921       if (m4 == 0)
4922          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "mdtr", r1, r2, r3);
4923       else
4924          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "mdtra", r1, r2, r3, m4);
4925    }
4926 
4927    return emit_RRF4(p, 0xb3d00000, r3, m4, r1, r2);
4928 }
4929 
4930 
4931 static UChar *
s390_emit_MXTRA(UChar * p,UChar r3,UChar m4,UChar r1,UChar r2)4932 s390_emit_MXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
4933 {
4934    vassert(s390_host_has_dfp);
4935    vassert(m4 == 0 || s390_host_has_fpext);
4936    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4937       if (m4 == 0)
4938          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "mxtr", r1, r2, r3);
4939       else
4940          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "mxtra", r1, r2, r3, m4);
4941    }
4942 
4943    return emit_RRF4(p, 0xb3d80000, r3, m4, r1, r2);
4944 }
4945 
4946 
4947 static UChar *
emit_E(UChar * p,UInt op)4948 emit_E(UChar *p, UInt op)
4949 {
4950    ULong the_insn = op;
4951 
4952    return emit_2bytes(p, the_insn);
4953 }
4954 
4955 
4956 static UChar *
s390_emit_PFPO(UChar * p)4957 s390_emit_PFPO(UChar *p)
4958 {
4959    vassert(s390_host_has_pfpo);
4960    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
4961       s390_disasm(ENC1(MNM), "pfpo");
4962    }
4963 
4964    return emit_E(p, 0x010a);
4965 }
4966 
4967 
4968 static UChar *
s390_emit_QADTR(UChar * p,UChar r3,UChar m4,UChar r1,UChar r2)4969 s390_emit_QADTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
4970 {
4971    vassert(s390_host_has_dfp);
4972    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4973       s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "qadtr", r1, r3, r2, m4);
4974 
4975    return emit_RRF4(p, 0xb3f50000, r3, m4, r1, r2);
4976 }
4977 
4978 
4979 static UChar *
s390_emit_QAXTR(UChar * p,UChar r3,UChar m4,UChar r1,UChar r2)4980 s390_emit_QAXTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
4981 {
4982    vassert(s390_host_has_dfp);
4983    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4984       s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "qaxtr", r1, r3, r2, m4);
4985 
4986    return emit_RRF4(p, 0xb3fd0000, r3, m4, r1, r2);
4987 }
4988 
4989 
4990 static UChar *
s390_emit_RRDTR(UChar * p,UChar r3,UChar m4,UChar r1,UChar r2)4991 s390_emit_RRDTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
4992 {
4993    vassert(s390_host_has_dfp);
4994    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
4995       s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), "rrdtr", r1, r3, r2, m4);
4996 
4997    return emit_RRF4(p, 0xb3f70000, r3, m4, r1, r2);
4998 }
4999 
5000 
5001 static UChar *
s390_emit_RRXTR(UChar * p,UChar r3,UChar m4,UChar r1,UChar r2)5002 s390_emit_RRXTR(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
5003 {
5004    vassert(s390_host_has_dfp);
5005    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5006       s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), "rrxtr", r1, r3, r2, m4);
5007 
5008    return emit_RRF4(p, 0xb3ff0000, r3, m4, r1, r2);
5009 }
5010 
5011 
5012 static UChar *
s390_emit_SDTRA(UChar * p,UChar r3,UChar m4,UChar r1,UChar r2)5013 s390_emit_SDTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
5014 {
5015    vassert(s390_host_has_dfp);
5016    vassert(m4 == 0 || s390_host_has_fpext);
5017    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
5018       if (m4 == 0)
5019          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "sdtr", r1, r2, r3);
5020       else
5021          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "sdtra", r1, r2, r3, m4);
5022    }
5023 
5024    return emit_RRF4(p, 0xb3d30000, r3, m4, r1, r2);
5025 }
5026 
5027 
5028 static UChar *
s390_emit_SXTRA(UChar * p,UChar r3,UChar m4,UChar r1,UChar r2)5029 s390_emit_SXTRA(UChar *p, UChar r3, UChar m4, UChar r1, UChar r2)
5030 {
5031    vassert(s390_host_has_dfp);
5032    vassert(m4 == 0 || s390_host_has_fpext);
5033    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
5034       if (m4 == 0)
5035          s390_disasm(ENC4(MNM, FPR, FPR, FPR), "sxtr", r1, r2, r3);
5036       else
5037          s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), "sxtra", r1, r2, r3, m4);
5038    }
5039 
5040    return emit_RRF4(p, 0xb3db0000, r3, m4, r1, r2);
5041 }
5042 
5043 
5044 static UChar *
s390_emit_SLDT(UChar * p,UChar r3,UChar r1,UChar r2)5045 s390_emit_SLDT(UChar *p, UChar r3, UChar r1, UChar r2)
5046 {
5047    vassert(s390_host_has_dfp);
5048    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5049       s390_disasm(ENC4(MNM, FPR, FPR, UDXB), "sldt", r1, r3, 0, 0, r2);
5050 
5051    return emit_RXF(p, 0xED0000000040ULL, r3, 0, r2, 0, r1);
5052 }
5053 
5054 
5055 static UChar *
s390_emit_SLXT(UChar * p,UChar r3,UChar r1,UChar r2)5056 s390_emit_SLXT(UChar *p, UChar r3, UChar r1, UChar r2)
5057 {
5058    vassert(s390_host_has_dfp);
5059    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5060       s390_disasm(ENC4(MNM, FPR, FPR, UDXB), "slxt", r1, r3, 0, 0, r2);
5061 
5062    return emit_RXF(p, 0xED0000000048ULL, r3, 0, r2, 0, r1);
5063 }
5064 
5065 
5066 static UChar *
s390_emit_SRDT(UChar * p,UChar r3,UChar r1,UChar r2)5067 s390_emit_SRDT(UChar *p, UChar r3, UChar r1, UChar r2)
5068 {
5069    vassert(s390_host_has_dfp);
5070    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5071       s390_disasm(ENC4(MNM, FPR, FPR, UDXB), "srdt", r1, r3, 0, 0, r2);
5072 
5073    return emit_RXF(p, 0xED0000000041ULL, r3, 0, r2, 0, r1);
5074 }
5075 
5076 
5077 static UChar *
s390_emit_SRXT(UChar * p,UChar r3,UChar r1,UChar r2)5078 s390_emit_SRXT(UChar *p, UChar r3, UChar r1, UChar r2)
5079 {
5080    vassert(s390_host_has_dfp);
5081    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5082       s390_disasm(ENC4(MNM, FPR, FPR, UDXB), "srxt", r1, r3, 0, 0, r2);
5083 
5084    return emit_RXF(p, 0xED0000000049ULL, r3, 0, r2, 0, r1);
5085 }
5086 
5087 
5088 static UChar *
s390_emit_LOCGR(UChar * p,UChar m3,UChar r1,UChar r2)5089 s390_emit_LOCGR(UChar *p, UChar m3, UChar r1, UChar r2)
5090 {
5091    vassert(s390_host_has_lsc);
5092    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5093       s390_disasm(ENC4(MNM, GPR, GPR, UINT), "locgr", r1, r2, m3);
5094 
5095    return emit_RRF3(p, 0xb9e20000, m3, r1, r2);
5096 }
5097 
5098 
5099 static UChar *
s390_emit_LOC(UChar * p,UChar r1,UChar m3,UChar b2,UShort dl2,UChar dh2)5100 s390_emit_LOC(UChar *p, UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2)
5101 {
5102    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5103       s390_disasm(ENC4(MNM, GPR, UINT, SDXB), "loc", r1, m3, dh2, dl2, 0, b2);
5104 
5105    return emit_RSY(p, 0xeb00000000f2ULL, r1, m3, b2, dl2, dh2);
5106 }
5107 
5108 
5109 static UChar *
s390_emit_LOCG(UChar * p,UChar r1,UChar m3,UChar b2,UShort dl2,UChar dh2)5110 s390_emit_LOCG(UChar *p, UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2)
5111 {
5112    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5113       s390_disasm(ENC4(MNM, GPR, UINT, SDXB), "locg", r1, m3, dh2, dl2, 0, b2);
5114 
5115    return emit_RSY(p, 0xeb00000000e2ULL, r1, m3, b2, dl2, dh2);
5116 }
5117 
5118 
5119 /* Provide a symbolic name for register "R0" */
5120 #define R0 0
5121 
5122 /* Split up a 20-bit displacement into its high and low piece
5123    suitable for passing as function arguments */
5124 #define DISP20(d) (((UInt)d) & 0xFFF), ((((UInt)d) >> 12) & 0xFF)
5125 
5126 /*---------------------------------------------------------------*/
5127 /*--- Helper functions                                        ---*/
5128 /*---------------------------------------------------------------*/
5129 
5130 static __inline__ Bool
uint_fits_signed_16bit(UInt val)5131 uint_fits_signed_16bit(UInt val)
5132 {
5133    UInt v = val & 0xFFFFu;
5134 
5135    /* sign extend */
5136    v = (Int)(v << 16) >> 16;
5137 
5138    return val == v;
5139 }
5140 
5141 
5142 static __inline__ Bool
ulong_fits_signed_16bit(ULong val)5143 ulong_fits_signed_16bit(ULong val)
5144 {
5145    ULong v = val & 0xFFFFu;
5146 
5147    /* sign extend */
5148    v = (Long)(v << 48) >> 48;
5149 
5150    return val == v;
5151 }
5152 
5153 
5154 static __inline__ Bool
ulong_fits_signed_32bit(ULong val)5155 ulong_fits_signed_32bit(ULong val)
5156 {
5157    ULong v = val & 0xFFFFFFFFu;
5158 
5159    /* sign extend */
5160    v = (Long)(v << 32) >> 32;
5161 
5162    return val == v;
5163 }
5164 
5165 
5166 static __inline__ Bool
ulong_fits_unsigned_32bit(ULong val)5167 ulong_fits_unsigned_32bit(ULong val)
5168 {
5169    return (val & 0xFFFFFFFFu) == val;
5170 }
5171 
5172 
5173 /* Load a 64-bit immediate VAL into register REG. */
5174 static UChar *
s390_emit_load_64imm(UChar * p,UChar reg,ULong val)5175 s390_emit_load_64imm(UChar *p, UChar reg, ULong val)
5176 {
5177    if (ulong_fits_signed_16bit(val)) {
5178       return s390_emit_LGHI(p, reg, val);
5179    }
5180 
5181    if (s390_host_has_eimm) {
5182       if (ulong_fits_unsigned_32bit(val)) {
5183          return s390_emit_LLILF(p, reg, val);
5184       }
5185       if (ulong_fits_signed_32bit(val)) {
5186          /* LGFI's sign extension will recreate the correct 64-bit value */
5187          return s390_emit_LGFI(p, reg, val);
5188       }
5189       /* Do it in two steps: upper half [0:31] and lower half [32:63] */
5190       p =  s390_emit_IIHF(p, reg, val >> 32);
5191       return s390_emit_IILF(p, reg, val & 0xFFFFFFFF);
5192    }
5193 
5194    /* Fall back */
5195    if (ulong_fits_unsigned_32bit(val)) {
5196       p = s390_emit_LLILH(p, reg, (val >> 16) & 0xFFFF); /* sets val[32:47]
5197                                                             val[0:31] = 0 */
5198       p = s390_emit_IILL(p, reg, val & 0xFFFF);          /* sets val[48:63] */
5199       return p;
5200    }
5201 
5202    p = s390_emit_IIHH(p, reg, (val >> 48) & 0xFFFF);
5203    p = s390_emit_IIHL(p, reg, (val >> 32) & 0xFFFF);
5204    p = s390_emit_IILH(p, reg, (val >> 16) & 0xFFFF);
5205    p = s390_emit_IILL(p, reg, val & 0xFFFF);
5206 
5207    return p;
5208 }
5209 
5210 /* Load a 32-bit immediate VAL into register REG. */
5211 static UChar *
s390_emit_load_32imm(UChar * p,UChar reg,UInt val)5212 s390_emit_load_32imm(UChar *p, UChar reg, UInt val)
5213 {
5214    if (uint_fits_signed_16bit(val)) {
5215       /* LHI's sign extension will recreate the correct 32-bit value */
5216       return s390_emit_LHI(p, reg, val);
5217    }
5218    if (s390_host_has_eimm) {
5219       return s390_emit_IILF(p, reg, val);
5220    }
5221    /* val[0:15]  --> (val >> 16) & 0xFFFF
5222       val[16:31] --> val & 0xFFFF */
5223    p = s390_emit_IILH(p, reg, (val >> 16) & 0xFFFF);
5224    return s390_emit_IILL(p, reg, val & 0xFFFF);
5225 }
5226 
5227 /*------------------------------------------------------------*/
5228 /*--- Wrapper functions                                    ---*/
5229 /*------------------------------------------------------------*/
5230 
5231 /* r1[32:63],r1+1[32:63] = r1+1[32:63] * memory[op2addr][0:31] */
5232 static UChar *
s390_emit_MFYw(UChar * p,UChar r1,UChar x,UChar b,UShort dl,UChar dh)5233 s390_emit_MFYw(UChar *p, UChar r1, UChar x, UChar b,  UShort dl, UChar dh)
5234 {
5235    if (s390_host_has_gie) {
5236       return s390_emit_MFY(p, r1, x, b, dl, dh);
5237    }
5238 
5239    /* Load from memory into R0, then MULTIPLY with R1 */
5240    p = s390_emit_LY(p, R0, x, b, dl, dh);
5241    return s390_emit_MR(p, r1, R0);
5242 }
5243 
5244 /* r1[32:63] = r1[32:63] * memory[op2addr][0:15] */
5245 static UChar *
s390_emit_MHYw(UChar * p,UChar r1,UChar x,UChar b,UShort dl,UChar dh)5246 s390_emit_MHYw(UChar *p, UChar r1, UChar x, UChar b,  UShort dl, UChar dh)
5247 {
5248    if (s390_host_has_gie) {
5249       return s390_emit_MHY(p, r1, x, b, dl, dh);
5250    }
5251 
5252    /* Load from memory into R0, then MULTIPLY with R1 */
5253    p = s390_emit_LHY(p, R0, x, b, dl, dh);
5254    return s390_emit_MSR(p, r1, R0);
5255 }
5256 
5257 /* r1[32:63] = r1[32:63] * i2 */
5258 static UChar *
s390_emit_MSFIw(UChar * p,UChar r1,UInt i2)5259 s390_emit_MSFIw(UChar *p, UChar r1, UInt i2)
5260 {
5261    if (s390_host_has_gie) {
5262       return s390_emit_MSFI(p, r1, i2);
5263    }
5264 
5265    /* Load I2 into R0; then MULTIPLY R0 with R1 */
5266    p = s390_emit_load_32imm(p, R0, i2);
5267    return s390_emit_MSR(p, r1, R0);
5268 }
5269 
5270 
5271 /* r1[32:63] = r1[32:63] & i2 */
5272 static UChar *
s390_emit_NILFw(UChar * p,UChar r1,UInt i2)5273 s390_emit_NILFw(UChar *p, UChar r1, UInt i2)
5274 {
5275    if (s390_host_has_eimm) {
5276       return s390_emit_NILF(p, r1, i2);
5277    }
5278 
5279    /* Load I2 into R0; then AND R0 with R1 */
5280    p = s390_emit_load_32imm(p, R0, i2);
5281    return s390_emit_NR(p, r1, R0);
5282 }
5283 
5284 
5285 /* r1[32:63] = r1[32:63] | i2 */
5286 static UChar *
s390_emit_OILFw(UChar * p,UChar r1,UInt i2)5287 s390_emit_OILFw(UChar *p, UChar r1, UInt i2)
5288 {
5289    if (s390_host_has_eimm) {
5290       return s390_emit_OILF(p, r1, i2);
5291    }
5292 
5293    /* Load I2 into R0; then AND R0 with R1 */
5294    p = s390_emit_load_32imm(p, R0, i2);
5295    return s390_emit_OR(p, r1, R0);
5296 }
5297 
5298 
5299 /* r1[32:63] = r1[32:63] ^ i2 */
5300 static UChar *
s390_emit_XILFw(UChar * p,UChar r1,UInt i2)5301 s390_emit_XILFw(UChar *p, UChar r1, UInt i2)
5302 {
5303    if (s390_host_has_eimm) {
5304       return s390_emit_XILF(p, r1, i2);
5305    }
5306 
5307    /* Load I2 into R0; then AND R0 with R1 */
5308    p = s390_emit_load_32imm(p, R0, i2);
5309    return s390_emit_XR(p, r1, R0);
5310 }
5311 
5312 
5313 /*  r1[32:63] = sign_extend(r2[56:63]) */
5314 static UChar *
s390_emit_LBRw(UChar * p,UChar r1,UChar r2)5315 s390_emit_LBRw(UChar *p, UChar r1, UChar r2)
5316 {
5317    if (s390_host_has_eimm) {
5318       return s390_emit_LBR(p, r1, r2);
5319    }
5320 
5321    p = s390_emit_LR(p, r1, r2);               /* r1 = r2 */
5322    p = s390_emit_SLL(p, r1, R0, 24);          /* r1 = r1 << 24  */
5323    return s390_emit_SRA(p, r1, R0, 24);       /* r1 = r1 >>a 24 */
5324 }
5325 
5326 
5327 /*  r1[0:63] = sign_extend(r2[56:63]) */
5328 static UChar *
s390_emit_LGBRw(UChar * p,UChar r1,UChar r2)5329 s390_emit_LGBRw(UChar *p, UChar r1, UChar r2)
5330 {
5331    if (s390_host_has_eimm) {
5332       return s390_emit_LGBR(p, r1, r2);
5333    }
5334 
5335    p = s390_emit_LR(p, r1, r2);                       /* r1 = r2 */
5336    p = s390_emit_SLLG(p, r1, r1, R0, DISP20(56));     /* r1 = r1 << 56  */
5337    return s390_emit_SRAG(p, r1, r1, R0, DISP20(56));  /* r1 = r1 >>a 56 */
5338 }
5339 
5340 
5341 /* r1[32:63] = sign_extend(r2[48:63]) */
5342 static UChar *
s390_emit_LHRw(UChar * p,UChar r1,UChar r2)5343 s390_emit_LHRw(UChar *p, UChar r1, UChar r2)
5344 {
5345    if (s390_host_has_eimm) {
5346       return s390_emit_LHR(p, r1, r2);
5347    }
5348 
5349    p = s390_emit_LR(p, r1, r2);               /* r1 = r2 */
5350    p = s390_emit_SLL(p, r1, R0, 16);          /* r1 = r1 << 16  */
5351    return s390_emit_SRA(p, r1, R0, 16);       /* r1 = r1 >>a 16 */
5352 }
5353 
5354 
5355 /* r1[0:63] = sign_extend(r2[48:63]) */
5356 static UChar *
s390_emit_LGHRw(UChar * p,UChar r1,UChar r2)5357 s390_emit_LGHRw(UChar *p, UChar r1, UChar r2)
5358 {
5359    if (s390_host_has_eimm) {
5360       return s390_emit_LGHR(p, r1, r2);
5361    }
5362 
5363    p = s390_emit_LR(p, r1, r2);               /* r1 = r2 */
5364    p = s390_emit_SLLG(p, r1, r1, R0, DISP20(48));     /* r1 = r1 << 48  */
5365    return s390_emit_SRAG(p, r1, r1, R0, DISP20(48));  /* r1 = r1 >>a 48 */
5366 }
5367 
5368 
5369 /* r1[0:63] = sign_extend(i2) */
5370 static UChar *
s390_emit_LGFIw(UChar * p,UChar r1,UInt i2)5371 s390_emit_LGFIw(UChar *p, UChar r1, UInt i2)
5372 {
5373    if (s390_host_has_eimm) {
5374       return s390_emit_LGFI(p, r1, i2);
5375    }
5376 
5377    p = s390_emit_load_32imm(p, R0, i2);
5378    return s390_emit_LGFR(p, r1, R0);
5379 }
5380 
5381 
5382 /* r1[32:63] = zero_extend($r2[56:63]) */
5383 static UChar *
s390_emit_LLCRw(UChar * p,UChar r1,UChar r2)5384 s390_emit_LLCRw(UChar *p, UChar r1, UChar r2)
5385 {
5386    if (s390_host_has_eimm) {
5387       return s390_emit_LLCR(p, r1, r2);
5388    }
5389 
5390    p = s390_emit_LR(p, r1, r2);
5391    p = s390_emit_LHI(p, R0, 0xFF);
5392    return s390_emit_NR(p, r1, R0);
5393 }
5394 
5395 
5396 /* r1[0:63] = zero_extend($r2[56:63]) */
5397 static UChar *
s390_emit_LLGCRw(UChar * p,UChar r1,UChar r2)5398 s390_emit_LLGCRw(UChar *p, UChar r1, UChar r2)
5399 {
5400    if (s390_host_has_eimm) {
5401       return s390_emit_LLGCR(p, r1, r2);
5402    }
5403 
5404    p = s390_emit_LR(p, r1, r2);
5405    p = s390_emit_LLILL(p, R0, 0xFF);
5406    return s390_emit_NGR(p, r1, R0);
5407 }
5408 
5409 
5410 /* r1[32:63] = zero_extend(r2[48:63]) */
5411 static UChar *
s390_emit_LLHRw(UChar * p,UChar r1,UChar r2)5412 s390_emit_LLHRw(UChar *p, UChar r1, UChar r2)
5413 {
5414    if (s390_host_has_eimm) {
5415       return s390_emit_LLHR(p, r1, r2);
5416    }
5417 
5418    p = s390_emit_LR(p, r1, r2);
5419    p = s390_emit_LLILL(p, R0, 0xFFFF);
5420    return s390_emit_NR(p, r1, R0);
5421 }
5422 
5423 
5424 /* r1[0:63] = zero_extend(r2[48:63]) */
5425 static UChar *
s390_emit_LLGHRw(UChar * p,UChar r1,UChar r2)5426 s390_emit_LLGHRw(UChar *p, UChar r1, UChar r2)
5427 {
5428    if (s390_host_has_eimm) {
5429       return s390_emit_LLGHR(p, r1, r2);
5430    }
5431 
5432    p = s390_emit_LR(p, r1, r2);
5433    p = s390_emit_LLILL(p, R0, 0xFFFF);
5434    return s390_emit_NGR(p, r1, R0);
5435 }
5436 
5437 
5438 /* r1[32:63] = zero_extend(mem[op2addr][0:7]) */
5439 static UChar *
s390_emit_LLCw(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl,UChar dh)5440 s390_emit_LLCw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl, UChar dh)
5441 {
5442    if (s390_host_has_eimm) {
5443       return s390_emit_LLC(p, r1, x2, b2, dl, dh);
5444    }
5445 
5446    if (dh == 0) {
5447       p = s390_emit_IC(p, r1, x2, b2, dl);
5448    } else {
5449       p = s390_emit_ICY(p, r1, x2, b2, dl, dh);
5450    }
5451    p = s390_emit_LLILL(p, R0, 0xFF);
5452    return s390_emit_NR(p, r1, R0);
5453 }
5454 
5455 
5456 /* r1[32:63] = zero_extend(mem[op2addr][0:15]) */
5457 static UChar *
s390_emit_LLHw(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl,UChar dh)5458 s390_emit_LLHw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl, UChar dh)
5459 {
5460    if (s390_host_has_eimm) {
5461       return s390_emit_LLH(p, r1, x2, b2, dl, dh);
5462    }
5463 
5464    p = s390_emit_LLGH(p, r1, x2, b2, dl, dh);
5465    p = s390_emit_LLILL(p, R0, 0xFFFF);
5466    return s390_emit_NR(p, r1, R0);
5467 }
5468 
5469 
5470 /* r1[0:63] = zero_extend(i2) */
5471 static UChar *
s390_emit_LLILFw(UChar * p,UChar r1,UInt i2)5472 s390_emit_LLILFw(UChar *p, UChar r1, UInt i2)
5473 {
5474    if (s390_host_has_eimm) {
5475       return s390_emit_LLILF(p, r1, i2);
5476    }
5477 
5478    p = s390_emit_LLILH(p, r1, (i2 >> 16) & 0xFFFF);  /* i2[0:15] */
5479    return s390_emit_OILL(p, r1, i2 & 0xFFFF);
5480 }
5481 
5482 
5483 /* r1[32:63] = r1[32:63] + i2 */
5484 static UChar *
s390_emit_AFIw(UChar * p,UChar r1,UInt i2)5485 s390_emit_AFIw(UChar *p, UChar r1, UInt i2)
5486 {
5487    if (s390_host_has_eimm) {
5488       return s390_emit_AFI(p, r1, i2);
5489    }
5490    /* Load 32 bit immediate to R0 then add */
5491    p = s390_emit_load_32imm(p, R0, i2);
5492    return s390_emit_AR(p, r1, R0);
5493 }
5494 
5495 
5496 /* r1[32:63] = r1[32:63] - i2 */
5497 static UChar *
s390_emit_SLFIw(UChar * p,UChar r1,UInt i2)5498 s390_emit_SLFIw(UChar *p, UChar r1, UInt i2)
5499 {
5500    if (s390_host_has_eimm) {
5501       return s390_emit_SLFI(p, r1, i2);
5502    }
5503 
5504    /* Load 32 bit immediate to R0 then subtract */
5505    p = s390_emit_load_32imm(p, R0, i2);
5506    return s390_emit_SR(p, r1, R0);
5507 }
5508 
5509 
5510 /* r1[0:63] = r1[0:63] - zero_extend(i2) */
5511 static UChar *
s390_emit_SLGFIw(UChar * p,UChar r1,UInt i2)5512 s390_emit_SLGFIw(UChar *p, UChar r1, UInt i2)
5513 {
5514    if (s390_host_has_eimm) {
5515       return s390_emit_SLGFI(p, r1, i2);
5516    }
5517 
5518    /* Load zero-extended 32 bit immediate to R0 then subtract */
5519    p = s390_emit_load_64imm(p, R0, i2);
5520    return s390_emit_SGR(p, r1, R0);
5521 }
5522 
5523 
5524 static UChar *
s390_emit_LTw(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl,UChar dh)5525 s390_emit_LTw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl, UChar dh)
5526 {
5527    if (s390_host_has_eimm) {
5528       return s390_emit_LT(p, r1, x2, b2, dl, dh);
5529    }
5530    /* Load 32 bit from memory to R0 then compare */
5531    if (dh == 0) {
5532       p = s390_emit_L(p, R0, x2, b2, dl);
5533    } else {
5534       p = s390_emit_LY(p, R0, x2, b2, dl, dh);
5535    }
5536    return s390_emit_LTR(p, r1, R0);
5537 }
5538 
5539 
5540 static UChar *
s390_emit_LTGw(UChar * p,UChar r1,UChar x2,UChar b2,UShort dl,UChar dh)5541 s390_emit_LTGw(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl, UChar dh)
5542 {
5543    if (s390_host_has_eimm) {
5544       return s390_emit_LTG(p, r1, x2, b2, dl, dh);
5545    }
5546    /* Load 64 bit from memory to R0 then compare */
5547    p = s390_emit_LG(p, R0, x2, b2, dl, dh);
5548    return s390_emit_LTGR(p, r1, R0);
5549 }
5550 
5551 
5552 static UChar *
s390_emit_CFIw(UChar * p,UChar r1,UInt i2)5553 s390_emit_CFIw(UChar *p, UChar r1, UInt i2)
5554 {
5555    if (s390_host_has_eimm) {
5556       return s390_emit_CFI(p, r1, i2);
5557    }
5558    /* Load 32 bit immediate to R0 then compare */
5559    p = s390_emit_load_32imm(p, R0, i2);
5560    return s390_emit_CR(p, r1, R0);
5561 }
5562 
5563 
5564 static UChar *
s390_emit_CLFIw(UChar * p,UChar r1,UInt i2)5565 s390_emit_CLFIw(UChar *p, UChar r1, UInt i2)
5566 {
5567    if (s390_host_has_eimm) {
5568       return s390_emit_CLFI(p, r1, i2);
5569    }
5570    /* Load 32 bit immediate to R0 then compare */
5571    p = s390_emit_load_32imm(p, R0, i2);
5572    return s390_emit_CLR(p, r1, R0);
5573 }
5574 
5575 
5576 static UChar *
s390_emit_LGDRw(UChar * p,UChar r1,UChar r2)5577 s390_emit_LGDRw(UChar *p, UChar r1, UChar r2)
5578 {
5579    if (s390_host_has_fgx) {
5580       return s390_emit_LGDR(p, r1, r2);
5581    }
5582 
5583    /* Store the FPR at memory[sp - 8]. This is safe because SP grows towards
5584       smaller addresses and is 8-byte aligned. Then load the GPR from that
5585       memory location/ */
5586    p = s390_emit_STDY(p, r2, R0, S390_REGNO_STACK_POINTER, DISP20(-8));
5587    return s390_emit_LG(p, r1, R0, S390_REGNO_STACK_POINTER, DISP20(-8));
5588 }
5589 
5590 
5591 static UChar *
s390_emit_LDGRw(UChar * p,UChar r1,UChar r2)5592 s390_emit_LDGRw(UChar *p, UChar r1, UChar r2)
5593 {
5594    if (s390_host_has_fgx) {
5595       return s390_emit_LDGR(p, r1, r2);
5596    }
5597 
5598    /* Store the GPR at memory[sp - 8]. This is safe because SP grows towards
5599       smaller addresses and is 8-byte aligned. Then load the FPR from that
5600       memory location/ */
5601    p = s390_emit_STG(p, r2, R0, S390_REGNO_STACK_POINTER, DISP20(-8));
5602    return s390_emit_LDY(p, r1, R0, S390_REGNO_STACK_POINTER, DISP20(-8));
5603 }
5604 
5605 
5606 static UChar *
s390_emit_VL(UChar * p,UChar v1,UChar x2,UChar b2,UShort d2)5607 s390_emit_VL(UChar *p, UChar v1, UChar x2, UChar b2, UShort d2)
5608 {
5609    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5610       s390_disasm(ENC3(MNM, VR, UDXB), "vl", v1, d2, x2, b2);
5611 
5612    return emit_VRX(p, 0xE70000000006ULL, v1, x2, b2, d2);
5613 }
5614 
5615 static UChar *
s390_emit_VLR(UChar * p,UChar v1,UChar v2)5616 s390_emit_VLR(UChar *p, UChar v1, UChar v2)
5617 {
5618    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5619       s390_disasm(ENC3(MNM, VR, UDXB), "vlr", v1, v2);
5620 
5621    return emit_VRR_VV(p, 0xE70000000056ULL, v1, v2);
5622 }
5623 
5624 
5625 static UChar *
s390_emit_VST(UChar * p,UChar v1,UChar x2,UChar b2,UShort d2)5626 s390_emit_VST(UChar *p, UChar v1, UChar x2, UChar b2, UShort d2)
5627 {
5628    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5629       s390_disasm(ENC3(MNM, VR, UDXB), "vst", v1, d2, x2, b2);
5630 
5631    return emit_VRX(p, 0xE7000000000eULL, v1, x2, b2, d2);
5632 }
5633 
5634 
5635 static UChar *
s390_emit_VLGV(UChar * p,UChar r1,UChar b2,UShort d2,UChar v3,UChar m4)5636 s390_emit_VLGV(UChar *p, UChar r1, UChar b2, UShort d2, UChar v3, UChar m4)
5637 {
5638    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5639       s390_disasm(ENC5(MNM, GPR, UDXB, VR, UINT), "vlgv", r1, d2, 0, b2, v3, m4);
5640 
5641    return emit_VRS(p, 0xE70000000021ULL, r1, b2, d2, v3, m4);
5642 }
5643 
5644 
5645 static UChar *
s390_emit_VLVG(UChar * p,UChar v1,UChar b2,UShort d2,UChar r3,UChar m4)5646 s390_emit_VLVG(UChar *p, UChar v1, UChar b2, UShort d2, UChar r3, UChar m4)
5647 {
5648    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5649       s390_disasm(ENC5(MNM, VR, UDXB, GPR, UINT), "vlvg", v1, d2, 0, b2, r3, m4);
5650 
5651    return emit_VRS(p, 0xE70000000022ULL, v1, b2, d2, r3, m4);
5652 }
5653 
5654 
5655 static UChar *
s390_emit_VPERM(UChar * p,UChar v1,UChar v2,UChar v3,UChar v4)5656 s390_emit_VPERM(UChar *p, UChar v1, UChar v2, UChar v3, UChar v4)
5657 {
5658    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5659       s390_disasm(ENC5(MNM, VR, VR, VR, VR), "vperm", v1, v2, v3, v4);
5660 
5661    return emit_VRR_VVVV(p, 0xE7000000008cULL, v1, v2, v3, v4);
5662 }
5663 
5664 static UChar *
s390_emit_VO(UChar * p,UChar v1,UChar v2,UChar v3)5665 s390_emit_VO(UChar *p, UChar v1, UChar v2, UChar v3)
5666 {
5667    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5668       s390_disasm(ENC4(MNM, VR, VR, VR), "vo", v1, v2, v3);
5669 
5670    return emit_VRR_VVV(p, 0xE7000000006aULL, v1, v2, v3);
5671 }
5672 
5673 static UChar *
s390_emit_VX(UChar * p,UChar v1,UChar v2,UChar v3)5674 s390_emit_VX(UChar *p, UChar v1, UChar v2, UChar v3)
5675 {
5676    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5677       s390_disasm(ENC4(MNM, VR, VR, VR), "vx", v1, v2, v3);
5678 
5679    return emit_VRR_VVV(p, 0xE7000000006dULL, v1, v2, v3);
5680 }
5681 
5682 static UChar *
s390_emit_VN(UChar * p,UChar v1,UChar v2,UChar v3)5683 s390_emit_VN(UChar *p, UChar v1, UChar v2, UChar v3)
5684 {
5685    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5686       s390_disasm(ENC4(MNM, VR, VR, VR), "vn", v1, v2, v3);
5687 
5688    return emit_VRR_VVV(p, 0xE70000000068ULL, v1, v2, v3);
5689 }
5690 
5691 static UChar*
s390_emit_VCEQ(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5692 s390_emit_VCEQ(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5693 {
5694    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5695       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vceq", v1, v2, v3, m4);
5696 
5697    return emit_VRR_VVVM(p, 0xE700000000f8ULL, v1, v2, v3, m4);
5698 }
5699 
5700 
5701 static UChar *
s390_emit_VGBM(UChar * p,UChar v1,UShort i2)5702 s390_emit_VGBM(UChar *p, UChar v1, UShort i2)
5703 {
5704    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5705       s390_disasm(ENC3(MNM, VR, UINT), "vgbm", v1, i2);
5706 
5707    return emit_VRI_VI(p, 0xE70000000044ULL, v1, i2);
5708 }
5709 
5710 
5711 static UChar *
s390_emit_VPK(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5712 s390_emit_VPK(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5713 {
5714    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5715       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vpk", v1, v2, v3, m4);
5716 
5717    return emit_VRR_VVVM(p, 0xE70000000094ULL, v1, v2, v3, m4);
5718 }
5719 
5720 
5721 static UChar *
s390_emit_VPKS(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5722 s390_emit_VPKS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5723 {
5724    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5725       s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), "vpks", v1, v2, v3, m4, 0);
5726 
5727    return emit_VRR_VVVM(p, 0xE70000000097ULL, v1, v2, v3, m4);
5728 }
5729 
5730 
5731 static UChar *
s390_emit_VPKLS(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5732 s390_emit_VPKLS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5733 {
5734    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5735       s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), "vpkls", v1, v2, v3, m4, 0);
5736 
5737    return emit_VRR_VVVM(p, 0xE70000000095ULL, v1, v2, v3, m4);
5738 }
5739 
5740 
5741 static UChar *
s390_emit_VREP(UChar * p,UChar v1,UChar v3,UChar m3)5742 s390_emit_VREP(UChar *p, UChar v1, UChar v3, UChar m3)
5743 {
5744    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5745       s390_disasm(ENC5(MNM, VR, VR, UINT, UINT), "vrep", v1, v3, 0, m3);
5746 
5747    return emit_VRR_VVM(p, 0xE7000000004DULL, v1, v3, m3);
5748 }
5749 
5750 
5751 
5752 static UChar *
s390_emit_VUPH(UChar * p,UChar v1,UChar v3,UChar m3)5753 s390_emit_VUPH(UChar *p, UChar v1, UChar v3, UChar m3)
5754 {
5755    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5756       s390_disasm(ENC4(MNM, VR, VR, UINT), "vuph", v1, v3, m3);
5757 
5758    return emit_VRR_VVM(p, 0xE700000000D7ULL, v1, v3, m3);
5759 }
5760 
5761 
5762 static UChar *
s390_emit_VUPLH(UChar * p,UChar v1,UChar v3,UChar m3)5763 s390_emit_VUPLH(UChar *p, UChar v1, UChar v3, UChar m3)
5764 {
5765    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5766       s390_disasm(ENC4(MNM, VR, VR, UINT), "vuplh", v1, v3, m3);
5767 
5768    return emit_VRR_VVM(p, 0xE700000000D5ULL, v1, v3, m3);
5769 }
5770 
5771 
5772 static UChar*
s390_emit_VMRH(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5773 s390_emit_VMRH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5774 {
5775    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5776       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vmrh", v1, v2, v3, m4);
5777 
5778    return emit_VRR_VVVM(p, 0xE70000000061ULL, v1, v2, v3, m4);
5779 }
5780 
5781 
5782 static UChar*
s390_emit_VMRL(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5783 s390_emit_VMRL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5784 {
5785    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5786       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vmrl", v1, v2, v3, m4);
5787 
5788    return emit_VRR_VVVM(p, 0xE70000000060ULL, v1, v2, v3, m4);
5789 }
5790 
5791 static UChar *
s390_emit_VA(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5792 s390_emit_VA(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5793 {
5794    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5795       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "va", v1, v2, v3, m4);
5796 
5797    return emit_VRR_VVVM(p, 0xE700000000f3ULL, v1, v2, v3, m4);
5798 }
5799 
5800 static UChar *
s390_emit_VS(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5801 s390_emit_VS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5802 {
5803    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5804       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vs", v1, v2, v3, m4);
5805 
5806    return emit_VRR_VVVM(p, 0xE700000000f7ULL, v1, v2, v3, m4);
5807 }
5808 
5809 static UChar *
s390_emit_VNO(UChar * p,UChar v1,UChar v2,UChar v3)5810 s390_emit_VNO(UChar *p, UChar v1, UChar v2, UChar v3)
5811 {
5812    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5813       s390_disasm(ENC4(MNM, VR, VR, VR), "vno", v1, v2, v3);
5814 
5815    return emit_VRR_VVV(p, 0xE7000000006bULL, v1, v2, v3);
5816 }
5817 
5818 static UChar *
s390_emit_VCH(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5819 s390_emit_VCH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5820 {
5821    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5822       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vch", v1, v2, v3, m4);
5823 
5824    return emit_VRR_VVVM(p, 0xE700000000fbULL, v1, v2, v3, m4);
5825 }
5826 
5827 static UChar *
s390_emit_VCHL(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5828 s390_emit_VCHL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5829 {
5830    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5831       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vchl", v1, v2, v3, m4);
5832 
5833    return emit_VRR_VVVM(p, 0xE700000000f9ULL, v1, v2, v3, m4);
5834 }
5835 
5836 static UChar *
s390_emit_VCLZ(UChar * p,UChar v1,UChar v2,UChar m4)5837 s390_emit_VCLZ(UChar *p, UChar v1, UChar v2, UChar m4)
5838 {
5839    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5840       s390_disasm(ENC4(MNM, VR, VR, UINT), "vclz", v1, v2, m4);
5841 
5842    return emit_VRR_VVM(p, 0xE70000000053ULL, v1, v2, m4);
5843 }
5844 
5845 static UChar *
s390_emit_VCTZ(UChar * p,UChar v1,UChar v2,UChar m4)5846 s390_emit_VCTZ(UChar *p, UChar v1, UChar v2, UChar m4)
5847 {
5848    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5849       s390_disasm(ENC4(MNM, VR, VR, UINT), "vctz", v1, v2, m4);
5850 
5851    return emit_VRR_VVM(p, 0xE70000000052ULL, v1, v2, m4);
5852 }
5853 
5854 static UChar *
s390_emit_VPOPCT(UChar * p,UChar v1,UChar v2,UChar m4)5855 s390_emit_VPOPCT(UChar *p, UChar v1, UChar v2, UChar m4)
5856 {
5857    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5858       s390_disasm(ENC4(MNM, VR, VR, UINT), "vpopct", v1, v2, m4);
5859 
5860    return emit_VRR_VVM(p, 0xE70000000050ULL, v1, v2, m4);
5861 }
5862 
5863 static UChar *
s390_emit_VMX(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5864 s390_emit_VMX(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5865 {
5866    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5867       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vmx", v1, v2, v3, m4);
5868 
5869    return emit_VRR_VVVM(p, 0xE700000000ffULL, v1, v2, v3, m4);
5870 }
5871 
5872 static UChar *
s390_emit_VMXL(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5873 s390_emit_VMXL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5874 {
5875    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5876       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vmxl", v1, v2, v3, m4);
5877 
5878    return emit_VRR_VVVM(p, 0xE700000000fdULL, v1, v2, v3, m4);
5879 }
5880 
5881 static UChar *
s390_emit_VMN(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5882 s390_emit_VMN(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5883 {
5884    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5885       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vmn", v1, v2, v3, m4);
5886 
5887    return emit_VRR_VVVM(p, 0xE700000000feULL, v1, v2, v3, m4);
5888 }
5889 
5890 static UChar *
s390_emit_VMNL(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5891 s390_emit_VMNL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5892 {
5893    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5894       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vmnl", v1, v2, v3, m4);
5895 
5896    return emit_VRR_VVVM(p, 0xE700000000fcULL, v1, v2, v3, m4);
5897 }
5898 
5899 static UChar *
s390_emit_VAVG(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5900 s390_emit_VAVG(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5901 {
5902    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5903       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vavg", v1, v2, v3, m4);
5904 
5905    return emit_VRR_VVVM(p, 0xE700000000f2ULL, v1, v2, v3, m4);
5906 }
5907 
5908 static UChar *
s390_emit_VAVGL(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5909 s390_emit_VAVGL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5910 {
5911    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5912       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vavgl", v1, v2, v3, m4);
5913 
5914    return emit_VRR_VVVM(p, 0xE700000000f0ULL, v1, v2, v3, m4);
5915 }
5916 
5917 static UChar *
s390_emit_VLP(UChar * p,UChar v1,UChar v2,UChar m3)5918 s390_emit_VLP(UChar *p, UChar v1, UChar v2, UChar m3)
5919 {
5920    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5921       s390_disasm(ENC4(MNM, VR, VR, UINT), "vlp", v1, v2, m3);
5922 
5923    return emit_VRR_VVM(p, 0xE700000000DFULL, v1, v2, m3);
5924 }
5925 
5926 static UChar *
s390_emit_VMH(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5927 s390_emit_VMH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5928 {
5929    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5930       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vmh", v1, v2, v3, m4);
5931 
5932    return emit_VRR_VVVM(p, 0xE700000000a3ULL, v1, v2, v3, m4);
5933 }
5934 
5935 static UChar *
s390_emit_VMLH(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5936 s390_emit_VMLH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5937 {
5938    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5939       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vmlh", v1, v2, v3, m4);
5940 
5941    return emit_VRR_VVVM(p, 0xE700000000a1ULL, v1, v2, v3, m4);
5942 }
5943 
5944 static UChar *
s390_emit_VML(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5945 s390_emit_VML(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5946 {
5947    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5948       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vml", v1, v2, v3, m4);
5949 
5950    return emit_VRR_VVVM(p, 0xE700000000a2ULL, v1, v2, v3, m4);
5951 }
5952 
5953 static UChar *
s390_emit_VME(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5954 s390_emit_VME(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5955 {
5956    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5957       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vme", v1, v2, v3, m4);
5958 
5959    return emit_VRR_VVVM(p, 0xE700000000a6ULL, v1, v2, v3, m4);
5960 }
5961 
5962 static UChar *
s390_emit_VMLE(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5963 s390_emit_VMLE(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5964 {
5965    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5966       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vmle", v1, v2, v3, m4);
5967 
5968    return emit_VRR_VVVM(p, 0xE700000000a4ULL, v1, v2, v3, m4);
5969 }
5970 
5971 static UChar *
s390_emit_VESLV(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5972 s390_emit_VESLV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5973 {
5974    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5975       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "veslv", v1, v2, v3, m4);
5976 
5977    return emit_VRR_VVVM(p, 0xE70000000070ULL, v1, v2, v3, m4);
5978 }
5979 
5980 static UChar *
s390_emit_VESRAV(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5981 s390_emit_VESRAV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5982 {
5983    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5984       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vesrav", v1, v2, v3, m4);
5985 
5986    return emit_VRR_VVVM(p, 0xE7000000007aULL, v1, v2, v3, m4);
5987 }
5988 
5989 static UChar *
s390_emit_VESRLV(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)5990 s390_emit_VESRLV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
5991 {
5992    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
5993       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vesrlv", v1, v2, v3, m4);
5994 
5995    return emit_VRR_VVVM(p, 0xE70000000078ULL, v1, v2, v3, m4);
5996 }
5997 
5998 static UChar *
s390_emit_VESL(UChar * p,UChar v1,UChar b2,UShort d2,UChar v3,UChar m4)5999 s390_emit_VESL(UChar *p, UChar v1, UChar b2, UShort d2, UChar v3, UChar m4)
6000 {
6001    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6002       s390_disasm(ENC5(MNM, VR, UDXB, VR, UINT), "vesl", v1, d2, 0, b2, v3, m4);
6003 
6004    return emit_VRS(p, 0xE70000000030ULL, v1, b2, d2, v3, m4);
6005 }
6006 
6007 static UChar *
s390_emit_VESRA(UChar * p,UChar v1,UChar b2,UShort d2,UChar v3,UChar m4)6008 s390_emit_VESRA(UChar *p, UChar v1, UChar b2, UShort d2, UChar v3, UChar m4)
6009 {
6010    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6011       s390_disasm(ENC5(MNM, VR, UDXB, VR, UINT), "vesra", v1, d2, 0, b2, v3, m4);
6012 
6013    return emit_VRS(p, 0xE7000000003aULL, v1, b2, d2, v3, m4);
6014 }
6015 
6016 static UChar *
s390_emit_VESRL(UChar * p,UChar v1,UChar b2,UShort d2,UChar v3,UChar m4)6017 s390_emit_VESRL(UChar *p, UChar v1, UChar b2, UShort d2, UChar v3, UChar m4)
6018 {
6019    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6020       s390_disasm(ENC5(MNM, VR, UDXB, VR, UINT), "vesrl", v1, d2, 0, b2, v3, m4);
6021 
6022    return emit_VRS(p, 0xE70000000038ULL, v1, b2, d2, v3, m4);
6023 }
6024 
6025 static UChar *
s390_emit_VERLLV(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)6026 s390_emit_VERLLV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
6027 {
6028    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6029       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "verllv", v1, v2, v3, m4);
6030 
6031    return emit_VRR_VVVM(p, 0xE70000000073ULL, v1, v2, v3, m4);
6032 }
6033 
6034 static UChar *
s390_emit_VSL(UChar * p,UChar v1,UChar v2,UChar v3)6035 s390_emit_VSL(UChar *p, UChar v1, UChar v2, UChar v3)
6036 {
6037    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6038       s390_disasm(ENC4(MNM, VR, VR, VR), "vsl", v1, v2, v3);
6039 
6040    return emit_VRR_VVV(p, 0xE70000000074ULL, v1, v2, v3);
6041 }
6042 
6043 static UChar *
s390_emit_VSRL(UChar * p,UChar v1,UChar v2,UChar v3)6044 s390_emit_VSRL(UChar *p, UChar v1, UChar v2, UChar v3)
6045 {
6046    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6047       s390_disasm(ENC4(MNM, VR, VR, VR), "vsrl", v1, v2, v3);
6048 
6049    return emit_VRR_VVV(p, 0xE7000000007cULL, v1, v2, v3);
6050 }
6051 
6052 static UChar *
s390_emit_VSRA(UChar * p,UChar v1,UChar v2,UChar v3)6053 s390_emit_VSRA(UChar *p, UChar v1, UChar v2, UChar v3)
6054 {
6055    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6056       s390_disasm(ENC4(MNM, VR, VR, VR), "vsra", v1, v2, v3);
6057 
6058    return emit_VRR_VVV(p, 0xE7000000007eULL, v1, v2, v3);
6059 }
6060 
6061 static UChar *
s390_emit_VSLB(UChar * p,UChar v1,UChar v2,UChar v3)6062 s390_emit_VSLB(UChar *p, UChar v1, UChar v2, UChar v3)
6063 {
6064    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6065       s390_disasm(ENC4(MNM, VR, VR, VR), "vslb", v1, v2, v3);
6066 
6067    return emit_VRR_VVV(p, 0xE70000000075ULL, v1, v2, v3);
6068 }
6069 
6070 static UChar *
s390_emit_VSRLB(UChar * p,UChar v1,UChar v2,UChar v3)6071 s390_emit_VSRLB(UChar *p, UChar v1, UChar v2, UChar v3)
6072 {
6073    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6074       s390_disasm(ENC4(MNM, VR, VR, VR), "vsrlb", v1, v2, v3);
6075 
6076    return emit_VRR_VVV(p, 0xE7000000007dULL, v1, v2, v3);
6077 }
6078 
6079 static UChar *
s390_emit_VSRAB(UChar * p,UChar v1,UChar v2,UChar v3)6080 s390_emit_VSRAB(UChar *p, UChar v1, UChar v2, UChar v3)
6081 {
6082    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6083       s390_disasm(ENC4(MNM, VR, VR, VR), "vsrab", v1, v2, v3);
6084 
6085    return emit_VRR_VVV(p, 0xE7000000007fULL, v1, v2, v3);
6086 }
6087 
6088 static UChar *
s390_emit_VSUM(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)6089 s390_emit_VSUM(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
6090 {
6091    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6092       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vsum", v1, v2, v3, m4);
6093 
6094    return emit_VRR_VVVM(p, 0xE70000000064ULL, v1, v2, v3, m4);
6095 }
6096 
6097 static UChar *
s390_emit_VSUMG(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)6098 s390_emit_VSUMG(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
6099 {
6100    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6101       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vsumg", v1, v2, v3, m4);
6102 
6103    return emit_VRR_VVVM(p, 0xE70000000065ULL, v1, v2, v3, m4);
6104 }
6105 
6106 static UChar *
s390_emit_VSUMQ(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4)6107 s390_emit_VSUMQ(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4)
6108 {
6109    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6110       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), "vsumq", v1, v2, v3, m4);
6111 
6112    return emit_VRR_VVVM(p, 0xE70000000067ULL, v1, v2, v3, m4);
6113 }
6114 
6115 static UChar *
s390_emit_VLVGP(UChar * p,UChar v1,UChar r2,UChar r3)6116 s390_emit_VLVGP(UChar *p, UChar v1, UChar r2, UChar r3)
6117 {
6118    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6119       s390_disasm(ENC4(MNM, VR, GPR, GPR), "vlvgp", v1, r2, r3);
6120 
6121    return emit_VRR_VRR(p, 0xE70000000062ULL, v1, r2, r3);
6122 }
6123 
6124 static UChar *
s390_emit_VFPSO(UChar * p,UChar v1,UChar v2,UChar m3,UChar m4,UChar m5)6125 s390_emit_VFPSO(UChar *p, UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
6126 {
6127    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6128       s390_disasm(ENC6(MNM, VR, VR, UINT, UINT, UINT), "vfpso", v1, v2, m3, m4,
6129                   m5);
6130 
6131    return emit_VRR_VVMMM(p, 0xE700000000CCULL, v1, v2, m3, m4, m5);
6132 }
6133 
6134 static UChar *
s390_emit_VFA(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4,UChar m5)6135 s390_emit_VFA(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
6136 {
6137    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6138       s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), "vfa", v1, v2, v3, m4, m5);
6139 
6140    return emit_VRR_VVVMM(p, 0xE700000000e3ULL, v1, v2, v3, m4, m5);
6141 }
6142 
6143 static UChar *
s390_emit_VFS(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4,UChar m5)6144 s390_emit_VFS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
6145 {
6146    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6147       s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), "vfs", v1, v2, v3, m4, m5);
6148 
6149    return emit_VRR_VVVMM(p, 0xE700000000e2ULL, v1, v2, v3, m4, m5);
6150 }
6151 
6152 static UChar *
s390_emit_VFM(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4,UChar m5)6153 s390_emit_VFM(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
6154 {
6155    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6156       s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), "vfm", v1, v2, v3, m4, m5);
6157 
6158    return emit_VRR_VVVMM(p, 0xE700000000e7ULL, v1, v2, v3, m4, m5);
6159 }
6160 
6161 static UChar *
s390_emit_VFD(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4,UChar m5)6162 s390_emit_VFD(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
6163 {
6164    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6165       s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), "vfd", v1, v2, v3, m4, m5);
6166 
6167    return emit_VRR_VVVMM(p, 0xE700000000e5ULL, v1, v2, v3, m4, m5);
6168 }
6169 
6170 static UChar *
s390_emit_VFSQ(UChar * p,UChar v1,UChar v2,UChar m3,UChar m4)6171 s390_emit_VFSQ(UChar *p, UChar v1, UChar v2, UChar m3, UChar m4)
6172 {
6173    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6174       s390_disasm(ENC5(MNM, VR, VR, UINT, UINT), "vfsq", v1, v2, m3, m4);
6175 
6176    return emit_VRR_VVMMM(p, 0xE700000000CEULL, v1, v2, m3, m4, 0);
6177 }
6178 
6179 static UChar *
s390_emit_VFMA(UChar * p,UChar v1,UChar v2,UChar v3,UChar v4,UChar m5,UChar m6)6180 s390_emit_VFMA(UChar *p, UChar v1, UChar v2, UChar v3, UChar v4, UChar m5,
6181                UChar m6)
6182 {
6183    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6184       s390_disasm(ENC7(MNM, VR, VR, VR, VR, UINT, UINT), "vfma",
6185                   v1, v2, v3, v4, m5, m6);
6186 
6187    return emit_VRRe_VVVVMM(p, 0xE7000000008fULL, v1, v2, v3, v4, m5, m6);
6188 }
6189 
6190 static UChar *
s390_emit_VFMS(UChar * p,UChar v1,UChar v2,UChar v3,UChar v4,UChar m5,UChar m6)6191 s390_emit_VFMS(UChar *p, UChar v1, UChar v2, UChar v3, UChar v4, UChar m5,
6192                UChar m6)
6193 {
6194    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6195       s390_disasm(ENC7(MNM, VR, VR, VR, VR, UINT, UINT), "vfms",
6196                   v1, v2, v3, v4, m5, m6);
6197 
6198    return emit_VRRe_VVVVMM(p, 0xE7000000008eULL, v1, v2, v3, v4, m5, m6);
6199 }
6200 
6201 static UChar *
s390_emit_VFCE(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4,UChar m5,UChar m6)6202 s390_emit_VFCE(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5,
6203                UChar m6)
6204 {
6205    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6206       s390_disasm(ENC7(MNM, VR, VR, VR, UINT, UINT, UINT), "vfce",
6207                   v1, v2, v3, m4, m5, m6);
6208 
6209    return emit_VRR_VVVMMM(p, 0xE700000000e8ULL, v1, v2, v3, m4, m5, m6);
6210 }
6211 
6212 static UChar *
s390_emit_VFCH(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4,UChar m5,UChar m6)6213 s390_emit_VFCH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5,
6214                UChar m6)
6215 {
6216    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6217       s390_disasm(ENC7(MNM, VR, VR, VR, UINT, UINT, UINT), "vfch",
6218                   v1, v2, v3, m4, m5, m6);
6219 
6220    return emit_VRR_VVVMMM(p, 0xE700000000ebULL, v1, v2, v3, m4, m5, m6);
6221 }
6222 
6223 static UChar *
s390_emit_VFCHE(UChar * p,UChar v1,UChar v2,UChar v3,UChar m4,UChar m5,UChar m6)6224 s390_emit_VFCHE(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5,
6225                 UChar m6)
6226 {
6227    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
6228       s390_disasm(ENC7(MNM, VR, VR, VR, UINT, UINT, UINT), "vfche",
6229                   v1, v2, v3, m4, m5, m6);
6230 
6231    return emit_VRR_VVVMMM(p, 0xE700000000eaULL, v1, v2, v3, m4, m5, m6);
6232 }
6233 
6234 /*---------------------------------------------------------------*/
6235 /*--- Constructors for the various s390_insn kinds            ---*/
6236 /*---------------------------------------------------------------*/
6237 
6238 s390_insn *
s390_insn_load(UChar size,HReg dst,s390_amode * src)6239 s390_insn_load(UChar size, HReg dst, s390_amode *src)
6240 {
6241    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6242 
6243    insn->tag  = S390_INSN_LOAD;
6244    insn->size = size;
6245    insn->variant.load.src  = src;
6246    insn->variant.load.dst  = dst;
6247 
6248    vassert(size == 1 || size == 2 || size == 4 || size == 8 || size == 16);
6249 
6250    return insn;
6251 }
6252 
6253 
6254 s390_insn *
s390_insn_store(UChar size,s390_amode * dst,HReg src)6255 s390_insn_store(UChar size, s390_amode *dst, HReg src)
6256 {
6257    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6258 
6259    insn->tag  = S390_INSN_STORE;
6260    insn->size = size;
6261    insn->variant.store.src  = src;
6262    insn->variant.store.dst  = dst;
6263 
6264    vassert(size == 1 || size == 2 || size == 4 || size == 8 || size == 16);
6265 
6266    return insn;
6267 }
6268 
6269 
6270 s390_insn *
s390_insn_move(UChar size,HReg dst,HReg src)6271 s390_insn_move(UChar size, HReg dst, HReg src)
6272 {
6273    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6274 
6275    insn->tag  = S390_INSN_MOVE;
6276    insn->size = size;
6277    insn->variant.move.src  = src;
6278    insn->variant.move.dst  = dst;
6279 
6280    vassert(size == 1 || size == 2 || size == 4 || size == 8 || size ==16);
6281 
6282    return insn;
6283 }
6284 
6285 
6286 s390_insn *
s390_insn_memcpy(UChar size,s390_amode * dst,s390_amode * src)6287 s390_insn_memcpy(UChar size, s390_amode *dst, s390_amode *src)
6288 {
6289    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6290 
6291    /* This insn will be mapped to MVC which requires base register
6292       plus 12-bit displacement */
6293    vassert(src->tag == S390_AMODE_B12);
6294    vassert(dst->tag == S390_AMODE_B12);
6295 
6296    insn->tag  = S390_INSN_MEMCPY;
6297    insn->size = size;
6298    insn->variant.memcpy.src = src;
6299    insn->variant.memcpy.dst = dst;
6300 
6301    vassert(size == 1 || size == 2 || size == 4 || size == 8);
6302 
6303    return insn;
6304 }
6305 
6306 
6307 s390_insn *
s390_insn_cond_move(UChar size,s390_cc_t cond,HReg dst,s390_opnd_RMI src)6308 s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst, s390_opnd_RMI src)
6309 {
6310    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6311 
6312    insn->tag  = S390_INSN_COND_MOVE;
6313    insn->size = size;
6314    insn->variant.cond_move.cond = cond;
6315    insn->variant.cond_move.src  = src;
6316    insn->variant.cond_move.dst  = dst;
6317 
6318    vassert(size == 1 || size == 2 || size == 4 || size == 8);
6319 
6320    return insn;
6321 }
6322 
6323 
6324 s390_insn *
s390_insn_load_immediate(UChar size,HReg dst,ULong value)6325 s390_insn_load_immediate(UChar size, HReg dst, ULong value)
6326 {
6327    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6328 
6329    insn->tag  = S390_INSN_LOAD_IMMEDIATE;
6330    insn->size = size;
6331    insn->variant.load_immediate.dst   = dst;
6332    insn->variant.load_immediate.value = value;
6333 
6334    return insn;
6335 }
6336 
6337 
6338 s390_insn *
s390_insn_alu(UChar size,s390_alu_t tag,HReg dst,s390_opnd_RMI op2)6339 s390_insn_alu(UChar size, s390_alu_t tag, HReg dst, s390_opnd_RMI op2)
6340 {
6341    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6342 
6343    insn->tag  = S390_INSN_ALU;
6344    insn->size = size;
6345    insn->variant.alu.tag = tag;
6346    insn->variant.alu.dst = dst;
6347    insn->variant.alu.op2 = op2;
6348 
6349    return insn;
6350 }
6351 
6352 
6353 s390_insn *
s390_insn_mul(UChar size,HReg dst_hi,HReg dst_lo,s390_opnd_RMI op2,Bool signed_multiply)6354 s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo, s390_opnd_RMI op2,
6355               Bool signed_multiply)
6356 {
6357    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6358 
6359    vassert(! hregIsVirtual(dst_hi));
6360    vassert(! hregIsVirtual(dst_lo));
6361 
6362    insn->tag  = signed_multiply ? S390_INSN_SMUL : S390_INSN_UMUL;
6363    insn->size = size;
6364    insn->variant.mul.dst_hi = dst_hi;
6365    insn->variant.mul.dst_lo = dst_lo;
6366    insn->variant.mul.op2 = op2;
6367 
6368    return insn;
6369 }
6370 
6371 
6372 s390_insn *
s390_insn_div(UChar size,HReg op1_hi,HReg op1_lo,s390_opnd_RMI op2,Bool signed_divide)6373 s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo, s390_opnd_RMI op2,
6374               Bool signed_divide)
6375 {
6376    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6377 
6378    vassert(size == 4 || size == 8);
6379    vassert(! hregIsVirtual(op1_hi));
6380    vassert(! hregIsVirtual(op1_lo));
6381 
6382    insn->tag  = signed_divide ? S390_INSN_SDIV : S390_INSN_UDIV;
6383    insn->size = size;
6384    insn->variant.div.op1_hi = op1_hi;
6385    insn->variant.div.op1_lo = op1_lo;
6386    insn->variant.div.op2 = op2;
6387 
6388    return insn;
6389 }
6390 
6391 
6392 s390_insn *
s390_insn_divs(UChar size,HReg rem,HReg op1,s390_opnd_RMI op2)6393 s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2)
6394 {
6395    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6396 
6397    vassert(size == 8);
6398    vassert(! hregIsVirtual(op1));
6399    vassert(! hregIsVirtual(rem));
6400 
6401    insn->tag  = S390_INSN_DIVS;
6402    insn->size = size;
6403    insn->variant.divs.rem = rem;   /* remainder */
6404    insn->variant.divs.op1 = op1;   /* also quotient */
6405    insn->variant.divs.op2 = op2;
6406 
6407    return insn;
6408 }
6409 
6410 
6411 s390_insn *
s390_insn_clz(UChar size,HReg num_bits,HReg clobber,s390_opnd_RMI src)6412 s390_insn_clz(UChar size, HReg num_bits, HReg clobber, s390_opnd_RMI src)
6413 {
6414    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6415 
6416    vassert(size == 8);
6417    vassert(! hregIsVirtual(num_bits));
6418    vassert(! hregIsVirtual(clobber));
6419 
6420    insn->tag  = S390_INSN_CLZ;
6421    insn->size = size;
6422    insn->variant.clz.num_bits = num_bits;
6423    insn->variant.clz.clobber  = clobber;
6424    insn->variant.clz.src = src;
6425 
6426    return insn;
6427 }
6428 
6429 
6430 s390_insn *
s390_insn_unop(UChar size,s390_unop_t tag,HReg dst,s390_opnd_RMI opnd)6431 s390_insn_unop(UChar size, s390_unop_t tag, HReg dst, s390_opnd_RMI opnd)
6432 {
6433    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6434 
6435    insn->tag  = S390_INSN_UNOP;
6436    insn->size = size;
6437    insn->variant.unop.tag = tag;
6438    insn->variant.unop.dst = dst;
6439    insn->variant.unop.src = opnd;
6440 
6441    return insn;
6442 }
6443 
6444 
6445 s390_insn *
s390_insn_test(UChar size,s390_opnd_RMI src)6446 s390_insn_test(UChar size, s390_opnd_RMI src)
6447 {
6448    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6449 
6450    vassert(size == 4 || size == 8);
6451 
6452    insn->tag  = S390_INSN_TEST;
6453    insn->size = size;
6454    insn->variant.test.src = src;
6455 
6456    return insn;
6457 }
6458 
6459 
6460 s390_insn *
s390_insn_cc2bool(HReg dst,s390_cc_t cond)6461 s390_insn_cc2bool(HReg dst, s390_cc_t cond)
6462 {
6463    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6464 
6465    insn->tag  = S390_INSN_CC2BOOL;
6466    insn->size = 0;   /* does not matter */
6467    insn->variant.cc2bool.cond = cond;
6468    insn->variant.cc2bool.dst  = dst;
6469 
6470    return insn;
6471 }
6472 
6473 
6474 s390_insn *
s390_insn_cas(UChar size,HReg op1,s390_amode * op2,HReg op3,HReg old_mem)6475 s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3, HReg old_mem)
6476 {
6477    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6478 
6479    vassert(size == 4 || size == 8);
6480    vassert(hregNumber(op2->x) == 0);
6481    vassert(op2->tag == S390_AMODE_B12 || op2->tag == S390_AMODE_B20);
6482 
6483    insn->tag  = S390_INSN_CAS;
6484    insn->size = size;
6485    insn->variant.cas.op1 = op1;
6486    insn->variant.cas.op2 = op2;
6487    insn->variant.cas.op3 = op3;
6488    insn->variant.cas.old_mem = old_mem;
6489 
6490    return insn;
6491 }
6492 
6493 
6494 s390_insn *
s390_insn_cdas(UChar size,HReg op1_high,HReg op1_low,s390_amode * op2,HReg op3_high,HReg op3_low,HReg old_mem_high,HReg old_mem_low,HReg scratch)6495 s390_insn_cdas(UChar size, HReg op1_high, HReg op1_low, s390_amode *op2,
6496                HReg op3_high, HReg op3_low, HReg old_mem_high, HReg old_mem_low,
6497                HReg scratch)
6498 {
6499    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6500    s390_cdas *cdas = LibVEX_Alloc_inline(sizeof(s390_cdas));
6501 
6502    vassert(size == 4 || size == 8);
6503    vassert(hregNumber(op2->x) == 0);
6504    vassert(hregNumber(scratch) == 1);  /* r0,r1 used as scratch reg pair */
6505    vassert(op2->tag == S390_AMODE_B12 || op2->tag == S390_AMODE_B20);
6506 
6507    insn->tag  = S390_INSN_CDAS;
6508    insn->size = size;
6509    insn->variant.cdas.details = cdas;
6510 
6511    cdas->op1_high = op1_high;
6512    cdas->op1_low  = op1_low;
6513    cdas->op2 = op2;
6514    cdas->op3_high = op3_high;
6515    cdas->op3_low  = op3_low;
6516    cdas->old_mem_high = old_mem_high;
6517    cdas->old_mem_low  = old_mem_low;
6518    cdas->scratch = scratch;
6519 
6520    return insn;
6521 }
6522 
6523 
6524 s390_insn *
s390_insn_compare(UChar size,HReg src1,s390_opnd_RMI src2,Bool signed_comparison)6525 s390_insn_compare(UChar size, HReg src1, s390_opnd_RMI src2,
6526                   Bool signed_comparison)
6527 {
6528    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6529 
6530    vassert(size == 4 || size == 8);
6531 
6532    insn->tag  = S390_INSN_COMPARE;
6533    insn->size = size;
6534    insn->variant.compare.src1 = src1;
6535    insn->variant.compare.src2 = src2;
6536    insn->variant.compare.signed_comparison = signed_comparison;
6537 
6538    return insn;
6539 }
6540 
6541 
6542 s390_insn *
s390_insn_helper_call(s390_cc_t cond,Addr64 target,UInt num_args,const HChar * name,RetLoc rloc)6543 s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args,
6544                       const HChar *name, RetLoc rloc)
6545 {
6546    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6547    s390_helper_call *helper_call = LibVEX_Alloc_inline(sizeof(s390_helper_call));
6548 
6549    insn->tag  = S390_INSN_HELPER_CALL;
6550    insn->size = 0;  /* does not matter */
6551    insn->variant.helper_call.details = helper_call;
6552 
6553    helper_call->cond = cond;
6554    helper_call->target = target;
6555    helper_call->num_args = num_args;
6556    helper_call->name = name;
6557    helper_call->rloc = rloc;
6558 
6559    vassert(is_sane_RetLoc(rloc));
6560 
6561    return insn;
6562 }
6563 
6564 
6565 s390_insn *
s390_insn_bfp_triop(UChar size,s390_bfp_triop_t tag,HReg dst,HReg op2,HReg op3)6566 s390_insn_bfp_triop(UChar size, s390_bfp_triop_t tag, HReg dst, HReg op2,
6567                     HReg op3)
6568 {
6569    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6570 
6571    vassert(size == 4 || size == 8);
6572 
6573    insn->tag  = S390_INSN_BFP_TRIOP;
6574    insn->size = size;
6575    insn->variant.bfp_triop.tag = tag;
6576    insn->variant.bfp_triop.dst = dst;
6577    insn->variant.bfp_triop.op2 = op2;
6578    insn->variant.bfp_triop.op3 = op3;
6579 
6580    return insn;
6581 }
6582 
6583 
6584 s390_insn *
s390_insn_bfp_binop(UChar size,s390_bfp_binop_t tag,HReg dst,HReg op2)6585 s390_insn_bfp_binop(UChar size, s390_bfp_binop_t tag, HReg dst, HReg op2)
6586 {
6587    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6588 
6589    vassert(size == 4 || size == 8);
6590 
6591    insn->tag  = S390_INSN_BFP_BINOP;
6592    insn->size = size;
6593    insn->variant.bfp_binop.tag = tag;
6594    insn->variant.bfp_binop.dst_hi = dst;
6595    insn->variant.bfp_binop.op2_hi = op2;
6596    insn->variant.bfp_binop.dst_lo = INVALID_HREG;
6597    insn->variant.bfp_binop.op2_lo = INVALID_HREG;
6598 
6599    return insn;
6600 }
6601 
6602 
6603 s390_insn *
s390_insn_bfp_unop(UChar size,s390_bfp_unop_t tag,HReg dst,HReg op)6604 s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst, HReg op)
6605 {
6606    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6607 
6608    vassert(size == 4 || size == 8);
6609 
6610    insn->tag  = S390_INSN_BFP_UNOP;
6611    insn->size = size;
6612    insn->variant.bfp_unop.tag = tag;
6613    insn->variant.bfp_unop.dst_hi = dst;
6614    insn->variant.bfp_unop.op_hi  = op;
6615    insn->variant.bfp_unop.dst_lo = INVALID_HREG;
6616    insn->variant.bfp_unop.op_lo  = INVALID_HREG;
6617 
6618    return insn;
6619 }
6620 
6621 
6622 s390_insn *
s390_insn_bfp_compare(UChar size,HReg dst,HReg op1,HReg op2)6623 s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2)
6624 {
6625    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6626 
6627    vassert(size == 4 || size == 8);
6628 
6629    insn->tag  = S390_INSN_BFP_COMPARE;
6630    insn->size = size;
6631    insn->variant.bfp_compare.dst = dst;
6632    insn->variant.bfp_compare.op1_hi = op1;
6633    insn->variant.bfp_compare.op2_hi = op2;
6634    insn->variant.bfp_compare.op1_lo = INVALID_HREG;
6635    insn->variant.bfp_compare.op2_lo = INVALID_HREG;
6636 
6637    return insn;
6638 }
6639 
6640 
6641 s390_insn *
s390_insn_bfp_convert(UChar size,s390_bfp_conv_t tag,HReg dst,HReg op,s390_bfp_round_t rounding_mode)6642 s390_insn_bfp_convert(UChar size, s390_bfp_conv_t tag, HReg dst, HReg op,
6643                       s390_bfp_round_t rounding_mode)
6644 {
6645    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6646 
6647    vassert(size == 4 || size == 8);
6648 
6649    insn->tag  = S390_INSN_BFP_CONVERT;
6650    insn->size = size;
6651    insn->variant.bfp_convert.tag = tag;
6652    insn->variant.bfp_convert.dst_hi = dst;
6653    insn->variant.bfp_convert.op_hi  = op;
6654    insn->variant.bfp_convert.dst_lo = INVALID_HREG;
6655    insn->variant.bfp_convert.op_lo  = INVALID_HREG;
6656    insn->variant.bfp_convert.rounding_mode = rounding_mode;
6657 
6658    return insn;
6659 }
6660 
6661 
6662 /* Check validity of a register pair for 128-bit FP. Valid register
6663    pairs are (0,2), (1,3), (4, 6), (5, 7), (8, 10), (9, 11), (12, 14),
6664    and (13, 15). */
6665 static Bool
is_valid_fp128_regpair(HReg hi,HReg lo)6666 is_valid_fp128_regpair(HReg hi, HReg lo)
6667 {
6668    UInt hi_regno = hregNumber(hi);
6669    UInt lo_regno = hregNumber(lo);
6670 
6671    if (lo_regno != hi_regno + 2) return False;
6672    if ((hi_regno & 0x2) != 0) return False;
6673 
6674    return True;
6675 }
6676 
6677 s390_insn *
s390_insn_bfp128_binop(UChar size,s390_bfp_binop_t tag,HReg dst_hi,HReg dst_lo,HReg op2_hi,HReg op2_lo)6678 s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t tag, HReg dst_hi,
6679                        HReg dst_lo, HReg op2_hi, HReg op2_lo)
6680 {
6681    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6682 
6683    vassert(size == 16);
6684    vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
6685    vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
6686 
6687    insn->tag  = S390_INSN_BFP_BINOP;
6688    insn->size = size;
6689    insn->variant.bfp_binop.tag = tag;
6690    insn->variant.bfp_binop.dst_hi = dst_hi;
6691    insn->variant.bfp_binop.dst_lo = dst_lo;
6692    insn->variant.bfp_binop.op2_hi = op2_hi;
6693    insn->variant.bfp_binop.op2_lo = op2_lo;
6694 
6695    return insn;
6696 }
6697 
6698 
6699 s390_insn *
s390_insn_bfp128_unop(UChar size,s390_bfp_unop_t tag,HReg dst_hi,HReg dst_lo,HReg op_hi,HReg op_lo)6700 s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t tag, HReg dst_hi,
6701                       HReg dst_lo, HReg op_hi, HReg op_lo)
6702 {
6703    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6704 
6705    vassert(size == 16);
6706    vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
6707    vassert(is_valid_fp128_regpair(op_hi, op_lo));
6708 
6709    insn->tag  = S390_INSN_BFP_UNOP;
6710    insn->size = size;
6711    insn->variant.bfp_unop.tag = tag;
6712    insn->variant.bfp_unop.dst_hi = dst_hi;
6713    insn->variant.bfp_unop.dst_lo = dst_lo;
6714    insn->variant.bfp_unop.op_hi = op_hi;
6715    insn->variant.bfp_unop.op_lo = op_lo;
6716 
6717    return insn;
6718 }
6719 
6720 
6721 s390_insn *
s390_insn_bfp128_compare(UChar size,HReg dst,HReg op1_hi,HReg op1_lo,HReg op2_hi,HReg op2_lo)6722 s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi, HReg op1_lo,
6723                          HReg op2_hi, HReg op2_lo)
6724 {
6725    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6726 
6727    vassert(size == 16);
6728    vassert(is_valid_fp128_regpair(op1_hi, op1_lo));
6729    vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
6730 
6731    insn->tag  = S390_INSN_BFP_COMPARE;
6732    insn->size = size;
6733    insn->variant.bfp_compare.dst = dst;
6734    insn->variant.bfp_compare.op1_hi = op1_hi;
6735    insn->variant.bfp_compare.op1_lo = op1_lo;
6736    insn->variant.bfp_compare.op2_hi = op2_hi;
6737    insn->variant.bfp_compare.op2_lo = op2_lo;
6738 
6739    return insn;
6740 }
6741 
6742 
6743 s390_insn *
s390_insn_bfp128_convert(UChar size,s390_bfp_conv_t tag,HReg dst_hi,HReg dst_lo,HReg op_hi,HReg op_lo,s390_bfp_round_t rounding_mode)6744 s390_insn_bfp128_convert(UChar size, s390_bfp_conv_t tag, HReg dst_hi,
6745                          HReg dst_lo, HReg op_hi, HReg op_lo,
6746                          s390_bfp_round_t rounding_mode)
6747 {
6748    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6749 
6750    if (size == 16) {
6751       /* From smaller or equal size to 16 bytes */
6752       vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
6753       vassert(hregIsInvalid(op_lo)
6754               || is_valid_fp128_regpair(op_hi, op_lo));
6755    } else {
6756       /* From 16 bytes to smaller size */
6757       vassert(is_valid_fp128_regpair(op_hi, op_lo));
6758    }
6759 
6760    insn->tag  = S390_INSN_BFP_CONVERT;
6761    insn->size = size;
6762    insn->variant.bfp_convert.tag = tag;
6763    insn->variant.bfp_convert.dst_hi = dst_hi;
6764    insn->variant.bfp_convert.dst_lo = dst_lo;
6765    insn->variant.bfp_convert.op_hi = op_hi;
6766    insn->variant.bfp_convert.op_lo = op_lo;
6767    insn->variant.bfp_convert.rounding_mode = rounding_mode;
6768 
6769    return insn;
6770 }
6771 
6772 
6773 s390_insn *
s390_insn_bfp128_convert_to(UChar size,s390_bfp_conv_t tag,HReg dst_hi,HReg dst_lo,HReg op)6774 s390_insn_bfp128_convert_to(UChar size, s390_bfp_conv_t tag, HReg dst_hi,
6775                             HReg dst_lo, HReg op)
6776 {
6777    /* Conversion to bfp128 never requires a rounding mode. Provide default
6778       rounding mode. It will not be used when emitting insns. */
6779    s390_bfp_round_t rounding_mode = S390_BFP_ROUND_NEAREST_EVEN;
6780 
6781    return s390_insn_bfp128_convert(size, tag, dst_hi, dst_lo, op,
6782                                    INVALID_HREG, rounding_mode);
6783 }
6784 
6785 
6786 s390_insn *
s390_insn_bfp128_convert_from(UChar size,s390_bfp_conv_t tag,HReg dst_hi,HReg dst_lo,HReg op_hi,HReg op_lo,s390_bfp_round_t rounding_mode)6787 s390_insn_bfp128_convert_from(UChar size, s390_bfp_conv_t tag, HReg dst_hi,
6788                               HReg dst_lo, HReg op_hi, HReg op_lo,
6789                               s390_bfp_round_t rounding_mode)
6790 {
6791    return s390_insn_bfp128_convert(size, tag, dst_hi, dst_lo, op_hi, op_lo,
6792                                    rounding_mode);
6793 }
6794 
6795 
6796 s390_insn *
s390_insn_dfp_binop(UChar size,s390_dfp_binop_t tag,HReg dst,HReg op2,HReg op3,s390_dfp_round_t rounding_mode)6797 s390_insn_dfp_binop(UChar size, s390_dfp_binop_t tag, HReg dst, HReg op2,
6798                     HReg op3, s390_dfp_round_t rounding_mode)
6799 {
6800    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6801    s390_dfp_binop *dfp_binop = LibVEX_Alloc_inline(sizeof(s390_dfp_binop));
6802 
6803    vassert(size == 8);
6804 
6805    insn->tag  = S390_INSN_DFP_BINOP;
6806    insn->size = size;
6807    insn->variant.dfp_binop.details = dfp_binop;
6808 
6809    dfp_binop->tag = tag;
6810    dfp_binop->dst_hi = dst;
6811    dfp_binop->op2_hi = op2;
6812    dfp_binop->op3_hi = op3;
6813    dfp_binop->dst_lo = INVALID_HREG;
6814    dfp_binop->op2_lo = INVALID_HREG;
6815    dfp_binop->op3_lo = INVALID_HREG;
6816    dfp_binop->rounding_mode = rounding_mode;
6817 
6818    return insn;
6819 }
6820 
6821 
6822 s390_insn *
s390_insn_dfp_unop(UChar size,s390_dfp_unop_t tag,HReg dst,HReg op)6823 s390_insn_dfp_unop(UChar size, s390_dfp_unop_t tag, HReg dst, HReg op)
6824 {
6825    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6826 
6827    vassert(size == 8);
6828 
6829    insn->tag  = S390_INSN_DFP_UNOP;
6830    insn->size = size;
6831    insn->variant.dfp_unop.tag = tag;
6832    insn->variant.dfp_unop.dst_hi = dst;
6833    insn->variant.dfp_unop.op_hi  = op;
6834    insn->variant.dfp_unop.dst_lo = INVALID_HREG;
6835    insn->variant.dfp_unop.op_lo  = INVALID_HREG;
6836 
6837    return insn;
6838 }
6839 
6840 
6841 s390_insn *
s390_insn_dfp_intop(UChar size,s390_dfp_intop_t tag,HReg dst,HReg op2,HReg op3)6842 s390_insn_dfp_intop(UChar size, s390_dfp_intop_t tag, HReg dst, HReg op2,
6843                     HReg op3)
6844 {
6845    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6846 
6847    vassert(size == 8);
6848 
6849    insn->tag  = S390_INSN_DFP_INTOP;
6850    insn->size = size;
6851    insn->variant.dfp_intop.tag = tag;
6852    insn->variant.dfp_intop.dst_hi = dst;
6853    insn->variant.dfp_intop.op2    = op2;
6854    insn->variant.dfp_intop.op3_hi = op3;
6855    insn->variant.dfp_intop.dst_lo = INVALID_HREG;
6856    insn->variant.dfp_intop.op3_lo = INVALID_HREG;
6857 
6858    return insn;
6859 }
6860 
6861 
6862 s390_insn *
s390_insn_dfp_compare(UChar size,s390_dfp_cmp_t tag,HReg dst,HReg op1,HReg op2)6863 s390_insn_dfp_compare(UChar size, s390_dfp_cmp_t tag, HReg dst,
6864                       HReg op1, HReg op2)
6865 {
6866    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6867 
6868    vassert(size == 8);
6869 
6870    insn->tag  = S390_INSN_DFP_COMPARE;
6871    insn->size = size;
6872    insn->variant.dfp_compare.tag = tag;
6873    insn->variant.dfp_compare.dst = dst;
6874    insn->variant.dfp_compare.op1_hi = op1;
6875    insn->variant.dfp_compare.op2_hi = op2;
6876    insn->variant.dfp_compare.op1_lo = INVALID_HREG;
6877    insn->variant.dfp_compare.op2_lo = INVALID_HREG;
6878 
6879    return insn;
6880 }
6881 
6882 
6883 s390_insn *
s390_insn_dfp_convert(UChar size,s390_dfp_conv_t tag,HReg dst,HReg op,s390_dfp_round_t rounding_mode)6884 s390_insn_dfp_convert(UChar size, s390_dfp_conv_t tag, HReg dst, HReg op,
6885                       s390_dfp_round_t rounding_mode)
6886 {
6887    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6888 
6889    vassert(size == 4 || size == 8);
6890 
6891    insn->tag  = S390_INSN_DFP_CONVERT;
6892    insn->size = size;
6893    insn->variant.dfp_convert.tag = tag;
6894    insn->variant.dfp_convert.dst_hi = dst;
6895    insn->variant.dfp_convert.op_hi  = op;
6896    insn->variant.dfp_convert.dst_lo = INVALID_HREG;
6897    insn->variant.dfp_convert.op_lo  = INVALID_HREG;
6898    insn->variant.dfp_convert.rounding_mode = rounding_mode;
6899 
6900    return insn;
6901 }
6902 
6903 
6904 s390_insn *
s390_insn_dfp_reround(UChar size,HReg dst,HReg op2,HReg op3,s390_dfp_round_t rounding_mode)6905 s390_insn_dfp_reround(UChar size, HReg dst, HReg op2, HReg op3,
6906                       s390_dfp_round_t rounding_mode)
6907 {
6908    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6909 
6910    vassert(size == 8);
6911 
6912    insn->tag  = S390_INSN_DFP_REROUND;
6913    insn->size = size;
6914    insn->variant.dfp_reround.dst_hi = dst;
6915    insn->variant.dfp_reround.op2 = op2;
6916    insn->variant.dfp_reround.op3_hi = op3;
6917    insn->variant.dfp_reround.dst_lo = INVALID_HREG;
6918    insn->variant.dfp_reround.op3_lo = INVALID_HREG;
6919    insn->variant.dfp_reround.rounding_mode = rounding_mode;
6920 
6921    return insn;
6922 }
6923 
6924 
6925 s390_insn *
s390_insn_fp_convert(UChar size,s390_fp_conv_t tag,HReg dst,HReg op,HReg r1,s390_dfp_round_t rounding_mode)6926 s390_insn_fp_convert(UChar size, s390_fp_conv_t tag, HReg dst, HReg op,
6927                      HReg r1, s390_dfp_round_t rounding_mode)
6928 {
6929    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6930    s390_fp_convert *fp_convert = LibVEX_Alloc_inline(sizeof(s390_fp_convert));
6931 
6932    vassert(size == 4 || size == 8);
6933 
6934    insn->tag  = S390_INSN_FP_CONVERT;
6935    insn->size = size;
6936    insn->variant.fp_convert.details = fp_convert;
6937 
6938    fp_convert->tag = tag;
6939    fp_convert->dst_hi = dst;
6940    fp_convert->op_hi  = op;
6941    fp_convert->r1 = r1;
6942    fp_convert->dst_lo = INVALID_HREG;
6943    fp_convert->op_lo  = INVALID_HREG;
6944    fp_convert->rounding_mode = rounding_mode;
6945 
6946    return insn;
6947 }
6948 
6949 
6950 s390_insn *
s390_insn_fp128_convert(UChar size,s390_fp_conv_t tag,HReg dst_hi,HReg dst_lo,HReg op_hi,HReg op_lo,HReg r1,s390_dfp_round_t rounding_mode)6951 s390_insn_fp128_convert(UChar size, s390_fp_conv_t tag, HReg dst_hi,
6952                         HReg dst_lo, HReg op_hi, HReg op_lo, HReg r1,
6953                         s390_dfp_round_t rounding_mode)
6954 {
6955    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6956    s390_fp_convert *fp_convert = LibVEX_Alloc_inline(sizeof(s390_fp_convert));
6957 
6958    vassert(size == 16);
6959 
6960    insn->tag  = S390_INSN_FP_CONVERT;
6961    insn->size = size;
6962    insn->variant.fp_convert.details = fp_convert;
6963 
6964    fp_convert->tag = tag;
6965    fp_convert->dst_hi = dst_hi;
6966    fp_convert->dst_lo = dst_lo;
6967    fp_convert->op_hi  = op_hi;
6968    fp_convert->r1 = r1;
6969    fp_convert->op_lo  = op_lo;
6970    fp_convert->rounding_mode = rounding_mode;
6971 
6972    return insn;
6973 }
6974 
6975 
6976 s390_insn *
s390_insn_dfp128_binop(UChar size,s390_dfp_binop_t tag,HReg dst_hi,HReg dst_lo,HReg op2_hi,HReg op2_lo,HReg op3_hi,HReg op3_lo,s390_dfp_round_t rounding_mode)6977 s390_insn_dfp128_binop(UChar size, s390_dfp_binop_t tag, HReg dst_hi,
6978                        HReg dst_lo, HReg op2_hi, HReg op2_lo, HReg op3_hi,
6979                        HReg op3_lo, s390_dfp_round_t rounding_mode)
6980 {
6981    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
6982    s390_dfp_binop *dfp_binop = LibVEX_Alloc_inline(sizeof(s390_dfp_binop));
6983 
6984    vassert(size == 16);
6985    vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
6986    vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
6987    vassert(is_valid_fp128_regpair(op3_hi, op3_lo));
6988 
6989    insn->tag  = S390_INSN_DFP_BINOP;
6990    insn->size = size;
6991    insn->variant.dfp_binop.details = dfp_binop;
6992 
6993    dfp_binop->tag = tag;
6994    dfp_binop->dst_hi = dst_hi;
6995    dfp_binop->dst_lo = dst_lo;
6996    dfp_binop->op2_hi = op2_hi;
6997    dfp_binop->op2_lo = op2_lo;
6998    dfp_binop->op3_hi = op3_hi;
6999    dfp_binop->op3_lo = op3_lo;
7000    dfp_binop->rounding_mode = rounding_mode;
7001 
7002    return insn;
7003 }
7004 
7005 
7006 s390_insn *
s390_insn_dfp128_unop(UChar size,s390_dfp_unop_t tag,HReg dst,HReg op_hi,HReg op_lo)7007 s390_insn_dfp128_unop(UChar size, s390_dfp_unop_t tag, HReg dst,
7008                       HReg op_hi, HReg op_lo)
7009 {
7010    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7011 
7012    /* destination is an 8 byte integer value */
7013    vassert(size == 8);
7014    vassert(is_valid_fp128_regpair(op_hi, op_lo));
7015 
7016    insn->tag  = S390_INSN_DFP_UNOP;
7017    insn->size = size;
7018    insn->variant.dfp_unop.tag = tag;
7019    insn->variant.dfp_unop.dst_hi = dst;
7020    insn->variant.dfp_unop.dst_lo = INVALID_HREG;
7021    insn->variant.dfp_unop.op_hi = op_hi;
7022    insn->variant.dfp_unop.op_lo = op_lo;
7023 
7024    return insn;
7025 }
7026 
7027 
7028 s390_insn *
s390_insn_dfp128_intop(UChar size,s390_dfp_intop_t tag,HReg dst_hi,HReg dst_lo,HReg op2,HReg op3_hi,HReg op3_lo)7029 s390_insn_dfp128_intop(UChar size, s390_dfp_intop_t tag, HReg dst_hi,
7030                        HReg dst_lo, HReg op2, HReg op3_hi, HReg op3_lo)
7031 {
7032    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7033 
7034    vassert(size == 16);
7035    vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
7036    vassert(is_valid_fp128_regpair(op3_hi, op3_lo));
7037 
7038    insn->tag  = S390_INSN_DFP_INTOP;
7039    insn->size = size;
7040    insn->variant.dfp_intop.tag = tag;
7041    insn->variant.dfp_intop.dst_hi = dst_hi;
7042    insn->variant.dfp_intop.dst_lo = dst_lo;
7043    insn->variant.dfp_intop.op2    = op2;
7044    insn->variant.dfp_intop.op3_hi = op3_hi;
7045    insn->variant.dfp_intop.op3_lo = op3_lo;
7046 
7047    return insn;
7048 }
7049 
7050 
7051 s390_insn *
s390_insn_dfp128_compare(UChar size,s390_dfp_cmp_t tag,HReg dst,HReg op1_hi,HReg op1_lo,HReg op2_hi,HReg op2_lo)7052 s390_insn_dfp128_compare(UChar size, s390_dfp_cmp_t tag, HReg dst, HReg op1_hi,
7053                          HReg op1_lo, HReg op2_hi, HReg op2_lo)
7054 {
7055    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7056 
7057    vassert(size == 16);
7058    vassert(is_valid_fp128_regpair(op1_hi, op1_lo));
7059    vassert(is_valid_fp128_regpair(op2_hi, op2_lo));
7060 
7061    insn->tag  = S390_INSN_DFP_COMPARE;
7062    insn->size = size;
7063    insn->variant.dfp_compare.tag = tag;
7064    insn->variant.dfp_compare.dst = dst;
7065    insn->variant.dfp_compare.op1_hi = op1_hi;
7066    insn->variant.dfp_compare.op1_lo = op1_lo;
7067    insn->variant.dfp_compare.op2_hi = op2_hi;
7068    insn->variant.dfp_compare.op2_lo = op2_lo;
7069 
7070    return insn;
7071 }
7072 
7073 
7074 static s390_insn *
s390_insn_dfp128_convert(UChar size,s390_dfp_conv_t tag,HReg dst_hi,HReg dst_lo,HReg op_hi,HReg op_lo,s390_dfp_round_t rounding_mode)7075 s390_insn_dfp128_convert(UChar size, s390_dfp_conv_t tag, HReg dst_hi,
7076                          HReg dst_lo, HReg op_hi, HReg op_lo,
7077                          s390_dfp_round_t rounding_mode)
7078 {
7079    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7080 
7081    if (size == 16) {
7082       /* From smaller size to 16 bytes */
7083       vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
7084       vassert(hregIsInvalid(op_lo));
7085    } else {
7086       /* From 16 bytes to smaller size */
7087       vassert(is_valid_fp128_regpair(op_hi, op_lo));
7088    }
7089 
7090    insn->tag  = S390_INSN_DFP_CONVERT;
7091    insn->size = size;
7092    insn->variant.dfp_convert.tag = tag;
7093    insn->variant.dfp_convert.dst_hi = dst_hi;
7094    insn->variant.dfp_convert.dst_lo = dst_lo;
7095    insn->variant.dfp_convert.op_hi = op_hi;
7096    insn->variant.dfp_convert.op_lo = op_lo;
7097    insn->variant.dfp_convert.rounding_mode = rounding_mode;
7098 
7099    return insn;
7100 }
7101 
7102 
7103 s390_insn *
s390_insn_dfp128_convert_to(UChar size,s390_dfp_conv_t tag,HReg dst_hi,HReg dst_lo,HReg op)7104 s390_insn_dfp128_convert_to(UChar size, s390_dfp_conv_t tag, HReg dst_hi,
7105                             HReg dst_lo, HReg op)
7106 {
7107    /* Conversion to dfp128 never requires a rounding mode. Provide default
7108       rounding mode. It will not be used when emitting insns. */
7109    s390_dfp_round_t rounding_mode = S390_DFP_ROUND_NEAREST_EVEN_4;
7110 
7111    return s390_insn_dfp128_convert(size, tag, dst_hi, dst_lo, op,
7112                                    INVALID_HREG, rounding_mode);
7113 }
7114 
7115 
7116 s390_insn *
s390_insn_dfp128_convert_from(UChar size,s390_dfp_conv_t tag,HReg dst_hi,HReg dst_lo,HReg op_hi,HReg op_lo,s390_dfp_round_t rounding_mode)7117 s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t tag, HReg dst_hi,
7118                               HReg dst_lo, HReg op_hi, HReg op_lo,
7119                               s390_dfp_round_t rounding_mode)
7120 {
7121    return s390_insn_dfp128_convert(size, tag, dst_hi, dst_lo, op_hi, op_lo,
7122                                    rounding_mode);
7123 }
7124 
7125 
7126 s390_insn *
s390_insn_dfp128_reround(UChar size,HReg dst_hi,HReg dst_lo,HReg op2,HReg op3_hi,HReg op3_lo,s390_dfp_round_t rounding_mode)7127 s390_insn_dfp128_reround(UChar size, HReg dst_hi, HReg dst_lo, HReg op2,
7128                          HReg op3_hi, HReg op3_lo,
7129                          s390_dfp_round_t rounding_mode)
7130 {
7131    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7132 
7133    vassert(size == 16);
7134    vassert(is_valid_fp128_regpair(dst_hi, dst_lo));
7135    vassert(is_valid_fp128_regpair(op3_hi, op3_lo));
7136 
7137    insn->tag  = S390_INSN_DFP_REROUND;
7138    insn->size = size;
7139    insn->variant.dfp_reround.dst_hi = dst_hi;
7140    insn->variant.dfp_reround.dst_lo = dst_lo;
7141    insn->variant.dfp_reround.op2    = op2;
7142    insn->variant.dfp_reround.op3_hi = op3_hi;
7143    insn->variant.dfp_reround.op3_lo = op3_lo;
7144    insn->variant.dfp_reround.rounding_mode = rounding_mode;
7145 
7146    return insn;
7147 }
7148 
7149 
7150 s390_insn *
s390_insn_mfence(void)7151 s390_insn_mfence(void)
7152 {
7153    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7154 
7155    insn->tag  = S390_INSN_MFENCE;
7156    insn->size = 0;   /* not needed */
7157 
7158    return insn;
7159 }
7160 
7161 
7162 s390_insn *
s390_insn_mimm(UChar size,s390_amode * dst,ULong value)7163 s390_insn_mimm(UChar size, s390_amode *dst, ULong value)
7164 {
7165    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7166 
7167    /* This insn will be mapped to insns that require base register
7168       plus 12-bit displacement */
7169    vassert(dst->tag == S390_AMODE_B12);
7170 
7171    insn->tag  = S390_INSN_MIMM;
7172    insn->size = size;
7173    insn->variant.mimm.dst = dst;
7174    insn->variant.mimm.value = value;
7175 
7176    return insn;
7177 }
7178 
7179 
7180 s390_insn *
s390_insn_madd(UChar size,s390_amode * dst,UChar delta,ULong value)7181 s390_insn_madd(UChar size, s390_amode *dst, UChar delta, ULong value)
7182 {
7183    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7184 
7185    vassert(size == 4 || size == 8);
7186 
7187    /* This insn will be mapped to an ASI or AGSI so we can only allow base
7188       register plus 12-bit / 20-bit displacement. */
7189    vassert(dst->tag == S390_AMODE_B12 || dst->tag == S390_AMODE_B20);
7190    /* ASI and AGSI require the GIE facility */
7191    vassert(s390_host_has_gie);
7192 
7193    insn->tag  = S390_INSN_MADD;
7194    insn->size = size;
7195    insn->variant.madd.dst   = dst;
7196    insn->variant.madd.delta = delta;
7197    insn->variant.madd.value = value;
7198 
7199    return insn;
7200 }
7201 
7202 
7203 s390_insn *
s390_insn_set_fpc_bfprm(UChar size,HReg mode)7204 s390_insn_set_fpc_bfprm(UChar size, HReg mode)
7205 {
7206    vassert(size == 4);
7207 
7208    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7209 
7210    insn->tag  = S390_INSN_SET_FPC_BFPRM;
7211    insn->size = size;
7212    insn->variant.set_fpc_bfprm.mode = mode;
7213 
7214    return insn;
7215 }
7216 
7217 
7218 s390_insn *
s390_insn_set_fpc_dfprm(UChar size,HReg mode)7219 s390_insn_set_fpc_dfprm(UChar size, HReg mode)
7220 {
7221    vassert(size == 4);
7222 
7223    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7224 
7225    insn->tag  = S390_INSN_SET_FPC_DFPRM;
7226    insn->size = size;
7227    insn->variant.set_fpc_dfprm.mode = mode;
7228 
7229    return insn;
7230 }
7231 
7232 
7233 s390_insn *
s390_insn_xdirect(s390_cc_t cond,Addr64 dst,s390_amode * guest_IA,Bool to_fast_entry)7234 s390_insn_xdirect(s390_cc_t cond, Addr64 dst, s390_amode *guest_IA,
7235                   Bool to_fast_entry)
7236 {
7237    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7238 
7239    vassert(guest_IA->tag == S390_AMODE_B12);
7240 
7241    insn->tag  = S390_INSN_XDIRECT;
7242    insn->size = 0;   /* does not matter */
7243 
7244    insn->variant.xdirect.cond = cond;
7245    insn->variant.xdirect.dst = dst;
7246    insn->variant.xdirect.guest_IA = guest_IA;
7247    insn->variant.xdirect.to_fast_entry = to_fast_entry;
7248 
7249    return insn;
7250 }
7251 
7252 
7253 s390_insn *
s390_insn_xindir(s390_cc_t cond,HReg dst,s390_amode * guest_IA)7254 s390_insn_xindir(s390_cc_t cond, HReg dst, s390_amode *guest_IA)
7255 {
7256    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7257 
7258    vassert(guest_IA->tag == S390_AMODE_B12);
7259 
7260    insn->tag  = S390_INSN_XINDIR;
7261    insn->size = 0;   /* does not matter */
7262 
7263    insn->variant.xindir.cond = cond;
7264    insn->variant.xindir.dst = dst;
7265    insn->variant.xindir.guest_IA = guest_IA;
7266 
7267    return insn;
7268 }
7269 
7270 
7271 s390_insn *
s390_insn_xassisted(s390_cc_t cond,HReg dst,s390_amode * guest_IA,IRJumpKind kind)7272 s390_insn_xassisted(s390_cc_t cond, HReg dst, s390_amode *guest_IA,
7273                     IRJumpKind kind)
7274 {
7275    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7276 
7277    vassert(guest_IA->tag == S390_AMODE_B12);
7278 
7279    insn->tag  = S390_INSN_XASSISTED;
7280    insn->size = 0;   /* does not matter */
7281 
7282    insn->variant.xassisted.cond = cond;
7283    insn->variant.xassisted.dst = dst;
7284    insn->variant.xassisted.guest_IA = guest_IA;
7285    insn->variant.xassisted.kind = kind;
7286 
7287    return insn;
7288 }
7289 
7290 
7291 s390_insn *
s390_insn_evcheck(s390_amode * counter,s390_amode * fail_addr)7292 s390_insn_evcheck(s390_amode *counter, s390_amode *fail_addr)
7293 {
7294    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7295 
7296    vassert(counter->tag   == S390_AMODE_B12);
7297    vassert(fail_addr->tag == S390_AMODE_B12);
7298 
7299    insn->tag  = S390_INSN_EVCHECK;
7300    insn->size = 0;   /* does not matter */
7301 
7302    insn->variant.evcheck.counter = counter;
7303    insn->variant.evcheck.fail_addr = fail_addr;
7304 
7305    return insn;
7306 }
7307 
7308 
7309 s390_insn *
s390_insn_profinc(void)7310 s390_insn_profinc(void)
7311 {
7312    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7313 
7314    insn->tag  = S390_INSN_PROFINC;
7315    insn->size = 0;   /* does not matter */
7316 
7317    return insn;
7318 }
7319 
7320 
7321 s390_insn *
s390_insn_vec_amodeop(UChar size,s390_vec_amodeop_t tag,HReg dst,HReg op1,s390_amode * op2)7322 s390_insn_vec_amodeop(UChar size, s390_vec_amodeop_t tag, HReg dst, HReg op1,
7323                     s390_amode *op2)
7324 {
7325    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7326 
7327    vassert(size == 1 || size == 2 || size == 4 || size == 8);
7328 
7329    insn->tag  = S390_INSN_VEC_AMODEOP;
7330    insn->size = size;
7331    insn->variant.vec_amodeop.tag = tag;
7332    insn->variant.vec_amodeop.dst = dst;
7333    insn->variant.vec_amodeop.op1 = op1;
7334    insn->variant.vec_amodeop.op2 = op2;
7335 
7336    return insn;
7337 }
7338 
s390_insn_vec_amodeintop(UChar size,s390_vec_amodeintop_t tag,HReg dst,s390_amode * op2,HReg op3)7339 s390_insn *s390_insn_vec_amodeintop(UChar size, s390_vec_amodeintop_t tag, HReg dst,
7340                                     s390_amode* op2, HReg op3)
7341 {
7342    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7343 
7344    vassert(size == 1 || size == 2 || size == 4 || size == 8);
7345 
7346    insn->tag  = S390_INSN_VEC_AMODEINTOP;
7347    insn->size = size;
7348    insn->variant.vec_amodeintop.tag = tag;
7349    insn->variant.vec_amodeintop.dst = dst;
7350    insn->variant.vec_amodeintop.op2 = op2;
7351    insn->variant.vec_amodeintop.op3 = op3;
7352 
7353    return insn;
7354 }
7355 
s390_insn_vec_binop(UChar size,s390_vec_binop_t tag,HReg dst,HReg op1,HReg op2)7356 s390_insn *s390_insn_vec_binop(UChar size, s390_vec_binop_t tag, HReg dst,
7357                                HReg op1, HReg op2)
7358 {
7359    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7360 
7361    vassert(size == 1 || size == 2 || size == 4 || size == 8 || size == 16);
7362 
7363    insn->tag  = S390_INSN_VEC_BINOP;
7364    insn->size = size;
7365    insn->variant.vec_binop.tag = tag;
7366    insn->variant.vec_binop.dst = dst;
7367    insn->variant.vec_binop.op1 = op1;
7368    insn->variant.vec_binop.op2 = op2;
7369 
7370    return insn;
7371 }
7372 
s390_insn_vec_triop(UChar size,s390_vec_triop_t tag,HReg dst,HReg op1,HReg op2,HReg op3)7373 s390_insn *s390_insn_vec_triop(UChar size, s390_vec_triop_t tag, HReg dst,
7374                                HReg op1, HReg op2, HReg op3)
7375 {
7376    s390_insn *insn = LibVEX_Alloc_inline(sizeof(s390_insn));
7377 
7378 
7379    insn->tag  = S390_INSN_VEC_TRIOP;
7380    insn->size = size;
7381    insn->variant.vec_triop.tag = tag;
7382    insn->variant.vec_triop.dst = dst;
7383    insn->variant.vec_triop.op1 = op1;
7384    insn->variant.vec_triop.op2 = op2;
7385    insn->variant.vec_triop.op3 = op3;
7386 
7387    return insn;
7388 }
7389 
7390 /*---------------------------------------------------------------*/
7391 /*--- Debug print                                             ---*/
7392 /*---------------------------------------------------------------*/
7393 
7394 static const HChar *
s390_cc_as_string(s390_cc_t cc)7395 s390_cc_as_string(s390_cc_t cc)
7396 {
7397    switch (cc) {
7398    case S390_CC_NEVER:  return "never";
7399    case S390_CC_OVFL:   return "overflow";
7400    case S390_CC_H:      return "greater than";     /* A > B ; high */
7401    case S390_CC_NLE:    return "not low or equal";
7402    case S390_CC_L:      return "less than";        /* A < B ; low */
7403    case S390_CC_NHE:    return "not high or equal";
7404    case S390_CC_LH:     return "low or high";
7405    case S390_CC_NE:     return "not equal";        /* A != B ; not zero */
7406    case S390_CC_E:      return "equal";            /* A == B ; zero */
7407    case S390_CC_NLH:    return "not low or high";
7408    case S390_CC_HE:     return "greater or equal"; /* A >= B ; high or equal*/
7409    case S390_CC_NL:     return "not low";          /* not low */
7410    case S390_CC_LE:     return "less or equal";    /* A <= B ; low or equal */
7411    case S390_CC_NH:     return "not high";
7412    case S390_CC_NO:     return "not overflow";
7413    case S390_CC_ALWAYS: return "always";
7414    default:
7415       vpanic("s390_cc_as_string");
7416    }
7417 }
7418 
7419 
7420 static const HChar *
s390_jump_kind_as_string(IRJumpKind kind)7421 s390_jump_kind_as_string(IRJumpKind kind)
7422 {
7423    switch (kind) {
7424    case Ijk_Boring:      return "Boring";
7425    case Ijk_Call:        return "Call";
7426    case Ijk_Ret:         return "Return";
7427    case Ijk_ClientReq:   return "ClientReq";
7428    case Ijk_Yield:       return "Yield";
7429    case Ijk_EmWarn:      return "EmWarn";
7430    case Ijk_EmFail:      return "EmFail";
7431    case Ijk_NoDecode:    return "NoDecode";
7432    case Ijk_MapFail:     return "MapFail";
7433    case Ijk_InvalICache: return "Invalidate";
7434    case Ijk_NoRedir:     return "NoRedir";
7435    case Ijk_SigTRAP:     return "SigTRAP";
7436    case Ijk_SigFPE:      return "SigFPE";
7437    case Ijk_SigSEGV:     return "SigSEGV";
7438    case Ijk_SigBUS:      return "SigBUS";
7439    case Ijk_Sys_syscall: return "Sys_syscall";
7440    default:
7441       vpanic("s390_jump_kind_as_string");
7442    }
7443 }
7444 
7445 
7446 /* Helper function for writing out a V insn */
7447 static void
s390_sprintf(HChar * buf,const HChar * fmt,...)7448 s390_sprintf(HChar *buf, const HChar *fmt, ...)
7449 {
7450    HChar *p;
7451    ULong value;
7452    va_list args;
7453    va_start(args, fmt);
7454 
7455    p = buf;
7456    for ( ; *fmt; ++fmt) {
7457       Int c = *fmt;
7458 
7459       if (c != '%') {
7460          *p++ = c;
7461          continue;
7462       }
7463 
7464       c = *++fmt;  /* next char */
7465       switch (c) {
7466       case '%':
7467          *p++ = c;   /* %% */
7468          continue;
7469 
7470       case 's':     /* %s */
7471          p += vex_sprintf(p, "%s", va_arg(args, HChar *));
7472          continue;
7473 
7474       case 'M':     /* %M = mnemonic */
7475          p += vex_sprintf(p, "%-8s", va_arg(args, HChar *));
7476          continue;
7477 
7478       case 'R':     /* %R = register */
7479          p += vex_sprintf(p, "%s", s390_hreg_as_string(va_arg(args, HReg)));
7480          continue;
7481 
7482       case 'A':     /* %A = amode */
7483          p += vex_sprintf(p, "%s",
7484                           s390_amode_as_string(va_arg(args, s390_amode *)));
7485          continue;
7486 
7487       case 'G':     /* %G = guest state @ offset */
7488          p += vex_sprintf(p, "guest[%u]", va_arg(args, UInt));
7489          continue;
7490 
7491       case 'C':     /* %C = condition code */
7492          p += vex_sprintf(p, "%s", s390_cc_as_string(va_arg(args, s390_cc_t)));
7493          continue;
7494 
7495       case 'J':     /* &J = jump kind */
7496          p += vex_sprintf(p, "%s",
7497                           s390_jump_kind_as_string(va_arg(args, IRJumpKind)));
7498          continue;
7499 
7500       case 'L': {   /* %L = argument list in helper call*/
7501          UInt i, num_args;
7502 
7503          num_args = va_arg(args, UInt);
7504 
7505          for (i = 0; i < num_args; ++i) {
7506             if (i != 0) p += vex_sprintf(p, ", ");
7507             p += vex_sprintf(p, "r%u", s390_gprno_from_arg_index(i));
7508          }
7509          continue;
7510       }
7511 
7512       case 'O': {   /* %O = RMI operand */
7513          s390_opnd_RMI *op = va_arg(args, s390_opnd_RMI *);
7514 
7515          switch (op->tag) {
7516          case S390_OPND_REG:
7517             p += vex_sprintf(p, "%s", s390_hreg_as_string(op->variant.reg));
7518             continue;
7519 
7520          case S390_OPND_AMODE:
7521             p += vex_sprintf(p, "%s", s390_amode_as_string(op->variant.am));
7522             continue;
7523 
7524          case S390_OPND_IMMEDIATE:
7525             value = op->variant.imm;
7526             goto print_value;
7527 
7528          default:
7529             goto fail;
7530          }
7531       }
7532 
7533       case 'I':     /* %I = immediate value */
7534          value = va_arg(args, ULong);
7535          goto print_value;
7536 
7537       print_value:
7538          if ((Long)value < 0)
7539             p += vex_sprintf(p, "%lld", (Long)value);
7540          else if (value < 100)
7541             p += vex_sprintf(p, "%llu", value);
7542          else
7543             p += vex_sprintf(p, "0x%llx", value);
7544          continue;
7545 
7546       default:
7547          goto fail;
7548       }
7549    }
7550    *p = '\0';
7551    va_end(args);
7552 
7553    return;
7554 
7555  fail: vpanic("s390_printf");
7556 }
7557 
7558 
7559 /* Decompile the given insn into a static buffer and return it */
7560 const HChar *
s390_insn_as_string(const s390_insn * insn)7561 s390_insn_as_string(const s390_insn *insn)
7562 {
7563    static HChar buf[300];  // large enough
7564    const HChar *op;
7565    HChar *p;
7566 
7567    buf[0] = '\0';
7568 
7569    switch (insn->tag) {
7570    case S390_INSN_LOAD:
7571       s390_sprintf(buf, "%M %R,%A", "v-load", insn->variant.load.dst,
7572                    insn->variant.load.src);
7573       break;
7574 
7575    case S390_INSN_STORE:
7576       s390_sprintf(buf, "%M %R,%A", "v-store", insn->variant.store.src,
7577                    insn->variant.store.dst);
7578       break;
7579 
7580    case S390_INSN_MOVE:
7581       s390_sprintf(buf, "%M %R,%R", "v-move", insn->variant.move.dst,
7582                    insn->variant.move.src);
7583       break;
7584 
7585    case S390_INSN_MEMCPY:
7586       s390_sprintf(buf, "%M %A,%A", "v-memcpy", insn->variant.memcpy.dst,
7587                    insn->variant.memcpy.src);
7588       break;
7589 
7590    case S390_INSN_COND_MOVE:
7591       s390_sprintf(buf, "%M if (%C) %R,%O", "v-move",
7592                    insn->variant.cond_move.cond, insn->variant.cond_move.dst,
7593                    &insn->variant.cond_move.src);
7594       break;
7595 
7596    case S390_INSN_LOAD_IMMEDIATE:
7597       s390_sprintf(buf, "%M %R,%I", "v-loadi", insn->variant.load_immediate.dst,
7598                    insn->variant.load_immediate.value);
7599       break;
7600 
7601    case S390_INSN_ALU:
7602       switch (insn->variant.alu.tag) {
7603       case S390_ALU_ADD:  op = "v-add";  break;
7604       case S390_ALU_SUB:  op = "v-sub";  break;
7605       case S390_ALU_MUL:  op = "v-mul";  break;
7606       case S390_ALU_AND:  op = "v-and";  break;
7607       case S390_ALU_OR:   op = "v-or";   break;
7608       case S390_ALU_XOR:  op = "v-xor";  break;
7609       case S390_ALU_LSH:  op = "v-lsh";  break;
7610       case S390_ALU_RSH:  op = "v-rsh";  break;
7611       case S390_ALU_RSHA: op = "v-rsha"; break;
7612       default: goto fail;
7613       }
7614       s390_sprintf(buf, "%M %R,%O", op, insn->variant.alu.dst, /* also op1 */
7615                    &insn->variant.alu.op2);
7616       break;
7617 
7618    case S390_INSN_SMUL:
7619    case S390_INSN_UMUL:
7620       if (insn->tag == S390_INSN_SMUL) {
7621          op = "v-muls";
7622       } else {
7623          op = "v-mulu";
7624       }
7625       s390_sprintf(buf, "%M %R,%O", op, insn->variant.mul.dst_hi,
7626                    &insn->variant.mul.op2);
7627       break;
7628 
7629    case S390_INSN_SDIV:
7630    case S390_INSN_UDIV:
7631       if (insn->tag == S390_INSN_SDIV) {
7632          op = "v-divs";
7633       } else {
7634          op = "v-divu";
7635       }
7636       s390_sprintf(buf, "%M %R,%O", op, insn->variant.div.op1_hi,
7637                    &insn->variant.div.op2);
7638       break;
7639 
7640    case S390_INSN_DIVS:
7641       s390_sprintf(buf, "%M %R,%O", "v-divsi", insn->variant.divs.op1,
7642                    &insn->variant.divs.op2);
7643       break;
7644 
7645    case S390_INSN_CLZ:
7646       s390_sprintf(buf, "%M %R,%O", "v-clz", insn->variant.clz.num_bits,
7647                    &insn->variant.clz.src);
7648       break;
7649 
7650    case S390_INSN_UNOP:
7651       switch (insn->variant.unop.tag) {
7652       case S390_ZERO_EXTEND_8:
7653       case S390_ZERO_EXTEND_16:
7654       case S390_ZERO_EXTEND_32:
7655          op = "v-zerox";
7656          break;
7657 
7658       case S390_SIGN_EXTEND_8:
7659       case S390_SIGN_EXTEND_16:
7660       case S390_SIGN_EXTEND_32:
7661          op = "v-signx";
7662          break;
7663 
7664       case S390_NEGATE:
7665          op = "v-neg";
7666          break;
7667 
7668       case S390_VEC_FILL:
7669          op = "v-vfill";
7670          break;
7671 
7672       case S390_VEC_DUPLICATE:
7673          op = "v-vdup";
7674          break;
7675 
7676       case S390_VEC_UNPACKLOWS:
7677          op = "v-vunpacks";
7678          break;
7679 
7680       case S390_VEC_UNPACKLOWU:
7681          op = "v-vunpacku";
7682          break;
7683 
7684       case S390_VEC_FLOAT_NEG:
7685          op = "v-vfloatneg";
7686          break;
7687 
7688       case S390_VEC_FLOAT_SQRT:
7689          op = "v-vfloatsqrt";
7690          break;
7691 
7692       case S390_VEC_FLOAT_ABS:
7693          op = "v-vfloatabs";
7694          break;
7695 
7696       default:
7697          goto fail;
7698       }
7699       s390_sprintf(buf, "%M %R,%O", op, insn->variant.unop.dst,
7700                    &insn->variant.unop.src);
7701       break;
7702 
7703    case S390_INSN_TEST:
7704       s390_sprintf(buf, "%M %O", "v-test", &insn->variant.test.src);
7705       break;
7706 
7707    case S390_INSN_CC2BOOL:
7708       s390_sprintf(buf, "%M %R,%C", "v-cc2b", insn->variant.cc2bool.dst,
7709                    insn->variant.cc2bool.cond);
7710       break;
7711 
7712    case S390_INSN_CAS:
7713       s390_sprintf(buf, "%M %R,%A,%R,%R", "v-cas", insn->variant.cas.op1,
7714                    insn->variant.cas.op2, insn->variant.cas.op3,
7715                    insn->variant.cas.old_mem);
7716       break;
7717 
7718    case S390_INSN_CDAS: {
7719       s390_cdas *cdas = insn->variant.cdas.details;
7720 
7721       s390_sprintf(buf, "%M %R,%R,%A,%R,%R,%R,%R", "v-cdas",
7722                    cdas->op1_high, cdas->op1_low, cdas->op2, cdas->op3_high,
7723                    cdas->op3_low, cdas->old_mem_high, cdas->old_mem_low);
7724       break;
7725    }
7726 
7727    case S390_INSN_COMPARE:
7728       if (insn->variant.compare.signed_comparison) {
7729          op = "v-cmps";
7730       } else {
7731          op = "v-cmpu";
7732       }
7733       s390_sprintf(buf, "%M %R,%O", op, insn->variant.compare.src1,
7734                    &insn->variant.compare.src2);
7735       break;
7736 
7737    case S390_INSN_HELPER_CALL: {
7738       s390_helper_call *helper_call = insn->variant.helper_call.details;
7739       s390_sprintf(buf, "%M if (%C) %s{%I}(%L)", "v-call",
7740                    helper_call->cond,
7741                    helper_call->name,
7742                    helper_call->target,
7743                    helper_call->num_args);
7744       return buf;   /* avoid printing "size = ..." which is meaningless */
7745    }
7746 
7747    case S390_INSN_BFP_TRIOP:
7748       switch (insn->variant.bfp_triop.tag) {
7749       case S390_BFP_MADD:  op = "v-fmadd";  break;
7750       case S390_BFP_MSUB:  op = "v-fmsub";  break;
7751       default: goto fail;
7752       }
7753       s390_sprintf(buf, "%M %R,%R,%R", op,
7754                    insn->variant.bfp_triop.dst  /* op1 same as dst */,
7755                    insn->variant.bfp_triop.op2, insn->variant.bfp_triop.op3);
7756       break;
7757 
7758    case S390_INSN_BFP_BINOP:
7759       switch (insn->variant.bfp_binop.tag) {
7760       case S390_BFP_ADD:      op = "v-fadd";  break;
7761       case S390_BFP_SUB:      op = "v-fsub";  break;
7762       case S390_BFP_MUL:      op = "v-fmul";  break;
7763       case S390_BFP_DIV:      op = "v-fdiv";  break;
7764       default: goto fail;
7765       }
7766       s390_sprintf(buf, "%M %R,%R", op,
7767                    insn->variant.bfp_binop.dst_hi  /* op1 same as dst */,
7768                    insn->variant.bfp_binop.op2_hi);
7769       break;
7770 
7771    case S390_INSN_BFP_COMPARE:
7772       s390_sprintf(buf, "%M %R,%R,%R", "v-fcmp", insn->variant.bfp_compare.dst,
7773                    insn->variant.bfp_compare.op1_hi,
7774                    insn->variant.bfp_compare.op2_hi);
7775       break;
7776 
7777    case S390_INSN_BFP_UNOP:
7778       switch (insn->variant.bfp_unop.tag) {
7779       case S390_BFP_ABS:         op = "v-fabs";  break;
7780       case S390_BFP_NABS:        op = "v-fnabs"; break;
7781       case S390_BFP_NEG:         op = "v-fneg";  break;
7782       case S390_BFP_SQRT:        op = "v-fsqrt"; break;
7783       default: goto fail;
7784       }
7785       s390_sprintf(buf, "%M %R,%R", op, insn->variant.bfp_unop.dst_hi,
7786                    insn->variant.bfp_unop.op_hi);
7787       break;
7788 
7789    case S390_INSN_BFP_CONVERT:
7790       switch (insn->variant.bfp_convert.tag) {
7791       case S390_BFP_I32_TO_F32:
7792       case S390_BFP_I32_TO_F64:
7793       case S390_BFP_I32_TO_F128:
7794       case S390_BFP_I64_TO_F32:
7795       case S390_BFP_I64_TO_F64:
7796       case S390_BFP_I64_TO_F128: op = "v-i2f"; break;
7797       case S390_BFP_U32_TO_F32:
7798       case S390_BFP_U32_TO_F64:
7799       case S390_BFP_U32_TO_F128:
7800       case S390_BFP_U64_TO_F32:
7801       case S390_BFP_U64_TO_F64:
7802       case S390_BFP_U64_TO_F128: op = "v-u2f"; break;
7803       case S390_BFP_F32_TO_I32:
7804       case S390_BFP_F32_TO_I64:
7805       case S390_BFP_F64_TO_I32:
7806       case S390_BFP_F64_TO_I64:
7807       case S390_BFP_F128_TO_I32:
7808       case S390_BFP_F128_TO_I64: op = "v-f2i"; break;
7809       case S390_BFP_F32_TO_U32:
7810       case S390_BFP_F32_TO_U64:
7811       case S390_BFP_F64_TO_U32:
7812       case S390_BFP_F64_TO_U64:
7813       case S390_BFP_F128_TO_U32:
7814       case S390_BFP_F128_TO_U64: op = "v-f2u"; break;
7815       case S390_BFP_F32_TO_F64:
7816       case S390_BFP_F32_TO_F128:
7817       case S390_BFP_F64_TO_F32:
7818       case S390_BFP_F64_TO_F128:
7819       case S390_BFP_F128_TO_F32:
7820       case S390_BFP_F128_TO_F64: op = "v-f2f"; break;
7821       case S390_BFP_F32_TO_F32I:
7822       case S390_BFP_F64_TO_F64I:
7823       case S390_BFP_F128_TO_F128I: op = "v-f2fi"; break;
7824       default: goto fail;
7825       }
7826       s390_sprintf(buf, "%M %R,%R", op, insn->variant.bfp_convert.dst_hi,
7827                    insn->variant.bfp_convert.op_hi);
7828       break;
7829 
7830    case S390_INSN_DFP_BINOP: {
7831       s390_dfp_binop *dfp_binop = insn->variant.dfp_binop.details;
7832 
7833       switch (dfp_binop->tag) {
7834       case S390_DFP_ADD:  op = "v-dadd";  break;
7835       case S390_DFP_SUB:  op = "v-dsub";  break;
7836       case S390_DFP_MUL:  op = "v-dmul";  break;
7837       case S390_DFP_DIV:  op = "v-ddiv";  break;
7838       case S390_DFP_QUANTIZE:  op = "v-dqua";  break;
7839       default: goto fail;
7840       }
7841       s390_sprintf(buf, "%M %R,%R,%R", op, dfp_binop->dst_hi,
7842                    dfp_binop->op2_hi, dfp_binop->op3_hi);
7843       break;
7844    }
7845 
7846    case S390_INSN_DFP_UNOP:
7847       switch (insn->variant.dfp_unop.tag) {
7848       case S390_DFP_EXTRACT_EXP_D64:
7849       case S390_DFP_EXTRACT_EXP_D128:  op = "v-d2exp";  break;
7850       case S390_DFP_EXTRACT_SIG_D64:
7851       case S390_DFP_EXTRACT_SIG_D128:  op = "v-d2sig";  break;
7852       default: goto fail;
7853       }
7854       s390_sprintf(buf, "%M %R,%R", op, insn->variant.dfp_unop.dst_hi,
7855                    insn->variant.dfp_unop.op_hi);
7856       break;
7857 
7858    case S390_INSN_DFP_INTOP:
7859       switch (insn->variant.dfp_intop.tag) {
7860       case S390_DFP_SHIFT_LEFT:  op = "v-dshl"; break;
7861       case S390_DFP_SHIFT_RIGHT: op = "v-dshr"; break;
7862       case S390_DFP_INSERT_EXP:  op = "v-diexp"; break;
7863       default: goto fail;
7864       }
7865       s390_sprintf(buf, "%M %R,%R,%R", op, insn->variant.dfp_intop.dst_hi,
7866                    insn->variant.dfp_intop.op2,
7867                    insn->variant.dfp_intop.op3_hi);
7868       break;
7869 
7870    case S390_INSN_DFP_COMPARE:
7871       switch (insn->variant.dfp_compare.tag) {
7872       case S390_DFP_COMPARE:     op = "v-dcmp"; break;
7873       case S390_DFP_COMPARE_EXP: op = "v-dcmpexp"; break;
7874       default: goto fail;
7875       }
7876       s390_sprintf(buf, "%M %R,%R,%R", op, insn->variant.dfp_compare.dst,
7877                    insn->variant.dfp_compare.op1_hi,
7878                    insn->variant.dfp_compare.op2_hi);
7879       break;
7880 
7881    case S390_INSN_DFP_CONVERT:
7882       switch (insn->variant.dfp_convert.tag) {
7883       case S390_DFP_D32_TO_D64:
7884       case S390_DFP_D64_TO_D32:
7885       case S390_DFP_D64_TO_D128:
7886       case S390_DFP_D128_TO_D64: op = "v-d2d"; break;
7887       case S390_DFP_I32_TO_D64:
7888       case S390_DFP_I32_TO_D128:
7889       case S390_DFP_I64_TO_D64:
7890       case S390_DFP_I64_TO_D128: op = "v-i2d"; break;
7891       case S390_DFP_U32_TO_D64:
7892       case S390_DFP_U32_TO_D128:
7893       case S390_DFP_U64_TO_D64:
7894       case S390_DFP_U64_TO_D128: op = "v-u2d"; break;
7895       case S390_DFP_D64_TO_I32:
7896       case S390_DFP_D128_TO_I32:
7897       case S390_DFP_D64_TO_I64:
7898       case S390_DFP_D128_TO_I64: op = "v-d2i"; break;
7899       case S390_DFP_D64_TO_U32:
7900       case S390_DFP_D64_TO_U64:
7901       case S390_DFP_D128_TO_U32:
7902       case S390_DFP_D128_TO_U64: op = "v-d2u"; break;
7903       default: goto fail;
7904       }
7905       s390_sprintf(buf, "%M %R,%R", op, insn->variant.dfp_convert.dst_hi,
7906                    insn->variant.dfp_convert.op_hi);
7907       break;
7908 
7909    case S390_INSN_DFP_REROUND:
7910       s390_sprintf(buf, "%M %R,%R,%R", "v-drrnd",
7911                    insn->variant.dfp_reround.dst_hi,
7912                    insn->variant.dfp_reround.op2,
7913                    insn->variant.dfp_reround.op3_hi);
7914       break;
7915 
7916    case S390_INSN_FP_CONVERT: {
7917       s390_fp_convert *fp_convert = insn->variant.fp_convert.details;
7918 
7919       switch (fp_convert->tag) {
7920       case S390_FP_F32_TO_D32:
7921       case S390_FP_F32_TO_D64:
7922       case S390_FP_F32_TO_D128:
7923       case S390_FP_F64_TO_D32:
7924       case S390_FP_F64_TO_D64:
7925       case S390_FP_F64_TO_D128:
7926       case S390_FP_F128_TO_D32:
7927       case S390_FP_F128_TO_D64:
7928       case S390_FP_F128_TO_D128: op = "v-f2d"; break;
7929       case S390_FP_D32_TO_F32:
7930       case S390_FP_D32_TO_F64:
7931       case S390_FP_D32_TO_F128:
7932       case S390_FP_D64_TO_F32:
7933       case S390_FP_D64_TO_F64:
7934       case S390_FP_D64_TO_F128:
7935       case S390_FP_D128_TO_F32:
7936       case S390_FP_D128_TO_F64:
7937       case S390_FP_D128_TO_F128: op = "v-d2f"; break;
7938       default: goto fail;
7939       }
7940       s390_sprintf(buf, "%M %R,%R", op, fp_convert->dst_hi,
7941                    fp_convert->op_hi);
7942       break;
7943    }
7944 
7945    case S390_INSN_MFENCE:
7946       s390_sprintf(buf, "%M", "v-mfence");
7947       return buf;   /* avoid printing "size = ..." which is meaningless */
7948 
7949    case S390_INSN_MIMM:
7950       s390_sprintf(buf, "%M %A,%I", "v-mimm", insn->variant.mimm.dst,
7951                    insn->variant.mimm.value);
7952       break;
7953 
7954    case S390_INSN_MADD:
7955       s390_sprintf(buf, "%M %A += %I  (= %I)", "v-madd",
7956                    insn->variant.madd.dst,
7957                    (Long)(Char)insn->variant.madd.delta,
7958                    insn->variant.madd.value);
7959       break;
7960 
7961    case S390_INSN_SET_FPC_BFPRM:
7962       s390_sprintf(buf, "%M %R", "v-set-fpc-bfprm",
7963                    insn->variant.set_fpc_bfprm.mode);
7964       break;
7965 
7966    case S390_INSN_SET_FPC_DFPRM:
7967       s390_sprintf(buf, "%M %R", "v-set-fpc-dfprm",
7968                    insn->variant.set_fpc_dfprm.mode);
7969       break;
7970 
7971    case S390_INSN_EVCHECK:
7972       s390_sprintf(buf, "%M counter = %A, fail-addr = %A", "v-evcheck",
7973                    insn->variant.evcheck.counter,
7974                    insn->variant.evcheck.fail_addr);
7975       return buf;   /* avoid printing "size = ..." which is meaningless */
7976 
7977    case S390_INSN_PROFINC:
7978       s390_sprintf(buf, "%M", "v-profinc");
7979       return buf;   /* avoid printing "size = ..." which is meaningless */
7980 
7981    case S390_INSN_XDIRECT:
7982       s390_sprintf(buf, "%M if (%C) %A = %I  %s", "v-xdirect",
7983                    insn->variant.xdirect.cond,
7984                    insn->variant.xdirect.guest_IA,
7985                    insn->variant.xdirect.dst,
7986                    insn->variant.xdirect.to_fast_entry ? "fast" : "slow");
7987       return buf;   /* avoid printing "size = ..." which is meaningless */
7988 
7989    case S390_INSN_XINDIR:
7990       s390_sprintf(buf, "%M if (%C) %A = %R", "v-xindir",
7991                    insn->variant.xindir.cond,
7992                    insn->variant.xindir.guest_IA,
7993                    insn->variant.xindir.dst);
7994       return buf;   /* avoid printing "size = ..." which is meaningless */
7995 
7996    case S390_INSN_XASSISTED:
7997       s390_sprintf(buf, "%M if (%C) %J %A = %R", "v-xassisted",
7998                    insn->variant.xassisted.cond,
7999                    insn->variant.xassisted.kind,
8000                    insn->variant.xassisted.guest_IA,
8001                    insn->variant.xassisted.dst);
8002       return buf;   /* avoid printing "size = ..." which is meaningless */
8003 
8004    case S390_INSN_VEC_AMODEOP:
8005       switch (insn->variant.vec_amodeop.tag) {
8006       case S390_VEC_GET_ELEM:  op = "v-vgetelem";  break;
8007       case S390_VEC_ELEM_SHL_INT: op = "v-veshl"; break;
8008       case S390_VEC_ELEM_SHRA_INT: op = "v-veshra"; break;
8009       case S390_VEC_ELEM_SHRL_INT: op = "v-veshrl"; break;
8010       default: goto fail;
8011       }
8012       s390_sprintf(buf, "%M %R, %R, %A", op, insn->variant.vec_amodeop.dst,
8013                    insn->variant.vec_amodeop.op1,
8014                    insn->variant.vec_amodeop.op2);
8015       break;
8016 
8017    case S390_INSN_VEC_AMODEINTOP:
8018       switch (insn->variant.vec_amodeintop.tag) {
8019       case S390_VEC_SET_ELEM:  op = "v-vsetelem";  break;
8020       default: goto fail;
8021       }
8022       s390_sprintf(buf, "%M %R, %A, %R", op, insn->variant.vec_amodeintop.dst,
8023                    insn->variant.vec_amodeintop.op2,
8024                    insn->variant.vec_amodeintop.op3);
8025       break;
8026 
8027    case S390_INSN_VEC_BINOP:
8028       switch (insn->variant.vec_binop.tag) {
8029       case S390_VEC_PACK:           op = "v-vpack"; break;
8030       case S390_VEC_PACK_SATURS:    op = "v-vpacksaturs"; break;
8031       case S390_VEC_PACK_SATURU:    op = "v-vpacksaturu"; break;
8032       case S390_VEC_COMPARE_EQUAL:  op = "v-vcmpeq"; break;
8033       case S390_VEC_OR:             op = "v-vor"; break;
8034       case S390_VEC_XOR:            op = "v-vxor";  break;
8035       case S390_VEC_AND:            op = "v-vand"; break;
8036       case S390_VEC_MERGEL:         op = "v-vmergel"; break;
8037       case S390_VEC_MERGEH:         op = "v-vmergeh"; break;
8038       case S390_VEC_NOR:            op = "v-vnor"; break;
8039       case S390_VEC_INT_ADD:        op = "v-vintadd"; break;
8040       case S390_VEC_INT_SUB:        op = "v-vintsub"; break;
8041       case S390_VEC_MAXU:           op = "v-vmaxu"; break;
8042       case S390_VEC_MAXS:           op = "v-vmaxs"; break;
8043       case S390_VEC_MINU:           op = "v-vminu"; break;
8044       case S390_VEC_MINS:           op = "v-vmins"; break;
8045       case S390_VEC_AVGU:           op = "v-vavgu"; break;
8046       case S390_VEC_AVGS:           op = "v-vavgs"; break;
8047       case S390_VEC_COMPARE_GREATERS: op = "v-vcmpgts"; break;
8048       case S390_VEC_COMPARE_GREATERU: op = "v-vcmpgtu"; break;
8049       case S390_VEC_INT_MUL_HIGHS:    op = "v-vintmulhis"; break;
8050       case S390_VEC_INT_MUL_HIGHU:    op = "v-vintmulhiu"; break;
8051       case S390_VEC_INT_MUL_LOW:      op = "v-vintmullo"; break;
8052       case S390_VEC_INT_MUL_EVENS:    op = "v-vintmulevens"; break;
8053       case S390_VEC_INT_MUL_EVENU:    op = "v-vintmulevenu"; break;
8054       case S390_VEC_ELEM_SHL_V:       op = "v-velemshl"; break;
8055       case S390_VEC_ELEM_SHRA_V:      op = "v-vshrav"; break;
8056       case S390_VEC_ELEM_SHRL_V:      op = "v-vshrlv"; break;
8057       case S390_VEC_ELEM_ROLL_V:      op = "v-vrollv"; break;
8058       case S390_VEC_SHL_BITS:         op = "v-vshlbits"; break;
8059       case S390_VEC_SHRL_BITS:        op = "v-vshrlbits"; break;
8060       case S390_VEC_SHRA_BITS:        op = "v-vshrabits"; break;
8061       case S390_VEC_SHL_BYTES:        op = "v-vshlbytes"; break;
8062       case S390_VEC_SHRL_BYTES:       op = "v-vshrlbytes"; break;
8063       case S390_VEC_SHRA_BYTES:       op = "v-vshrabytes"; break;
8064       case S390_VEC_PWSUM_W:          op = "v-vpwsumw"; break;
8065       case S390_VEC_PWSUM_DW:         op = "v-vpwsumdw"; break;
8066       case S390_VEC_PWSUM_QW:         op = "v-vpwsumqw"; break;
8067       case S390_VEC_INIT_FROM_GPRS:   op = "v-vinitfromgprs"; break;
8068       case S390_VEC_FLOAT_ADD:        op = "v-vfloatadd"; break;
8069       case S390_VEC_FLOAT_SUB:        op = "v-vfloatsub"; break;
8070       case S390_VEC_FLOAT_MUL:        op = "v-vfloatmul"; break;
8071       case S390_VEC_FLOAT_DIV:        op = "v-vfloatdiv"; break;
8072       case S390_VEC_FLOAT_COMPARE_EQUAL: op = "v-vfloatcmpeq"; break;
8073       case S390_VEC_FLOAT_COMPARE_LESS_OR_EQUAL:  op = "v-vfloatcmple"; break;
8074       case S390_VEC_FLOAT_COMPARE_LESS: op = "v-vfloatcmpl"; break;
8075       default: goto fail;
8076       }
8077       s390_sprintf(buf, "%M %R, %R, %R", op, insn->variant.vec_binop.dst,
8078                    insn->variant.vec_binop.op1, insn->variant.vec_binop.op2);
8079       break;
8080 
8081    case S390_INSN_VEC_TRIOP:
8082       switch (insn->variant.vec_triop.tag) {
8083       case S390_VEC_PERM:  op = "v-vperm";  break;
8084       case S390_VEC_FLOAT_MADD: op = "v-vfloatmadd"; break;
8085       case S390_VEC_FLOAT_MSUB: op = "v-vfloatmsub"; break;
8086       default: goto fail;
8087       }
8088       s390_sprintf(buf, "%M %R, %R, %R, %R", op, insn->variant.vec_triop.dst,
8089                    insn->variant.vec_triop.op1, insn->variant.vec_triop.op2,
8090                    insn->variant.vec_triop.op3);
8091       break;
8092 
8093    default: goto fail;
8094    }
8095 
8096    /* Write out how many bytes are involved in the operation */
8097 
8098    {
8099       UInt len, i;
8100 
8101       for (p = buf; *p; ++p)
8102          continue;
8103 
8104       len = p - buf;
8105 
8106       if (len < 32) {
8107          for (i = len; i < 32; ++i)
8108             p += vex_sprintf(p, " ");
8109       } else {
8110          p += vex_sprintf(p, "\t");
8111       }
8112    }
8113 
8114    /* Special cases first */
8115    switch (insn->tag) {
8116    case S390_INSN_UNOP:
8117       switch (insn->variant.unop.tag) {
8118       case S390_SIGN_EXTEND_8:
8119       case S390_ZERO_EXTEND_8:  p += vex_sprintf(p, "1 -> "); goto common;
8120       case S390_SIGN_EXTEND_16:
8121       case S390_ZERO_EXTEND_16: p += vex_sprintf(p, "2 -> "); goto common;
8122       case S390_SIGN_EXTEND_32:
8123       case S390_ZERO_EXTEND_32: p += vex_sprintf(p, "4 -> "); goto common;
8124       default:
8125          goto common;
8126       }
8127 
8128    case S390_INSN_BFP_CONVERT:
8129       switch (insn->variant.bfp_convert.tag) {
8130       case S390_BFP_I32_TO_F32:
8131       case S390_BFP_I32_TO_F64:
8132       case S390_BFP_I32_TO_F128:
8133       case S390_BFP_U32_TO_F32:
8134       case S390_BFP_U32_TO_F64:
8135       case S390_BFP_U32_TO_F128:
8136       case S390_BFP_F32_TO_I32:
8137       case S390_BFP_F32_TO_I64:
8138       case S390_BFP_F32_TO_U32:
8139       case S390_BFP_F32_TO_U64:
8140       case S390_BFP_F32_TO_F64:
8141       case S390_BFP_F32_TO_F128: p += vex_sprintf(p, "4 -> "); goto common;
8142       case S390_BFP_I64_TO_F32:
8143       case S390_BFP_I64_TO_F64:
8144       case S390_BFP_I64_TO_F128:
8145       case S390_BFP_U64_TO_F32:
8146       case S390_BFP_U64_TO_F64:
8147       case S390_BFP_U64_TO_F128:
8148       case S390_BFP_F64_TO_I32:
8149       case S390_BFP_F64_TO_I64:
8150       case S390_BFP_F64_TO_U32:
8151       case S390_BFP_F64_TO_U64:
8152       case S390_BFP_F64_TO_F32:
8153       case S390_BFP_F64_TO_F128: p += vex_sprintf(p, "8 -> "); goto common;
8154       case S390_BFP_F128_TO_I32:
8155       case S390_BFP_F128_TO_I64:
8156       case S390_BFP_F128_TO_U32:
8157       case S390_BFP_F128_TO_U64:
8158       case S390_BFP_F128_TO_F32:
8159       case S390_BFP_F128_TO_F64: p += vex_sprintf(p, "16 -> "); goto common;
8160       default:
8161          goto common;
8162       }
8163 
8164    case S390_INSN_DFP_CONVERT:
8165       switch (insn->variant.dfp_convert.tag) {
8166       case S390_DFP_D32_TO_D64:
8167       case S390_DFP_I32_TO_D64:
8168       case S390_DFP_I32_TO_D128:
8169       case S390_DFP_U32_TO_D64:
8170       case S390_DFP_U32_TO_D128: p += vex_sprintf(p, "4 -> "); goto common;
8171       case S390_DFP_D64_TO_D32:
8172       case S390_DFP_D64_TO_D128:
8173       case S390_DFP_I64_TO_D64:
8174       case S390_DFP_I64_TO_D128:
8175       case S390_DFP_U64_TO_D64:
8176       case S390_DFP_U64_TO_D128:
8177       case S390_DFP_D64_TO_I32:
8178       case S390_DFP_D64_TO_I64:
8179       case S390_DFP_D64_TO_U32:
8180       case S390_DFP_D64_TO_U64:  p += vex_sprintf(p, "8 -> "); goto common;
8181       case S390_DFP_D128_TO_D64:
8182       case S390_DFP_D128_TO_I32:
8183       case S390_DFP_D128_TO_I64:
8184       case S390_DFP_D128_TO_U32:
8185       case S390_DFP_D128_TO_U64: p += vex_sprintf(p, "16 -> "); goto common;
8186       default:
8187          goto common;
8188       }
8189 
8190    case S390_INSN_FP_CONVERT: {
8191       s390_fp_convert *fp_convert = insn->variant.fp_convert.details;
8192 
8193       switch (fp_convert->tag) {
8194       case S390_FP_F32_TO_D32:
8195       case S390_FP_F32_TO_D64:
8196       case S390_FP_F32_TO_D128:
8197       case S390_FP_D32_TO_F32:
8198       case S390_FP_D32_TO_F64:
8199       case S390_FP_D32_TO_F128:  p += vex_sprintf(p, "4 -> "); goto common;
8200       case S390_FP_F64_TO_D32:
8201       case S390_FP_F64_TO_D64:
8202       case S390_FP_F64_TO_D128:
8203       case S390_FP_D64_TO_F32:
8204       case S390_FP_D64_TO_F64:
8205       case S390_FP_D64_TO_F128:  p += vex_sprintf(p, "8 -> "); goto common;
8206       case S390_FP_F128_TO_D32:
8207       case S390_FP_F128_TO_D64:
8208       case S390_FP_F128_TO_D128:
8209       case S390_FP_D128_TO_F32:
8210       case S390_FP_D128_TO_F64:
8211       case S390_FP_D128_TO_F128: p += vex_sprintf(p, "16 -> "); goto common;
8212       default:
8213          goto common;
8214       }
8215    }
8216 
8217    default:
8218       goto common;
8219    }
8220 
8221    /* Common case */
8222  common:
8223    vex_sprintf(p, "%u bytes", (UInt)insn->size);
8224 
8225    return buf;
8226 
8227  fail: vpanic("s390_insn_as_string");
8228 }
8229 
8230 
8231 
8232 /* Load NUM bytes from memory into register REG using addressing mode AM. */
8233 static UChar *
s390_emit_load_mem(UChar * p,UInt num,UChar reg,const s390_amode * am)8234 s390_emit_load_mem(UChar *p, UInt num, UChar reg, const s390_amode *am)
8235 {
8236    UInt b = hregNumber(am->b);
8237    UInt x = hregNumber(am->x);  /* 0 for B12 and B20 */
8238    UInt d = am->d;
8239 
8240    switch (am->tag) {
8241    case S390_AMODE_B12:
8242    case S390_AMODE_BX12:
8243       switch (num) {
8244       case 1:  return s390_emit_IC(p, reg, x, b, d);
8245       case 2:  return s390_emit_LH(p, reg, x, b, d);
8246       case 4:  return s390_emit_L(p, reg, x, b, d);
8247       case 8:  return s390_emit_LG(p, reg, x, b, DISP20(d));
8248       case 16: return s390_emit_VL(p, reg, x, b, d);
8249       default: goto fail;
8250       }
8251       break;
8252 
8253    case S390_AMODE_B20:
8254    case S390_AMODE_BX20:
8255       switch (num) {
8256       case 1: return s390_emit_ICY(p, reg, x, b, DISP20(d));
8257       case 2: return s390_emit_LHY(p, reg, x, b, DISP20(d));
8258       case 4: return s390_emit_LY(p, reg, x, b, DISP20(d));
8259       case 8: return s390_emit_LG(p, reg, x, b, DISP20(d));
8260       default: goto fail;
8261       }
8262       break;
8263 
8264    default: goto fail;
8265    }
8266 
8267  fail:
8268    vpanic("s390_emit_load_mem");
8269 }
8270 
8271 
8272 /* Load condition code into register REG */
8273 static UChar *
s390_emit_load_cc(UChar * p,UChar reg)8274 s390_emit_load_cc(UChar *p, UChar reg)
8275 {
8276    p = s390_emit_LGHI(p, reg, 0);  /* Clear out, cc not affected */
8277    p = s390_emit_IPM(p, reg, reg);
8278    /* Shift 28 bits to the right --> [0,1,2,3] */
8279    return s390_emit_SRL(p, reg, 0, 28); /* REG = cc */
8280 }
8281 
8282 
8283 /*---------------------------------------------------------------*/
8284 /*--- Code generation                                         ---*/
8285 /*---------------------------------------------------------------*/
8286 
8287 /* Do not load more bytes than requested. */
8288 static UChar *
s390_insn_load_emit(UChar * buf,const s390_insn * insn)8289 s390_insn_load_emit(UChar *buf, const s390_insn *insn)
8290 {
8291    UInt r, x, b, d;
8292    const s390_amode *src;
8293 
8294    src = insn->variant.load.src;
8295 
8296    r = hregNumber(insn->variant.load.dst);
8297 
8298    if (hregClass(insn->variant.load.dst) == HRcFlt64) {
8299       b = hregNumber(src->b);
8300       x = hregNumber(src->x);  /* 0 for B12 and B20 */
8301       d = src->d;
8302 
8303       switch (insn->size) {
8304 
8305       case 4:
8306          switch (src->tag) {
8307          case S390_AMODE_B12:
8308          case S390_AMODE_BX12:
8309             return s390_emit_LE(buf, r, x, b, d);
8310 
8311          case S390_AMODE_B20:
8312          case S390_AMODE_BX20:
8313             return s390_emit_LEY(buf, r, x, b, DISP20(d));
8314          }
8315          break;
8316 
8317       case 8:
8318          switch (src->tag) {
8319          case S390_AMODE_B12:
8320          case S390_AMODE_BX12:
8321             return s390_emit_LD(buf, r, x, b, d);
8322 
8323          case S390_AMODE_B20:
8324          case S390_AMODE_BX20:
8325             return s390_emit_LDY(buf, r, x, b, DISP20(d));
8326          }
8327          break;
8328       }
8329       vpanic("s390_insn_load_emit");
8330    }
8331 
8332    /* Integer stuff */
8333    return s390_emit_load_mem(buf, insn->size, r, src);
8334 }
8335 
8336 
8337 static UChar *
s390_insn_store_emit(UChar * buf,const s390_insn * insn)8338 s390_insn_store_emit(UChar *buf, const s390_insn *insn)
8339 {
8340    UInt r, x, b, d;
8341    const s390_amode *dst;
8342 
8343    dst = insn->variant.store.dst;
8344 
8345    r = hregNumber(insn->variant.store.src);
8346    b = hregNumber(dst->b);
8347    x = hregNumber(dst->x);  /* 0 for B12 and B20 */
8348    d = dst->d;
8349 
8350    if (hregClass(insn->variant.store.src) == HRcFlt64) {
8351       switch (insn->size) {
8352 
8353       case 4:
8354          switch (dst->tag) {
8355          case S390_AMODE_B12:
8356          case S390_AMODE_BX12:
8357             return s390_emit_STE(buf, r, x, b, d);
8358 
8359          case S390_AMODE_B20:
8360          case S390_AMODE_BX20:
8361             return s390_emit_STEY(buf, r, x, b, DISP20(d));
8362          }
8363          break;
8364 
8365       case 8:
8366          switch (dst->tag) {
8367          case S390_AMODE_B12:
8368          case S390_AMODE_BX12:
8369             return s390_emit_STD(buf, r, x, b, d);
8370 
8371          case S390_AMODE_B20:
8372          case S390_AMODE_BX20:
8373             return s390_emit_STDY(buf, r, x, b, DISP20(d));
8374          }
8375          break;
8376       }
8377       vpanic("s390_insn_store_emit");
8378    }
8379 
8380    if (hregClass(insn->variant.store.src) == HRcVec128) {
8381       vassert(insn->size == 16);
8382       switch (dst->tag) {
8383       case S390_AMODE_B12:
8384       case S390_AMODE_BX12:
8385          return s390_emit_VST(buf, r, x, b, d);
8386 
8387       default:
8388          vpanic("s390_insn_store_emit: unknown dst->tag for HRcVec128");
8389       }
8390    }
8391    /* Integer stuff */
8392    switch (insn->size) {
8393    case 1:
8394       switch (dst->tag) {
8395       case S390_AMODE_B12:
8396       case S390_AMODE_BX12:
8397          return s390_emit_STC(buf, r, x, b, d);
8398 
8399       case S390_AMODE_B20:
8400       case S390_AMODE_BX20:
8401          return s390_emit_STCY(buf, r, x, b, DISP20(d));
8402       }
8403       break;
8404 
8405    case 2:
8406       switch (dst->tag) {
8407       case S390_AMODE_B12:
8408       case S390_AMODE_BX12:
8409          return s390_emit_STH(buf, r, x, b, d);
8410 
8411       case S390_AMODE_B20:
8412       case S390_AMODE_BX20:
8413          return s390_emit_STHY(buf, r, x, b, DISP20(d));
8414       }
8415       break;
8416 
8417    case 4:
8418       switch (dst->tag) {
8419       case S390_AMODE_B12:
8420       case S390_AMODE_BX12:
8421          return s390_emit_ST(buf, r, x, b, d);
8422 
8423       case S390_AMODE_B20:
8424       case S390_AMODE_BX20:
8425          return s390_emit_STY(buf, r, x, b, DISP20(d));
8426       }
8427       break;
8428 
8429    case 8:
8430       return s390_emit_STG(buf, r, x, b, DISP20(d));
8431 
8432    default:
8433       break;
8434    }
8435 
8436    vpanic("s390_insn_store_emit");
8437 }
8438 
8439 
8440 static UChar *
s390_insn_move_emit(UChar * buf,const s390_insn * insn)8441 s390_insn_move_emit(UChar *buf, const s390_insn *insn)
8442 {
8443    UInt dst, src;
8444    HRegClass dst_class, src_class;
8445 
8446    dst = hregNumber(insn->variant.move.dst);
8447    src = hregNumber(insn->variant.move.src);
8448 
8449    dst_class = hregClass(insn->variant.move.dst);
8450    src_class = hregClass(insn->variant.move.src);
8451 
8452    if (dst_class == src_class) {
8453       if (dst_class == HRcInt64)
8454          return s390_emit_LGR(buf, dst, src);
8455       if (dst_class == HRcFlt64)
8456          return s390_emit_LDR(buf, dst, src);
8457       if (dst_class == HRcVec128) {
8458          return s390_emit_VLR(buf, dst, src);
8459       }
8460    } else {
8461       if (dst_class == HRcFlt64 && src_class == HRcInt64) {
8462          if (insn->size == 4) {
8463             buf = s390_emit_SLLG(buf, R0, src, 0, DISP20(32)); /* r0 = src << 32 */
8464             return s390_emit_LDGRw(buf, dst, R0);
8465          } else {
8466             return s390_emit_LDGRw(buf, dst, src);
8467          }
8468       }
8469       if (dst_class == HRcInt64 && src_class == HRcFlt64) {
8470          if (insn->size == 4) {
8471             buf = s390_emit_LGDRw(buf, dst, src);
8472             return s390_emit_SRLG(buf, dst, dst, 0, DISP20(32)); /* dst >>= 32 */
8473          } else {
8474             return s390_emit_LGDRw(buf, dst, src);
8475          }
8476       }
8477       /* A move between floating point registers and general purpose
8478          registers of different size should never occur and indicates
8479          an error elsewhere. */
8480    }
8481 
8482    vpanic("s390_insn_move_emit");
8483 }
8484 
8485 
8486 static UChar *
s390_insn_memcpy_emit(UChar * buf,const s390_insn * insn)8487 s390_insn_memcpy_emit(UChar *buf, const s390_insn *insn)
8488 {
8489    s390_amode *dst = insn->variant.memcpy.dst;
8490    s390_amode *src = insn->variant.memcpy.src;
8491 
8492    return s390_emit_MVC(buf, insn->size - 1, hregNumber(dst->b), dst->d,
8493                         hregNumber(src->b), src->d);
8494 }
8495 
8496 
8497 static UChar *
s390_insn_load_immediate_emit(UChar * buf,const s390_insn * insn)8498 s390_insn_load_immediate_emit(UChar *buf, const s390_insn *insn)
8499 {
8500    UInt  r;
8501    ULong value = insn->variant.load_immediate.value;
8502 
8503    r = hregNumber(insn->variant.load_immediate.dst);
8504 
8505    if (hregClass(insn->variant.load_immediate.dst) == HRcFlt64) {
8506       vassert(value == 0);
8507       switch (insn->size) {
8508       case 4: return s390_emit_LZER(buf, r, value);
8509       case 8: return s390_emit_LZDR(buf, r, value);
8510       }
8511       vpanic("s390_insn_load_immediate_emit");
8512    }
8513 
8514    switch (insn->size) {
8515    case 1:
8516    case 2:
8517       /* Load the immediate values as a 4 byte value. That does not hurt as
8518          those extra bytes will not be looked at. Fall through .... */
8519    case 4:
8520       return s390_emit_load_32imm(buf, r, value);
8521 
8522    case 8:
8523       return s390_emit_load_64imm(buf, r, value);
8524    }
8525 
8526    vpanic("s390_insn_load_immediate_emit");
8527 }
8528 
8529 
8530 /* There is no easy way to do ALU operations on 1-byte or 2-byte operands.
8531    So we simply perform a 4-byte operation. Doing so uses possibly undefined
8532    bits and produces an undefined result in those extra bit positions. But
8533    upstream does not look at those positions, so this is OK. */
8534 static UChar *
s390_insn_alu_emit(UChar * buf,const s390_insn * insn)8535 s390_insn_alu_emit(UChar *buf, const s390_insn *insn)
8536 {
8537    s390_opnd_RMI op2;
8538    UInt dst;
8539 
8540    dst = hregNumber(insn->variant.alu.dst);
8541    op2 = insn->variant.alu.op2;
8542 
8543    /* Second operand is in a register */
8544    if (op2.tag == S390_OPND_REG) {
8545       UInt r2 = hregNumber(op2.variant.reg);
8546 
8547       switch (insn->size) {
8548       case 1:
8549       case 2:
8550       case 4:
8551          switch (insn->variant.alu.tag) {
8552          case S390_ALU_ADD:  return s390_emit_AR(buf, dst, r2);
8553          case S390_ALU_SUB:  return s390_emit_SR(buf, dst, r2);
8554          case S390_ALU_MUL:  return s390_emit_MSR(buf, dst, r2);
8555          case S390_ALU_AND:  return s390_emit_NR(buf, dst, r2);
8556          case S390_ALU_OR:   return s390_emit_OR(buf, dst, r2);
8557          case S390_ALU_XOR:  return s390_emit_XR(buf, dst, r2);
8558          case S390_ALU_LSH:  return s390_emit_SLL(buf, dst, r2, 0);
8559          case S390_ALU_RSH:  return s390_emit_SRL(buf, dst, r2, 0);
8560          case S390_ALU_RSHA: return s390_emit_SRA(buf, dst, r2, 0);
8561          }
8562          goto fail;
8563 
8564       case 8:
8565          switch (insn->variant.alu.tag) {
8566          case S390_ALU_ADD:  return s390_emit_AGR(buf, dst, r2);
8567          case S390_ALU_SUB:  return s390_emit_SGR(buf, dst, r2);
8568          case S390_ALU_MUL:  return s390_emit_MSGR(buf, dst, r2);
8569          case S390_ALU_AND:  return s390_emit_NGR(buf, dst, r2);
8570          case S390_ALU_OR:   return s390_emit_OGR(buf, dst, r2);
8571          case S390_ALU_XOR:  return s390_emit_XGR(buf, dst, r2);
8572          case S390_ALU_LSH:  return s390_emit_SLLG(buf, dst, dst, r2, DISP20(0));
8573          case S390_ALU_RSH:  return s390_emit_SRLG(buf, dst, dst, r2, DISP20(0));
8574          case S390_ALU_RSHA: return s390_emit_SRAG(buf, dst, dst, r2, DISP20(0));
8575          }
8576          goto fail;
8577       }
8578       goto fail;
8579    }
8580 
8581    /* 2nd operand is in memory */
8582    if (op2.tag == S390_OPND_AMODE) {
8583       UInt b, x, d;
8584       const s390_amode *src = op2.variant.am;
8585 
8586       b = hregNumber(src->b);
8587       x = hregNumber(src->x);  /* 0 for B12 and B20 */
8588       d = src->d;
8589 
8590       /* Shift operands are special here as there are no opcodes that
8591          allow a memory operand. So we first load the 2nd operand into
8592          some register. R0 is used to save restore the contents of the
8593          chosen register.. */
8594 
8595       if (insn->variant.alu.tag == S390_ALU_LSH ||
8596           insn->variant.alu.tag == S390_ALU_RSH ||
8597           insn->variant.alu.tag == S390_ALU_RSHA) {
8598          UInt b2;
8599 
8600          /* Choose a register (other than DST or R0) into which to stick the
8601             shift amount. The following works because r15 is reserved and
8602             thusly dst != 15. */
8603          vassert(dst != 15);  /* extra paranoia */
8604          b2 = (dst + 1) % 16;
8605 
8606          buf = s390_emit_LGR(buf, R0, b2);  /* save */
8607 
8608          /* Loading SRC to B2 does not modify R0. */
8609          buf = s390_emit_load_mem(buf, insn->size, b2, src);
8610 
8611          if (insn->size == 8) {
8612             switch (insn->variant.alu.tag) {
8613             case S390_ALU_LSH:
8614                buf = s390_emit_SLLG(buf, dst, dst, b2, DISP20(0));
8615                break;
8616             case S390_ALU_RSH:
8617                buf = s390_emit_SRLG(buf, dst, dst, b2, DISP20(0));
8618                break;
8619             case S390_ALU_RSHA:
8620                buf = s390_emit_SRAG(buf, dst, dst, b2, DISP20(0));
8621                break;
8622             default: /* unreachable */
8623                goto fail;
8624             }
8625          } else {
8626             switch (insn->variant.alu.tag) {
8627             case S390_ALU_LSH:
8628                buf = s390_emit_SLL(buf, dst, b2, 0);
8629                break;
8630             case S390_ALU_RSH:
8631                buf = s390_emit_SRL(buf, dst, b2, 0);
8632                break;
8633             case S390_ALU_RSHA:
8634                buf = s390_emit_SRA(buf, dst, b2, 0);
8635                break;
8636             default: /* unreachable */
8637                goto fail;
8638             }
8639          }
8640          return s390_emit_LGR(buf, b2, R0);  /* restore */
8641       }
8642 
8643       switch (insn->size) {
8644       case 1:
8645          /* Move the byte from memory into scratch register r0 */
8646          buf = s390_emit_load_mem(buf, 1, R0, src);
8647 
8648          switch (insn->variant.alu.tag) {
8649          case S390_ALU_ADD: return s390_emit_AR(buf, dst, R0);
8650          case S390_ALU_SUB: return s390_emit_SR(buf, dst, R0);
8651          case S390_ALU_MUL: return s390_emit_MSR(buf, dst, R0);
8652          case S390_ALU_AND: return s390_emit_NR(buf, dst, R0);
8653          case S390_ALU_OR:  return s390_emit_OR(buf, dst, R0);
8654          case S390_ALU_XOR: return s390_emit_XR(buf, dst, R0);
8655          case S390_ALU_LSH:
8656          case S390_ALU_RSH:
8657          case S390_ALU_RSHA: ; /* avoid GCC warning */
8658          }
8659          goto fail;
8660 
8661       case 2:
8662          switch (src->tag) {
8663          case S390_AMODE_B12:
8664          case S390_AMODE_BX12:
8665             switch (insn->variant.alu.tag) {
8666             case S390_ALU_ADD:
8667                return s390_emit_AH(buf, dst, x, b, d);
8668 
8669             case S390_ALU_SUB:
8670                return s390_emit_SH(buf, dst, x, b, d);
8671 
8672             case S390_ALU_MUL:
8673                return s390_emit_MH(buf, dst, x, b, d);
8674 
8675                /* For bitwise operations: Move two bytes from memory into scratch
8676                   register r0; then perform operation */
8677             case S390_ALU_AND:
8678                buf = s390_emit_LH(buf, R0, x, b, d);
8679                return s390_emit_NR(buf, dst, R0);
8680 
8681             case S390_ALU_OR:
8682                buf = s390_emit_LH(buf, R0, x, b, d);
8683                return s390_emit_OR(buf, dst, R0);
8684 
8685             case S390_ALU_XOR:
8686                buf = s390_emit_LH(buf, R0, x, b, d);
8687                return s390_emit_XR(buf, dst, R0);
8688 
8689             case S390_ALU_LSH:
8690             case S390_ALU_RSH:
8691             case S390_ALU_RSHA: ; /* avoid GCC warning */
8692             }
8693             goto fail;
8694 
8695          case S390_AMODE_B20:
8696          case S390_AMODE_BX20:
8697             switch (insn->variant.alu.tag) {
8698             case S390_ALU_ADD:
8699                return s390_emit_AHY(buf, dst, x, b, DISP20(d));
8700 
8701             case S390_ALU_SUB:
8702                return s390_emit_SHY(buf, dst, x, b, DISP20(d));
8703 
8704             case S390_ALU_MUL:
8705                return s390_emit_MHYw(buf, dst, x, b, DISP20(d));
8706 
8707                /* For bitwise operations: Move two bytes from memory into scratch
8708                   register r0; then perform operation */
8709             case S390_ALU_AND:
8710                buf = s390_emit_LHY(buf, R0, x, b, DISP20(d));
8711                return s390_emit_NR(buf, dst, R0);
8712 
8713             case S390_ALU_OR:
8714                buf = s390_emit_LHY(buf, R0, x, b, DISP20(d));
8715                return s390_emit_OR(buf, dst, R0);
8716 
8717             case S390_ALU_XOR:
8718                buf = s390_emit_LHY(buf, R0, x, b, DISP20(d));
8719                return s390_emit_XR(buf, dst, R0);
8720 
8721             case S390_ALU_LSH:
8722             case S390_ALU_RSH:
8723             case S390_ALU_RSHA: ; /* avoid GCC warning */
8724             }
8725             goto fail;
8726          }
8727          goto fail;
8728 
8729       case 4:
8730          switch (src->tag) {
8731          case S390_AMODE_B12:
8732          case S390_AMODE_BX12:
8733             switch (insn->variant.alu.tag) {
8734             case S390_ALU_ADD: return s390_emit_A(buf, dst, x, b, d);
8735             case S390_ALU_SUB: return s390_emit_S(buf, dst, x, b, d);
8736             case S390_ALU_MUL: return s390_emit_MS(buf, dst, x, b, d);
8737             case S390_ALU_AND: return s390_emit_N(buf, dst, x, b, d);
8738             case S390_ALU_OR:  return s390_emit_O(buf, dst, x, b, d);
8739             case S390_ALU_XOR: return s390_emit_X(buf, dst, x, b, d);
8740             case S390_ALU_LSH:
8741             case S390_ALU_RSH:
8742             case S390_ALU_RSHA: ; /* avoid GCC warning */
8743             }
8744             goto fail;
8745 
8746          case S390_AMODE_B20:
8747          case S390_AMODE_BX20:
8748             switch (insn->variant.alu.tag) {
8749             case S390_ALU_ADD: return s390_emit_AY(buf, dst, x, b, DISP20(d));
8750             case S390_ALU_SUB: return s390_emit_SY(buf, dst, x, b, DISP20(d));
8751             case S390_ALU_MUL: return s390_emit_MSY(buf, dst, x, b, DISP20(d));
8752             case S390_ALU_AND: return s390_emit_NY(buf, dst, x, b, DISP20(d));
8753             case S390_ALU_OR:  return s390_emit_OY(buf, dst, x, b, DISP20(d));
8754             case S390_ALU_XOR: return s390_emit_XY(buf, dst, x, b, DISP20(d));
8755             case S390_ALU_LSH:
8756             case S390_ALU_RSH:
8757             case S390_ALU_RSHA: ; /* avoid GCC warning */
8758             }
8759             goto fail;
8760          }
8761          goto fail;
8762 
8763       case 8:
8764          switch (insn->variant.alu.tag) {
8765          case S390_ALU_ADD: return s390_emit_AG(buf, dst, x, b, DISP20(d));
8766          case S390_ALU_SUB: return s390_emit_SG(buf, dst, x, b, DISP20(d));
8767          case S390_ALU_MUL: return s390_emit_MSG(buf, dst, x, b, DISP20(d));
8768          case S390_ALU_AND: return s390_emit_NG(buf, dst, x, b, DISP20(d));
8769          case S390_ALU_OR:  return s390_emit_OG(buf, dst, x, b, DISP20(d));
8770          case S390_ALU_XOR: return s390_emit_XG(buf, dst, x, b, DISP20(d));
8771          case S390_ALU_LSH:
8772          case S390_ALU_RSH:
8773          case S390_ALU_RSHA: ; /* avoid GCC warning */
8774          }
8775          goto fail;
8776       }
8777       goto fail;
8778    }
8779 
8780    /* 2nd operand is an immediate value */
8781    if (op2.tag == S390_OPND_IMMEDIATE) {
8782       ULong value;
8783 
8784       /* No masking of the value is required as it is not sign extended */
8785       value = op2.variant.imm;
8786 
8787       switch (insn->size) {
8788       case 1:
8789       case 2:
8790          /* There is no 1-byte opcode. Do the computation in
8791             2 bytes. The extra byte will be ignored. */
8792          switch (insn->variant.alu.tag) {
8793          case S390_ALU_ADD:
8794             return s390_emit_AHI(buf, dst, value);
8795 
8796          case S390_ALU_SUB:
8797             return s390_emit_SLFIw(buf, dst, value);
8798 
8799          case S390_ALU_MUL:
8800             return s390_emit_MHI(buf, dst, value);
8801 
8802          case S390_ALU_AND: return s390_emit_NILL(buf, dst, value);
8803          case S390_ALU_OR:  return s390_emit_OILL(buf, dst, value);
8804          case S390_ALU_XOR:
8805             /* There is no XILL instruction.  Load the immediate value into
8806                R0 and combine with the destination register. */
8807             buf = s390_emit_LHI(buf, R0, value);
8808             return s390_emit_XR(buf, dst, R0);
8809 
8810          case S390_ALU_LSH:
8811             return s390_emit_SLL(buf, dst, 0, value);
8812 
8813          case S390_ALU_RSH:
8814             return s390_emit_SRL(buf, dst, 0, value);
8815 
8816          case S390_ALU_RSHA:
8817             return s390_emit_SRA(buf, dst, 0, value);
8818          }
8819          goto fail;
8820 
8821       case 4:
8822          switch (insn->variant.alu.tag) {
8823          case S390_ALU_ADD:
8824             if (uint_fits_signed_16bit(value)) {
8825                return s390_emit_AHI(buf, dst, value);
8826             }
8827             return s390_emit_AFIw(buf, dst, value);
8828 
8829          case S390_ALU_SUB:  return s390_emit_SLFIw(buf, dst, value);
8830          case S390_ALU_MUL:  return s390_emit_MSFIw(buf, dst, value);
8831          case S390_ALU_AND:  return s390_emit_NILFw(buf, dst, value);
8832          case S390_ALU_OR:   return s390_emit_OILFw(buf, dst, value);
8833          case S390_ALU_XOR:  return s390_emit_XILFw(buf, dst, value);
8834          case S390_ALU_LSH:  return s390_emit_SLL(buf, dst, 0, value);
8835          case S390_ALU_RSH:  return s390_emit_SRL(buf, dst, 0, value);
8836          case S390_ALU_RSHA: return s390_emit_SRA(buf, dst, 0, value);
8837          }
8838          goto fail;
8839 
8840       case 8:
8841          switch (insn->variant.alu.tag) {
8842          case S390_ALU_ADD:
8843             if (ulong_fits_signed_16bit(value)) {
8844                return s390_emit_AGHI(buf, dst, value);
8845             }
8846             if (ulong_fits_signed_32bit(value) && s390_host_has_eimm) {
8847                return s390_emit_AGFI(buf, dst, value);
8848             }
8849             /* Load constant into R0 then add */
8850             buf = s390_emit_load_64imm(buf, R0, value);
8851             return s390_emit_AGR(buf, dst, R0);
8852 
8853          case S390_ALU_SUB:
8854             if (ulong_fits_unsigned_32bit(value)) {
8855                return s390_emit_SLGFIw(buf, dst, value);
8856             }
8857             /* Load value into R0; then subtract from destination reg */
8858             buf = s390_emit_load_64imm(buf, R0, value);
8859             return s390_emit_SGR(buf, dst, R0);
8860 
8861          case S390_ALU_MUL:
8862             if (ulong_fits_signed_32bit(value) && s390_host_has_gie) {
8863                return s390_emit_MSGFI(buf, dst, value);
8864             }
8865             /* Load constant into R0 then add */
8866             buf = s390_emit_load_64imm(buf, R0, value);
8867             return s390_emit_MSGR(buf, dst, R0);
8868 
8869             /* Do it in two steps: upper half [0:31] and lower half [32:63] */
8870          case S390_ALU_AND:
8871             if (s390_host_has_eimm) {
8872                buf  = s390_emit_NIHF(buf, dst, value >> 32);
8873                return s390_emit_NILF(buf, dst, value & 0xFFFFFFFF);
8874             }
8875             /* Load value into R0; then combine with destination reg */
8876             buf = s390_emit_load_64imm(buf, R0, value);
8877             return s390_emit_NGR(buf, dst, R0);
8878 
8879          case S390_ALU_OR:
8880             if (s390_host_has_eimm) {
8881                buf  = s390_emit_OIHF(buf, dst, value >> 32);
8882                return s390_emit_OILF(buf, dst, value & 0xFFFFFFFF);
8883             }
8884             /* Load value into R0; then combine with destination reg */
8885             buf = s390_emit_load_64imm(buf, R0, value);
8886             return s390_emit_OGR(buf, dst, R0);
8887 
8888          case S390_ALU_XOR:
8889             if (s390_host_has_eimm) {
8890                buf  = s390_emit_XIHF(buf, dst, value >> 32);
8891                return s390_emit_XILF(buf, dst, value & 0xFFFFFFFF);
8892             }
8893             /* Load value into R0; then combine with destination reg */
8894             buf = s390_emit_load_64imm(buf, R0, value);
8895             return s390_emit_XGR(buf, dst, R0);
8896 
8897             /* No special considerations for long displacement here. Only the six
8898                least significant bits of VALUE will be taken; all other bits are
8899                ignored. So the DH2 bits are irrelevant and do not influence the
8900                shift operation, independent of whether long-displacement is available
8901                or not. */
8902          case S390_ALU_LSH:  return s390_emit_SLLG(buf, dst, dst, 0, DISP20(value));
8903          case S390_ALU_RSH:  return s390_emit_SRLG(buf, dst, dst, 0, DISP20(value));
8904          case S390_ALU_RSHA: return s390_emit_SRAG(buf, dst, dst, 0, DISP20(value));
8905          }
8906          goto fail;
8907       }
8908       goto fail;
8909    }
8910 
8911  fail:
8912    vpanic("s390_insn_alu_emit");
8913 }
8914 
8915 
8916 static UChar *
s390_widen_emit(UChar * buf,const s390_insn * insn,UInt from_size,Bool sign_extend)8917 s390_widen_emit(UChar *buf, const s390_insn *insn, UInt from_size,
8918                 Bool sign_extend)
8919 {
8920    s390_opnd_RMI opnd = insn->variant.unop.src;
8921 
8922    switch (opnd.tag) {
8923    case S390_OPND_REG: {
8924       UChar r1 = hregNumber(insn->variant.unop.dst);
8925       UChar r2 = hregNumber(opnd.variant.reg);
8926 
8927       switch (from_size) {
8928       case 1:
8929          /* Widening to a half-word is implemented like widening to a word
8930             because the upper half-word will not be looked at. */
8931          if (insn->size == 4 || insn->size == 2) {  /* 8 --> 32    8 --> 16 */
8932             if (sign_extend)
8933                return s390_emit_LBRw(buf, r1, r2);
8934             else
8935                return s390_emit_LLCRw(buf, r1, r2);
8936          }
8937          if (insn->size == 8) {  /* 8 --> 64 */
8938             if (sign_extend)
8939                return s390_emit_LGBRw(buf, r1, r2);
8940             else
8941                return s390_emit_LLGCRw(buf, r1, r2);
8942          }
8943          goto fail;
8944 
8945       case 2:
8946          if (insn->size == 4) {  /* 16 --> 32 */
8947             if (sign_extend)
8948                return s390_emit_LHRw(buf, r1, r2);
8949             else
8950                return s390_emit_LLHRw(buf, r1, r2);
8951          }
8952          if (insn->size == 8) {  /* 16 --> 64 */
8953             if (sign_extend)
8954                return s390_emit_LGHRw(buf, r1, r2);
8955             else
8956                return s390_emit_LLGHRw(buf, r1, r2);
8957          }
8958          goto fail;
8959 
8960       case 4:
8961          if (insn->size == 8) {  /* 32 --> 64 */
8962             if (sign_extend)
8963                return s390_emit_LGFR(buf, r1, r2);
8964             else
8965                return s390_emit_LLGFR(buf, r1, r2);
8966          }
8967          goto fail;
8968 
8969       default: /* unexpected "from" size */
8970          goto fail;
8971       }
8972    }
8973 
8974    case S390_OPND_AMODE: {
8975       UChar r1 = hregNumber(insn->variant.unop.dst);
8976       const s390_amode *src = opnd.variant.am;
8977       UChar b = hregNumber(src->b);
8978       UChar x = hregNumber(src->x);
8979       Int   d = src->d;
8980 
8981       switch (from_size) {
8982       case 1:
8983          if (insn->size == 4 || insn->size == 2) {
8984             if (sign_extend)
8985                return s390_emit_LB(buf, r1, x, b, DISP20(d));
8986             else
8987                return s390_emit_LLCw(buf, r1, x, b, DISP20(d));
8988          }
8989          if (insn->size == 8) {
8990             if (sign_extend)
8991                return s390_emit_LGB(buf, r1, x, b, DISP20(d));
8992             else
8993                return s390_emit_LLGC(buf, r1, x, b, DISP20(d));
8994          }
8995          goto fail;
8996 
8997       case 2:
8998          if (insn->size == 4) {  /* 16 --> 32 */
8999             if (sign_extend == 0)
9000                return s390_emit_LLHw(buf, r1, x, b, DISP20(d));
9001 
9002             switch (src->tag) {
9003             case S390_AMODE_B12:
9004             case S390_AMODE_BX12:
9005                return s390_emit_LH(buf, r1, x, b, d);
9006 
9007             case S390_AMODE_B20:
9008             case S390_AMODE_BX20:
9009                return s390_emit_LHY(buf, r1, x, b, DISP20(d));
9010             }
9011             goto fail;
9012          }
9013          if (insn->size == 8) {  /* 16 --> 64 */
9014             if (sign_extend)
9015                return s390_emit_LGH(buf, r1, x, b, DISP20(d));
9016             else
9017                return s390_emit_LLGH(buf, r1, x, b, DISP20(d));
9018          }
9019          goto fail;
9020 
9021       case 4:
9022          if (insn->size == 8) {  /* 32 --> 64 */
9023             if (sign_extend)
9024                return s390_emit_LGF(buf, r1, x, b, DISP20(d));
9025             else
9026                return s390_emit_LLGF(buf, r1, x, b, DISP20(d));
9027          }
9028          goto fail;
9029 
9030       default: /* unexpected "from" size */
9031          goto fail;
9032       }
9033    }
9034 
9035    case S390_OPND_IMMEDIATE: {
9036       UChar r1 = hregNumber(insn->variant.unop.dst);
9037       ULong value = opnd.variant.imm;
9038 
9039       switch (from_size) {
9040       case 1:
9041          if (insn->size == 4 || insn->size == 2) {  /* 8 --> 32   8 --> 16 */
9042             if (sign_extend) {
9043                /* host can do the sign extension to 16-bit; LHI does the rest */
9044                return s390_emit_LHI(buf, r1, (Short)(Char)(UChar)value);
9045             } else {
9046                return s390_emit_LHI(buf, r1, value);
9047             }
9048          }
9049          if (insn->size == 8) {  /* 8 --> 64 */
9050             if (sign_extend) {
9051                /* host can do the sign extension to 16-bit; LGHI does the rest */
9052                return s390_emit_LGHI(buf, r1, (Short)(Char)(UChar)value);
9053             } else {
9054                return s390_emit_LGHI(buf, r1, value);
9055             }
9056          }
9057          goto fail;
9058 
9059       case 2:
9060          if (insn->size == 4) {  /* 16 --> 32 */
9061             return s390_emit_LHI(buf, r1, value);
9062          }
9063          if (insn->size == 8) {  /* 16 --> 64 */
9064             if (sign_extend)
9065                return s390_emit_LGHI(buf, r1, value);
9066             else
9067                return s390_emit_LLILL(buf, r1, value);
9068          }
9069          goto fail;
9070 
9071       case 4:
9072          if (insn->size == 8) {  /* 32 --> 64 */
9073             if (sign_extend)
9074                return s390_emit_LGFIw(buf, r1, value);
9075             else
9076                return s390_emit_LLILFw(buf, r1, value);
9077          }
9078          goto fail;
9079 
9080       default: /* unexpected "from" size */
9081          goto fail;
9082       }
9083    }
9084    }
9085 
9086  fail:
9087    vpanic("s390_widen_emit");
9088 }
9089 
9090 
9091 static UChar *
s390_negate_emit(UChar * buf,const s390_insn * insn)9092 s390_negate_emit(UChar *buf, const s390_insn *insn)
9093 {
9094    s390_opnd_RMI opnd;
9095 
9096    opnd = insn->variant.unop.src;
9097 
9098    switch (opnd.tag) {
9099    case S390_OPND_REG: {
9100       UChar r1 = hregNumber(insn->variant.unop.dst);
9101       UChar r2 = hregNumber(opnd.variant.reg);
9102 
9103       switch (insn->size) {
9104       case 1:
9105       case 2:
9106       case 4:
9107          return s390_emit_LCR(buf, r1, r2);
9108 
9109       case 8:
9110          return s390_emit_LCGR(buf, r1, r2);
9111 
9112       default:
9113          goto fail;
9114       }
9115    }
9116 
9117    case S390_OPND_AMODE: {
9118       UChar r1 = hregNumber(insn->variant.unop.dst);
9119 
9120       /* Load bytes into scratch register R0, then negate */
9121       buf = s390_emit_load_mem(buf, insn->size, R0, opnd.variant.am);
9122 
9123       switch (insn->size) {
9124       case 1:
9125       case 2:
9126       case 4:
9127          return s390_emit_LCR(buf, r1, R0);
9128 
9129       case 8:
9130          return s390_emit_LCGR(buf, r1, R0);
9131 
9132       default:
9133          goto fail;
9134       }
9135    }
9136 
9137    case S390_OPND_IMMEDIATE: {
9138       UChar r1 = hregNumber(insn->variant.unop.dst);
9139       ULong value = opnd.variant.imm;
9140 
9141       value = ~value + 1;   /* two's complement */
9142 
9143       switch (insn->size) {
9144       case 1:
9145       case 2:
9146          /* Load the immediate values as a 4 byte value. That does not hurt as
9147             those extra bytes will not be looked at. Fall through .... */
9148       case 4:
9149          return s390_emit_load_32imm(buf, r1, value);
9150 
9151       case 8:
9152          return s390_emit_load_64imm(buf, r1, value);
9153 
9154       default:
9155          goto fail;
9156       }
9157    }
9158    }
9159 
9160  fail:
9161    vpanic("s390_negate_emit");
9162 }
9163 
9164 
9165 static UChar *
s390_insn_unop_emit(UChar * buf,const s390_insn * insn)9166 s390_insn_unop_emit(UChar *buf, const s390_insn *insn)
9167 {
9168    switch (insn->variant.unop.tag) {
9169    case S390_ZERO_EXTEND_8:  return s390_widen_emit(buf, insn, 1, 0);
9170    case S390_ZERO_EXTEND_16: return s390_widen_emit(buf, insn, 2, 0);
9171    case S390_ZERO_EXTEND_32: return s390_widen_emit(buf, insn, 4, 0);
9172 
9173    case S390_SIGN_EXTEND_8:  return s390_widen_emit(buf, insn, 1, 1);
9174    case S390_SIGN_EXTEND_16: return s390_widen_emit(buf, insn, 2, 1);
9175    case S390_SIGN_EXTEND_32: return s390_widen_emit(buf, insn, 4, 1);
9176 
9177    case S390_NEGATE:         return s390_negate_emit(buf, insn);
9178    case S390_VEC_FILL: {
9179       vassert(insn->variant.unop.src.tag == S390_OPND_IMMEDIATE);
9180       UChar v1 = hregNumber(insn->variant.unop.dst);
9181       UShort i2 = insn->variant.unop.src.variant.imm;
9182       return s390_emit_VGBM(buf, v1, i2);
9183       }
9184    case S390_VEC_DUPLICATE: {
9185       vassert(insn->variant.unop.src.tag == S390_OPND_REG);
9186       UChar v1 = hregNumber(insn->variant.unop.dst);
9187       UChar v2 = hregNumber(insn->variant.unop.src.variant.reg);
9188       return s390_emit_VREP(buf, v1, v2, s390_getM_from_size(insn->size));
9189       }
9190    case S390_VEC_UNPACKLOWS: {
9191       vassert(insn->variant.unop.src.tag == S390_OPND_REG);
9192       vassert(insn->size < 8);
9193       UChar v1 = hregNumber(insn->variant.unop.dst);
9194       UChar v2 = hregNumber(insn->variant.unop.src.variant.reg);
9195       return s390_emit_VUPH(buf, v1, v2, s390_getM_from_size(insn->size));
9196       }
9197    case S390_VEC_UNPACKLOWU: {
9198       vassert(insn->variant.unop.src.tag == S390_OPND_REG);
9199       vassert(insn->size < 8);
9200       UChar v1 = hregNumber(insn->variant.unop.dst);
9201       UChar v2 = hregNumber(insn->variant.unop.src.variant.reg);
9202       return s390_emit_VUPLH(buf, v1, v2, s390_getM_from_size(insn->size));
9203       }
9204 
9205    case S390_VEC_ABS:{
9206       vassert(insn->variant.unop.src.tag == S390_OPND_REG);
9207       UChar v1 = hregNumber(insn->variant.unop.dst);
9208       UChar v2 = hregNumber(insn->variant.unop.src.variant.reg);
9209       return s390_emit_VLP(buf, v1, v2, s390_getM_from_size(insn->size));
9210    }
9211 
9212    case S390_VEC_COUNT_LEADING_ZEROES:{
9213       vassert(insn->variant.unop.src.tag == S390_OPND_REG);
9214       UChar v1 = hregNumber(insn->variant.unop.dst);
9215       UChar v2 = hregNumber(insn->variant.unop.src.variant.reg);
9216       return s390_emit_VCLZ(buf, v1, v2, s390_getM_from_size(insn->size));
9217    }
9218 
9219    case S390_VEC_COUNT_TRAILING_ZEROES:{
9220       vassert(insn->variant.unop.src.tag == S390_OPND_REG);
9221       UChar v1 = hregNumber(insn->variant.unop.dst);
9222       UChar v2 = hregNumber(insn->variant.unop.src.variant.reg);
9223       return s390_emit_VCTZ(buf, v1, v2, s390_getM_from_size(insn->size));
9224    }
9225 
9226    case S390_VEC_COUNT_ONES:{
9227       vassert(insn->variant.unop.src.tag == S390_OPND_REG);
9228       UChar v1 = hregNumber(insn->variant.unop.dst);
9229       UChar v2 = hregNumber(insn->variant.unop.src.variant.reg);
9230       return s390_emit_VPOPCT(buf, v1, v2, s390_getM_from_size(insn->size));
9231    }
9232 
9233    case S390_VEC_FLOAT_NEG: {
9234       vassert(insn->variant.unop.src.tag == S390_OPND_REG);
9235       vassert(insn->size == 8);
9236       UChar v1 = hregNumber(insn->variant.unop.dst);
9237       UChar v2 = hregNumber(insn->variant.unop.src.variant.reg);
9238       return s390_emit_VFPSO(buf, v1, v2, s390_getM_from_size(insn->size), 0, 0);
9239    }
9240    case S390_VEC_FLOAT_ABS: {
9241       vassert(insn->variant.unop.src.tag == S390_OPND_REG);
9242       vassert(insn->size == 8);
9243       UChar v1 = hregNumber(insn->variant.unop.dst);
9244       UChar v2 = hregNumber(insn->variant.unop.src.variant.reg);
9245       return s390_emit_VFPSO(buf, v1, v2, s390_getM_from_size(insn->size), 0, 2);
9246    }
9247    case S390_VEC_FLOAT_SQRT: {
9248       vassert(insn->variant.unop.src.tag == S390_OPND_REG);
9249       vassert(insn->size == 8);
9250       UChar v1 = hregNumber(insn->variant.unop.dst);
9251       UChar v2 = hregNumber(insn->variant.unop.src.variant.reg);
9252       return s390_emit_VFSQ(buf, v1, v2, s390_getM_from_size(insn->size), 0);
9253    }
9254    default:
9255       vpanic("s390_insn_unop_emit");
9256    }
9257 }
9258 
9259 
9260 /* Only 4-byte and 8-byte operands are handled. 1-byte and 2-byte
9261    comparisons will have been converted to 4-byte comparisons in
9262    s390_isel_cc and should not occur here. */
9263 static UChar *
s390_insn_test_emit(UChar * buf,const s390_insn * insn)9264 s390_insn_test_emit(UChar *buf, const s390_insn *insn)
9265 {
9266    s390_opnd_RMI opnd;
9267 
9268    opnd = insn->variant.test.src;
9269 
9270    switch (opnd.tag) {
9271    case S390_OPND_REG: {
9272       UInt reg = hregNumber(opnd.variant.reg);
9273 
9274       switch (insn->size) {
9275       case 4:
9276          return s390_emit_LTR(buf, reg, reg);
9277 
9278       case 8:
9279          return s390_emit_LTGR(buf, reg, reg);
9280 
9281       default:
9282          goto fail;
9283       }
9284    }
9285 
9286    case S390_OPND_AMODE: {
9287       const s390_amode *am = opnd.variant.am;
9288       UChar b = hregNumber(am->b);
9289       UChar x = hregNumber(am->x);
9290       Int   d = am->d;
9291 
9292       switch (insn->size) {
9293       case 4:
9294          return s390_emit_LTw(buf, R0, x, b, DISP20(d));
9295 
9296       case 8:
9297          return s390_emit_LTGw(buf, R0, x, b, DISP20(d));
9298 
9299       default:
9300          goto fail;
9301       }
9302    }
9303 
9304    case S390_OPND_IMMEDIATE: {
9305       ULong value = opnd.variant.imm;
9306 
9307       switch (insn->size) {
9308       case 4:
9309          buf = s390_emit_load_32imm(buf, R0, value);
9310          return s390_emit_LTR(buf, R0, R0);
9311 
9312       case 8:
9313          buf = s390_emit_load_64imm(buf, R0, value);
9314          return s390_emit_LTGR(buf, R0, R0);
9315 
9316       default:
9317          goto fail;
9318       }
9319    }
9320 
9321    default:
9322       goto fail;
9323    }
9324 
9325  fail:
9326    vpanic("s390_insn_test_emit");
9327 }
9328 
9329 
9330 static UChar *
s390_insn_cc2bool_emit(UChar * buf,const s390_insn * insn)9331 s390_insn_cc2bool_emit(UChar *buf, const s390_insn *insn)
9332 {
9333    UChar r1 = hregNumber(insn->variant.cc2bool.dst);
9334    s390_cc_t cond = insn->variant.cc2bool.cond;
9335 
9336    /* Make the destination register be 1 or 0, depending on whether
9337       the relevant condition holds. A 64-bit value is computed. */
9338    if (cond == S390_CC_ALWAYS)
9339       return s390_emit_LGHI(buf, r1, 1);  /* r1 = 1 */
9340 
9341    buf = s390_emit_load_cc(buf, r1);                 /* r1 = cc */
9342    buf = s390_emit_LGHI(buf, R0, cond);              /* r0 = mask */
9343    buf = s390_emit_SLLG(buf, r1, R0, r1, DISP20(0)); /* r1 = mask << cc */
9344    buf = s390_emit_SRLG(buf, r1, r1, 0,  DISP20(3)); /* r1 = r1 >> 3 */
9345    buf = s390_emit_NILL(buf, r1, 1);                 /* r1 = r1 & 0x1 */
9346 
9347    return buf;
9348 }
9349 
9350 
9351 /* Only 4-byte and 8-byte operands are handled. */
9352 static UChar *
s390_insn_cas_emit(UChar * buf,const s390_insn * insn)9353 s390_insn_cas_emit(UChar *buf, const s390_insn *insn)
9354 {
9355    UChar r1, r3, b, old;
9356    Int d;
9357    s390_amode *am;
9358 
9359    r1 = hregNumber(insn->variant.cas.op1); /* expected value */
9360    r3 = hregNumber(insn->variant.cas.op3);
9361    old= hregNumber(insn->variant.cas.old_mem);
9362    am = insn->variant.cas.op2;
9363    b  = hregNumber(am->b);
9364    d  = am->d;
9365 
9366    vassert(am->tag == S390_AMODE_B12 || am->tag == S390_AMODE_B20);
9367 
9368    switch (insn->size) {
9369    case 4:
9370       /* r1 must not be overwritten. So copy it to R0 and let CS clobber it */
9371       buf = s390_emit_LR(buf, R0, r1);
9372       if (am->tag == S390_AMODE_B12)
9373          buf = s390_emit_CS(buf, R0, r3, b, d);
9374       else
9375          buf = s390_emit_CSY(buf, R0, r3, b, DISP20(d));
9376       /* Now copy R0 which has the old memory value to OLD */
9377       return s390_emit_LR(buf, old, R0);
9378 
9379    case 8:
9380       /* r1 must not be overwritten. So copy it to R0 and let CS clobber it */
9381       buf = s390_emit_LGR(buf, R0, r1);
9382       buf = s390_emit_CSG(buf, R0, r3, b, DISP20(d));
9383       /* Now copy R0 which has the old memory value to OLD */
9384       return s390_emit_LGR(buf, old, R0);
9385 
9386    default:
9387       goto fail;
9388    }
9389 
9390  fail:
9391    vpanic("s390_insn_cas_emit");
9392 }
9393 
9394 
9395 /* Only 4-byte and 8-byte operands are handled. */
9396 static UChar *
s390_insn_cdas_emit(UChar * buf,const s390_insn * insn)9397 s390_insn_cdas_emit(UChar *buf, const s390_insn *insn)
9398 {
9399    UChar r1, r1p1, r3, /*r3p1,*/ b, old_high, old_low, scratch;
9400    Int d;
9401    s390_amode *am;
9402    s390_cdas *cdas = insn->variant.cdas.details;
9403 
9404    r1   = hregNumber(cdas->op1_high); /* expected value */
9405    r1p1 = hregNumber(cdas->op1_low);  /* expected value */
9406    r3   = hregNumber(cdas->op3_high);
9407    /* r3p1 = hregNumber(cdas->op3_low); */ /* unused */
9408    old_high = hregNumber(cdas->old_mem_high);
9409    old_low  = hregNumber(cdas->old_mem_low);
9410    scratch  = hregNumber(cdas->scratch);
9411    am = cdas->op2;
9412    b  = hregNumber(am->b);
9413    d  = am->d;
9414 
9415    vassert(scratch == 1);
9416    vassert(am->tag == S390_AMODE_B12 || am->tag == S390_AMODE_B20);
9417 
9418    switch (insn->size) {
9419    case 4:
9420       /* r1, r1+1 must not be overwritten. So copy them to R0,scratch
9421          and let CDS/CDSY clobber it */
9422       buf = s390_emit_LR(buf, R0, r1);
9423       buf = s390_emit_LR(buf, scratch, r1p1);
9424 
9425       if (am->tag == S390_AMODE_B12)
9426          buf = s390_emit_CDS(buf, R0, r3, b, d);
9427       else
9428          buf = s390_emit_CDSY(buf, R0, r3, b, DISP20(d));
9429 
9430       /* Now copy R0,scratch which has the old memory value to OLD */
9431       buf = s390_emit_LR(buf, old_high, R0);
9432       buf = s390_emit_LR(buf, old_low,  scratch);
9433       return buf;
9434 
9435    case 8:
9436       /* r1, r1+1 must not be overwritten. So copy them to R0,scratch
9437          and let CDSG clobber it */
9438       buf = s390_emit_LGR(buf, R0, r1);
9439       buf = s390_emit_LGR(buf, scratch, r1p1);
9440 
9441       buf = s390_emit_CDSG(buf, R0, r3, b, DISP20(d));
9442 
9443       /* Now copy R0,scratch which has the old memory value to OLD */
9444       buf = s390_emit_LGR(buf, old_high, R0);
9445       buf = s390_emit_LGR(buf, old_low,  scratch);
9446       return buf;
9447 
9448    default:
9449       goto fail;
9450    }
9451 
9452  fail:
9453    vpanic("s390_insn_cdas_emit");
9454 }
9455 
9456 
9457 /* Only 4-byte and 8-byte comparisons are handled. 1-byte and 2-byte
9458    comparisons will have been converted to 4-byte comparisons in
9459    s390_isel_cc and should not occur here. */
9460 static UChar *
s390_insn_compare_emit(UChar * buf,const s390_insn * insn)9461 s390_insn_compare_emit(UChar *buf, const s390_insn *insn)
9462 {
9463    s390_opnd_RMI op2;
9464    HReg op1;
9465    Bool signed_comparison;
9466 
9467    op1 = insn->variant.compare.src1;
9468    op2 = insn->variant.compare.src2;
9469    signed_comparison = insn->variant.compare.signed_comparison;
9470 
9471    switch (op2.tag) {
9472    case S390_OPND_REG: {
9473       UInt r1 = hregNumber(op1);
9474       UInt r2 = hregNumber(op2.variant.reg);
9475 
9476       switch (insn->size) {
9477       case 4:
9478          if (signed_comparison)
9479             return s390_emit_CR(buf, r1, r2);
9480          else
9481             return s390_emit_CLR(buf, r1, r2);
9482 
9483       case 8:
9484          if (signed_comparison)
9485             return s390_emit_CGR(buf, r1, r2);
9486          else
9487             return s390_emit_CLGR(buf, r1, r2);
9488 
9489       default:
9490          goto fail;
9491       }
9492    }
9493 
9494    case S390_OPND_AMODE: {
9495       UChar r1 = hregNumber(op1);
9496       const s390_amode *am = op2.variant.am;
9497       UChar b = hregNumber(am->b);
9498       UChar x = hregNumber(am->x);
9499       Int   d = am->d;
9500 
9501       switch (insn->size) {
9502       case 4:
9503          switch (am->tag) {
9504          case S390_AMODE_B12:
9505          case S390_AMODE_BX12:
9506             if (signed_comparison)
9507                return s390_emit_C(buf, r1, x, b, d);
9508             else
9509                return s390_emit_CL(buf, r1, x, b, d);
9510 
9511          case S390_AMODE_B20:
9512          case S390_AMODE_BX20:
9513             if (signed_comparison)
9514                return s390_emit_CY(buf, r1, x, b, DISP20(d));
9515             else
9516                return s390_emit_CLY(buf, r1, x, b, DISP20(d));
9517          }
9518          goto fail;
9519 
9520       case 8:
9521          if (signed_comparison)
9522             return s390_emit_CG(buf, r1, x, b, DISP20(d));
9523          else
9524             return s390_emit_CLG(buf, r1, x, b, DISP20(d));
9525 
9526       default:
9527          goto fail;
9528       }
9529    }
9530 
9531    case S390_OPND_IMMEDIATE: {
9532       UChar r1 = hregNumber(op1);
9533       ULong value = op2.variant.imm;
9534 
9535       switch (insn->size) {
9536       case 4:
9537          if (signed_comparison)
9538             return s390_emit_CFIw(buf, r1, value);
9539          else
9540             return s390_emit_CLFIw(buf, r1, value);
9541 
9542       case 8:
9543          if (s390_host_has_eimm) {
9544             if (signed_comparison) {
9545                if (ulong_fits_signed_32bit(value))
9546                   return s390_emit_CGFI(buf, r1, value);
9547             } else {
9548                if (ulong_fits_unsigned_32bit(value))
9549                   return s390_emit_CLGFI(buf, r1, value);
9550             }
9551          }
9552          buf = s390_emit_load_64imm(buf, R0, value);
9553          if (signed_comparison)
9554             return s390_emit_CGR(buf, r1, R0);
9555          else
9556             return s390_emit_CLGR(buf, r1, R0);
9557 
9558       default:
9559          goto fail;
9560       }
9561    }
9562 
9563    default:
9564       goto fail;
9565    }
9566 
9567  fail:
9568    vpanic("s390_insn_compare_emit");
9569 }
9570 
9571 
9572 static UChar *
s390_insn_mul_emit(UChar * buf,const s390_insn * insn)9573 s390_insn_mul_emit(UChar *buf, const s390_insn *insn)
9574 {
9575    s390_opnd_RMI op2;
9576    UChar r1;
9577    Bool signed_multiply;
9578 
9579    /* The register number identifying the register pair */
9580    r1  = hregNumber(insn->variant.mul.dst_hi);
9581 
9582    op2 = insn->variant.mul.op2;
9583    signed_multiply = insn->tag == S390_INSN_SMUL;
9584 
9585    switch (op2.tag) {
9586    case S390_OPND_REG: {
9587       UInt r2 = hregNumber(op2.variant.reg);
9588 
9589       switch (insn->size) {
9590       case 1:
9591       case 2:
9592       case 4:
9593          if (signed_multiply)
9594             return s390_emit_MR(buf, r1, r2);
9595          else
9596             return s390_emit_MLR(buf, r1, r2);
9597 
9598       case 8:
9599          if (signed_multiply)
9600             vpanic("s390_insn_mul_emit");
9601          else
9602             return s390_emit_MLGR(buf, r1, r2);
9603 
9604       default:
9605          goto fail;
9606       }
9607    }
9608 
9609    case S390_OPND_AMODE: {
9610       const s390_amode *am = op2.variant.am;
9611       UChar b = hregNumber(am->b);
9612       UChar x = hregNumber(am->x);
9613       Int   d = am->d;
9614 
9615       switch (insn->size) {
9616       case 1:
9617       case 2:
9618          /* Load bytes into scratch register R0, then multiply */
9619          buf = s390_emit_load_mem(buf, insn->size, R0, am);
9620          if (signed_multiply)
9621             return s390_emit_MR(buf, r1, R0);
9622          else
9623             return s390_emit_MLR(buf, r1, R0);
9624 
9625       case 4:
9626          switch (am->tag) {
9627          case S390_AMODE_B12:
9628          case S390_AMODE_BX12:
9629             if (signed_multiply)
9630                return s390_emit_M(buf, r1, x, b, d);
9631             else
9632                return s390_emit_ML(buf, r1, x, b, DISP20(d));
9633 
9634          case S390_AMODE_B20:
9635          case S390_AMODE_BX20:
9636             if (signed_multiply)
9637                return s390_emit_MFYw(buf, r1, x, b, DISP20(d));
9638             else
9639                return s390_emit_ML(buf, r1, x, b, DISP20(d));
9640          }
9641          goto fail;
9642 
9643       case 8:
9644          if (signed_multiply)
9645             vpanic("s390_insn_mul_emit");
9646          else
9647             return s390_emit_MLG(buf, r1, x, b, DISP20(d));
9648 
9649       default:
9650          goto fail;
9651       }
9652    }
9653 
9654    case S390_OPND_IMMEDIATE: {
9655       ULong value = op2.variant.imm;
9656 
9657       switch (insn->size) {
9658       case 1:
9659       case 2:
9660       case 4:
9661          buf = s390_emit_load_32imm(buf, R0, value);
9662          if (signed_multiply)
9663             return s390_emit_MR(buf, r1, R0);
9664          else
9665             return s390_emit_MLR(buf, r1, R0);
9666 
9667       case 8:
9668          buf = s390_emit_load_64imm(buf, R0, value);
9669          if (signed_multiply)
9670             vpanic("s390_insn_mul_emit");
9671          else
9672             return s390_emit_MLGR(buf, r1, R0);
9673 
9674       default:
9675          goto fail;
9676       }
9677    }
9678 
9679    default:
9680       goto fail;
9681    }
9682 
9683  fail:
9684    vpanic("s390_insn_mul_emit");
9685 }
9686 
9687 
9688 static UChar *
s390_insn_div_emit(UChar * buf,const s390_insn * insn)9689 s390_insn_div_emit(UChar *buf, const s390_insn *insn)
9690 {
9691    s390_opnd_RMI op2;
9692    UChar r1;
9693    Bool signed_divide;
9694 
9695    r1  = hregNumber(insn->variant.div.op1_hi);
9696    op2 = insn->variant.div.op2;
9697    signed_divide = insn->tag == S390_INSN_SDIV;
9698 
9699    switch (op2.tag) {
9700    case S390_OPND_REG: {
9701       UInt r2 = hregNumber(op2.variant.reg);
9702 
9703       switch (insn->size) {
9704       case 4:
9705          if (signed_divide)
9706             return s390_emit_DR(buf, r1, r2);
9707          else
9708             return s390_emit_DLR(buf, r1, r2);
9709 
9710       case 8:
9711          if (signed_divide)
9712             vpanic("s390_insn_div_emit");
9713          else
9714             return s390_emit_DLGR(buf, r1, r2);
9715 
9716       default:
9717          goto fail;
9718       }
9719    }
9720 
9721    case S390_OPND_AMODE: {
9722       const s390_amode *am = op2.variant.am;
9723       UChar b = hregNumber(am->b);
9724       UChar x = hregNumber(am->x);
9725       Int   d = am->d;
9726 
9727       switch (insn->size) {
9728       case 4:
9729          switch (am->tag) {
9730          case S390_AMODE_B12:
9731          case S390_AMODE_BX12:
9732             if (signed_divide)
9733                return s390_emit_D(buf, r1, x, b, d);
9734             else
9735                return s390_emit_DL(buf, r1, x, b, DISP20(d));
9736 
9737          case S390_AMODE_B20:
9738          case S390_AMODE_BX20:
9739             if (signed_divide) {
9740                buf = s390_emit_LY(buf, R0, x, b, DISP20(d));
9741                return s390_emit_DR(buf, r1, R0);
9742             } else
9743                return s390_emit_DL(buf, r1, x, b, DISP20(d));
9744          }
9745          goto fail;
9746 
9747       case 8:
9748          if (signed_divide)
9749             vpanic("s390_insn_div_emit");
9750          else
9751             return s390_emit_DLG(buf, r1, x, b, DISP20(d));
9752 
9753       default:
9754          goto fail;
9755       }
9756    }
9757 
9758    case S390_OPND_IMMEDIATE: {
9759       ULong value = op2.variant.imm;
9760 
9761       switch (insn->size) {
9762       case 4:
9763          buf = s390_emit_load_32imm(buf, R0, value);
9764          if (signed_divide)
9765             return s390_emit_DR(buf, r1, R0);
9766          else
9767             return s390_emit_DLR(buf, r1, R0);
9768 
9769       case 8:
9770          buf = s390_emit_load_64imm(buf, R0, value);
9771          if (signed_divide)
9772             vpanic("s390_insn_div_emit");
9773          else
9774             return s390_emit_DLGR(buf, r1, R0);
9775 
9776       default:
9777          goto fail;
9778       }
9779    }
9780 
9781    default:
9782       goto fail;
9783    }
9784 
9785  fail:
9786    vpanic("s390_insn_div_emit");
9787 }
9788 
9789 
9790 static UChar *
s390_insn_divs_emit(UChar * buf,const s390_insn * insn)9791 s390_insn_divs_emit(UChar *buf, const s390_insn *insn)
9792 {
9793    s390_opnd_RMI op2;
9794    UChar r1;
9795 
9796    r1  = hregNumber(insn->variant.divs.rem);
9797    op2 = insn->variant.divs.op2;
9798 
9799    switch (op2.tag) {
9800    case S390_OPND_REG: {
9801       UInt r2 = hregNumber(op2.variant.reg);
9802 
9803       return s390_emit_DSGR(buf, r1, r2);
9804    }
9805 
9806    case S390_OPND_AMODE: {
9807       const s390_amode *am = op2.variant.am;
9808       UChar b = hregNumber(am->b);
9809       UChar x = hregNumber(am->x);
9810       Int   d = am->d;
9811 
9812       return s390_emit_DSG(buf, r1, x, b, DISP20(d));
9813    }
9814 
9815    case S390_OPND_IMMEDIATE: {
9816       ULong value = op2.variant.imm;
9817 
9818       buf = s390_emit_load_64imm(buf, R0, value);
9819       return s390_emit_DSGR(buf, r1, R0);
9820    }
9821 
9822    default:
9823       goto fail;
9824    }
9825 
9826  fail:
9827    vpanic("s390_insn_divs_emit");
9828 }
9829 
9830 
9831 static UChar *
s390_insn_clz_emit(UChar * buf,const s390_insn * insn)9832 s390_insn_clz_emit(UChar *buf, const s390_insn *insn)
9833 {
9834    s390_opnd_RMI src;
9835    UChar r1, r1p1, r2, *p;
9836 
9837    r1   = hregNumber(insn->variant.clz.num_bits);
9838    r1p1 = hregNumber(insn->variant.clz.clobber);
9839 
9840    vassert((r1 & 0x1) == 0);
9841    vassert(r1p1 == r1 + 1);
9842 
9843    p = buf;
9844    src = insn->variant.clz.src;
9845 
9846    /* Get operand and move it to r2 */
9847    switch (src.tag) {
9848    case S390_OPND_REG:
9849       r2 = hregNumber(src.variant.reg);
9850       break;
9851 
9852    case S390_OPND_AMODE: {
9853       const s390_amode *am = src.variant.am;
9854       UChar b = hregNumber(am->b);
9855       UChar x = hregNumber(am->x);
9856       Int   d = am->d;
9857 
9858       p  = s390_emit_LG(p, R0, x, b, DISP20(d));
9859       r2 = R0;
9860       break;
9861    }
9862 
9863    case S390_OPND_IMMEDIATE: {
9864       ULong value = src.variant.imm;
9865 
9866       p  = s390_emit_load_64imm(p, R0, value);
9867       r2 = R0;
9868       break;
9869    }
9870 
9871    default:
9872       goto fail;
9873    }
9874 
9875    /* Use FLOGR if you can */
9876    if (s390_host_has_eimm) {
9877       return s390_emit_FLOGR(p, r1, r2);
9878    }
9879 
9880    /*
9881       r0 = r2;
9882       r1 = 64;
9883       while (r0 != 0) {
9884         r1 -= 1;
9885         r0 >>= 1;
9886       }
9887    */
9888    p = s390_emit_LTGR(p, R0, r2);
9889    p = s390_emit_LLILL(p, r1,  64);
9890 
9891    p = s390_emit_BRC(p, S390_CC_E, (4 + 4 + 6 + 4 + 4)/ 2);  /* 4 bytes */
9892    p = s390_emit_AGHI(p, r1, (UShort)-1);         /* r1  -= 1;  4 bytes */
9893    p = s390_emit_SRLG(p, R0, R0, R0, DISP20(1));  /* r0 >>= 1;  6 bytes */
9894    p = s390_emit_LTGR(p, R0, R0);                 /* set cc     4 bytes */
9895    p = s390_emit_BRC(p, S390_CC_NE,               /*            4 bytes */
9896                      (UShort)(-(4 + 6 + 4) / 2));
9897    return p;
9898 
9899  fail:
9900    vpanic("s390_insn_clz_emit");
9901 }
9902 
9903 
9904 /* Returns a value == BUF to denote failure, != BUF to denote success. */
9905 static UChar *
s390_insn_helper_call_emit(UChar * buf,const s390_insn * insn)9906 s390_insn_helper_call_emit(UChar *buf, const s390_insn *insn)
9907 {
9908    s390_cc_t cond;
9909    ULong target;
9910    Int delta;
9911    s390_helper_call *helper_call = insn->variant.helper_call.details;
9912 
9913    cond = helper_call->cond;
9914    target = helper_call->target;
9915 
9916    const Bool not_always = (cond != S390_CC_ALWAYS);
9917    const Bool not_void_return = (helper_call->rloc.pri != RLPri_None);
9918 
9919    /* We have this situation:
9920       ( *** code in this braces is for  not_always && not_void_return*** )
9921          ...
9922          before:
9923            brc{!cond} else
9924            call_helper
9925          preElse:
9926          ***  j after ***
9927          else:
9928          *** load_64imm $0x5555555555555555, %%r2  *** // e.g. for Int RetLoc
9929          after:
9930          ...
9931    */
9932 
9933    // before:
9934    UChar *pBefore = buf;
9935    if (not_always) {
9936       /* 4 bytes (a BRC insn) to be filled in here */
9937       buf += 4;
9938    }
9939 
9940    // call_helper
9941    /* Load the target address into a register, that
9942       (a) is not used for passing parameters to the helper and
9943       (b) can be clobbered by the callee
9944       (c) is not special to the BASR insn
9945       r1 is the only choice.
9946       Also, need to arrange for the return address be put into the
9947       link-register */
9948    buf = s390_emit_load_64imm(buf, 1, target);
9949 
9950    /* Stash away the client's FPC register because the helper might change it. */
9951    buf = s390_emit_STFPC(buf, S390_REGNO_STACK_POINTER, S390_OFFSET_SAVED_FPC_C);
9952 
9953    buf = s390_emit_BASR(buf, S390_REGNO_LINK_REGISTER, 1);      // call helper
9954 
9955    buf = s390_emit_LFPC(buf, S390_REGNO_STACK_POINTER,          // restore FPC
9956                         S390_OFFSET_SAVED_FPC_C);
9957 
9958    // preElse:
9959    UChar* pPreElse = buf;
9960    if (not_always && not_void_return) {
9961       /* 4 bytes (a BRC insn) to be filled in here */
9962       buf += 4;
9963    }
9964 
9965    // else:
9966    UChar* pElse = buf;
9967    if (not_always && not_void_return) {
9968       switch (helper_call->rloc.pri) {
9969       case RLPri_Int:
9970          buf = s390_emit_load_64imm(buf, S390_REGNO_RETURN_VALUE, 0x5555555555555555ULL);
9971          break;
9972       default:
9973          ppS390Instr(insn, True);
9974          vpanic("s390_insn_helper_call_emit: invalid conditional RetLoc.");
9975       }
9976    }
9977 
9978    // after:
9979    UChar* pAfter = buf;
9980 
9981    // fill "brc{!cond} else"
9982    if(not_always)
9983    {
9984       delta = pElse - pBefore;
9985       delta >>= 1;  /* immediate constant is #half-words */
9986       vassert(delta > 0 && delta < (1 << 16));
9987       s390_emit_BRC(pBefore, s390_cc_invert(cond), delta);
9988    }
9989 
9990    // fill "brc{ALWAYS} after"
9991    if (not_always && not_void_return)
9992    {
9993       delta = pAfter - pPreElse;
9994       delta >>= 1;  /* immediate constant is #half-words */
9995       vassert(delta > 0 && delta < (1 << 16));
9996       s390_emit_BRC(pPreElse, S390_CC_ALWAYS, delta);
9997    }
9998 
9999    return buf;
10000 }
10001 
10002 
10003 static UChar *
s390_insn_cond_move_emit(UChar * buf,const s390_insn * insn)10004 s390_insn_cond_move_emit(UChar *buf, const s390_insn *insn)
10005 {
10006    HReg dst;
10007    s390_opnd_RMI src;
10008    s390_cc_t cond;
10009    UChar *p, *ptmp = 0;   /* avoid compiler warnings */
10010 
10011    cond = insn->variant.cond_move.cond;
10012    dst  = insn->variant.cond_move.dst;
10013    src  = insn->variant.cond_move.src;
10014 
10015    if (cond == S390_CC_NEVER) return buf;
10016 
10017    p = buf;
10018 
10019    if (s390_host_has_lsc) {
10020       /* LOCx is not the preferred way to implement an unconditional load. */
10021       if (cond != S390_CC_ALWAYS) goto use_branch_insn;
10022 
10023       switch (src.tag) {
10024       case S390_OPND_REG:
10025          return s390_emit_LOCGR(p, cond, hregNumber(dst),
10026                                 hregNumber(src.variant.reg));
10027 
10028       case S390_OPND_AMODE: {
10029          const s390_amode *am = src.variant.am;
10030 
10031          /* We cannot use LOCx for loads less than 4 bytes. In that case
10032             load into R0 and then use LOCGR. Do the same if the amode uses
10033             an index register. */
10034          if (insn->size < 4 ||
10035              am->tag == S390_AMODE_BX12 || am->tag == S390_AMODE_BX20) {
10036             p = s390_emit_load_mem(p, insn->size, R0, am);
10037             p = s390_emit_LOCGR(p, cond, hregNumber(dst), R0);
10038             return p;
10039          }
10040 
10041          vassert(am->tag == S390_AMODE_B12 || am->tag == S390_AMODE_B20);
10042          vassert(insn->size == 4 || insn->size == 8);
10043 
10044          UInt b = hregNumber(am->b);
10045          UInt d = am->d;
10046 
10047          if (insn->size == 4) {
10048             return s390_emit_LOC(p, hregNumber(dst), cond, b, DISP20(d));
10049          }
10050          return s390_emit_LOCG(p, hregNumber(dst), cond, b, DISP20(d));
10051       }
10052 
10053       case S390_OPND_IMMEDIATE: {
10054          ULong value = src.variant.imm;
10055 
10056          /* Load value into R0, then use LOCGR */
10057          if (insn->size <= 4) {
10058             p = s390_emit_load_32imm(p, R0, value);
10059             return s390_emit_LOCGR(p, cond, hregNumber(dst), R0);
10060          }
10061 
10062          vassert(insn->size == 8);
10063          p = s390_emit_load_64imm(p, R0, value);
10064          return s390_emit_LOCGR(p, cond, hregNumber(dst), R0);
10065       }
10066       }
10067    }
10068 
10069 use_branch_insn:
10070    /* Branch (if cond fails) over move instrs */
10071    if (cond != S390_CC_ALWAYS) {
10072       /* Don't know how many bytes to jump over yet.
10073          Make space for a BRC instruction (4 bytes) and fill in later. */
10074       ptmp = p;   /*  to be filled in here */
10075       p += 4;
10076    }
10077 
10078    // cond true: move src => dst
10079 
10080    switch (src.tag) {
10081    case S390_OPND_REG:
10082       p = s390_emit_LGR(p, hregNumber(dst), hregNumber(src.variant.reg));
10083       break;
10084 
10085    case S390_OPND_AMODE:
10086       p = s390_emit_load_mem(p, insn->size, hregNumber(dst), src.variant.am);
10087       break;
10088 
10089    case S390_OPND_IMMEDIATE: {
10090       ULong value = src.variant.imm;
10091       UInt  r = hregNumber(dst);
10092 
10093       switch (insn->size) {
10094       case 1:
10095       case 2:
10096          /* Load the immediate values as a 4 byte value. That does not hurt as
10097             those extra bytes will not be looked at. Fall through .... */
10098       case 4:
10099          p = s390_emit_load_32imm(p, r, value);
10100          break;
10101 
10102       case 8:
10103          p = s390_emit_load_64imm(p, r, value);
10104          break;
10105       }
10106       break;
10107    }
10108 
10109    default:
10110       goto fail;
10111    }
10112 
10113    if (cond != S390_CC_ALWAYS) {
10114       Int delta = p - ptmp;
10115 
10116       delta >>= 1;  /* immediate constant is #half-words */
10117       vassert(delta > 0 && delta < (1 << 16));
10118       s390_emit_BRC(ptmp, s390_cc_invert(cond), delta);
10119    }
10120 
10121    return p;
10122 
10123  fail:
10124    vpanic("s390_insn_cond_move_emit");
10125 }
10126 
10127 
10128 static UChar *
s390_insn_bfp_triop_emit(UChar * buf,const s390_insn * insn)10129 s390_insn_bfp_triop_emit(UChar *buf, const s390_insn *insn)
10130 {
10131    UInt r1 = hregNumber(insn->variant.bfp_triop.dst);
10132    UInt r2 = hregNumber(insn->variant.bfp_triop.op2);
10133    UInt r3 = hregNumber(insn->variant.bfp_triop.op3);
10134 
10135    switch (insn->size) {
10136    case 4:
10137       switch (insn->variant.bfp_triop.tag) {
10138       case S390_BFP_MADD:  return s390_emit_MAEBR(buf, r1, r3, r2);
10139       case S390_BFP_MSUB:  return s390_emit_MSEBR(buf, r1, r3, r2);
10140       default:  goto fail;
10141       }
10142       break;
10143 
10144    case 8:
10145       switch (insn->variant.bfp_triop.tag) {
10146       case S390_BFP_MADD:  return s390_emit_MADBR(buf, r1, r3, r2);
10147       case S390_BFP_MSUB:  return s390_emit_MSDBR(buf, r1, r3, r2);
10148       default:  goto fail;
10149       }
10150       break;
10151 
10152    default:  goto fail;
10153    }
10154 
10155  fail:
10156    vpanic("s390_insn_bfp_triop_emit");
10157 }
10158 
10159 
10160 static UChar *
s390_insn_bfp_binop_emit(UChar * buf,const s390_insn * insn)10161 s390_insn_bfp_binop_emit(UChar *buf, const s390_insn *insn)
10162 {
10163    UInt r1 = hregNumber(insn->variant.bfp_binop.dst_hi);
10164    UInt r2 = hregNumber(insn->variant.bfp_binop.op2_hi);
10165 
10166    switch (insn->size) {
10167    case 4:
10168       switch (insn->variant.bfp_binop.tag) {
10169       case S390_BFP_ADD:     return s390_emit_AEBR(buf, r1, r2);
10170       case S390_BFP_SUB:     return s390_emit_SEBR(buf, r1, r2);
10171       case S390_BFP_MUL:     return s390_emit_MEEBR(buf, r1, r2);
10172       case S390_BFP_DIV:     return s390_emit_DEBR(buf, r1, r2);
10173       default:  goto fail;
10174       }
10175       break;
10176 
10177    case 8:
10178       switch (insn->variant.bfp_binop.tag) {
10179       case S390_BFP_ADD:     return s390_emit_ADBR(buf, r1, r2);
10180       case S390_BFP_SUB:     return s390_emit_SDBR(buf, r1, r2);
10181       case S390_BFP_MUL:     return s390_emit_MDBR(buf, r1, r2);
10182       case S390_BFP_DIV:     return s390_emit_DDBR(buf, r1, r2);
10183       default:  goto fail;
10184       }
10185       break;
10186 
10187    case 16:
10188       switch (insn->variant.bfp_binop.tag) {
10189       case S390_BFP_ADD:     return s390_emit_AXBR(buf, r1, r2);
10190       case S390_BFP_SUB:     return s390_emit_SXBR(buf, r1, r2);
10191       case S390_BFP_MUL:     return s390_emit_MXBR(buf, r1, r2);
10192       case S390_BFP_DIV:     return s390_emit_DXBR(buf, r1, r2);
10193       default:  goto fail;
10194       }
10195       break;
10196 
10197    default:  goto fail;
10198    }
10199 
10200  fail:
10201    vpanic("s390_insn_bfp_binop_emit");
10202 }
10203 
10204 
10205 static UChar *
s390_insn_bfp_unop_emit(UChar * buf,const s390_insn * insn)10206 s390_insn_bfp_unop_emit(UChar *buf, const s390_insn *insn)
10207 {
10208    UInt  r1 = hregNumber(insn->variant.bfp_unop.dst_hi);
10209    UInt  r2 = hregNumber(insn->variant.bfp_unop.op_hi);
10210 
10211    switch (insn->variant.bfp_unop.tag) {
10212    case S390_BFP_ABS:
10213       switch (insn->size) {
10214       case 4:   return s390_emit_LPEBR(buf, r1, r2);
10215       case 8:   return s390_emit_LPDBR(buf, r1, r2);
10216       case 16:  return s390_emit_LPXBR(buf, r1, r2);
10217       default:  goto fail;
10218       }
10219       break;
10220 
10221    case S390_BFP_NABS:
10222       switch (insn->size) {
10223       case 4:   return s390_emit_LNEBR(buf, r1, r2);
10224       case 8:   return s390_emit_LNDBR(buf, r1, r2);
10225       case 16:  return s390_emit_LNXBR(buf, r1, r2);
10226       default:  goto fail;
10227       }
10228       break;
10229 
10230    case S390_BFP_NEG:
10231       switch (insn->size) {
10232       case 4:   return s390_emit_LCEBR(buf, r1, r2);
10233       case 8:   return s390_emit_LCDBR(buf, r1, r2);
10234       case 16:  return s390_emit_LCXBR(buf, r1, r2);
10235       default:  goto fail;
10236       }
10237       break;
10238 
10239    case S390_BFP_SQRT:
10240       switch (insn->size) {
10241       case 4:   return s390_emit_SQEBR(buf, r1, r2);
10242       case 8:   return s390_emit_SQDBR(buf, r1, r2);
10243       case 16:  return s390_emit_SQXBR(buf, r1, r2);
10244       default:  goto fail;
10245       }
10246       break;
10247 
10248    default: goto fail;
10249    }
10250 
10251  fail:
10252    vpanic("s390_insn_bfp_unop_emit");
10253 }
10254 
10255 
10256 static UChar *
s390_insn_bfp_convert_emit(UChar * buf,const s390_insn * insn)10257 s390_insn_bfp_convert_emit(UChar *buf, const s390_insn *insn)
10258 {
10259    UInt  r1 = hregNumber(insn->variant.bfp_convert.dst_hi);
10260    UInt  r2 = hregNumber(insn->variant.bfp_convert.op_hi);
10261    s390_bfp_round_t m3 = insn->variant.bfp_convert.rounding_mode;
10262    /* The IEEE-inexact-exception control is not modelled. So the
10263       m4 field is 0 (which is what GCC does, too) */
10264    const UInt m4 = 0;
10265 
10266    switch (insn->variant.bfp_convert.tag) {
10267       /* Convert to fixed */
10268    case S390_BFP_F32_TO_I32:  return s390_emit_CFEBR(buf, m3, r1, r2);
10269    case S390_BFP_F64_TO_I32:  return s390_emit_CFDBR(buf, m3, r1, r2);
10270    case S390_BFP_F128_TO_I32: return s390_emit_CFXBR(buf, m3, r1, r2);
10271    case S390_BFP_F32_TO_I64:  return s390_emit_CGEBR(buf, m3, r1, r2);
10272    case S390_BFP_F64_TO_I64:  return s390_emit_CGDBR(buf, m3, r1, r2);
10273    case S390_BFP_F128_TO_I64: return s390_emit_CGXBR(buf, m3, r1, r2);
10274 
10275       /* Convert to logical */
10276    case S390_BFP_F32_TO_U32:  return s390_emit_CLFEBR(buf, m3, m4, r1, r2);
10277    case S390_BFP_F64_TO_U32:  return s390_emit_CLFDBR(buf, m3, m4, r1, r2);
10278    case S390_BFP_F128_TO_U32: return s390_emit_CLFXBR(buf, m3, m4, r1, r2);
10279    case S390_BFP_F32_TO_U64:  return s390_emit_CLGEBR(buf, m3, m4, r1, r2);
10280    case S390_BFP_F64_TO_U64:  return s390_emit_CLGDBR(buf, m3, m4, r1, r2);
10281    case S390_BFP_F128_TO_U64: return s390_emit_CLGXBR(buf, m3, m4, r1, r2);
10282 
10283       /* Convert from fixed */
10284    case S390_BFP_I32_TO_F32:  return s390_emit_CEFBRA(buf, m3, m4, r1, r2);
10285    case S390_BFP_I32_TO_F64:  return s390_emit_CDFBRA(buf,  0, m4, r1, r2);
10286    case S390_BFP_I32_TO_F128: return s390_emit_CXFBRA(buf,  0, m4, r1, r2);
10287    case S390_BFP_I64_TO_F32:  return s390_emit_CEGBRA(buf, m3, m4, r1, r2);
10288    case S390_BFP_I64_TO_F64:  return s390_emit_CDGBRA(buf, m3, m4, r1, r2);
10289    case S390_BFP_I64_TO_F128: return s390_emit_CXGBRA(buf,  0, m4, r1, r2);
10290 
10291       /* Convert from logical */
10292    case S390_BFP_U32_TO_F32:  return s390_emit_CELFBR(buf, m3, m4, r1, r2);
10293    case S390_BFP_U32_TO_F64:  return s390_emit_CDLFBR(buf, m3, m4, r1, r2);
10294    case S390_BFP_U32_TO_F128: return s390_emit_CXLFBR(buf, m3, m4, r1, r2);
10295    case S390_BFP_U64_TO_F32:  return s390_emit_CELGBR(buf, m3, m4, r1, r2);
10296    case S390_BFP_U64_TO_F64:  return s390_emit_CDLGBR(buf, m3, m4, r1, r2);
10297    case S390_BFP_U64_TO_F128: return s390_emit_CXLGBR(buf, m3, m4, r1, r2);
10298 
10299       /* Load lengthened */
10300    case S390_BFP_F32_TO_F64:  return s390_emit_LDEBR(buf, r1, r2);
10301    case S390_BFP_F32_TO_F128: return s390_emit_LXEBR(buf, r1, r2);
10302    case S390_BFP_F64_TO_F128: return s390_emit_LXDBR(buf, r1, r2);
10303 
10304       /* Load rounded */
10305    case S390_BFP_F64_TO_F32:  return s390_emit_LEDBRA(buf, m3, m4, r1, r2);
10306    case S390_BFP_F128_TO_F32: return s390_emit_LEXBRA(buf, m3, m4, r1, r2);
10307    case S390_BFP_F128_TO_F64: return s390_emit_LDXBRA(buf, m3, m4, r1, r2);
10308 
10309       /* Load FP integer */
10310    case S390_BFP_F32_TO_F32I: return s390_emit_FIEBRA(buf, m3, m4, r1, r2);
10311    case S390_BFP_F64_TO_F64I: return s390_emit_FIDBRA(buf, m3, m4, r1, r2);
10312    case S390_BFP_F128_TO_F128I: return s390_emit_FIXBRA(buf, m3, m4, r1, r2);
10313 
10314    default: goto fail;
10315    }
10316 
10317  fail:
10318    vpanic("s390_insn_bfp_convert_emit");
10319 }
10320 
10321 
10322 static UChar *
s390_insn_bfp_compare_emit(UChar * buf,const s390_insn * insn)10323 s390_insn_bfp_compare_emit(UChar *buf, const s390_insn *insn)
10324 {
10325    UInt dst = hregNumber(insn->variant.bfp_compare.dst);
10326    UInt r1  = hregNumber(insn->variant.bfp_compare.op1_hi);
10327    UInt r2  = hregNumber(insn->variant.bfp_compare.op2_hi);
10328 
10329    switch (insn->size) {
10330    case 4:  buf = s390_emit_CEBR(buf, r1, r2); break;
10331    case 8:  buf = s390_emit_CDBR(buf, r1, r2); break;
10332    case 16: buf = s390_emit_CXBR(buf, r1, r2); break;
10333    default:  goto fail;
10334    }
10335 
10336    return s390_emit_load_cc(buf, dst);  /* Load condition code into DST */
10337 
10338  fail:
10339    vpanic("s390_insn_bfp_compare_emit");
10340 }
10341 
10342 
10343 static UChar *
s390_insn_dfp_binop_emit(UChar * buf,const s390_insn * insn)10344 s390_insn_dfp_binop_emit(UChar *buf, const s390_insn *insn)
10345 {
10346    s390_dfp_binop *dfp_binop = insn->variant.dfp_binop.details;
10347 
10348    UInt r1 = hregNumber(dfp_binop->dst_hi);
10349    UInt r2 = hregNumber(dfp_binop->op2_hi);
10350    UInt r3 = hregNumber(dfp_binop->op3_hi);
10351    s390_dfp_round_t m4 = dfp_binop->rounding_mode;
10352 
10353    switch (insn->size) {
10354    case 8:
10355       switch (dfp_binop->tag) {
10356       case S390_DFP_ADD: return s390_emit_ADTRA(buf, r3, m4, r1, r2);
10357       case S390_DFP_SUB: return s390_emit_SDTRA(buf, r3, m4, r1, r2);
10358       case S390_DFP_MUL: return s390_emit_MDTRA(buf, r3, m4, r1, r2);
10359       case S390_DFP_DIV: return s390_emit_DDTRA(buf, r3, m4, r1, r2);
10360       case S390_DFP_QUANTIZE: return s390_emit_QADTR(buf, r3, m4, r1, r2);
10361       default:  goto fail;
10362       }
10363       break;
10364 
10365    case 16:
10366       switch (dfp_binop->tag) {
10367       case S390_DFP_ADD:     return s390_emit_AXTRA(buf, r3, m4, r1, r2);
10368       case S390_DFP_SUB:     return s390_emit_SXTRA(buf, r3, m4, r1, r2);
10369       case S390_DFP_MUL:     return s390_emit_MXTRA(buf, r3, m4, r1, r2);
10370       case S390_DFP_DIV:     return s390_emit_DXTRA(buf, r3, m4, r1, r2);
10371       case S390_DFP_QUANTIZE: return s390_emit_QAXTR(buf, r3, m4, r1, r2);
10372       default:  goto fail;
10373       }
10374       break;
10375 
10376    default:  goto fail;
10377    }
10378 
10379  fail:
10380    vpanic("s390_insn_dfp_binop_emit");
10381 }
10382 
10383 
10384 static UChar *
s390_insn_dfp_reround_emit(UChar * buf,const s390_insn * insn)10385 s390_insn_dfp_reround_emit(UChar *buf, const s390_insn *insn)
10386 {
10387    UInt r1 = hregNumber(insn->variant.dfp_reround.dst_hi);
10388    UInt r2 = hregNumber(insn->variant.dfp_reround.op2);
10389    UInt r3 = hregNumber(insn->variant.dfp_reround.op3_hi);
10390    s390_dfp_round_t m4 = insn->variant.dfp_reround.rounding_mode;
10391 
10392    switch (insn->size) {
10393    case 8:
10394       return s390_emit_RRDTR(buf, r3, m4, r1, r2);
10395 
10396    case 16:
10397       return s390_emit_RRXTR(buf, r3, m4, r1, r2);
10398 
10399    default: goto fail;
10400    }
10401  fail:
10402    vpanic("s390_insn_dfp_reround_emit");
10403 }
10404 
10405 
10406 static UChar *
s390_insn_dfp_unop_emit(UChar * buf,const s390_insn * insn)10407 s390_insn_dfp_unop_emit(UChar *buf, const s390_insn *insn)
10408 {
10409    UInt  r1 = hregNumber(insn->variant.dfp_unop.dst_hi);
10410    UInt  r2 = hregNumber(insn->variant.dfp_unop.op_hi);
10411 
10412    switch (insn->variant.dfp_unop.tag) {
10413    case S390_DFP_EXTRACT_EXP_D64:  return s390_emit_EEDTR(buf, r1, r2); break;
10414    case S390_DFP_EXTRACT_EXP_D128: return s390_emit_EEXTR(buf, r1, r2); break;
10415    case S390_DFP_EXTRACT_SIG_D64:  return s390_emit_ESDTR(buf, r1, r2); break;
10416    case S390_DFP_EXTRACT_SIG_D128: return s390_emit_ESXTR(buf, r1, r2); break;
10417    default: goto fail;
10418    }
10419  fail:
10420    vpanic("s390_insn_dfp_unop_emit");
10421 }
10422 
10423 
10424 static UChar *
s390_insn_dfp_intop_emit(UChar * buf,const s390_insn * insn)10425 s390_insn_dfp_intop_emit(UChar *buf, const s390_insn *insn)
10426 {
10427    UInt r1 = hregNumber(insn->variant.dfp_intop.dst_hi);
10428    UInt r2 = hregNumber(insn->variant.dfp_intop.op2);
10429    UInt r3 = hregNumber(insn->variant.dfp_intop.op3_hi);
10430 
10431    switch (insn->size) {
10432    case 8:
10433       switch (insn->variant.dfp_intop.tag) {
10434       case S390_DFP_SHIFT_LEFT:  return s390_emit_SLDT(buf, r3, r1, r2);
10435       case S390_DFP_SHIFT_RIGHT: return s390_emit_SRDT(buf, r3, r1, r2);
10436       case S390_DFP_INSERT_EXP:  return s390_emit_IEDTR(buf, r3, r1, r2);
10437       default:  goto fail;
10438       }
10439       break;
10440 
10441    case 16:
10442       switch (insn->variant.dfp_intop.tag) {
10443       case S390_DFP_SHIFT_LEFT:  return s390_emit_SLXT(buf, r3, r1, r2);
10444       case S390_DFP_SHIFT_RIGHT: return s390_emit_SRXT(buf, r3, r1, r2);
10445       case S390_DFP_INSERT_EXP:  return s390_emit_IEXTR(buf, r3, r1, r2);
10446       default:  goto fail;
10447       }
10448       break;
10449 
10450    default: goto fail;
10451    }
10452 
10453  fail:
10454    vpanic("s390_insn_dfp_intop_emit");
10455 }
10456 
10457 
10458 static UChar *
s390_insn_dfp_compare_emit(UChar * buf,const s390_insn * insn)10459 s390_insn_dfp_compare_emit(UChar *buf, const s390_insn *insn)
10460 {
10461    UInt dst = hregNumber(insn->variant.dfp_compare.dst);
10462    UInt r1  = hregNumber(insn->variant.dfp_compare.op1_hi);
10463    UInt r2  = hregNumber(insn->variant.dfp_compare.op2_hi);
10464 
10465    switch (insn->size) {
10466    case 8:
10467       switch(insn->variant.dfp_compare.tag) {
10468       case S390_DFP_COMPARE:     buf = s390_emit_CDTR(buf, r1, r2); break;
10469       case S390_DFP_COMPARE_EXP: buf = s390_emit_CEDTR(buf, r1, r2); break;
10470       default: goto fail;
10471       }
10472       break;
10473 
10474    case 16:
10475       switch(insn->variant.dfp_compare.tag) {
10476       case S390_DFP_COMPARE:     buf = s390_emit_CXTR(buf, r1, r2); break;
10477       case S390_DFP_COMPARE_EXP: buf = s390_emit_CEXTR(buf, r1, r2); break;
10478       default: goto fail;
10479       }
10480       break;
10481 
10482    default:  goto fail;
10483    }
10484 
10485    return s390_emit_load_cc(buf, dst);  /* Load condition code into DST */
10486 
10487  fail:
10488    vpanic("s390_insn_dfp_compare_emit");
10489 }
10490 
10491 
10492 static UChar *
s390_insn_dfp_convert_emit(UChar * buf,const s390_insn * insn)10493 s390_insn_dfp_convert_emit(UChar *buf, const s390_insn *insn)
10494 {
10495    UInt  r1 = hregNumber(insn->variant.dfp_convert.dst_hi);
10496    UInt  r2 = hregNumber(insn->variant.dfp_convert.op_hi);
10497    s390_dfp_round_t m3 = insn->variant.dfp_convert.rounding_mode;
10498    /* The IEEE-inexact-exception control is not modelled. So the
10499       m4 field is 0 (which is what GCC does, too) */
10500    const UInt m4 = 0;
10501 
10502    switch (insn->variant.dfp_convert.tag) {
10503 
10504       /* Convert to fixed */
10505    case S390_DFP_D64_TO_I32:  return s390_emit_CFDTR(buf, m3, m4, r1, r2);
10506    case S390_DFP_D128_TO_I32: return s390_emit_CFXTR(buf, m3, m4, r1, r2);
10507    case S390_DFP_D64_TO_I64:  return s390_emit_CGDTR(buf, m3, m4, r1, r2);
10508    case S390_DFP_D128_TO_I64: return s390_emit_CGXTR(buf, m3, m4, r1, r2);
10509 
10510       /* Convert to logical */
10511    case S390_DFP_D64_TO_U32:  return s390_emit_CLFDTR(buf, m3, m4, r1, r2);
10512    case S390_DFP_D128_TO_U32: return s390_emit_CLFXTR(buf, m3, m4, r1, r2);
10513    case S390_DFP_D64_TO_U64:  return s390_emit_CLGDTR(buf, m3, m4, r1, r2);
10514    case S390_DFP_D128_TO_U64: return s390_emit_CLGXTR(buf, m3, m4, r1, r2);
10515 
10516       /* Convert from fixed */
10517    case S390_DFP_I32_TO_D64:  return s390_emit_CDFTR(buf, 0, m4, r1, r2);
10518    case S390_DFP_I32_TO_D128: return s390_emit_CXFTR(buf, 0, m4, r1, r2);
10519    case S390_DFP_I64_TO_D64:  return s390_emit_CDGTRA(buf, m3, m4, r1, r2);
10520    case S390_DFP_I64_TO_D128: return s390_emit_CXGTR(buf, 0, m4, r1, r2);
10521 
10522       /* Convert from logical */
10523    case S390_DFP_U32_TO_D64:  return s390_emit_CDLFTR(buf, m3, m4, r1, r2);
10524    case S390_DFP_U64_TO_D64:  return s390_emit_CDLGTR(buf, m3, m4, r1, r2);
10525    case S390_DFP_U32_TO_D128: return s390_emit_CXLFTR(buf, m3, m4, r1, r2);
10526    case S390_DFP_U64_TO_D128: return s390_emit_CXLGTR(buf, m3, m4, r1, r2);
10527 
10528       /* Load lengthened */
10529    case S390_DFP_D32_TO_D64:   return s390_emit_LDETR(buf, m4, r1, r2);
10530    case S390_DFP_D64_TO_D128:  return s390_emit_LXDTR(buf, m4, r1, r2);
10531 
10532       /* Load rounded */
10533    case S390_DFP_D64_TO_D32:   return s390_emit_LEDTR(buf, m3, m4, r1, r2);
10534    case S390_DFP_D128_TO_D64:  return s390_emit_LDXTR(buf, m3, m4, r1, r2);
10535 
10536    default: goto fail;
10537    }
10538 
10539  fail:
10540    vpanic("s390_insn_dfp_convert_emit");
10541 }
10542 
10543 
10544 static UChar *
s390_insn_fp_convert_emit(UChar * buf,const s390_insn * insn)10545 s390_insn_fp_convert_emit(UChar *buf, const s390_insn *insn)
10546 {
10547    UInt pfpo;
10548    s390_fp_convert *fp_convert = insn->variant.fp_convert.details;
10549    s390_dfp_round_t rm = fp_convert->rounding_mode;
10550 
10551    vassert(rm < 2 || rm > 7);
10552 
10553    switch (fp_convert->tag) {
10554    case S390_FP_F32_TO_D32:   pfpo = S390_PFPO_F32_TO_D32   << 8; break;
10555    case S390_FP_F32_TO_D64:   pfpo = S390_PFPO_F32_TO_D64   << 8; break;
10556    case S390_FP_F32_TO_D128:  pfpo = S390_PFPO_F32_TO_D128  << 8; break;
10557    case S390_FP_F64_TO_D32:   pfpo = S390_PFPO_F64_TO_D32   << 8; break;
10558    case S390_FP_F64_TO_D64:   pfpo = S390_PFPO_F64_TO_D64   << 8; break;
10559    case S390_FP_F64_TO_D128:  pfpo = S390_PFPO_F64_TO_D128  << 8; break;
10560    case S390_FP_F128_TO_D32:  pfpo = S390_PFPO_F128_TO_D32  << 8; break;
10561    case S390_FP_F128_TO_D64:  pfpo = S390_PFPO_F128_TO_D64  << 8; break;
10562    case S390_FP_F128_TO_D128: pfpo = S390_PFPO_F128_TO_D128 << 8; break;
10563    case S390_FP_D32_TO_F32:   pfpo = S390_PFPO_D32_TO_F32   << 8; break;
10564    case S390_FP_D32_TO_F64:   pfpo = S390_PFPO_D32_TO_F64   << 8; break;
10565    case S390_FP_D32_TO_F128:  pfpo = S390_PFPO_D32_TO_F128  << 8; break;
10566    case S390_FP_D64_TO_F32:   pfpo = S390_PFPO_D64_TO_F32   << 8; break;
10567    case S390_FP_D64_TO_F64:   pfpo = S390_PFPO_D64_TO_F64   << 8; break;
10568    case S390_FP_D64_TO_F128:  pfpo = S390_PFPO_D64_TO_F128  << 8; break;
10569    case S390_FP_D128_TO_F32:  pfpo = S390_PFPO_D128_TO_F32  << 8; break;
10570    case S390_FP_D128_TO_F64:  pfpo = S390_PFPO_D128_TO_F64  << 8; break;
10571    case S390_FP_D128_TO_F128: pfpo = S390_PFPO_D128_TO_F128 << 8; break;
10572    default: goto fail;
10573    }
10574 
10575    pfpo = pfpo | rm;
10576    buf = s390_emit_load_32imm(buf, R0, pfpo);
10577    buf = s390_emit_PFPO(buf);
10578    return buf;
10579 
10580  fail:
10581    vpanic("s390_insn_fp_convert_emit");
10582 }
10583 
10584 
10585 static UChar *
s390_insn_mfence_emit(UChar * buf,const s390_insn * insn)10586 s390_insn_mfence_emit(UChar *buf, const s390_insn *insn)
10587 {
10588    return s390_emit_BCR(buf, 0xF, 0x0);
10589 }
10590 
10591 
10592 static UChar *
s390_insn_mimm_emit(UChar * buf,const s390_insn * insn)10593 s390_insn_mimm_emit(UChar *buf, const s390_insn *insn)
10594 {
10595    s390_amode *am = insn->variant.mimm.dst;
10596    UChar b = hregNumber(am->b);
10597    Int   d = am->d;
10598    ULong value = insn->variant.mimm.value;
10599 
10600    if (value == 0) {
10601       return s390_emit_XC(buf, insn->size - 1, b, d, b, d);
10602    }
10603 
10604    if (insn->size == 1) {
10605       return s390_emit_MVI(buf, value & 0xFF, b, d);
10606    }
10607 
10608    if (s390_host_has_gie && ulong_fits_signed_16bit(value)) {
10609       value &= 0xFFFF;
10610       switch (insn->size) {
10611       case 2: return s390_emit_MVHHI(buf, b, d, value);
10612       case 4: return s390_emit_MVHI(buf,  b, d, value);
10613       case 8: return s390_emit_MVGHI(buf, b, d, value);
10614       }
10615    } else {
10616       // Load value to R0, then store.
10617       switch (insn->size) {
10618       case 2:
10619          buf = s390_emit_LHI(buf, R0, value & 0xFFFF);
10620          return s390_emit_STH(buf, R0, 0, b, d);
10621       case 4:
10622          buf = s390_emit_load_32imm(buf, R0, value);
10623          return s390_emit_ST(buf, R0, 0, b, d);
10624       case 8:
10625          buf = s390_emit_load_64imm(buf, R0, value);
10626          return s390_emit_STG(buf, R0, 0, b, DISP20(d));
10627       }
10628    }
10629 
10630    vpanic("s390_insn_mimm_emit");
10631 }
10632 
10633 
10634 static UChar *
s390_insn_madd_emit(UChar * buf,const s390_insn * insn)10635 s390_insn_madd_emit(UChar *buf, const s390_insn *insn)
10636 {
10637    s390_amode *am = insn->variant.madd.dst;
10638    UChar b = hregNumber(am->b);
10639    Int   d = am->d;
10640 
10641    if (insn->size == 4) {
10642       return s390_emit_ASI(buf, insn->variant.madd.delta, b, DISP20(d));
10643    }
10644 
10645    return s390_emit_AGSI(buf, insn->variant.madd.delta, b, DISP20(d));
10646 }
10647 
10648 
10649 static UChar *
s390_insn_set_fpc_bfprm_emit(UChar * buf,const s390_insn * insn)10650 s390_insn_set_fpc_bfprm_emit(UChar *buf, const s390_insn *insn)
10651 {
10652    UInt mode = hregNumber(insn->variant.set_fpc_bfprm.mode);
10653 
10654    /* Copy FPC from guest state to R0 and OR in the new rounding mode */
10655    buf = s390_emit_L(buf, R0, 0, S390_REGNO_GUEST_STATE_POINTER,
10656                      S390X_GUEST_OFFSET(guest_fpc));   // r0 = guest_fpc
10657 
10658    buf = s390_emit_NILL(buf, R0, 0xFFF8); /* Clear out right-most 3 bits */
10659    buf = s390_emit_OR(buf, R0, mode);     /* OR in the new rounding mode */
10660    buf = s390_emit_SFPC(buf, R0);         /* Load FPC register from R0 */
10661 
10662    return buf;
10663 }
10664 
10665 
10666 static UChar *
s390_insn_set_fpc_dfprm_emit(UChar * buf,const s390_insn * insn)10667 s390_insn_set_fpc_dfprm_emit(UChar *buf, const s390_insn *insn)
10668 {
10669    UInt mode = hregNumber(insn->variant.set_fpc_dfprm.mode);
10670 
10671    /* Copy FPC from guest state to R0 and OR in the new rounding mode */
10672    buf = s390_emit_L(buf, R0, 0, S390_REGNO_GUEST_STATE_POINTER,
10673                      S390X_GUEST_OFFSET(guest_fpc));   // r0 = guest_fpc
10674 
10675    /* DFP rounding mode is set at bit position 25:27 in FPC register */
10676    buf = s390_emit_NILL(buf, R0, 0xFF8F); /* Clear out 25:27 bits */
10677    buf = s390_emit_SLL(buf, mode, 0, 4);  /* bring mode to 25:27 bits */
10678    buf = s390_emit_OR(buf, R0, mode);     /* OR in the new rounding mode */
10679    buf = s390_emit_SFPC(buf, R0);         /* Load FPC register from R0 */
10680 
10681    return buf;
10682 }
10683 
10684 
10685 /* Define convenience functions needed for translation chaining.
10686    Any changes need to be applied to the functions in concert. */
10687 
10688 static __inline__ Bool
s390_insn_is_BRCL(const UChar * p,UChar condition)10689 s390_insn_is_BRCL(const UChar *p, UChar condition)
10690 {
10691    return p[0] == 0xc0 && p[1] == ((condition << 4) | 0x04);
10692 }
10693 
10694 static __inline__ Bool
s390_insn_is_BR(const UChar * p,UChar reg)10695 s390_insn_is_BR(const UChar *p, UChar reg)
10696 {
10697    return p[0] == 0x07 && p[1] == (0xF0 | reg);  /* BCR 15,reg */
10698 }
10699 
10700 
10701 /* The length of the BASR insn */
10702 #define S390_BASR_LEN  2
10703 
10704 
10705 /* Load the 64-bit VALUE into REG. Note that this function must NOT
10706    optimise the generated code by looking at the value. I.e. using
10707    LGHI if value == 0 would be very wrong. */
10708 static UChar *
s390_tchain_load64(UChar * buf,UChar regno,ULong value)10709 s390_tchain_load64(UChar *buf, UChar regno, ULong value)
10710 {
10711    UChar *begin = buf;
10712 
10713    if (s390_host_has_eimm) {
10714       /* Do it in two steps: upper half [0:31] and lower half [32:63] */
10715       buf = s390_emit_IIHF(buf, regno, value >> 32);
10716       buf = s390_emit_IILF(buf, regno, value & 0xFFFFFFFF);
10717    } else {
10718       buf = s390_emit_IILL(buf, regno, value & 0xFFFF);
10719       value >>= 16;
10720       buf = s390_emit_IILH(buf, regno, value & 0xFFFF);
10721       value >>= 16;
10722       buf = s390_emit_IIHL(buf, regno, value & 0xFFFF);
10723       value >>= 16;
10724       buf = s390_emit_IIHH(buf, regno, value & 0xFFFF);
10725    }
10726 
10727    vassert(buf - begin == s390_tchain_load64_len());
10728 
10729    return buf;
10730 }
10731 
10732 /* Return number of bytes generated by s390_tchain_load64 */
10733 static UInt
s390_tchain_load64_len(void)10734 s390_tchain_load64_len(void)
10735 {
10736    if (s390_host_has_eimm) {
10737       return 6 + 6;      /* IIHF + IILF */
10738    }
10739    return 4 + 4 + 4 + 4; /* IIHH + IIHL + IILH + IILL */
10740 }
10741 
10742 /* Verify that CODE is the code sequence generated by s390_tchain_load64
10743    to load VALUE into REGNO. Return pointer to the byte following the
10744    insn sequence. */
10745 static const UChar *
s390_tchain_verify_load64(const UChar * code,UChar regno,ULong value)10746 s390_tchain_verify_load64(const UChar *code, UChar regno, ULong value)
10747 {
10748    UInt regmask = regno << 4;
10749    UInt hw;
10750 
10751    if (s390_host_has_eimm) {
10752       /* Check for IIHF */
10753       vassert(code[0]  ==  0xC0);
10754       vassert(code[1]  == (0x08 | regmask));
10755       vassert(*(const UInt *)&code[2] == (value >> 32));
10756       /* Check for IILF */
10757       vassert(code[6]  ==  0xC0);
10758       vassert(code[7]  == (0x09 | regmask));
10759       vassert(*(const UInt *)&code[8] == (value & 0xFFFFFFFF));
10760    } else {
10761       /* Check for IILL */
10762       hw = value & 0xFFFF;
10763       vassert(code[0]  ==  0xA5);
10764       vassert(code[1]  == (0x03 | regmask));
10765       vassert(code[2]  == (hw >> 8));
10766       vassert(code[3]  == (hw & 0xFF));
10767 
10768       /* Check for IILH */
10769       hw = (value >> 16) & 0xFFFF;
10770       vassert(code[4]  ==  0xA5);
10771       vassert(code[5]  == (0x02 | regmask));
10772       vassert(code[6]  == (hw >> 8));
10773       vassert(code[7]  == (hw & 0xFF));
10774 
10775       /* Check for IIHL */
10776       hw = (value >> 32) & 0xFFFF;
10777       vassert(code[8]  ==  0xA5);
10778       vassert(code[9]  == (0x01 | regmask));
10779       vassert(code[10] == (hw >> 8));
10780       vassert(code[11] == (hw & 0xFF));
10781 
10782       /* Check for IIHH */
10783       hw = (value >> 48) & 0xFFFF;
10784       vassert(code[12] ==  0xA5);
10785       vassert(code[13] == (0x00 | regmask));
10786       vassert(code[14] == (hw >> 8));
10787       vassert(code[15] == (hw & 0xFF));
10788    }
10789 
10790    return code + s390_tchain_load64_len();
10791 }
10792 
10793 /* CODE points to the code sequence as generated by s390_tchain_load64.
10794    Change the loaded value to IMM64. Return pointer to the byte following
10795    the patched code sequence. */
10796 static UChar *
s390_tchain_patch_load64(UChar * code,ULong imm64)10797 s390_tchain_patch_load64(UChar *code, ULong imm64)
10798 {
10799    if (s390_host_has_eimm) {
10800       /* Patch IIHF */
10801       *(UInt *)&code[2] = imm64 >> 32;
10802       /* Patch IILF */
10803       *(UInt *)&code[8] = imm64 & 0xFFFFFFFF;
10804    } else {
10805       code[3]  = imm64 & 0xFF; imm64 >>= 8;
10806       code[2]  = imm64 & 0xFF; imm64 >>= 8;
10807       code[7]  = imm64 & 0xFF; imm64 >>= 8;
10808       code[6]  = imm64 & 0xFF; imm64 >>= 8;
10809       code[11] = imm64 & 0xFF; imm64 >>= 8;
10810       code[10] = imm64 & 0xFF; imm64 >>= 8;
10811       code[15] = imm64 & 0xFF; imm64 >>= 8;
10812       code[14] = imm64 & 0xFF; imm64 >>= 8;
10813    }
10814 
10815    return code + s390_tchain_load64_len();
10816 }
10817 
10818 
10819 /* NB: what goes on here has to be very closely coordinated with the
10820    chainXDirect_S390 and unchainXDirect_S390 below. */
10821 static UChar *
s390_insn_xdirect_emit(UChar * buf,const s390_insn * insn,const void * disp_cp_chain_me_to_slowEP,const void * disp_cp_chain_me_to_fastEP)10822 s390_insn_xdirect_emit(UChar *buf, const s390_insn *insn,
10823                        const void *disp_cp_chain_me_to_slowEP,
10824                        const void *disp_cp_chain_me_to_fastEP)
10825 {
10826    /* We're generating chain-me requests here, so we need to be
10827       sure this is actually allowed -- no-redir translations can't
10828       use chain-me's.  Hence: */
10829    vassert(disp_cp_chain_me_to_slowEP != NULL);
10830    vassert(disp_cp_chain_me_to_fastEP != NULL);
10831 
10832    /* Use ptmp for backpatching conditional jumps. */
10833    UChar *ptmp = buf;
10834 
10835    /* First off, if this is conditional, create a conditional
10836       jump over the rest of it. */
10837    s390_cc_t cond = insn->variant.xdirect.cond;
10838 
10839    if (cond != S390_CC_ALWAYS) {
10840       /* So we have something like this
10841          if (cond) do_xdirect;
10842          Y: ...
10843          We convert this into
10844          if (! cond) goto Y;        // BRC opcode; 4 bytes
10845          do_xdirect;
10846          Y:
10847       */
10848       /* 4 bytes (a BRC insn) to be filled in here */
10849       buf += 4;
10850    }
10851 
10852    /* Update the guest IA. */
10853    buf = s390_emit_load_64imm(buf, R0, insn->variant.xdirect.dst);
10854 
10855    const s390_amode *amode = insn->variant.xdirect.guest_IA;
10856    vassert(amode->tag == S390_AMODE_B12);
10857    UInt b = hregNumber(amode->b);
10858    UInt d = amode->d;
10859 
10860    buf = s390_emit_STG(buf, R0, 0, b, DISP20(d));
10861 
10862    /* Load the chosen entry point into the scratch reg */
10863    const void *disp_cp_chain_me;
10864 
10865    disp_cp_chain_me =
10866       insn->variant.xdirect.to_fast_entry ? disp_cp_chain_me_to_fastEP
10867                                           : disp_cp_chain_me_to_slowEP;
10868    /* Get the address of the beginning of the load64 code sequence into %r1.
10869       Do not change the register! This is part of the protocol with the
10870       dispatcher. */
10871    buf = s390_emit_BASR(buf, 1, R0);
10872 
10873    /* --- FIRST PATCHABLE BYTE follows (must not modify %r1) --- */
10874    Addr64 addr = (Addr)disp_cp_chain_me;
10875    buf = s390_tchain_load64(buf, S390_REGNO_TCHAIN_SCRATCH, addr);
10876 
10877    /* goto *tchain_scratch */
10878    buf = s390_emit_BCR(buf, S390_CC_ALWAYS, S390_REGNO_TCHAIN_SCRATCH);
10879 
10880    /* --- END of PATCHABLE BYTES --- */
10881 
10882    /* Fix up the conditional jump, if there was one. */
10883    if (cond != S390_CC_ALWAYS) {
10884       Int delta = buf - ptmp;
10885 
10886       delta >>= 1;  /* immediate constant is #half-words */
10887       vassert(delta > 0 && delta < (1 << 16));
10888       s390_emit_BRC(ptmp, s390_cc_invert(cond), delta);
10889    }
10890 
10891    return buf;
10892 }
10893 
10894 /* Return the number of patchable bytes from an xdirect insn. */
10895 static UInt
s390_xdirect_patchable_len(void)10896 s390_xdirect_patchable_len(void)
10897 {
10898    return s390_tchain_load64_len() + S390_BASR_LEN;
10899 }
10900 
10901 
10902 static UChar *
s390_insn_xindir_emit(UChar * buf,const s390_insn * insn,const void * disp_cp_xindir)10903 s390_insn_xindir_emit(UChar *buf, const s390_insn *insn,
10904                       const void *disp_cp_xindir)
10905 {
10906    /* We're generating transfers that could lead indirectly to a
10907       chain-me, so we need to be sure this is actually allowed --
10908       no-redir translations are not allowed to reach normal
10909       translations without going through the scheduler.  That means
10910       no XDirects or XIndirs out from no-redir translations.
10911       Hence: */
10912    vassert(disp_cp_xindir != NULL);
10913 
10914    /* Use ptmp for backpatching conditional jumps. */
10915    UChar *ptmp = buf;
10916 
10917    /* First off, if this is conditional, create a conditional
10918       jump over the rest of it. */
10919    s390_cc_t cond = insn->variant.xdirect.cond;
10920 
10921    if (cond != S390_CC_ALWAYS) {
10922       /* So we have something like this
10923          if (cond) do_xdirect;
10924          Y: ...
10925          We convert this into
10926          if (! cond) goto Y;        // BRC opcode; 4 bytes
10927          do_xdirect;
10928          Y:
10929       */
10930       /* 4 bytes (a BRC insn) to be filled in here */
10931       buf += 4;
10932    }
10933 
10934    /* Update the guest IA with the address in xdirect.dst. */
10935    const s390_amode *amode = insn->variant.xindir.guest_IA;
10936 
10937    vassert(amode->tag == S390_AMODE_B12);
10938    UInt b = hregNumber(amode->b);
10939    UInt d = amode->d;
10940    UInt regno = hregNumber(insn->variant.xindir.dst);
10941 
10942    buf = s390_emit_STG(buf, regno, 0, b, DISP20(d));
10943 
10944    /* load tchain_scratch, #disp_indir */
10945    buf = s390_tchain_load64(buf, S390_REGNO_TCHAIN_SCRATCH,
10946                             (Addr)disp_cp_xindir);
10947    /* goto *tchain_direct */
10948    buf = s390_emit_BCR(buf, S390_CC_ALWAYS, S390_REGNO_TCHAIN_SCRATCH);
10949 
10950    /* Fix up the conditional jump, if there was one. */
10951    if (cond != S390_CC_ALWAYS) {
10952       Int delta = buf - ptmp;
10953 
10954       delta >>= 1;  /* immediate constant is #half-words */
10955       vassert(delta > 0 && delta < (1 << 16));
10956       s390_emit_BRC(ptmp, s390_cc_invert(cond), delta);
10957    }
10958 
10959    return buf;
10960 }
10961 
10962 static UChar *
s390_insn_xassisted_emit(UChar * buf,const s390_insn * insn,const void * disp_cp_xassisted)10963 s390_insn_xassisted_emit(UChar *buf, const s390_insn *insn,
10964                          const void *disp_cp_xassisted)
10965 {
10966    /* Use ptmp for backpatching conditional jumps. */
10967    UChar *ptmp = buf;
10968 
10969    /* First off, if this is conditional, create a conditional
10970       jump over the rest of it. */
10971    s390_cc_t cond = insn->variant.xdirect.cond;
10972 
10973    if (cond != S390_CC_ALWAYS) {
10974       /* So we have something like this
10975          if (cond) do_xdirect;
10976          Y: ...
10977          We convert this into
10978          if (! cond) goto Y;        // BRC opcode; 4 bytes
10979          do_xdirect;
10980          Y:
10981       */
10982       /* 4 bytes (a BRC insn) to be filled in here */
10983       buf += 4;
10984    }
10985 
10986    /* Update the guest IA with the address in xassisted.dst. */
10987    const s390_amode *amode = insn->variant.xassisted.guest_IA;
10988 
10989    vassert(amode->tag == S390_AMODE_B12);
10990    UInt b = hregNumber(amode->b);
10991    UInt d = amode->d;
10992    UInt regno = hregNumber(insn->variant.xassisted.dst);
10993 
10994    buf = s390_emit_STG(buf, regno, 0, b, DISP20(d));
10995 
10996    UInt trcval = 0;
10997 
10998    switch (insn->variant.xassisted.kind) {
10999    case Ijk_ClientReq:   trcval = VEX_TRC_JMP_CLIENTREQ;   break;
11000    case Ijk_Sys_syscall: trcval = VEX_TRC_JMP_SYS_SYSCALL; break;
11001    case Ijk_Yield:       trcval = VEX_TRC_JMP_YIELD;       break;
11002    case Ijk_EmWarn:      trcval = VEX_TRC_JMP_EMWARN;      break;
11003    case Ijk_EmFail:      trcval = VEX_TRC_JMP_EMFAIL;      break;
11004    case Ijk_MapFail:     trcval = VEX_TRC_JMP_MAPFAIL;     break;
11005    case Ijk_NoDecode:    trcval = VEX_TRC_JMP_NODECODE;    break;
11006    case Ijk_InvalICache: trcval = VEX_TRC_JMP_INVALICACHE; break;
11007    case Ijk_NoRedir:     trcval = VEX_TRC_JMP_NOREDIR;     break;
11008    case Ijk_SigTRAP:     trcval = VEX_TRC_JMP_SIGTRAP;     break;
11009    case Ijk_SigFPE:      trcval = VEX_TRC_JMP_SIGFPE;      break;
11010    case Ijk_SigSEGV:     trcval = VEX_TRC_JMP_SIGSEGV;     break;
11011    case Ijk_Boring:      trcval = VEX_TRC_JMP_BORING;      break;
11012       /* We don't expect to see the following being assisted. */
11013    case Ijk_Ret:
11014    case Ijk_Call:
11015       /* fallthrough */
11016    default:
11017       ppIRJumpKind(insn->variant.xassisted.kind);
11018       vpanic("s390_insn_xassisted_emit: unexpected jump kind");
11019    }
11020 
11021    vassert(trcval != 0);
11022 
11023    /* guest_state_pointer = trcval */
11024    buf = s390_emit_LGHI(buf, S390_REGNO_GUEST_STATE_POINTER, trcval);
11025 
11026    /* load tchain_scratch, #disp_assisted */
11027    buf = s390_tchain_load64(buf, S390_REGNO_TCHAIN_SCRATCH,
11028                             (Addr)disp_cp_xassisted);
11029 
11030    /* goto *tchain_direct */
11031    buf = s390_emit_BCR(buf, S390_CC_ALWAYS, S390_REGNO_TCHAIN_SCRATCH);
11032 
11033    /* Fix up the conditional jump, if there was one. */
11034    if (cond != S390_CC_ALWAYS) {
11035       Int delta = buf - ptmp;
11036 
11037       delta >>= 1;  /* immediate constant is #half-words */
11038       vassert(delta > 0 && delta < (1 << 16));
11039       s390_emit_BRC(ptmp, s390_cc_invert(cond), delta);
11040    }
11041 
11042    return buf;
11043 }
11044 
11045 
11046 /* Pseudo code:
11047 
11048    guest_state[host_EvC_COUNTER] -= 1;
11049    if (guest_state[host_EvC_COUNTER] >= 0) goto nofail;
11050    goto guest_state[host_EvC_FAILADDR];
11051    nofail: ;
11052 
11053    The dispatch counter is a 32-bit value. */
11054 static UChar *
s390_insn_evcheck_emit(UChar * buf,const s390_insn * insn,VexEndness endness_host)11055 s390_insn_evcheck_emit(UChar *buf, const s390_insn *insn,
11056                        VexEndness endness_host)
11057 {
11058    s390_amode *amode;
11059    UInt b, d;
11060    UChar *code_begin, *code_end;
11061 
11062    code_begin = buf;
11063 
11064    amode = insn->variant.evcheck.counter;
11065    vassert(amode->tag == S390_AMODE_B12);
11066    b = hregNumber(amode->b);
11067    d = amode->d;
11068 
11069    /* Decrement the dispatch counter in the guest state */
11070    if (s390_host_has_gie) {
11071       buf = s390_emit_ASI(buf, -1, b, DISP20(d));   /* 6 bytes */
11072    } else {
11073       buf = s390_emit_LHI(buf, R0, -1);             /* 4 bytes */
11074       buf = s390_emit_A(buf, R0, 0, b, d);          /* 4 bytes */
11075       buf = s390_emit_ST(buf, R0, 0, b, d);         /* 4 bytes */
11076    }
11077 
11078    /* Jump over the next insn if >= 0 */
11079    buf = s390_emit_BRC(buf, S390_CC_HE, (4 + 6 + 2) / 2);  /* 4 bytes */
11080 
11081    /* Computed goto to fail_address */
11082    amode = insn->variant.evcheck.fail_addr;
11083    b = hregNumber(amode->b);
11084    d = amode->d;
11085    buf = s390_emit_LG(buf, S390_REGNO_TCHAIN_SCRATCH, 0, b, DISP20(d));  /* 6 bytes */
11086    buf = s390_emit_BCR(buf, S390_CC_ALWAYS, S390_REGNO_TCHAIN_SCRATCH);  /* 2 bytes */
11087 
11088    code_end = buf;
11089 
11090    /* Make sure the size of the generated code is identical to the size
11091       returned by evCheckSzB_S390 */
11092    vassert(evCheckSzB_S390() == code_end - code_begin);
11093 
11094    return buf;
11095 }
11096 
11097 
11098 static UChar *
s390_insn_profinc_emit(UChar * buf,const s390_insn * insn)11099 s390_insn_profinc_emit(UChar *buf,
11100                        const s390_insn *insn __attribute__((unused)))
11101 {
11102    /* Generate a code template to increment a memory location whose
11103       address will be known later as an immediate value. This code
11104       template will be patched once the memory location is known.
11105       For now we do this with address == 0. */
11106    buf = s390_tchain_load64(buf, S390_REGNO_TCHAIN_SCRATCH, 0);
11107    if (s390_host_has_gie) {
11108       buf = s390_emit_AGSI(buf, 1, S390_REGNO_TCHAIN_SCRATCH, DISP20(0));
11109    } else {
11110       buf = s390_emit_LGHI(buf, R0, 1);
11111       buf = s390_emit_AG( buf, R0, 0, S390_REGNO_TCHAIN_SCRATCH, DISP20(0));
11112       buf = s390_emit_STG(buf, R0, 0, S390_REGNO_TCHAIN_SCRATCH, DISP20(0));
11113    }
11114 
11115    return buf;
11116 }
11117 
11118 
11119 static UChar *
s390_insn_vec_amodeop_emit(UChar * buf,const s390_insn * insn)11120 s390_insn_vec_amodeop_emit(UChar *buf, const s390_insn *insn)
11121 {
11122    UChar v1 = hregNumber(insn->variant.vec_amodeop.dst);
11123    UChar v2 = hregNumber(insn->variant.vec_amodeop.op1);
11124    s390_amode* op2 = insn->variant.vec_amodeop.op2;
11125 
11126    vassert(hregNumber(op2->x) == 0);
11127    vassert(fits_unsigned_12bit(op2->d));
11128 
11129    UChar b = hregNumber(op2->b);
11130    UShort d = op2->d;
11131 
11132 
11133    switch (insn->variant.vec_amodeop.tag) {
11134    case S390_VEC_GET_ELEM:
11135       return s390_emit_VLGV(buf, v1, b, d, v2, s390_getM_from_size(insn->size));
11136 
11137    case S390_VEC_ELEM_SHL_INT:
11138       return s390_emit_VESL(buf, v1, b, d, v2, s390_getM_from_size(insn->size));
11139 
11140    case S390_VEC_ELEM_SHRA_INT:
11141       return s390_emit_VESRA(buf, v1, b, d, v2, s390_getM_from_size(insn->size));
11142 
11143    case S390_VEC_ELEM_SHRL_INT:
11144       return s390_emit_VESRL(buf, v1, b, d, v2, s390_getM_from_size(insn->size));
11145 
11146    default:  goto fail;
11147    }
11148 
11149  fail:
11150    vpanic("s390_insn_vec_amodeop_emit");
11151 }
11152 
11153 
11154 static UChar *
s390_insn_vec_amodeintop_emit(UChar * buf,const s390_insn * insn)11155 s390_insn_vec_amodeintop_emit(UChar *buf, const s390_insn *insn)
11156 {
11157    UChar v1 = hregNumber(insn->variant.vec_amodeintop.dst);
11158    s390_amode* op2 = insn->variant.vec_amodeintop.op2;
11159    UChar r3 = hregNumber(insn->variant.vec_amodeintop.op3);
11160 
11161    vassert(hregNumber(op2->x) == 0);
11162    UChar b = hregNumber(op2->b);
11163    UShort d = op2->d;
11164 
11165    switch (insn->variant.vec_amodeintop.tag) {
11166    case S390_VEC_SET_ELEM:
11167       return s390_emit_VLVG(buf, v1, b, d, r3, s390_getM_from_size(insn->size));
11168    default:  goto fail;
11169    }
11170 
11171  fail:
11172    vpanic("s390_insn_vec_amodeop_emit");
11173 }
11174 
11175 
11176 static UChar *
s390_insn_vec_binop_emit(UChar * buf,const s390_insn * insn)11177 s390_insn_vec_binop_emit(UChar *buf, const s390_insn *insn)
11178 {
11179    s390_vec_binop_t tag = insn->variant.vec_binop.tag;
11180    UChar size = insn->size;
11181    UChar v1 = hregNumber(insn->variant.vec_binop.dst);
11182    UChar v2 = hregNumber(insn->variant.vec_binop.op1);
11183    UChar v3 = hregNumber(insn->variant.vec_binop.op2);
11184 
11185    switch (tag) {
11186       case S390_VEC_PACK:
11187          return s390_emit_VPK(buf, v1, v2, v3, s390_getM_from_size(size));
11188       case S390_VEC_PACK_SATURU:
11189          return s390_emit_VPKLS(buf, v1, v2, v3, s390_getM_from_size(size));
11190       case S390_VEC_PACK_SATURS:
11191          return s390_emit_VPKS(buf, v1, v2, v3, s390_getM_from_size(size));
11192       case S390_VEC_COMPARE_EQUAL:
11193          return s390_emit_VCEQ(buf, v1, v2, v3, s390_getM_from_size(size));
11194       case S390_VEC_OR:
11195          return s390_emit_VO(buf, v1, v2, v3);
11196       case S390_VEC_XOR:
11197          return s390_emit_VX(buf, v1, v2, v3);
11198       case S390_VEC_AND:
11199          return s390_emit_VN(buf, v1, v2, v3);
11200       case S390_VEC_MERGEL:
11201          return s390_emit_VMRL(buf, v1, v2, v3, s390_getM_from_size(size));
11202       case S390_VEC_MERGEH:
11203          return s390_emit_VMRH(buf, v1, v2, v3, s390_getM_from_size(size));
11204       case S390_VEC_NOR:
11205          return s390_emit_VNO(buf, v1, v2, v3);
11206       case S390_VEC_INT_ADD:
11207          return s390_emit_VA(buf, v1, v2, v3, s390_getM_from_size(size));
11208       case S390_VEC_INT_SUB:
11209          return s390_emit_VS(buf, v1, v2, v3, s390_getM_from_size(size));
11210       case S390_VEC_MAXU:
11211          return s390_emit_VMXL(buf, v1, v2, v3, s390_getM_from_size(size));
11212       case S390_VEC_MAXS:
11213          return s390_emit_VMX(buf, v1, v2, v3, s390_getM_from_size(size));
11214       case S390_VEC_MINU:
11215          return s390_emit_VMNL(buf, v1, v2, v3, s390_getM_from_size(size));
11216       case S390_VEC_MINS:
11217          return s390_emit_VMN(buf, v1, v2, v3, s390_getM_from_size(size));
11218       case S390_VEC_AVGU:
11219          return s390_emit_VAVGL(buf, v1, v2, v3, s390_getM_from_size(size));
11220       case S390_VEC_AVGS:
11221          return s390_emit_VAVG(buf, v1, v2, v3, s390_getM_from_size(size));
11222       case S390_VEC_COMPARE_GREATERS:
11223          return s390_emit_VCH(buf, v1, v2, v3, s390_getM_from_size(size));
11224       case S390_VEC_COMPARE_GREATERU:
11225          return s390_emit_VCHL(buf, v1, v2, v3, s390_getM_from_size(size));
11226       case S390_VEC_INT_MUL_HIGHS:
11227          return s390_emit_VMH(buf, v1, v2, v3, s390_getM_from_size(size));
11228       case S390_VEC_INT_MUL_HIGHU:
11229          return s390_emit_VMLH(buf, v1, v2, v3, s390_getM_from_size(size));
11230       case S390_VEC_INT_MUL_LOW:
11231          return s390_emit_VML(buf, v1, v2, v3, s390_getM_from_size(size));
11232       case S390_VEC_INT_MUL_EVENS:
11233          return s390_emit_VME(buf, v1, v2, v3, s390_getM_from_size(size));
11234       case S390_VEC_INT_MUL_EVENU:
11235          return s390_emit_VMLE(buf, v1, v2, v3, s390_getM_from_size(size));
11236       case S390_VEC_ELEM_SHL_V:
11237          return s390_emit_VESLV(buf, v1, v2, v3, s390_getM_from_size(size));
11238       case S390_VEC_ELEM_SHRA_V:
11239          return s390_emit_VESRAV(buf, v1, v2, v3, s390_getM_from_size(size));
11240       case S390_VEC_ELEM_SHRL_V:
11241          return s390_emit_VESRLV(buf, v1, v2, v3, s390_getM_from_size(size));
11242       case S390_VEC_ELEM_ROLL_V:
11243          return s390_emit_VERLLV(buf, v1, v2, v3, s390_getM_from_size(size));
11244       case S390_VEC_SHL_BITS:
11245          return s390_emit_VSL(buf, v1, v2, v3);
11246       case S390_VEC_SHRL_BITS:
11247          return s390_emit_VSRL(buf, v1, v2, v3);
11248       case S390_VEC_SHRA_BITS:
11249          return s390_emit_VSRA(buf, v1, v2, v3);
11250       case S390_VEC_SHL_BYTES:
11251          return s390_emit_VSLB(buf, v1, v2, v3);
11252       case S390_VEC_SHRL_BYTES:
11253          return s390_emit_VSRLB(buf, v1, v2, v3);
11254       case S390_VEC_SHRA_BYTES:
11255          return s390_emit_VSRAB(buf, v1, v2, v3);
11256       case S390_VEC_PWSUM_W:
11257          vassert((size == 1) || (size == 2));
11258          return s390_emit_VSUM(buf, v1, v2, v3, s390_getM_from_size(size));
11259       case S390_VEC_PWSUM_DW:
11260          vassert((size == 2) || (size == 4));
11261          return s390_emit_VSUMG(buf, v1, v2, v3, s390_getM_from_size(size));
11262       case S390_VEC_PWSUM_QW:
11263          vassert((size == 4) || (size == 8));
11264          return s390_emit_VSUMQ(buf, v1, v2, v3, s390_getM_from_size(size));
11265       case S390_VEC_INIT_FROM_GPRS:
11266          return s390_emit_VLVGP(buf, v1, v2, v3);
11267       case S390_VEC_FLOAT_ADD:
11268          return s390_emit_VFA(buf, v1, v2, v3, s390_getM_from_size(size), 0);
11269       case S390_VEC_FLOAT_SUB:
11270          return s390_emit_VFS(buf, v1, v2, v3, s390_getM_from_size(size), 0);
11271       case S390_VEC_FLOAT_MUL:
11272          return s390_emit_VFM(buf, v1, v2, v3, s390_getM_from_size(size), 0);
11273       case S390_VEC_FLOAT_DIV:
11274          return s390_emit_VFD(buf, v1, v2, v3, s390_getM_from_size(size), 0);
11275       case S390_VEC_FLOAT_COMPARE_EQUAL:
11276          return s390_emit_VFCE(buf, v1, v2, v3, s390_getM_from_size(size), 0, 0);
11277       case S390_VEC_FLOAT_COMPARE_LESS_OR_EQUAL:
11278          return s390_emit_VFCH(buf, v1, v3, v2, s390_getM_from_size(size), 0, 0);
11279       case S390_VEC_FLOAT_COMPARE_LESS:
11280          return s390_emit_VFCHE(buf, v1, v3, v2, s390_getM_from_size(size), 0, 0);
11281 
11282       default:
11283          goto fail;
11284    }
11285 
11286    fail:
11287       ppS390Instr(insn, True);
11288       vpanic("s390_insn_vec_binop_emit");
11289 
11290 }
11291 
11292 
11293 static UChar *
s390_insn_vec_triop_emit(UChar * buf,const s390_insn * insn)11294 s390_insn_vec_triop_emit(UChar *buf, const s390_insn *insn)
11295 {
11296    s390_vec_triop_t tag = insn->variant.vec_triop.tag;
11297    UChar v1 = hregNumber(insn->variant.vec_triop.dst);
11298    UChar v2 = hregNumber(insn->variant.vec_triop.op1);
11299    UChar v3 = hregNumber(insn->variant.vec_triop.op2);
11300    UChar v4 = hregNumber(insn->variant.vec_triop.op3);
11301 
11302    switch (tag) {
11303       case S390_VEC_PERM: {
11304          vassert(insn->size == 16);
11305          return s390_emit_VPERM(buf, v1, v2, v3, v4);
11306       }
11307       case S390_VEC_FLOAT_MADD:
11308          return s390_emit_VFMA(buf, v1, v2, v3, v4, 0, 3);
11309       case S390_VEC_FLOAT_MSUB:
11310          return s390_emit_VFMS(buf, v1, v2, v3, v4, 0, 3);
11311       default:
11312          goto fail;
11313    }
11314 
11315    fail:
11316       vpanic("s390_insn_vec_triop_emit");
11317 
11318 }
11319 
11320 
11321 Int
emit_S390Instr(Bool * is_profinc,UChar * buf,Int nbuf,const s390_insn * insn,Bool mode64,VexEndness endness_host,const void * disp_cp_chain_me_to_slowEP,const void * disp_cp_chain_me_to_fastEP,const void * disp_cp_xindir,const void * disp_cp_xassisted)11322 emit_S390Instr(Bool *is_profinc, UChar *buf, Int nbuf, const s390_insn *insn,
11323                Bool mode64, VexEndness endness_host,
11324                const void *disp_cp_chain_me_to_slowEP,
11325                const void *disp_cp_chain_me_to_fastEP,
11326                const void *disp_cp_xindir,
11327                const void *disp_cp_xassisted)
11328 {
11329    UChar *end;
11330 
11331    /* Used to be 48 bytes. Make sure it stays low */
11332    vassert(sizeof(s390_insn) == 32);
11333 
11334    switch (insn->tag) {
11335    case S390_INSN_LOAD:
11336       end = s390_insn_load_emit(buf, insn);
11337       break;
11338 
11339    case S390_INSN_STORE:
11340       end = s390_insn_store_emit(buf, insn);
11341       break;
11342 
11343    case S390_INSN_MOVE:
11344       end = s390_insn_move_emit(buf, insn);
11345       break;
11346 
11347    case S390_INSN_MEMCPY:
11348       end = s390_insn_memcpy_emit(buf, insn);
11349       break;
11350 
11351    case S390_INSN_COND_MOVE:
11352       end = s390_insn_cond_move_emit(buf, insn);
11353       break;
11354 
11355    case S390_INSN_LOAD_IMMEDIATE:
11356       end = s390_insn_load_immediate_emit(buf, insn);
11357       break;
11358 
11359    case S390_INSN_ALU:
11360       end = s390_insn_alu_emit(buf, insn);
11361       break;
11362 
11363    case S390_INSN_SMUL:
11364    case S390_INSN_UMUL:
11365       end = s390_insn_mul_emit(buf, insn);
11366       break;
11367 
11368    case S390_INSN_SDIV:
11369    case S390_INSN_UDIV:
11370       end = s390_insn_div_emit(buf, insn);
11371       break;
11372 
11373    case S390_INSN_DIVS:
11374       end = s390_insn_divs_emit(buf, insn);
11375       break;
11376 
11377    case S390_INSN_CLZ:
11378       end = s390_insn_clz_emit(buf, insn);
11379       break;
11380 
11381    case S390_INSN_UNOP:
11382       end = s390_insn_unop_emit(buf, insn);
11383       break;
11384 
11385    case S390_INSN_TEST:
11386       end = s390_insn_test_emit(buf, insn);
11387       break;
11388 
11389    case S390_INSN_CC2BOOL:
11390       end = s390_insn_cc2bool_emit(buf, insn);
11391       break;
11392 
11393    case S390_INSN_CAS:
11394       end = s390_insn_cas_emit(buf, insn);
11395       break;
11396 
11397    case S390_INSN_CDAS:
11398       end = s390_insn_cdas_emit(buf, insn);
11399       break;
11400 
11401    case S390_INSN_COMPARE:
11402       end = s390_insn_compare_emit(buf, insn);
11403       break;
11404 
11405    case S390_INSN_HELPER_CALL:
11406       end = s390_insn_helper_call_emit(buf, insn);
11407       if (end == buf) goto fail;
11408       break;
11409 
11410    case S390_INSN_BFP_TRIOP:
11411       end = s390_insn_bfp_triop_emit(buf, insn);
11412       break;
11413 
11414    case S390_INSN_BFP_BINOP:
11415       end = s390_insn_bfp_binop_emit(buf, insn);
11416       break;
11417 
11418    case S390_INSN_BFP_UNOP:
11419       end = s390_insn_bfp_unop_emit(buf, insn);
11420       break;
11421 
11422    case S390_INSN_BFP_COMPARE:
11423       end = s390_insn_bfp_compare_emit(buf, insn);
11424       break;
11425 
11426    case S390_INSN_BFP_CONVERT:
11427       end = s390_insn_bfp_convert_emit(buf, insn);
11428       break;
11429 
11430    case S390_INSN_DFP_BINOP:
11431       end = s390_insn_dfp_binop_emit(buf, insn);
11432       break;
11433 
11434    case S390_INSN_DFP_UNOP:
11435       end = s390_insn_dfp_unop_emit(buf, insn);
11436       break;
11437 
11438    case S390_INSN_DFP_INTOP:
11439       end = s390_insn_dfp_intop_emit(buf, insn);
11440       break;
11441 
11442    case S390_INSN_DFP_COMPARE:
11443       end = s390_insn_dfp_compare_emit(buf, insn);
11444       break;
11445 
11446    case S390_INSN_DFP_CONVERT:
11447       end = s390_insn_dfp_convert_emit(buf, insn);
11448       break;
11449 
11450    case S390_INSN_DFP_REROUND:
11451       end = s390_insn_dfp_reround_emit(buf, insn);
11452       break;
11453 
11454    case S390_INSN_FP_CONVERT:
11455       end = s390_insn_fp_convert_emit(buf, insn);
11456       break;
11457 
11458    case S390_INSN_MFENCE:
11459       end = s390_insn_mfence_emit(buf, insn);
11460       break;
11461 
11462    case S390_INSN_MIMM:
11463       end = s390_insn_mimm_emit(buf, insn);
11464       break;
11465 
11466    case S390_INSN_MADD:
11467       end = s390_insn_madd_emit(buf, insn);
11468       break;
11469 
11470    case S390_INSN_SET_FPC_BFPRM:
11471       end = s390_insn_set_fpc_bfprm_emit(buf, insn);
11472       break;
11473 
11474    case S390_INSN_SET_FPC_DFPRM:
11475       end = s390_insn_set_fpc_dfprm_emit(buf, insn);
11476       break;
11477 
11478    case S390_INSN_PROFINC:
11479       end = s390_insn_profinc_emit(buf, insn);
11480       /* Tell the caller .. */
11481       vassert(*is_profinc == False);
11482       *is_profinc = True;
11483       break;
11484 
11485    case S390_INSN_EVCHECK:
11486       end = s390_insn_evcheck_emit(buf, insn, endness_host);
11487       break;
11488 
11489    case S390_INSN_XDIRECT:
11490       end = s390_insn_xdirect_emit(buf, insn, disp_cp_chain_me_to_slowEP,
11491                                    disp_cp_chain_me_to_fastEP);
11492       break;
11493 
11494    case S390_INSN_XINDIR:
11495       end = s390_insn_xindir_emit(buf, insn, disp_cp_xindir);
11496       break;
11497 
11498    case S390_INSN_XASSISTED:
11499       end = s390_insn_xassisted_emit(buf, insn, disp_cp_xassisted);
11500       break;
11501 
11502    case S390_INSN_VEC_AMODEOP:
11503       end = s390_insn_vec_amodeop_emit(buf, insn);
11504       break;
11505 
11506    case S390_INSN_VEC_AMODEINTOP:
11507       end = s390_insn_vec_amodeintop_emit(buf, insn);
11508       break;
11509 
11510    case S390_INSN_VEC_BINOP:
11511       end = s390_insn_vec_binop_emit(buf, insn);
11512       break;
11513 
11514    case S390_INSN_VEC_TRIOP:
11515       end = s390_insn_vec_triop_emit(buf, insn);
11516       break;
11517    fail:
11518    default:
11519       vpanic("emit_S390Instr");
11520    }
11521 
11522    vassert(end - buf <= nbuf);
11523 
11524    return end - buf;
11525 }
11526 
11527 
11528 /* Return the number of bytes emitted for an S390_INSN_EVCHECK.
11529    See s390_insn_evcheck_emit */
11530 Int
evCheckSzB_S390(void)11531 evCheckSzB_S390(void)
11532 {
11533    return s390_host_has_gie ? 18 : 24;
11534 }
11535 
11536 
11537 /* Patch the counter address into CODE_TO_PATCH as previously
11538    generated by s390_insn_profinc_emit. */
11539 VexInvalRange
patchProfInc_S390(VexEndness endness_host,void * code_to_patch,const ULong * location_of_counter)11540 patchProfInc_S390(VexEndness endness_host,
11541                   void *code_to_patch, const ULong *location_of_counter)
11542 {
11543    vassert(sizeof(ULong *) == 8);
11544 
11545    s390_tchain_verify_load64(code_to_patch, S390_REGNO_TCHAIN_SCRATCH, 0);
11546 
11547    UChar *p = s390_tchain_patch_load64(code_to_patch,
11548                                        (Addr)location_of_counter);
11549 
11550    UInt len = p - (UChar *)code_to_patch;
11551    VexInvalRange vir = { (HWord)code_to_patch, len };
11552    return vir;
11553 }
11554 
11555 
11556 /* NB: what goes on here has to be very closely coordinated with the
11557    s390_insn_xdirect_emit code above. */
11558 VexInvalRange
chainXDirect_S390(VexEndness endness_host,void * place_to_chain,const void * disp_cp_chain_me_EXPECTED,const void * place_to_jump_to)11559 chainXDirect_S390(VexEndness endness_host,
11560                   void *place_to_chain,
11561                   const void *disp_cp_chain_me_EXPECTED,
11562                   const void *place_to_jump_to)
11563 {
11564    vassert(endness_host == VexEndnessBE);
11565 
11566    /* What we're expecting to see @ PLACE_TO_CHAIN is:
11567 
11568         load  tchain_scratch, #disp_cp_chain_me_EXPECTED
11569         goto *tchain_scratch
11570    */
11571    const UChar *next;
11572    next = s390_tchain_verify_load64(place_to_chain, S390_REGNO_TCHAIN_SCRATCH,
11573                                     (Addr)disp_cp_chain_me_EXPECTED);
11574    vassert(s390_insn_is_BR(next, S390_REGNO_TCHAIN_SCRATCH));
11575 
11576    /* And what we want to change it to is either:
11577         (general case):
11578 
11579           load  tchain_scratch, #place_to_jump_to
11580           goto *tchain_scratch
11581 
11582       ---OR---
11583 
11584         in the case where the displacement is small enough
11585 
11586           BRCL delta       where delta is in half-words
11587           invalid opcodes
11588 
11589       In both cases the replacement has the same length as the original.
11590       To remain sane & verifiable,
11591       (1) limit the displacement for the short form to
11592           (say) +/- one billion, so as to avoid wraparound
11593           off-by-ones
11594       (2) even if the short form is applicable, once every (say)
11595           1024 times use the long form anyway, so as to maintain
11596           verifiability
11597    */
11598 
11599    /* This is the delta we need to put into a BRCL insn. Note, that the
11600       offset in BRCL is in half-words. Hence division by 2. */
11601    Long delta =
11602       (Long)((const UChar *)place_to_jump_to - (const UChar *)place_to_chain) / 2;
11603    Bool shortOK = delta >= -1000*1000*1000 && delta < 1000*1000*1000;
11604 
11605    static UInt shortCTR = 0; /* DO NOT MAKE NON-STATIC */
11606    if (shortOK) {
11607       shortCTR++; // thread safety bleh
11608       if (0 == (shortCTR & 0x3FF)) {
11609          shortOK = False;
11610          if (0)
11611             vex_printf("QQQ chainXDirect_S390: shortCTR = %u, "
11612                        "using long jmp\n", shortCTR);
11613       }
11614    }
11615 
11616    /* And make the modifications. */
11617    UChar *p = (UChar *)place_to_chain;
11618    if (shortOK) {
11619       p = s390_emit_BRCL(p, S390_CC_ALWAYS, delta);  /* 6 bytes */
11620 
11621       /* Make sure that BRCL fits into the patchable part of an xdirect
11622          code sequence */
11623       vassert(6 <= s390_xdirect_patchable_len());
11624 
11625       /* Fill remaining bytes with 0x00 (invalid opcode) */
11626       Int i;
11627       for (i = 0; i < s390_xdirect_patchable_len() - 6; ++i)
11628          p[i] = 0x00;
11629    } else {
11630       /*
11631           load  tchain_scratch, #place_to_jump_to
11632           goto *tchain_scratch
11633       */
11634       Addr64 addr = (Addr)place_to_jump_to;
11635       p = s390_tchain_load64(p, S390_REGNO_TCHAIN_SCRATCH, addr);
11636       /* There is not need to emit a BCR here, as it is already there. */
11637    }
11638 
11639    UInt len = p - (UChar *)place_to_chain;
11640    VexInvalRange vir = { (HWord)place_to_chain, len };
11641    return vir;
11642 }
11643 
11644 
11645 /* NB: what goes on here has to be very closely coordinated with the
11646    s390_insn_xdirect_emit code above. */
11647 VexInvalRange
unchainXDirect_S390(VexEndness endness_host,void * place_to_unchain,const void * place_to_jump_to_EXPECTED,const void * disp_cp_chain_me)11648 unchainXDirect_S390(VexEndness endness_host,
11649                     void *place_to_unchain,
11650                     const void *place_to_jump_to_EXPECTED,
11651                     const void *disp_cp_chain_me)
11652 {
11653    vassert(endness_host == VexEndnessBE);
11654 
11655    /* What we're expecting to see @ PLACE_TO_UNCHAIN:
11656 
11657           load  tchain_scratch, #place_to_jump_to_EXPECTED
11658           goto *tchain_scratch
11659 
11660       ---OR---
11661         in the case where the displacement falls within 32 bits
11662 
11663           BRCL delta
11664           invalid opcodes
11665    */
11666    UChar *p = place_to_unchain;
11667 
11668    Bool uses_short_form = False;
11669 
11670    if (s390_insn_is_BRCL(p, S390_CC_ALWAYS)) {
11671       /* Looks like the short form */
11672       Int num_hw = *(Int *)&p[2];
11673       Int delta = 2 *num_hw;
11674 
11675       vassert(p + delta == place_to_jump_to_EXPECTED);
11676 
11677       Int i;
11678       for (i = 0; i < s390_xdirect_patchable_len() - 6; ++i)
11679          vassert(p[6+i] == 0x00);
11680       uses_short_form = True;
11681    } else {
11682       /* Should be the long form */
11683       const UChar *next;
11684 
11685       next = s390_tchain_verify_load64(p, S390_REGNO_TCHAIN_SCRATCH,
11686                                        (Addr)place_to_jump_to_EXPECTED);
11687       /* Check for BR *tchain_scratch */
11688       vassert(s390_insn_is_BR(next, S390_REGNO_TCHAIN_SCRATCH));
11689    }
11690 
11691    /* And what we want to change it to is:
11692 
11693         load  tchain_scratch, #disp_cp_chain_me
11694         goto *tchain_scratch
11695    */
11696 
11697    /* Get the address of the beginning of the load64 code sequence into %r1.
11698       Do not change the register! This is part of the protocol with the
11699       dispatcher.
11700       Note: the incoming argument PLACE_TO_CHAIN points to the beginning of the
11701       load64 insn sequence. That sequence is prefixed with a BASR to get its
11702       address (see s390_insn_xdirect_emit).  */
11703    p = s390_emit_BASR(p - S390_BASR_LEN, 1, R0);
11704 
11705    Addr64 addr = (Addr)disp_cp_chain_me;
11706    p = s390_tchain_load64(p, S390_REGNO_TCHAIN_SCRATCH, addr);
11707 
11708    /* Emit the BCR in case the short form was used. In case of the long
11709       form, the BCR is already there. */
11710    if (uses_short_form)
11711       s390_emit_BCR(p, S390_CC_ALWAYS, S390_REGNO_TCHAIN_SCRATCH);
11712 
11713    UInt len = p - (UChar *)place_to_unchain;
11714    VexInvalRange vir = { (HWord)place_to_unchain, len };
11715    return vir;
11716 }
11717 
11718 /*---------------------------------------------------------------*/
11719 /*--- end                                    host_s390_defs.c ---*/
11720 /*---------------------------------------------------------------*/
11721