• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- mode: C; c-basic-offset: 3; -*- */
2 
3 /*---------------------------------------------------------------*/
4 /*--- begin                                 guest_s390_toIR.c ---*/
5 /*---------------------------------------------------------------*/
6 
7 /*
8    This file is part of Valgrind, a dynamic binary instrumentation
9    framework.
10 
11    Copyright IBM Corp. 2010-2017
12 
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17 
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26    02110-1301, USA.
27 
28    The GNU General Public License is contained in the file COPYING.
29 */
30 
31 /* Contributed by Florian Krohm and Christian Borntraeger */
32 
33 /* Translates s390 code to IR. */
34 
35 #include "libvex_basictypes.h"
36 #include "libvex_ir.h"
37 #include "libvex_emnote.h"
38 #include "libvex_s390x_common.h"
39 #include "main_util.h"               /* vassert */
40 #include "main_globals.h"            /* vex_traceflags */
41 #include "guest_generic_bb_to_IR.h"  /* DisResult */
42 #include "guest_s390_defs.h"         /* prototypes for this file's functions */
43 #include "s390_disasm.h"
44 #include "s390_defs.h"               /* S390_BFP_ROUND_xyzzy */
45 #include "host_s390_defs.h"          /* s390_host_has_xyzzy */
46 
47 
48 /*------------------------------------------------------------*/
49 /*--- Forward declarations                                 ---*/
50 /*------------------------------------------------------------*/
51 static UInt s390_decode_and_irgen(const UChar *, UInt, DisResult *);
52 static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
53 static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
54 
55 
56 /*------------------------------------------------------------*/
57 /*--- Globals                                              ---*/
58 /*------------------------------------------------------------*/
59 
60 /* The IRSB* into which we're generating code. */
61 static IRSB *irsb;
62 
63 /* The guest address for the instruction currently being
64    translated. */
65 static Addr64 guest_IA_curr_instr;
66 
67 /* The guest address for the instruction following the current instruction. */
68 static Addr64 guest_IA_next_instr;
69 
70 /* Result of disassembly step. */
71 static DisResult *dis_res;
72 
73 /* Resteer function and callback data */
74 static Bool (*resteer_fn)(void *, Addr);
75 static void *resteer_data;
76 
77 /* Whether to print diagnostics for illegal instructions. */
78 static Bool sigill_diag;
79 
80 /* The last seen execute target instruction */
81 ULong last_execute_target;
82 
83 /* The possible outcomes of a decoding operation */
84 typedef enum {
85    S390_DECODE_OK,
86    S390_DECODE_UNKNOWN_INSN,
87    S390_DECODE_UNIMPLEMENTED_INSN,
88    S390_DECODE_UNKNOWN_SPECIAL_INSN,
89    S390_DECODE_ERROR
90 } s390_decode_t;
91 
92 
93 /*------------------------------------------------------------*/
94 /*--- Helpers for constructing IR.                         ---*/
95 /*------------------------------------------------------------*/
96 
97 /* Add a statement to the current irsb. */
98 static __inline__ void
stmt(IRStmt * st)99 stmt(IRStmt *st)
100 {
101    addStmtToIRSB(irsb, st);
102 }
103 
104 /* Allocate a new temporary of the given type. */
105 static __inline__ IRTemp
newTemp(IRType type)106 newTemp(IRType type)
107 {
108    vassert(isPlausibleIRType(type));
109 
110    return newIRTemp(irsb->tyenv, type);
111 }
112 
113 /* Create an expression node for a temporary */
114 static __inline__ IRExpr *
mkexpr(IRTemp tmp)115 mkexpr(IRTemp tmp)
116 {
117    return IRExpr_RdTmp(tmp);
118 }
119 
120 /* Generate an expression node for an address. */
121 static __inline__ IRExpr *
mkaddr_expr(Addr64 addr)122 mkaddr_expr(Addr64 addr)
123 {
124    return IRExpr_Const(IRConst_U64(addr));
125 }
126 
127 /* Add a statement that assigns to a temporary */
128 static __inline__ void
assign(IRTemp dst,IRExpr * expr)129 assign(IRTemp dst, IRExpr *expr)
130 {
131    stmt(IRStmt_WrTmp(dst, expr));
132 }
133 
134 /* Write an address into the guest_IA */
135 static __inline__ void
put_IA(IRExpr * address)136 put_IA(IRExpr *address)
137 {
138    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
139 }
140 
141 /* Create a temporary of the given type and assign the expression to it */
142 static __inline__ IRTemp
mktemp(IRType type,IRExpr * expr)143 mktemp(IRType type, IRExpr *expr)
144 {
145    IRTemp temp = newTemp(type);
146 
147    assign(temp, expr);
148 
149    return temp;
150 }
151 
152 /* Create a unary expression */
153 static __inline__ IRExpr *
unop(IROp kind,IRExpr * op)154 unop(IROp kind, IRExpr *op)
155 {
156    return IRExpr_Unop(kind, op);
157 }
158 
159 /* Create a binary expression */
160 static __inline__ IRExpr *
binop(IROp kind,IRExpr * op1,IRExpr * op2)161 binop(IROp kind, IRExpr *op1, IRExpr *op2)
162 {
163    return IRExpr_Binop(kind, op1, op2);
164 }
165 
166 /* Create a ternary expression */
167 static __inline__ IRExpr *
triop(IROp kind,IRExpr * op1,IRExpr * op2,IRExpr * op3)168 triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
169 {
170    return IRExpr_Triop(kind, op1, op2, op3);
171 }
172 
173 /* Create a quaternary expression */
174 static __inline__  IRExpr *
qop(IROp kind,IRExpr * op1,IRExpr * op2,IRExpr * op3,IRExpr * op4)175 qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
176 {
177    return IRExpr_Qop(kind, op1, op2, op3, op4);
178 }
179 
180 /* Create an expression node for an 8-bit integer constant */
181 static __inline__ IRExpr *
mkU8(UInt value)182 mkU8(UInt value)
183 {
184    vassert(value < 256);
185 
186    return IRExpr_Const(IRConst_U8((UChar)value));
187 }
188 
189 /* Create an expression node for a 16-bit integer constant */
190 static __inline__ IRExpr *
mkU16(UInt value)191 mkU16(UInt value)
192 {
193    vassert(value < 65536);
194 
195    return IRExpr_Const(IRConst_U16((UShort)value));
196 }
197 
198 /* Create an expression node for a 32-bit integer constant */
199 static __inline__ IRExpr *
mkU32(UInt value)200 mkU32(UInt value)
201 {
202    return IRExpr_Const(IRConst_U32(value));
203 }
204 
205 /* Create an expression node for a 64-bit integer constant */
206 static __inline__ IRExpr *
mkU64(ULong value)207 mkU64(ULong value)
208 {
209    return IRExpr_Const(IRConst_U64(value));
210 }
211 
212 /* Create an expression node for a 32-bit floating point constant
213    whose value is given by a bit pattern. */
214 static __inline__ IRExpr *
mkF32i(UInt value)215 mkF32i(UInt value)
216 {
217    return IRExpr_Const(IRConst_F32i(value));
218 }
219 
220 /* Create an expression node for a 32-bit floating point constant
221    whose value is given by a bit pattern. */
222 static __inline__ IRExpr *
mkF64i(ULong value)223 mkF64i(ULong value)
224 {
225    return IRExpr_Const(IRConst_F64i(value));
226 }
227 
228 /* Little helper function for my sanity. ITE = if-then-else */
229 static IRExpr *
mkite(IRExpr * condition,IRExpr * iftrue,IRExpr * iffalse)230 mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
231 {
232    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
233 
234    return IRExpr_ITE(condition, iftrue, iffalse);
235 }
236 
237 /* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
238 static __inline__ void
store(IRExpr * addr,IRExpr * data)239 store(IRExpr *addr, IRExpr *data)
240 {
241    stmt(IRStmt_Store(Iend_BE, addr, data));
242 }
243 
244 /* Create an expression that loads a TYPE sized value from ADDR.
245    This is a big-endian machine. */
246 static __inline__ IRExpr *
load(IRType type,IRExpr * addr)247 load(IRType type, IRExpr *addr)
248 {
249    return IRExpr_Load(Iend_BE, type, addr);
250 }
251 
252 /* Function call */
253 static void
call_function(IRExpr * callee_address)254 call_function(IRExpr *callee_address)
255 {
256    put_IA(callee_address);
257 
258    dis_res->whatNext    = Dis_StopHere;
259    dis_res->jk_StopHere = Ijk_Call;
260 }
261 
262 /* Function call with known target. */
263 static void
call_function_and_chase(Addr64 callee_address)264 call_function_and_chase(Addr64 callee_address)
265 {
266    if (resteer_fn(resteer_data, callee_address)) {
267       dis_res->whatNext   = Dis_ResteerU;
268       dis_res->continueAt = callee_address;
269    } else {
270       put_IA(mkaddr_expr(callee_address));
271 
272       dis_res->whatNext = Dis_StopHere;
273       dis_res->jk_StopHere = Ijk_Call;
274    }
275 }
276 
277 /* Function return sequence */
278 static void
return_from_function(IRExpr * return_address)279 return_from_function(IRExpr *return_address)
280 {
281    put_IA(return_address);
282 
283    dis_res->whatNext    = Dis_StopHere;
284    dis_res->jk_StopHere = Ijk_Ret;
285 }
286 
287 /* A conditional branch whose target is not known at instrumentation time.
288 
289    if (condition) goto computed_target;
290 
291    Needs to be represented as:
292 
293    if (! condition) goto next_instruction;
294    goto computed_target;
295 */
296 static void
if_condition_goto_computed(IRExpr * condition,IRExpr * target)297 if_condition_goto_computed(IRExpr *condition, IRExpr *target)
298 {
299    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
300 
301    condition = unop(Iop_Not1, condition);
302 
303    stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
304                     S390X_GUEST_OFFSET(guest_IA)));
305 
306    put_IA(target);
307 
308    dis_res->whatNext    = Dis_StopHere;
309    dis_res->jk_StopHere = Ijk_Boring;
310 }
311 
312 /* A conditional branch whose target is known at instrumentation time. */
313 static void
if_condition_goto(IRExpr * condition,Addr64 target)314 if_condition_goto(IRExpr *condition, Addr64 target)
315 {
316    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
317 
318    stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
319                     S390X_GUEST_OFFSET(guest_IA)));
320 
321    put_IA(mkaddr_expr(guest_IA_next_instr));
322 
323    dis_res->whatNext    = Dis_StopHere;
324    dis_res->jk_StopHere = Ijk_Boring;
325 }
326 
327 /* An unconditional branch. Target may or may not be known at instrumentation
328    time. */
329 static void
always_goto(IRExpr * target)330 always_goto(IRExpr *target)
331 {
332    put_IA(target);
333 
334    dis_res->whatNext    = Dis_StopHere;
335    dis_res->jk_StopHere = Ijk_Boring;
336 }
337 
338 
339 /* An unconditional branch to a known target. */
340 static void
always_goto_and_chase(Addr64 target)341 always_goto_and_chase(Addr64 target)
342 {
343    if (resteer_fn(resteer_data, target)) {
344       /* Follow into the target */
345       dis_res->whatNext   = Dis_ResteerU;
346       dis_res->continueAt = target;
347    } else {
348       put_IA(mkaddr_expr(target));
349 
350       dis_res->whatNext    = Dis_StopHere;
351       dis_res->jk_StopHere = Ijk_Boring;
352    }
353 }
354 
355 /* A system call */
356 static void
system_call(IRExpr * sysno)357 system_call(IRExpr *sysno)
358 {
359    /* Store the system call number in the pseudo register. */
360    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
361 
362    /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
363    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
364                    mkU64(guest_IA_curr_instr)));
365 
366    put_IA(mkaddr_expr(guest_IA_next_instr));
367 
368    /* It's important that all ArchRegs carry their up-to-date value
369       at this point.  So we declare an end-of-block here, which
370       forces any TempRegs caching ArchRegs to be flushed. */
371    dis_res->whatNext    = Dis_StopHere;
372    dis_res->jk_StopHere = Ijk_Sys_syscall;
373 }
374 
375 /* A side exit that branches back to the current insn if CONDITION is
376    true. Does not set DisResult. */
377 static void
iterate_if(IRExpr * condition)378 iterate_if(IRExpr *condition)
379 {
380    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
381 
382    stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
383                     S390X_GUEST_OFFSET(guest_IA)));
384 }
385 
386 /* A side exit that branches back to the current insn.
387    Does not set DisResult. */
388 static __inline__ void
iterate(void)389 iterate(void)
390 {
391    iterate_if(IRExpr_Const(IRConst_U1(True)));
392 }
393 
394 /* A side exit that branches back to the insn immediately following the
395    current insn if CONDITION is true. Does not set DisResult. */
396 static void
next_insn_if(IRExpr * condition)397 next_insn_if(IRExpr *condition)
398 {
399    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
400 
401    stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
402                     S390X_GUEST_OFFSET(guest_IA)));
403 }
404 
405 /* Convenience function to restart the current insn */
406 static void
restart_if(IRExpr * condition)407 restart_if(IRExpr *condition)
408 {
409    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
410 
411    stmt(IRStmt_Exit(condition, Ijk_InvalICache,
412                     IRConst_U64(guest_IA_curr_instr),
413                     S390X_GUEST_OFFSET(guest_IA)));
414 }
415 
416 /* Convenience function to yield to thread scheduler */
417 static void
yield_if(IRExpr * condition)418 yield_if(IRExpr *condition)
419 {
420    stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
421                     S390X_GUEST_OFFSET(guest_IA)));
422 }
423 
424 static __inline__ IRExpr *get_fpr_dw0(UInt);
425 static __inline__ void    put_fpr_dw0(UInt, IRExpr *);
426 static __inline__ IRExpr *get_dpr_dw0(UInt);
427 static __inline__ void    put_dpr_dw0(UInt, IRExpr *);
428 
429 /* Read a floating point register pair and combine their contents into a
430    128-bit value */
431 static IRExpr *
get_fpr_pair(UInt archreg)432 get_fpr_pair(UInt archreg)
433 {
434    IRExpr *high = get_fpr_dw0(archreg);
435    IRExpr *low  = get_fpr_dw0(archreg + 2);
436 
437    return binop(Iop_F64HLtoF128, high, low);
438 }
439 
440 /* Write a 128-bit floating point value into a register pair. */
441 static void
put_fpr_pair(UInt archreg,IRExpr * expr)442 put_fpr_pair(UInt archreg, IRExpr *expr)
443 {
444    IRExpr *high = unop(Iop_F128HItoF64, expr);
445    IRExpr *low  = unop(Iop_F128LOtoF64, expr);
446 
447    put_fpr_dw0(archreg,     high);
448    put_fpr_dw0(archreg + 2, low);
449 }
450 
451 /* Read a floating point register pair cointaining DFP value
452    and combine their contents into a 128-bit value */
453 
454 static IRExpr *
get_dpr_pair(UInt archreg)455 get_dpr_pair(UInt archreg)
456 {
457    IRExpr *high = get_dpr_dw0(archreg);
458    IRExpr *low  = get_dpr_dw0(archreg + 2);
459 
460    return binop(Iop_D64HLtoD128, high, low);
461 }
462 
463 /* Write a 128-bit decimal floating point value into a register pair. */
464 static void
put_dpr_pair(UInt archreg,IRExpr * expr)465 put_dpr_pair(UInt archreg, IRExpr *expr)
466 {
467    IRExpr *high = unop(Iop_D128HItoD64, expr);
468    IRExpr *low  = unop(Iop_D128LOtoD64, expr);
469 
470    put_dpr_dw0(archreg,     high);
471    put_dpr_dw0(archreg + 2, low);
472 }
473 
474 /* Terminate the current IRSB with an emulation failure. */
475 static void
emulation_failure_with_expr(IRExpr * emfailure)476 emulation_failure_with_expr(IRExpr *emfailure)
477 {
478    vassert(typeOfIRExpr(irsb->tyenv, emfailure) == Ity_I32);
479 
480    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emfailure));
481    dis_res->whatNext = Dis_StopHere;
482    dis_res->jk_StopHere = Ijk_EmFail;
483 }
484 
485 static void
emulation_failure(VexEmNote fail_kind)486 emulation_failure(VexEmNote fail_kind)
487 {
488    emulation_failure_with_expr(mkU32(fail_kind));
489 }
490 
491 /* Terminate the current IRSB with an emulation warning. */
492 static void
emulation_warning_with_expr(IRExpr * emwarning)493 emulation_warning_with_expr(IRExpr *emwarning)
494 {
495    vassert(typeOfIRExpr(irsb->tyenv, emwarning) == Ity_I32);
496 
497    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emwarning));
498    dis_res->whatNext = Dis_StopHere;
499    dis_res->jk_StopHere = Ijk_EmWarn;
500 }
501 
502 static void
emulation_warning(VexEmNote warn_kind)503 emulation_warning(VexEmNote warn_kind)
504 {
505    emulation_warning_with_expr(mkU32(warn_kind));
506 }
507 
508 /*------------------------------------------------------------*/
509 /*--- IR Debugging aids.                                   ---*/
510 /*------------------------------------------------------------*/
511 #if 0
512 
513 static ULong
514 s390_do_print(HChar *text, ULong value)
515 {
516    vex_printf("%s %llu\n", text, value);
517    return 0;
518 }
519 
520 static void
521 s390_print(HChar *text, IRExpr *value)
522 {
523    IRDirty *d;
524 
525    d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
526                          mkIRExprVec_2(mkU64((ULong)text), value));
527    stmt(IRStmt_Dirty(d));
528 }
529 #endif
530 
531 
532 /*------------------------------------------------------------*/
533 /*--- Build the flags thunk.                               ---*/
534 /*------------------------------------------------------------*/
535 
536 /* Completely fill the flags thunk. We're always filling all fields.
537    Apparently, that is better for redundant PUT elimination. */
538 static void
s390_cc_thunk_fill(IRExpr * op,IRExpr * dep1,IRExpr * dep2,IRExpr * ndep)539 s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
540 {
541    UInt op_off, dep1_off, dep2_off, ndep_off;
542 
543    op_off   = S390X_GUEST_OFFSET(guest_CC_OP);
544    dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
545    dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
546    ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
547 
548    stmt(IRStmt_Put(op_off,   op));
549    stmt(IRStmt_Put(dep1_off, dep1));
550    stmt(IRStmt_Put(dep2_off, dep2));
551    stmt(IRStmt_Put(ndep_off, ndep));
552 }
553 
554 
555 /* Create an expression for V and widen the result to 64 bit. */
556 static IRExpr *
s390_cc_widen(IRTemp v,Bool sign_extend)557 s390_cc_widen(IRTemp v, Bool sign_extend)
558 {
559    IRExpr *expr;
560 
561    expr = mkexpr(v);
562 
563    switch (typeOfIRTemp(irsb->tyenv, v)) {
564    case Ity_I64:
565       break;
566    case Ity_I32:
567       expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
568       break;
569    case Ity_I16:
570       expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
571       break;
572    case Ity_I8:
573       expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
574       break;
575    default:
576       vpanic("s390_cc_widen");
577    }
578 
579    return expr;
580 }
581 
582 static void
s390_cc_thunk_put1(UInt opc,IRTemp d1,Bool sign_extend)583 s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
584 {
585    IRExpr *op, *dep1, *dep2, *ndep;
586 
587    op   = mkU64(opc);
588    dep1 = s390_cc_widen(d1, sign_extend);
589    dep2 = mkU64(0);
590    ndep = mkU64(0);
591 
592    s390_cc_thunk_fill(op, dep1, dep2, ndep);
593 }
594 
595 
596 static void
s390_cc_thunk_put2(UInt opc,IRTemp d1,IRTemp d2,Bool sign_extend)597 s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
598 {
599    IRExpr *op, *dep1, *dep2, *ndep;
600 
601    op   = mkU64(opc);
602    dep1 = s390_cc_widen(d1, sign_extend);
603    dep2 = s390_cc_widen(d2, sign_extend);
604    ndep = mkU64(0);
605 
606    s390_cc_thunk_fill(op, dep1, dep2, ndep);
607 }
608 
609 
610 /* memcheck believes that the NDEP field in the flags thunk is always
611    defined. But for some flag computations (e.g. add with carry) that is
612    just not true. We therefore need to convey to memcheck that the value
613    of the ndep field does matter and therefore we make the DEP2 field
614    depend on it:
615 
616    DEP2 = original_DEP2 ^ NDEP
617 
618    In s390_calculate_cc we exploit that  (a^b)^b == a
619    I.e. we xor the DEP2 value with the NDEP value to recover the
620    original_DEP2 value. */
621 static void
s390_cc_thunk_put3(UInt opc,IRTemp d1,IRTemp d2,IRTemp nd,Bool sign_extend)622 s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
623 {
624    IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
625 
626    op   = mkU64(opc);
627    dep1 = s390_cc_widen(d1, sign_extend);
628    dep2 = s390_cc_widen(d2, sign_extend);
629    ndep = s390_cc_widen(nd, sign_extend);
630 
631    dep2x = binop(Iop_Xor64, dep2, ndep);
632 
633    s390_cc_thunk_fill(op, dep1, dep2x, ndep);
634 }
635 
636 
637 /* Write one floating point value into the flags thunk */
638 static void
s390_cc_thunk_put1f(UInt opc,IRTemp d1)639 s390_cc_thunk_put1f(UInt opc, IRTemp d1)
640 {
641    IRExpr *op, *dep1, *dep2, *ndep;
642 
643    /* Make the CC_DEP1 slot appear completely defined.
644       Otherwise, assigning a 32-bit value will cause memcheck
645       to trigger an undefinedness error.
646    */
647    if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
648       UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
649       stmt(IRStmt_Put(dep1_off, mkU64(0)));
650    }
651    op   = mkU64(opc);
652    dep1 = mkexpr(d1);
653    dep2 = mkU64(0);
654    ndep = mkU64(0);
655 
656    s390_cc_thunk_fill(op, dep1, dep2, ndep);
657 }
658 
659 
660 /* Write a floating point value and an integer into the flags thunk. The
661    integer value is zero-extended first. */
662 static void
s390_cc_thunk_putFZ(UInt opc,IRTemp d1,IRTemp d2)663 s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
664 {
665    IRExpr *op, *dep1, *dep2, *ndep;
666 
667    /* Make the CC_DEP1 slot appear completely defined.
668       Otherwise, assigning a 32-bit value will cause memcheck
669       to trigger an undefinedness error.
670    */
671    if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
672       UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
673       stmt(IRStmt_Put(dep1_off, mkU64(0)));
674    }
675    op   = mkU64(opc);
676    dep1 = mkexpr(d1);
677    dep2 = s390_cc_widen(d2, False);
678    ndep = mkU64(0);
679 
680    s390_cc_thunk_fill(op, dep1, dep2, ndep);
681 }
682 
683 
684 /* Write a 128-bit floating point value into the flags thunk. This is
685    done by splitting the value into two 64-bits values. */
686 static void
s390_cc_thunk_put1f128(UInt opc,IRTemp d1)687 s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
688 {
689    IRExpr *op, *hi, *lo, *ndep;
690 
691    op   = mkU64(opc);
692    hi   = unop(Iop_F128HItoF64, mkexpr(d1));
693    lo   = unop(Iop_F128LOtoF64, mkexpr(d1));
694    ndep = mkU64(0);
695 
696    s390_cc_thunk_fill(op, hi, lo, ndep);
697 }
698 
699 
700 /* Write a 128-bit floating point value and an integer into the flags thunk.
701    The integer value is zero-extended first. */
702 static void
s390_cc_thunk_put1f128Z(UInt opc,IRTemp d1,IRTemp nd)703 s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
704 {
705    IRExpr *op, *hi, *lo, *lox, *ndep;
706 
707    op   = mkU64(opc);
708    hi   = unop(Iop_F128HItoF64, mkexpr(d1));
709    lo   = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
710    ndep = s390_cc_widen(nd, False);
711 
712    lox = binop(Iop_Xor64, lo, ndep);  /* convey dependency */
713 
714    s390_cc_thunk_fill(op, hi, lox, ndep);
715 }
716 
717 
718 /* Write a 128-bit decimal floating point value into the flags thunk.
719    This is done by splitting the value into two 64-bits values. */
720 static void
s390_cc_thunk_put1d128(UInt opc,IRTemp d1)721 s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
722 {
723    IRExpr *op, *hi, *lo, *ndep;
724 
725    op   = mkU64(opc);
726    hi   = unop(Iop_D128HItoD64, mkexpr(d1));
727    lo   = unop(Iop_D128LOtoD64, mkexpr(d1));
728    ndep = mkU64(0);
729 
730    s390_cc_thunk_fill(op, hi, lo, ndep);
731 }
732 
733 
734 /* Write a 128-bit decimal floating point value and an integer into the flags
735    thunk. The integer value is zero-extended first. */
736 static void
s390_cc_thunk_put1d128Z(UInt opc,IRTemp d1,IRTemp nd)737 s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
738 {
739    IRExpr *op, *hi, *lo, *lox, *ndep;
740 
741    op   = mkU64(opc);
742    hi   = unop(Iop_D128HItoD64, mkexpr(d1));
743    lo   = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
744    ndep = s390_cc_widen(nd, False);
745 
746    lox = binop(Iop_Xor64, lo, ndep);  /* convey dependency */
747 
748    s390_cc_thunk_fill(op, hi, lox, ndep);
749 }
750 
751 
752 static void
s390_cc_set(UInt val)753 s390_cc_set(UInt val)
754 {
755    s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
756                       mkU64(val), mkU64(0), mkU64(0));
757 }
758 
759 /* Build IR to calculate the condition code from flags thunk.
760    Returns an expression of type Ity_I32 */
761 static IRExpr *
s390_call_calculate_cc(void)762 s390_call_calculate_cc(void)
763 {
764    IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
765 
766    op   = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP),   Ity_I64);
767    dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
768    dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
769    ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
770 
771    args = mkIRExprVec_4(op, dep1, dep2, ndep);
772    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
773                         "s390_calculate_cc", &s390_calculate_cc, args);
774 
775    /* Exclude OP and NDEP from definedness checking.  We're only
776       interested in DEP1 and DEP2. */
777    call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
778 
779    return call;
780 }
781 
782 /* Build IR to calculate the internal condition code for a "compare and branch"
783    insn. Returns an expression of type Ity_I32 */
784 static IRExpr *
s390_call_calculate_icc(UInt m,UInt opc,IRTemp op1,IRTemp op2)785 s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
786 {
787    IRExpr **args, *call, *op, *dep1, *dep2, *mask;
788 
789    switch (opc) {
790    case S390_CC_OP_SIGNED_COMPARE:
791       dep1 = s390_cc_widen(op1, True);
792       dep2 = s390_cc_widen(op2, True);
793       break;
794 
795    case S390_CC_OP_UNSIGNED_COMPARE:
796       dep1 = s390_cc_widen(op1, False);
797       dep2 = s390_cc_widen(op2, False);
798       break;
799 
800    default:
801       vpanic("s390_call_calculate_icc");
802    }
803 
804    mask = mkU64(m);
805    op   = mkU64(opc);
806 
807    args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
808    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
809                         "s390_calculate_cond", &s390_calculate_cond, args);
810 
811    /* Exclude the requested condition, OP and NDEP from definedness
812       checking.  We're only interested in DEP1 and DEP2. */
813    call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
814 
815    return call;
816 }
817 
818 /* Build IR to calculate the condition code from flags thunk.
819    Returns an expression of type Ity_I32 */
820 static IRExpr *
s390_call_calculate_cond(UInt m)821 s390_call_calculate_cond(UInt m)
822 {
823    IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
824 
825    mask = mkU64(m);
826    op   = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP),   Ity_I64);
827    dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
828    dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
829    ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
830 
831    args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
832    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
833                         "s390_calculate_cond", &s390_calculate_cond, args);
834 
835    /* Exclude the requested condition, OP and NDEP from definedness
836       checking.  We're only interested in DEP1 and DEP2. */
837    call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
838 
839    return call;
840 }
841 
842 #define s390_cc_thunk_putZ(op,dep1)  s390_cc_thunk_put1(op,dep1,False)
843 #define s390_cc_thunk_putS(op,dep1)  s390_cc_thunk_put1(op,dep1,True)
844 #define s390_cc_thunk_putF(op,dep1)  s390_cc_thunk_put1f(op,dep1)
845 #define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
846 #define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
847 #define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
848 #define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
849         s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
850 #define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
851         s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
852 
853 
854 
855 
856 /*------------------------------------------------------------*/
857 /*--- Guest register access                                ---*/
858 /*------------------------------------------------------------*/
859 
860 
861 /*------------------------------------------------------------*/
862 /*--- ar registers                                         ---*/
863 /*------------------------------------------------------------*/
864 
865 /* Return the guest state offset of a ar register. */
866 static UInt
ar_offset(UInt archreg)867 ar_offset(UInt archreg)
868 {
869    static const UInt offset[16] = {
870       S390X_GUEST_OFFSET(guest_a0),
871       S390X_GUEST_OFFSET(guest_a1),
872       S390X_GUEST_OFFSET(guest_a2),
873       S390X_GUEST_OFFSET(guest_a3),
874       S390X_GUEST_OFFSET(guest_a4),
875       S390X_GUEST_OFFSET(guest_a5),
876       S390X_GUEST_OFFSET(guest_a6),
877       S390X_GUEST_OFFSET(guest_a7),
878       S390X_GUEST_OFFSET(guest_a8),
879       S390X_GUEST_OFFSET(guest_a9),
880       S390X_GUEST_OFFSET(guest_a10),
881       S390X_GUEST_OFFSET(guest_a11),
882       S390X_GUEST_OFFSET(guest_a12),
883       S390X_GUEST_OFFSET(guest_a13),
884       S390X_GUEST_OFFSET(guest_a14),
885       S390X_GUEST_OFFSET(guest_a15),
886    };
887 
888    vassert(archreg < 16);
889 
890    return offset[archreg];
891 }
892 
893 
894 /* Return the guest state offset of word #0 of a ar register. */
895 static __inline__ UInt
ar_w0_offset(UInt archreg)896 ar_w0_offset(UInt archreg)
897 {
898    return ar_offset(archreg) + 0;
899 }
900 
901 /* Write word #0 of a ar to the guest state. */
902 static __inline__ void
put_ar_w0(UInt archreg,IRExpr * expr)903 put_ar_w0(UInt archreg, IRExpr *expr)
904 {
905    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
906 
907    stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
908 }
909 
910 /* Read word #0 of a ar register. */
911 static __inline__ IRExpr *
get_ar_w0(UInt archreg)912 get_ar_w0(UInt archreg)
913 {
914    return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
915 }
916 
917 
918 /*------------------------------------------------------------*/
919 /*--- fpr registers                                        ---*/
920 /*------------------------------------------------------------*/
921 
922 /* Return the guest state offset of a fpr register. */
923 static UInt
fpr_offset(UInt archreg)924 fpr_offset(UInt archreg)
925 {
926    static const UInt offset[16] = {
927       S390X_GUEST_OFFSET(guest_f0),
928       S390X_GUEST_OFFSET(guest_f1),
929       S390X_GUEST_OFFSET(guest_f2),
930       S390X_GUEST_OFFSET(guest_f3),
931       S390X_GUEST_OFFSET(guest_f4),
932       S390X_GUEST_OFFSET(guest_f5),
933       S390X_GUEST_OFFSET(guest_f6),
934       S390X_GUEST_OFFSET(guest_f7),
935       S390X_GUEST_OFFSET(guest_f8),
936       S390X_GUEST_OFFSET(guest_f9),
937       S390X_GUEST_OFFSET(guest_f10),
938       S390X_GUEST_OFFSET(guest_f11),
939       S390X_GUEST_OFFSET(guest_f12),
940       S390X_GUEST_OFFSET(guest_f13),
941       S390X_GUEST_OFFSET(guest_f14),
942       S390X_GUEST_OFFSET(guest_f15),
943    };
944 
945    vassert(archreg < 16);
946 
947    return offset[archreg];
948 }
949 
950 
951 /* Return the guest state offset of word #0 of a fpr register. */
952 static __inline__ UInt
fpr_w0_offset(UInt archreg)953 fpr_w0_offset(UInt archreg)
954 {
955    return fpr_offset(archreg) + 0;
956 }
957 
958 /* Write word #0 of a fpr to the guest state. */
959 static __inline__ void
put_fpr_w0(UInt archreg,IRExpr * expr)960 put_fpr_w0(UInt archreg, IRExpr *expr)
961 {
962    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
963 
964    stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
965 }
966 
967 /* Read word #0 of a fpr register. */
968 static __inline__ IRExpr *
get_fpr_w0(UInt archreg)969 get_fpr_w0(UInt archreg)
970 {
971    return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
972 }
973 
974 /* Return the guest state offset of double word #0 of a fpr register. */
975 static __inline__ UInt
fpr_dw0_offset(UInt archreg)976 fpr_dw0_offset(UInt archreg)
977 {
978    return fpr_offset(archreg) + 0;
979 }
980 
981 /* Write double word #0 of a fpr to the guest state. */
982 static __inline__ void
put_fpr_dw0(UInt archreg,IRExpr * expr)983 put_fpr_dw0(UInt archreg, IRExpr *expr)
984 {
985    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
986 
987    stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
988 }
989 
990 /* Read double word #0 of a fpr register. */
991 static __inline__ IRExpr *
get_fpr_dw0(UInt archreg)992 get_fpr_dw0(UInt archreg)
993 {
994    return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
995 }
996 
997 /* Write word #0 of a dpr to the guest state. */
998 static __inline__ void
put_dpr_w0(UInt archreg,IRExpr * expr)999 put_dpr_w0(UInt archreg, IRExpr *expr)
1000 {
1001    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
1002 
1003    stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
1004 }
1005 
1006 /* Read word #0 of a dpr register. */
1007 static __inline__ IRExpr *
get_dpr_w0(UInt archreg)1008 get_dpr_w0(UInt archreg)
1009 {
1010    return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
1011 }
1012 
1013 /* Write double word #0 of a fpr containg DFP value to the guest state. */
1014 static __inline__ void
put_dpr_dw0(UInt archreg,IRExpr * expr)1015 put_dpr_dw0(UInt archreg, IRExpr *expr)
1016 {
1017    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
1018 
1019    stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1020 }
1021 
1022 /* Read double word #0 of a fpr register containing DFP value. */
1023 static __inline__ IRExpr *
get_dpr_dw0(UInt archreg)1024 get_dpr_dw0(UInt archreg)
1025 {
1026    return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1027 }
1028 
1029 /*------------------------------------------------------------*/
1030 /*--- gpr registers                                        ---*/
1031 /*------------------------------------------------------------*/
1032 
1033 /* Return the guest state offset of a gpr register. */
1034 static UInt
gpr_offset(UInt archreg)1035 gpr_offset(UInt archreg)
1036 {
1037    static const UInt offset[16] = {
1038       S390X_GUEST_OFFSET(guest_r0),
1039       S390X_GUEST_OFFSET(guest_r1),
1040       S390X_GUEST_OFFSET(guest_r2),
1041       S390X_GUEST_OFFSET(guest_r3),
1042       S390X_GUEST_OFFSET(guest_r4),
1043       S390X_GUEST_OFFSET(guest_r5),
1044       S390X_GUEST_OFFSET(guest_r6),
1045       S390X_GUEST_OFFSET(guest_r7),
1046       S390X_GUEST_OFFSET(guest_r8),
1047       S390X_GUEST_OFFSET(guest_r9),
1048       S390X_GUEST_OFFSET(guest_r10),
1049       S390X_GUEST_OFFSET(guest_r11),
1050       S390X_GUEST_OFFSET(guest_r12),
1051       S390X_GUEST_OFFSET(guest_r13),
1052       S390X_GUEST_OFFSET(guest_r14),
1053       S390X_GUEST_OFFSET(guest_r15),
1054    };
1055 
1056    vassert(archreg < 16);
1057 
1058    return offset[archreg];
1059 }
1060 
1061 
1062 /* Return the guest state offset of word #0 of a gpr register. */
1063 static __inline__ UInt
gpr_w0_offset(UInt archreg)1064 gpr_w0_offset(UInt archreg)
1065 {
1066    return gpr_offset(archreg) + 0;
1067 }
1068 
1069 /* Write word #0 of a gpr to the guest state. */
1070 static __inline__ void
put_gpr_w0(UInt archreg,IRExpr * expr)1071 put_gpr_w0(UInt archreg, IRExpr *expr)
1072 {
1073    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1074 
1075    stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1076 }
1077 
1078 /* Read word #0 of a gpr register. */
1079 static __inline__ IRExpr *
get_gpr_w0(UInt archreg)1080 get_gpr_w0(UInt archreg)
1081 {
1082    return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1083 }
1084 
1085 /* Return the guest state offset of double word #0 of a gpr register. */
1086 static __inline__ UInt
gpr_dw0_offset(UInt archreg)1087 gpr_dw0_offset(UInt archreg)
1088 {
1089    return gpr_offset(archreg) + 0;
1090 }
1091 
1092 /* Write double word #0 of a gpr to the guest state. */
1093 static __inline__ void
put_gpr_dw0(UInt archreg,IRExpr * expr)1094 put_gpr_dw0(UInt archreg, IRExpr *expr)
1095 {
1096    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1097 
1098    stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1099 }
1100 
1101 /* Read double word #0 of a gpr register. */
1102 static __inline__ IRExpr *
get_gpr_dw0(UInt archreg)1103 get_gpr_dw0(UInt archreg)
1104 {
1105    return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1106 }
1107 
1108 /* Return the guest state offset of half word #1 of a gpr register. */
1109 static __inline__ UInt
gpr_hw1_offset(UInt archreg)1110 gpr_hw1_offset(UInt archreg)
1111 {
1112    return gpr_offset(archreg) + 2;
1113 }
1114 
1115 /* Write half word #1 of a gpr to the guest state. */
1116 static __inline__ void
put_gpr_hw1(UInt archreg,IRExpr * expr)1117 put_gpr_hw1(UInt archreg, IRExpr *expr)
1118 {
1119    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1120 
1121    stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1122 }
1123 
1124 /* Read half word #1 of a gpr register. */
1125 static __inline__ IRExpr *
get_gpr_hw1(UInt archreg)1126 get_gpr_hw1(UInt archreg)
1127 {
1128    return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1129 }
1130 
1131 /* Return the guest state offset of byte #6 of a gpr register. */
1132 static __inline__ UInt
gpr_b6_offset(UInt archreg)1133 gpr_b6_offset(UInt archreg)
1134 {
1135    return gpr_offset(archreg) + 6;
1136 }
1137 
1138 /* Write byte #6 of a gpr to the guest state. */
1139 static __inline__ void
put_gpr_b6(UInt archreg,IRExpr * expr)1140 put_gpr_b6(UInt archreg, IRExpr *expr)
1141 {
1142    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1143 
1144    stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1145 }
1146 
1147 /* Read byte #6 of a gpr register. */
1148 static __inline__ IRExpr *
get_gpr_b6(UInt archreg)1149 get_gpr_b6(UInt archreg)
1150 {
1151    return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1152 }
1153 
1154 /* Return the guest state offset of byte #3 of a gpr register. */
1155 static __inline__ UInt
gpr_b3_offset(UInt archreg)1156 gpr_b3_offset(UInt archreg)
1157 {
1158    return gpr_offset(archreg) + 3;
1159 }
1160 
1161 /* Write byte #3 of a gpr to the guest state. */
1162 static __inline__ void
put_gpr_b3(UInt archreg,IRExpr * expr)1163 put_gpr_b3(UInt archreg, IRExpr *expr)
1164 {
1165    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1166 
1167    stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1168 }
1169 
1170 /* Read byte #3 of a gpr register. */
1171 static __inline__ IRExpr *
get_gpr_b3(UInt archreg)1172 get_gpr_b3(UInt archreg)
1173 {
1174    return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1175 }
1176 
1177 /* Return the guest state offset of byte #0 of a gpr register. */
1178 static __inline__ UInt
gpr_b0_offset(UInt archreg)1179 gpr_b0_offset(UInt archreg)
1180 {
1181    return gpr_offset(archreg) + 0;
1182 }
1183 
1184 /* Write byte #0 of a gpr to the guest state. */
1185 static __inline__ void
put_gpr_b0(UInt archreg,IRExpr * expr)1186 put_gpr_b0(UInt archreg, IRExpr *expr)
1187 {
1188    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1189 
1190    stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1191 }
1192 
1193 /* Read byte #0 of a gpr register. */
1194 static __inline__ IRExpr *
get_gpr_b0(UInt archreg)1195 get_gpr_b0(UInt archreg)
1196 {
1197    return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1198 }
1199 
1200 /* Return the guest state offset of word #1 of a gpr register. */
1201 static __inline__ UInt
gpr_w1_offset(UInt archreg)1202 gpr_w1_offset(UInt archreg)
1203 {
1204    return gpr_offset(archreg) + 4;
1205 }
1206 
1207 /* Write word #1 of a gpr to the guest state. */
1208 static __inline__ void
put_gpr_w1(UInt archreg,IRExpr * expr)1209 put_gpr_w1(UInt archreg, IRExpr *expr)
1210 {
1211    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1212 
1213    stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1214 }
1215 
1216 /* Read word #1 of a gpr register. */
1217 static __inline__ IRExpr *
get_gpr_w1(UInt archreg)1218 get_gpr_w1(UInt archreg)
1219 {
1220    return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1221 }
1222 
1223 /* Return the guest state offset of half word #3 of a gpr register. */
1224 static __inline__ UInt
gpr_hw3_offset(UInt archreg)1225 gpr_hw3_offset(UInt archreg)
1226 {
1227    return gpr_offset(archreg) + 6;
1228 }
1229 
1230 /* Write half word #3 of a gpr to the guest state. */
1231 static __inline__ void
put_gpr_hw3(UInt archreg,IRExpr * expr)1232 put_gpr_hw3(UInt archreg, IRExpr *expr)
1233 {
1234    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1235 
1236    stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1237 }
1238 
1239 /* Read half word #3 of a gpr register. */
1240 static __inline__ IRExpr *
get_gpr_hw3(UInt archreg)1241 get_gpr_hw3(UInt archreg)
1242 {
1243    return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1244 }
1245 
1246 /* Return the guest state offset of byte #7 of a gpr register. */
1247 static __inline__ UInt
gpr_b7_offset(UInt archreg)1248 gpr_b7_offset(UInt archreg)
1249 {
1250    return gpr_offset(archreg) + 7;
1251 }
1252 
1253 /* Write byte #7 of a gpr to the guest state. */
1254 static __inline__ void
put_gpr_b7(UInt archreg,IRExpr * expr)1255 put_gpr_b7(UInt archreg, IRExpr *expr)
1256 {
1257    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1258 
1259    stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1260 }
1261 
1262 /* Read byte #7 of a gpr register. */
1263 static __inline__ IRExpr *
get_gpr_b7(UInt archreg)1264 get_gpr_b7(UInt archreg)
1265 {
1266    return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1267 }
1268 
1269 /* Return the guest state offset of half word #0 of a gpr register. */
1270 static __inline__ UInt
gpr_hw0_offset(UInt archreg)1271 gpr_hw0_offset(UInt archreg)
1272 {
1273    return gpr_offset(archreg) + 0;
1274 }
1275 
1276 /* Write half word #0 of a gpr to the guest state. */
1277 static __inline__ void
put_gpr_hw0(UInt archreg,IRExpr * expr)1278 put_gpr_hw0(UInt archreg, IRExpr *expr)
1279 {
1280    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1281 
1282    stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1283 }
1284 
1285 /* Read half word #0 of a gpr register. */
1286 static __inline__ IRExpr *
get_gpr_hw0(UInt archreg)1287 get_gpr_hw0(UInt archreg)
1288 {
1289    return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1290 }
1291 
1292 /* Return the guest state offset of byte #4 of a gpr register. */
1293 static __inline__ UInt
gpr_b4_offset(UInt archreg)1294 gpr_b4_offset(UInt archreg)
1295 {
1296    return gpr_offset(archreg) + 4;
1297 }
1298 
1299 /* Write byte #4 of a gpr to the guest state. */
1300 static __inline__ void
put_gpr_b4(UInt archreg,IRExpr * expr)1301 put_gpr_b4(UInt archreg, IRExpr *expr)
1302 {
1303    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1304 
1305    stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1306 }
1307 
1308 /* Read byte #4 of a gpr register. */
1309 static __inline__ IRExpr *
get_gpr_b4(UInt archreg)1310 get_gpr_b4(UInt archreg)
1311 {
1312    return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1313 }
1314 
1315 /* Return the guest state offset of byte #1 of a gpr register. */
1316 static __inline__ UInt
gpr_b1_offset(UInt archreg)1317 gpr_b1_offset(UInt archreg)
1318 {
1319    return gpr_offset(archreg) + 1;
1320 }
1321 
1322 /* Write byte #1 of a gpr to the guest state. */
1323 static __inline__ void
put_gpr_b1(UInt archreg,IRExpr * expr)1324 put_gpr_b1(UInt archreg, IRExpr *expr)
1325 {
1326    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1327 
1328    stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1329 }
1330 
1331 /* Read byte #1 of a gpr register. */
1332 static __inline__ IRExpr *
get_gpr_b1(UInt archreg)1333 get_gpr_b1(UInt archreg)
1334 {
1335    return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1336 }
1337 
1338 /* Return the guest state offset of half word #2 of a gpr register. */
1339 static __inline__ UInt
gpr_hw2_offset(UInt archreg)1340 gpr_hw2_offset(UInt archreg)
1341 {
1342    return gpr_offset(archreg) + 4;
1343 }
1344 
1345 /* Write half word #2 of a gpr to the guest state. */
1346 static __inline__ void
put_gpr_hw2(UInt archreg,IRExpr * expr)1347 put_gpr_hw2(UInt archreg, IRExpr *expr)
1348 {
1349    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1350 
1351    stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1352 }
1353 
1354 /* Read half word #2 of a gpr register. */
1355 static __inline__ IRExpr *
get_gpr_hw2(UInt archreg)1356 get_gpr_hw2(UInt archreg)
1357 {
1358    return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1359 }
1360 
1361 /* Return the guest state offset of byte #5 of a gpr register. */
1362 static __inline__ UInt
gpr_b5_offset(UInt archreg)1363 gpr_b5_offset(UInt archreg)
1364 {
1365    return gpr_offset(archreg) + 5;
1366 }
1367 
1368 /* Write byte #5 of a gpr to the guest state. */
1369 static __inline__ void
put_gpr_b5(UInt archreg,IRExpr * expr)1370 put_gpr_b5(UInt archreg, IRExpr *expr)
1371 {
1372    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1373 
1374    stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1375 }
1376 
1377 /* Read byte #5 of a gpr register. */
1378 static __inline__ IRExpr *
get_gpr_b5(UInt archreg)1379 get_gpr_b5(UInt archreg)
1380 {
1381    return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1382 }
1383 
1384 /* Return the guest state offset of byte #2 of a gpr register. */
1385 static __inline__ UInt
gpr_b2_offset(UInt archreg)1386 gpr_b2_offset(UInt archreg)
1387 {
1388    return gpr_offset(archreg) + 2;
1389 }
1390 
1391 /* Write byte #2 of a gpr to the guest state. */
1392 static __inline__ void
put_gpr_b2(UInt archreg,IRExpr * expr)1393 put_gpr_b2(UInt archreg, IRExpr *expr)
1394 {
1395    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1396 
1397    stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1398 }
1399 
1400 /* Read byte #2 of a gpr register. */
1401 static __inline__ IRExpr *
get_gpr_b2(UInt archreg)1402 get_gpr_b2(UInt archreg)
1403 {
1404    return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1405 }
1406 
1407 /* Return the guest state offset of the counter register. */
1408 static UInt
counter_offset(void)1409 counter_offset(void)
1410 {
1411    return S390X_GUEST_OFFSET(guest_counter);
1412 }
1413 
1414 /* Return the guest state offset of double word #0 of the counter register. */
1415 static __inline__ UInt
counter_dw0_offset(void)1416 counter_dw0_offset(void)
1417 {
1418    return counter_offset() + 0;
1419 }
1420 
1421 /* Write double word #0 of the counter to the guest state. */
1422 static __inline__ void
put_counter_dw0(IRExpr * expr)1423 put_counter_dw0(IRExpr *expr)
1424 {
1425    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1426 
1427    stmt(IRStmt_Put(counter_dw0_offset(), expr));
1428 }
1429 
1430 /* Read double word #0 of the counter register. */
1431 static __inline__ IRExpr *
get_counter_dw0(void)1432 get_counter_dw0(void)
1433 {
1434    return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1435 }
1436 
1437 /* Return the guest state offset of word #0 of the counter register. */
1438 static __inline__ UInt
counter_w0_offset(void)1439 counter_w0_offset(void)
1440 {
1441    return counter_offset() + 0;
1442 }
1443 
1444 /* Return the guest state offset of word #1 of the counter register. */
1445 static __inline__ UInt
counter_w1_offset(void)1446 counter_w1_offset(void)
1447 {
1448    return counter_offset() + 4;
1449 }
1450 
1451 /* Write word #0 of the counter to the guest state. */
1452 static __inline__ void
put_counter_w0(IRExpr * expr)1453 put_counter_w0(IRExpr *expr)
1454 {
1455    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1456 
1457    stmt(IRStmt_Put(counter_w0_offset(), expr));
1458 }
1459 
1460 /* Read word #0 of the counter register. */
1461 static __inline__ IRExpr *
get_counter_w0(void)1462 get_counter_w0(void)
1463 {
1464    return IRExpr_Get(counter_w0_offset(), Ity_I32);
1465 }
1466 
1467 /* Write word #1 of the counter to the guest state. */
1468 static __inline__ void
put_counter_w1(IRExpr * expr)1469 put_counter_w1(IRExpr *expr)
1470 {
1471    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1472 
1473    stmt(IRStmt_Put(counter_w1_offset(), expr));
1474 }
1475 
1476 /* Read word #1 of the counter register. */
1477 static __inline__ IRExpr *
get_counter_w1(void)1478 get_counter_w1(void)
1479 {
1480    return IRExpr_Get(counter_w1_offset(), Ity_I32);
1481 }
1482 
1483 /* Return the guest state offset of the fpc register. */
1484 static UInt
fpc_offset(void)1485 fpc_offset(void)
1486 {
1487    return S390X_GUEST_OFFSET(guest_fpc);
1488 }
1489 
1490 /* Return the guest state offset of word #0 of the fpc register. */
1491 static __inline__ UInt
fpc_w0_offset(void)1492 fpc_w0_offset(void)
1493 {
1494    return fpc_offset() + 0;
1495 }
1496 
1497 /* Write word #0 of the fpc to the guest state. */
1498 static __inline__ void
put_fpc_w0(IRExpr * expr)1499 put_fpc_w0(IRExpr *expr)
1500 {
1501    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1502 
1503    stmt(IRStmt_Put(fpc_w0_offset(), expr));
1504 }
1505 
1506 /* Read word #0 of the fpc register. */
1507 static __inline__ IRExpr *
get_fpc_w0(void)1508 get_fpc_w0(void)
1509 {
1510    return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1511 }
1512 
1513 
1514 /*------------------------------------------------------------*/
1515 /*--- Rounding modes                                       ---*/
1516 /*------------------------------------------------------------*/
1517 
1518 /* Extract the bfp rounding mode from the guest FPC reg and encode it as an
1519    IRRoundingMode:
1520 
1521    rounding mode | s390 | IR
1522    -------------------------
1523    to nearest    |  00  | 00
1524    to zero       |  01  | 11
1525    to +infinity  |  10  | 10
1526    to -infinity  |  11  | 01
1527 
1528    So:  IR = (4 - s390) & 3
1529 */
1530 static IRExpr *
get_bfp_rounding_mode_from_fpc(void)1531 get_bfp_rounding_mode_from_fpc(void)
1532 {
1533    IRTemp fpc_bits = newTemp(Ity_I32);
1534 
1535    /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1536       Prior to that bits [30:31] contained the bfp rounding mode with
1537       bit 29 being unused and having a value of 0. So we can always
1538       extract the least significant 3 bits. */
1539    assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1540 
1541    /* fixs390:
1542 
1543 
1544       if (! s390_host_has_fpext && rounding_mode > 3) {
1545          emulation warning @ runtime and
1546          set fpc to round nearest
1547       }
1548    */
1549 
1550    /* For now silently adjust an unsupported rounding mode to "nearest" */
1551    IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1552                            mkexpr(fpc_bits),
1553                            mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
1554 
1555    // rm_IR = (4 - rm_s390) & 3;
1556    return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1557 }
1558 
1559 /* Encode the s390 rounding mode as it appears in the m3 field of certain
1560    instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1561    represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1562    Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1563    considers the default rounding mode (4.3.3). */
1564 static IRTemp
encode_bfp_rounding_mode(UChar mode)1565 encode_bfp_rounding_mode(UChar mode)
1566 {
1567    IRExpr *rm;
1568 
1569    switch (mode) {
1570    case S390_BFP_ROUND_PER_FPC:
1571       rm = get_bfp_rounding_mode_from_fpc();
1572       break;
1573    case S390_BFP_ROUND_NEAREST_AWAY:  /* not supported */
1574    case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1575    case S390_BFP_ROUND_NEAREST_EVEN:  rm = mkU32(Irrm_NEAREST); break;
1576    case S390_BFP_ROUND_ZERO:          rm = mkU32(Irrm_ZERO);    break;
1577    case S390_BFP_ROUND_POSINF:        rm = mkU32(Irrm_PosINF);  break;
1578    case S390_BFP_ROUND_NEGINF:        rm = mkU32(Irrm_NegINF);  break;
1579    default:
1580       vpanic("encode_bfp_rounding_mode");
1581    }
1582 
1583    return mktemp(Ity_I32, rm);
1584 }
1585 
1586 /* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1587    IRRoundingMode:
1588 
1589    rounding mode                     | s390  | IR
1590    ------------------------------------------------
1591    to nearest, ties to even          |  000  | 000
1592    to zero                           |  001  | 011
1593    to +infinity                      |  010  | 010
1594    to -infinity                      |  011  | 001
1595    to nearest, ties away from 0      |  100  | 100
1596    to nearest, ties toward 0         |  101  | 111
1597    to away from 0                    |  110  | 110
1598    to prepare for shorter precision  |  111  | 101
1599 
1600    So:  IR = (s390 ^ ((s390 << 1) & 2))
1601 */
1602 static IRExpr *
get_dfp_rounding_mode_from_fpc(void)1603 get_dfp_rounding_mode_from_fpc(void)
1604 {
1605    IRTemp fpc_bits = newTemp(Ity_I32);
1606 
1607    /* The dfp rounding mode is stored in bits [25:27].
1608       extract the bits at 25:27 and right shift 4 times. */
1609    assign(fpc_bits, binop(Iop_Shr32,
1610                           binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1611                           mkU8(4)));
1612 
1613    IRExpr *rm_s390 = mkexpr(fpc_bits);
1614    // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1615 
1616    return binop(Iop_Xor32, rm_s390,
1617                 binop( Iop_And32,
1618                        binop(Iop_Shl32, rm_s390, mkU8(1)),
1619                        mkU32(2)));
1620 }
1621 
1622 /* Encode the s390 rounding mode as it appears in the m3 field of certain
1623    instructions to VEX's IRRoundingMode. */
1624 static IRTemp
encode_dfp_rounding_mode(UChar mode)1625 encode_dfp_rounding_mode(UChar mode)
1626 {
1627    IRExpr *rm;
1628 
1629    switch (mode) {
1630    case S390_DFP_ROUND_PER_FPC_0:
1631    case S390_DFP_ROUND_PER_FPC_2:
1632       rm = get_dfp_rounding_mode_from_fpc(); break;
1633    case S390_DFP_ROUND_NEAREST_EVEN_4:
1634    case S390_DFP_ROUND_NEAREST_EVEN_8:
1635       rm = mkU32(Irrm_NEAREST); break;
1636    case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1637    case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1638       rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
1639    case S390_DFP_ROUND_PREPARE_SHORT_3:
1640    case S390_DFP_ROUND_PREPARE_SHORT_15:
1641       rm = mkU32(Irrm_PREPARE_SHORTER); break;
1642    case S390_DFP_ROUND_ZERO_5:
1643    case S390_DFP_ROUND_ZERO_9:
1644       rm = mkU32(Irrm_ZERO ); break;
1645    case S390_DFP_ROUND_POSINF_6:
1646    case S390_DFP_ROUND_POSINF_10:
1647       rm = mkU32(Irrm_PosINF); break;
1648    case S390_DFP_ROUND_NEGINF_7:
1649    case S390_DFP_ROUND_NEGINF_11:
1650       rm = mkU32(Irrm_NegINF); break;
1651    case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1652       rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
1653    case S390_DFP_ROUND_AWAY_0:
1654       rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
1655    default:
1656       vpanic("encode_dfp_rounding_mode");
1657    }
1658 
1659    return mktemp(Ity_I32, rm);
1660 }
1661 
1662 
1663 /*------------------------------------------------------------*/
1664 /*--- Condition code helpers                               ---*/
1665 /*------------------------------------------------------------*/
1666 
1667 /* The result of a Iop_CmpFxx operation is a condition code. It is
1668    encoded using the values defined in type IRCmpFxxResult.
1669    Before we can store the condition code into the guest state (or do
1670    anything else with it for that matter) we need to convert it to
1671    the encoding that s390 uses. This is what this function does.
1672 
1673    s390     VEX                b6 b2 b0   cc.1  cc.0
1674    0      0x40 EQ             1  0  0     0     0
1675    1      0x01 LT             0  0  1     0     1
1676    2      0x00 GT             0  0  0     1     0
1677    3      0x45 Unordered      1  1  1     1     1
1678 
1679    The following bits from the VEX encoding are interesting:
1680    b0, b2, b6  with b0 being the LSB. We observe:
1681 
1682    cc.0 = b0;
1683    cc.1 = b2 | (~b0 & ~b6)
1684 
1685    with cc being the s390 condition code.
1686 */
1687 static IRExpr *
convert_vex_bfpcc_to_s390(IRTemp vex_cc)1688 convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1689 {
1690    IRTemp cc0  = newTemp(Ity_I32);
1691    IRTemp cc1  = newTemp(Ity_I32);
1692    IRTemp b0   = newTemp(Ity_I32);
1693    IRTemp b2   = newTemp(Ity_I32);
1694    IRTemp b6   = newTemp(Ity_I32);
1695 
1696    assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1697    assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1698                     mkU32(1)));
1699    assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1700                     mkU32(1)));
1701 
1702    assign(cc0, mkexpr(b0));
1703    assign(cc1, binop(Iop_Or32, mkexpr(b2),
1704                      binop(Iop_And32,
1705                            binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1706                            binop(Iop_Sub32, mkU32(1), mkexpr(b6))  /* ~b6 */
1707                            )));
1708 
1709    return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1710 }
1711 
1712 
1713 /* The result of a Iop_CmpDxx operation is a condition code. It is
1714    encoded using the values defined in type IRCmpDxxResult.
1715    Before we can store the condition code into the guest state (or do
1716    anything else with it for that matter) we need to convert it to
1717    the encoding that s390 uses. This is what this function does. */
1718 static IRExpr *
convert_vex_dfpcc_to_s390(IRTemp vex_cc)1719 convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1720 {
1721    /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1722       same. currently. */
1723    return convert_vex_bfpcc_to_s390(vex_cc);
1724 }
1725 
1726 
1727 /*------------------------------------------------------------*/
1728 /*--- Build IR for formats                                 ---*/
1729 /*------------------------------------------------------------*/
1730 static void
s390_format_I(const HChar * (* irgen)(UChar i),UChar i)1731 s390_format_I(const HChar *(*irgen)(UChar i),
1732               UChar i)
1733 {
1734    const HChar *mnm = irgen(i);
1735 
1736    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1737       s390_disasm(ENC2(MNM, UINT), mnm, i);
1738 }
1739 
1740 static void
s390_format_E(const HChar * (* irgen)(void))1741 s390_format_E(const HChar *(*irgen)(void))
1742 {
1743    const HChar *mnm = irgen();
1744 
1745    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1746       s390_disasm(ENC1(MNM), mnm);
1747 }
1748 
1749 static void
s390_format_RI(const HChar * (* irgen)(UChar r1,UShort i2),UChar r1,UShort i2)1750 s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
1751                UChar r1, UShort i2)
1752 {
1753    irgen(r1, i2);
1754 }
1755 
1756 static void
s390_format_RI_RU(const HChar * (* irgen)(UChar r1,UShort i2),UChar r1,UShort i2)1757 s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
1758                   UChar r1, UShort i2)
1759 {
1760    const HChar *mnm = irgen(r1, i2);
1761 
1762    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1763       s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1764 }
1765 
1766 static void
s390_format_RI_RI(const HChar * (* irgen)(UChar r1,UShort i2),UChar r1,UShort i2)1767 s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
1768                   UChar r1, UShort i2)
1769 {
1770    const HChar *mnm = irgen(r1, i2);
1771 
1772    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1773       s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1774 }
1775 
1776 static void
s390_format_RI_RP(const HChar * (* irgen)(UChar r1,UShort i2),UChar r1,UShort i2)1777 s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
1778                   UChar r1, UShort i2)
1779 {
1780    const HChar *mnm = irgen(r1, i2);
1781 
1782    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1783       s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1784 }
1785 
1786 static void
s390_format_RIE_RRP(const HChar * (* irgen)(UChar r1,UChar r3,UShort i2),UChar r1,UChar r3,UShort i2)1787 s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1788                     UChar r1, UChar r3, UShort i2)
1789 {
1790    const HChar *mnm = irgen(r1, r3, i2);
1791 
1792    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1793       s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1794 }
1795 
1796 static void
s390_format_RIE_RRI0(const HChar * (* irgen)(UChar r1,UChar r3,UShort i2),UChar r1,UChar r3,UShort i2)1797 s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1798                      UChar r1, UChar r3, UShort i2)
1799 {
1800    const HChar *mnm = irgen(r1, r3, i2);
1801 
1802    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1803       s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1804 }
1805 
1806 static void
s390_format_RIE_RRUUU(const HChar * (* irgen)(UChar r1,UChar r2,UChar i3,UChar i4,UChar i5),UChar r1,UChar r2,UChar i3,UChar i4,UChar i5)1807 s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1808                                             UChar i4, UChar i5),
1809                       UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1810 {
1811    const HChar *mnm = irgen(r1, r2, i3, i4, i5);
1812 
1813    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1814       s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1815                   i5);
1816 }
1817 
1818 static void
s390_format_RIE_RRPU(const HChar * (* irgen)(UChar r1,UChar r2,UShort i4,UChar m3),UChar r1,UChar r2,UShort i4,UChar m3)1819 s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1820                                            UChar m3),
1821                      UChar r1, UChar r2, UShort i4, UChar m3)
1822 {
1823    const HChar *mnm = irgen(r1, r2, i4, m3);
1824 
1825    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1826       s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1827                   r2, m3, (Int)(Short)i4);
1828 }
1829 
1830 static void
s390_format_RIE_RUPU(const HChar * (* irgen)(UChar r1,UChar m3,UShort i4,UChar i2),UChar r1,UChar m3,UShort i4,UChar i2)1831 s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1832                                            UChar i2),
1833                      UChar r1, UChar m3, UShort i4, UChar i2)
1834 {
1835    const HChar *mnm = irgen(r1, m3, i4, i2);
1836 
1837    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1838       s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1839                   r1, i2, m3, (Int)(Short)i4);
1840 }
1841 
1842 static void
s390_format_RIE_RUPI(const HChar * (* irgen)(UChar r1,UChar m3,UShort i4,UChar i2),UChar r1,UChar m3,UShort i4,UChar i2)1843 s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1844                                            UChar i2),
1845                      UChar r1, UChar m3, UShort i4, UChar i2)
1846 {
1847    const HChar *mnm = irgen(r1, m3, i4, i2);
1848 
1849    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1850       s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1851                   (Int)(Char)i2, m3, (Int)(Short)i4);
1852 }
1853 
1854 static void
s390_format_RIL(const HChar * (* irgen)(UChar r1,UInt i2),UChar r1,UInt i2)1855 s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
1856                 UChar r1, UInt i2)
1857 {
1858    irgen(r1, i2);
1859 }
1860 
1861 static void
s390_format_RIL_RU(const HChar * (* irgen)(UChar r1,UInt i2),UChar r1,UInt i2)1862 s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
1863                    UChar r1, UInt i2)
1864 {
1865    const HChar *mnm = irgen(r1, i2);
1866 
1867    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1868       s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1869 }
1870 
1871 static void
s390_format_RIL_RI(const HChar * (* irgen)(UChar r1,UInt i2),UChar r1,UInt i2)1872 s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
1873                    UChar r1, UInt i2)
1874 {
1875    const HChar *mnm = irgen(r1, i2);
1876 
1877    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1878       s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1879 }
1880 
1881 static void
s390_format_RIL_RP(const HChar * (* irgen)(UChar r1,UInt i2),UChar r1,UInt i2)1882 s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
1883                    UChar r1, UInt i2)
1884 {
1885    const HChar *mnm = irgen(r1, i2);
1886 
1887    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1888       s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1889 }
1890 
1891 static void
s390_format_RIL_UP(const HChar * (* irgen)(void),UChar r1,UInt i2)1892 s390_format_RIL_UP(const HChar *(*irgen)(void),
1893                    UChar r1, UInt i2)
1894 {
1895    const HChar *mnm = irgen();
1896 
1897    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1898       s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1899 }
1900 
1901 static void
s390_format_RIS_RURDI(const HChar * (* irgen)(UChar r1,UChar m3,UChar i2,IRTemp op4addr),UChar r1,UChar m3,UChar b4,UShort d4,UChar i2)1902 s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1903                       IRTemp op4addr),
1904                       UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1905 {
1906    const HChar *mnm;
1907    IRTemp op4addr = newTemp(Ity_I64);
1908 
1909    assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1910           mkU64(0)));
1911 
1912    mnm = irgen(r1, m3, i2, op4addr);
1913 
1914    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1915       s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1916                   (Int)(Char)i2, m3, d4, 0, b4);
1917 }
1918 
1919 static void
s390_format_RIS_RURDU(const HChar * (* irgen)(UChar r1,UChar m3,UChar i2,IRTemp op4addr),UChar r1,UChar m3,UChar b4,UShort d4,UChar i2)1920 s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1921                       IRTemp op4addr),
1922                       UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1923 {
1924    const HChar *mnm;
1925    IRTemp op4addr = newTemp(Ity_I64);
1926 
1927    assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1928           mkU64(0)));
1929 
1930    mnm = irgen(r1, m3, i2, op4addr);
1931 
1932    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1933       s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1934                   i2, m3, d4, 0, b4);
1935 }
1936 
1937 static void
s390_format_RR(const HChar * (* irgen)(UChar r1,UChar r2),UChar r1,UChar r2)1938 s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
1939                UChar r1, UChar r2)
1940 {
1941    irgen(r1, r2);
1942 }
1943 
1944 static void
s390_format_RR_RR(const HChar * (* irgen)(UChar r1,UChar r2),UChar r1,UChar r2)1945 s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
1946                   UChar r1, UChar r2)
1947 {
1948    const HChar *mnm = irgen(r1, r2);
1949 
1950    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1951       s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1952 }
1953 
1954 static void
s390_format_RR_FF(const HChar * (* irgen)(UChar r1,UChar r2),UChar r1,UChar r2)1955 s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
1956                   UChar r1, UChar r2)
1957 {
1958    const HChar *mnm = irgen(r1, r2);
1959 
1960    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1961       s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1962 }
1963 
1964 static void
s390_format_RRE(const HChar * (* irgen)(UChar r1,UChar r2),UChar r1,UChar r2)1965 s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
1966                 UChar r1, UChar r2)
1967 {
1968    irgen(r1, r2);
1969 }
1970 
1971 static void
s390_format_RRE_RR(const HChar * (* irgen)(UChar r1,UChar r2),UChar r1,UChar r2)1972 s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
1973                    UChar r1, UChar r2)
1974 {
1975    const HChar *mnm = irgen(r1, r2);
1976 
1977    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1978       s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1979 }
1980 
1981 static void
s390_format_RRE_FF(const HChar * (* irgen)(UChar r1,UChar r2),UChar r1,UChar r2)1982 s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
1983                    UChar r1, UChar r2)
1984 {
1985    const HChar *mnm = irgen(r1, r2);
1986 
1987    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1988       s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1989 }
1990 
1991 static void
s390_format_RRE_RF(const HChar * (* irgen)(UChar,UChar),UChar r1,UChar r2)1992 s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
1993                    UChar r1, UChar r2)
1994 {
1995    const HChar *mnm = irgen(r1, r2);
1996 
1997    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1998       s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1999 }
2000 
2001 static void
s390_format_RRE_FR(const HChar * (* irgen)(UChar r1,UChar r2),UChar r1,UChar r2)2002 s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
2003                    UChar r1, UChar r2)
2004 {
2005    const HChar *mnm = irgen(r1, r2);
2006 
2007    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2008       s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
2009 }
2010 
2011 static void
s390_format_RRE_R0(const HChar * (* irgen)(UChar r1),UChar r1)2012 s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
2013                    UChar r1)
2014 {
2015    const HChar *mnm = irgen(r1);
2016 
2017    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2018       s390_disasm(ENC2(MNM, GPR), mnm, r1);
2019 }
2020 
2021 static void
s390_format_RRE_F0(const HChar * (* irgen)(UChar r1),UChar r1)2022 s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
2023                    UChar r1)
2024 {
2025    const HChar *mnm = irgen(r1);
2026 
2027    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2028       s390_disasm(ENC2(MNM, FPR), mnm, r1);
2029 }
2030 
2031 static void
s390_format_RRF_M0RERE(const HChar * (* irgen)(UChar m3,UChar r1,UChar r2),UChar m3,UChar r1,UChar r2)2032 s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
2033                        UChar m3, UChar r1, UChar r2)
2034 {
2035    const HChar *mnm = irgen(m3, r1, r2);
2036 
2037    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2038       s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
2039 }
2040 
2041 static void
s390_format_RRF_F0FF(const HChar * (* irgen)(UChar,UChar,UChar),UChar r1,UChar r3,UChar r2)2042 s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
2043                      UChar r1, UChar r3, UChar r2)
2044 {
2045    const HChar *mnm = irgen(r1, r3, r2);
2046 
2047    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2048       s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2049 }
2050 
2051 static void
s390_format_RRF_F0FR(const HChar * (* irgen)(UChar,UChar,UChar),UChar r3,UChar r1,UChar r2)2052 s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2053                      UChar r3, UChar r1, UChar r2)
2054 {
2055    const HChar *mnm = irgen(r3, r1, r2);
2056 
2057    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2058       s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2059 }
2060 
2061 static void
s390_format_RRF_UUFF(const HChar * (* irgen)(UChar m3,UChar m4,UChar r1,UChar r2),UChar m3,UChar m4,UChar r1,UChar r2)2062 s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2063                                            UChar r2),
2064                      UChar m3, UChar m4, UChar r1, UChar r2)
2065 {
2066    const HChar *mnm = irgen(m3, m4, r1, r2);
2067 
2068    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2069       s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2070 }
2071 
2072 static void
s390_format_RRF_0UFF(const HChar * (* irgen)(UChar m4,UChar r1,UChar r2),UChar m4,UChar r1,UChar r2)2073 s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2074                      UChar m4, UChar r1, UChar r2)
2075 {
2076    const HChar *mnm = irgen(m4, r1, r2);
2077 
2078    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2079       s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2080 }
2081 
2082 static void
s390_format_RRF_UUFR(const HChar * (* irgen)(UChar m3,UChar m4,UChar r1,UChar r2),UChar m3,UChar m4,UChar r1,UChar r2)2083 s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2084                                            UChar r2),
2085                      UChar m3, UChar m4, UChar r1, UChar r2)
2086 {
2087    const HChar *mnm = irgen(m3, m4, r1, r2);
2088 
2089    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2090       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2091 }
2092 
2093 static void
s390_format_RRF_UURF(const HChar * (* irgen)(UChar m3,UChar m4,UChar r1,UChar r2),UChar m3,UChar m4,UChar r1,UChar r2)2094 s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2095                                            UChar r2),
2096                      UChar m3, UChar m4, UChar r1, UChar r2)
2097 {
2098    const HChar *mnm = irgen(m3, m4, r1, r2);
2099 
2100    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2101       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2102 }
2103 
2104 
2105 static void
s390_format_RRF_U0RR(const HChar * (* irgen)(UChar m3,UChar r1,UChar r2),UChar m3,UChar r1,UChar r2,Int xmnm_kind)2106 s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
2107                      UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2108 {
2109    irgen(m3, r1, r2);
2110 
2111    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2112       s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2113 }
2114 
2115 static void
s390_format_RRF_F0FF2(const HChar * (* irgen)(UChar,UChar,UChar),UChar r3,UChar r1,UChar r2)2116 s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
2117                       UChar r3, UChar r1, UChar r2)
2118 {
2119    const HChar *mnm = irgen(r3, r1, r2);
2120 
2121    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2122       s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2123 }
2124 
2125 static void
s390_format_RRF_FFRU(const HChar * (* irgen)(UChar,UChar,UChar,UChar),UChar r3,UChar m4,UChar r1,UChar r2)2126 s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2127                      UChar r3, UChar m4, UChar r1, UChar r2)
2128 {
2129    const HChar *mnm = irgen(r3, m4, r1, r2);
2130 
2131    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2132       s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2133 }
2134 
2135 static void
s390_format_RRF_FUFF(const HChar * (* irgen)(UChar,UChar,UChar,UChar),UChar r3,UChar m4,UChar r1,UChar r2)2136 s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2137                      UChar r3, UChar m4, UChar r1, UChar r2)
2138 {
2139    const HChar *mnm = irgen(r3, m4, r1, r2);
2140 
2141    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2142       s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2143 }
2144 
2145 static void
s390_format_RRF_FUFF2(const HChar * (* irgen)(UChar,UChar,UChar,UChar),UChar r3,UChar m4,UChar r1,UChar r2)2146 s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2147                       UChar r3, UChar m4, UChar r1, UChar r2)
2148 {
2149    const HChar *mnm = irgen(r3, m4, r1, r2);
2150 
2151    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2152       s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2153 }
2154 
2155 static void
s390_format_RRF_R0RR2(const HChar * (* irgen)(UChar r3,UChar r1,UChar r2),UChar r3,UChar r1,UChar r2)2156 s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
2157                       UChar r3, UChar r1, UChar r2)
2158 {
2159    const HChar *mnm = irgen(r3, r1, r2);
2160 
2161    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2162       s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2163 }
2164 
2165 static void
s390_format_RRS(const HChar * (* irgen)(UChar r1,UChar r2,UChar m3,IRTemp op4addr),UChar r1,UChar r2,UChar b4,UShort d4,UChar m3)2166 s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2167                                       IRTemp op4addr),
2168                 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2169 {
2170    const HChar *mnm;
2171    IRTemp op4addr = newTemp(Ity_I64);
2172 
2173    assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2174           mkU64(0)));
2175 
2176    mnm = irgen(r1, r2, m3, op4addr);
2177 
2178    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2179       s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2180                   r2, m3, d4, 0, b4);
2181 }
2182 
2183 static void
s390_format_RS_R0RD(const HChar * (* irgen)(UChar r1,IRTemp op2addr),UChar r1,UChar b2,UShort d2)2184 s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2185                     UChar r1, UChar b2, UShort d2)
2186 {
2187    const HChar *mnm;
2188    IRTemp op2addr = newTemp(Ity_I64);
2189 
2190    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2191           mkU64(0)));
2192 
2193    mnm = irgen(r1, op2addr);
2194 
2195    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2196       s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2197 }
2198 
2199 static void
s390_format_RS_RRRD(const HChar * (* irgen)(UChar r1,UChar r3,IRTemp op2addr),UChar r1,UChar r3,UChar b2,UShort d2)2200 s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2201                     UChar r1, UChar r3, UChar b2, UShort d2)
2202 {
2203    const HChar *mnm;
2204    IRTemp op2addr = newTemp(Ity_I64);
2205 
2206    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2207           mkU64(0)));
2208 
2209    mnm = irgen(r1, r3, op2addr);
2210 
2211    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2212       s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2213 }
2214 
2215 static void
s390_format_RS_RURD(const HChar * (* irgen)(UChar r1,UChar r3,IRTemp op2addr),UChar r1,UChar r3,UChar b2,UShort d2)2216 s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2217                     UChar r1, UChar r3, UChar b2, UShort d2)
2218 {
2219    const HChar *mnm;
2220    IRTemp op2addr = newTemp(Ity_I64);
2221 
2222    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2223           mkU64(0)));
2224 
2225    mnm = irgen(r1, r3, op2addr);
2226 
2227    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2228       s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2229 }
2230 
2231 static void
s390_format_RS_AARD(const HChar * (* irgen)(UChar,UChar,IRTemp),UChar r1,UChar r3,UChar b2,UShort d2)2232 s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
2233                     UChar r1, UChar r3, UChar b2, UShort d2)
2234 {
2235    const HChar *mnm;
2236    IRTemp op2addr = newTemp(Ity_I64);
2237 
2238    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2239           mkU64(0)));
2240 
2241    mnm = irgen(r1, r3, op2addr);
2242 
2243    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2244       s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2245 }
2246 
2247 static void
s390_format_RSI_RRP(const HChar * (* irgen)(UChar r1,UChar r3,UShort i2),UChar r1,UChar r3,UShort i2)2248 s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
2249                     UChar r1, UChar r3, UShort i2)
2250 {
2251    const HChar *mnm = irgen(r1, r3, i2);
2252 
2253    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2254       s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2255 }
2256 
2257 static void
s390_format_RSY_RRRD(const HChar * (* irgen)(UChar r1,UChar r3,IRTemp op2addr),UChar r1,UChar r3,UChar b2,UShort dl2,UChar dh2)2258 s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2259                      UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2260 {
2261    const HChar *mnm;
2262    IRTemp op2addr = newTemp(Ity_I64);
2263    IRTemp d2 = newTemp(Ity_I64);
2264 
2265    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2266    assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2267           mkU64(0)));
2268 
2269    mnm = irgen(r1, r3, op2addr);
2270 
2271    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2272       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2273 }
2274 
2275 static void
s390_format_RSY_AARD(const HChar * (* irgen)(UChar,UChar,IRTemp),UChar r1,UChar r3,UChar b2,UShort dl2,UChar dh2)2276 s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
2277                      UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2278 {
2279    const HChar *mnm;
2280    IRTemp op2addr = newTemp(Ity_I64);
2281    IRTemp d2 = newTemp(Ity_I64);
2282 
2283    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2284    assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2285           mkU64(0)));
2286 
2287    mnm = irgen(r1, r3, op2addr);
2288 
2289    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2290       s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2291 }
2292 
2293 static void
s390_format_RSY_RURD(const HChar * (* irgen)(UChar r1,UChar r3,IRTemp op2addr),UChar r1,UChar r3,UChar b2,UShort dl2,UChar dh2)2294 s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2295                      UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2296 {
2297    const HChar *mnm;
2298    IRTemp op2addr = newTemp(Ity_I64);
2299    IRTemp d2 = newTemp(Ity_I64);
2300 
2301    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2302    assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2303           mkU64(0)));
2304 
2305    mnm = irgen(r1, r3, op2addr);
2306 
2307    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2308       s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2309 }
2310 
2311 static void
s390_format_RSY_RDRM(const HChar * (* irgen)(UChar r1,IRTemp op2addr),UChar r1,UChar m3,UChar b2,UShort dl2,UChar dh2,Int xmnm_kind)2312 s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2313                      UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2314                      Int xmnm_kind)
2315 {
2316    IRTemp op2addr = newTemp(Ity_I64);
2317    IRTemp d2 = newTemp(Ity_I64);
2318 
2319    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2320 
2321    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2322    assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2323           mkU64(0)));
2324 
2325    irgen(r1, op2addr);
2326 
2327    vassert(dis_res->whatNext == Dis_Continue);
2328 
2329    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2330       s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2331 }
2332 
2333 static void
s390_format_RX(const HChar * (* irgen)(UChar r1,UChar x2,UChar b2,UShort d2,IRTemp op2addr),UChar r1,UChar x2,UChar b2,UShort d2)2334 s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
2335                IRTemp op2addr),
2336                UChar r1, UChar x2, UChar b2, UShort d2)
2337 {
2338    IRTemp op2addr = newTemp(Ity_I64);
2339 
2340    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2341           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2342           mkU64(0)));
2343 
2344    irgen(r1, x2, b2, d2, op2addr);
2345 }
2346 
2347 static void
s390_format_RX_RRRD(const HChar * (* irgen)(UChar r1,IRTemp op2addr),UChar r1,UChar x2,UChar b2,UShort d2)2348 s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2349                     UChar r1, UChar x2, UChar b2, UShort d2)
2350 {
2351    const HChar *mnm;
2352    IRTemp op2addr = newTemp(Ity_I64);
2353 
2354    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2355           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2356           mkU64(0)));
2357 
2358    mnm = irgen(r1, op2addr);
2359 
2360    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2361       s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2362 }
2363 
2364 static void
s390_format_RX_FRRD(const HChar * (* irgen)(UChar r1,IRTemp op2addr),UChar r1,UChar x2,UChar b2,UShort d2)2365 s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2366                     UChar r1, UChar x2, UChar b2, UShort d2)
2367 {
2368    const HChar *mnm;
2369    IRTemp op2addr = newTemp(Ity_I64);
2370 
2371    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2372           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2373           mkU64(0)));
2374 
2375    mnm = irgen(r1, op2addr);
2376 
2377    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2378       s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2379 }
2380 
2381 static void
s390_format_RXE_FRRD(const HChar * (* irgen)(UChar r1,IRTemp op2addr),UChar r1,UChar x2,UChar b2,UShort d2)2382 s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2383                      UChar r1, UChar x2, UChar b2, UShort d2)
2384 {
2385    const HChar *mnm;
2386    IRTemp op2addr = newTemp(Ity_I64);
2387 
2388    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2389           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2390           mkU64(0)));
2391 
2392    mnm = irgen(r1, op2addr);
2393 
2394    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2395       s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2396 }
2397 
2398 static void
s390_format_RXF_FRRDF(const HChar * (* irgen)(UChar,IRTemp,UChar),UChar r3,UChar x2,UChar b2,UShort d2,UChar r1)2399 s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
2400                       UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2401 {
2402    const HChar *mnm;
2403    IRTemp op2addr = newTemp(Ity_I64);
2404 
2405    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2406           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2407           mkU64(0)));
2408 
2409    mnm = irgen(r3, op2addr, r1);
2410 
2411    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2412       s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2413 }
2414 
2415 static void
s390_format_RXY_RRRD(const HChar * (* irgen)(UChar r1,IRTemp op2addr),UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2416 s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2417                      UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2418 {
2419    const HChar *mnm;
2420    IRTemp op2addr = newTemp(Ity_I64);
2421    IRTemp d2 = newTemp(Ity_I64);
2422 
2423    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2424    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2425           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2426           mkU64(0)));
2427 
2428    mnm = irgen(r1, op2addr);
2429 
2430    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2431       s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2432 }
2433 
2434 static void
s390_format_RXY_FRRD(const HChar * (* irgen)(UChar r1,IRTemp op2addr),UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2435 s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2436                      UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2437 {
2438    const HChar *mnm;
2439    IRTemp op2addr = newTemp(Ity_I64);
2440    IRTemp d2 = newTemp(Ity_I64);
2441 
2442    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2443    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2444           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2445           mkU64(0)));
2446 
2447    mnm = irgen(r1, op2addr);
2448 
2449    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2450       s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2451 }
2452 
2453 static void
s390_format_RXY_URRD(const HChar * (* irgen)(void),UChar r1,UChar x2,UChar b2,UShort dl2,UChar dh2)2454 s390_format_RXY_URRD(const HChar *(*irgen)(void),
2455                      UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2456 {
2457    const HChar *mnm;
2458    IRTemp op2addr = newTemp(Ity_I64);
2459    IRTemp d2 = newTemp(Ity_I64);
2460 
2461    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2462    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2463           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2464           mkU64(0)));
2465 
2466    mnm = irgen();
2467 
2468    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2469       s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2470 }
2471 
2472 static void
s390_format_S_RD(const HChar * (* irgen)(IRTemp op2addr),UChar b2,UShort d2)2473 s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
2474                  UChar b2, UShort d2)
2475 {
2476    const HChar *mnm;
2477    IRTemp op2addr = newTemp(Ity_I64);
2478 
2479    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2480           mkU64(0)));
2481 
2482    mnm = irgen(op2addr);
2483 
2484    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2485       s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2486 }
2487 
2488 static void
s390_format_SI_URD(const HChar * (* irgen)(UChar i2,IRTemp op1addr),UChar i2,UChar b1,UShort d1)2489 s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
2490                    UChar i2, UChar b1, UShort d1)
2491 {
2492    const HChar *mnm;
2493    IRTemp op1addr = newTemp(Ity_I64);
2494 
2495    assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2496           mkU64(0)));
2497 
2498    mnm = irgen(i2, op1addr);
2499 
2500    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2501       s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2502 }
2503 
2504 static void
s390_format_SIY_URD(const HChar * (* irgen)(UChar i2,IRTemp op1addr),UChar i2,UChar b1,UShort dl1,UChar dh1)2505 s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
2506                     UChar i2, UChar b1, UShort dl1, UChar dh1)
2507 {
2508    const HChar *mnm;
2509    IRTemp op1addr = newTemp(Ity_I64);
2510    IRTemp d1 = newTemp(Ity_I64);
2511 
2512    assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2513    assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2514           mkU64(0)));
2515 
2516    mnm = irgen(i2, op1addr);
2517 
2518    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2519       s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2520 }
2521 
2522 static void
s390_format_SIY_IRD(const HChar * (* irgen)(UChar i2,IRTemp op1addr),UChar i2,UChar b1,UShort dl1,UChar dh1)2523 s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
2524                     UChar i2, UChar b1, UShort dl1, UChar dh1)
2525 {
2526    const HChar *mnm;
2527    IRTemp op1addr = newTemp(Ity_I64);
2528    IRTemp d1 = newTemp(Ity_I64);
2529 
2530    assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2531    assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2532           mkU64(0)));
2533 
2534    mnm = irgen(i2, op1addr);
2535 
2536    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2537       s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2538 }
2539 
2540 static void
s390_format_SS_L0RDRD(const HChar * (* irgen)(UChar,IRTemp,IRTemp),UChar l,UChar b1,UShort d1,UChar b2,UShort d2)2541 s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
2542                       UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2543 {
2544    const HChar *mnm;
2545    IRTemp op1addr = newTemp(Ity_I64);
2546    IRTemp op2addr = newTemp(Ity_I64);
2547 
2548    assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2549           mkU64(0)));
2550    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2551           mkU64(0)));
2552 
2553    mnm = irgen(l, op1addr, op2addr);
2554 
2555    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2556       s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2557 }
2558 
2559 static void
s390_format_SIL_RDI(const HChar * (* irgen)(UShort i2,IRTemp op1addr),UChar b1,UShort d1,UShort i2)2560 s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
2561                     UChar b1, UShort d1, UShort i2)
2562 {
2563    const HChar *mnm;
2564    IRTemp op1addr = newTemp(Ity_I64);
2565 
2566    assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2567           mkU64(0)));
2568 
2569    mnm = irgen(i2, op1addr);
2570 
2571    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2572       s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2573 }
2574 
2575 static void
s390_format_SIL_RDU(const HChar * (* irgen)(UShort i2,IRTemp op1addr),UChar b1,UShort d1,UShort i2)2576 s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
2577                     UChar b1, UShort d1, UShort i2)
2578 {
2579    const HChar *mnm;
2580    IRTemp op1addr = newTemp(Ity_I64);
2581 
2582    assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2583           mkU64(0)));
2584 
2585    mnm = irgen(i2, op1addr);
2586 
2587    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2588       s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2589 }
2590 
2591 
2592 
2593 /*------------------------------------------------------------*/
2594 /*--- Build IR for opcodes                                 ---*/
2595 /*------------------------------------------------------------*/
2596 
2597 static const HChar *
s390_irgen_AR(UChar r1,UChar r2)2598 s390_irgen_AR(UChar r1, UChar r2)
2599 {
2600    IRTemp op1 = newTemp(Ity_I32);
2601    IRTemp op2 = newTemp(Ity_I32);
2602    IRTemp result = newTemp(Ity_I32);
2603 
2604    assign(op1, get_gpr_w1(r1));
2605    assign(op2, get_gpr_w1(r2));
2606    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2607    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2608    put_gpr_w1(r1, mkexpr(result));
2609 
2610    return "ar";
2611 }
2612 
2613 static const HChar *
s390_irgen_AGR(UChar r1,UChar r2)2614 s390_irgen_AGR(UChar r1, UChar r2)
2615 {
2616    IRTemp op1 = newTemp(Ity_I64);
2617    IRTemp op2 = newTemp(Ity_I64);
2618    IRTemp result = newTemp(Ity_I64);
2619 
2620    assign(op1, get_gpr_dw0(r1));
2621    assign(op2, get_gpr_dw0(r2));
2622    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2623    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2624    put_gpr_dw0(r1, mkexpr(result));
2625 
2626    return "agr";
2627 }
2628 
2629 static const HChar *
s390_irgen_AGFR(UChar r1,UChar r2)2630 s390_irgen_AGFR(UChar r1, UChar r2)
2631 {
2632    IRTemp op1 = newTemp(Ity_I64);
2633    IRTemp op2 = newTemp(Ity_I64);
2634    IRTemp result = newTemp(Ity_I64);
2635 
2636    assign(op1, get_gpr_dw0(r1));
2637    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2638    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2639    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2640    put_gpr_dw0(r1, mkexpr(result));
2641 
2642    return "agfr";
2643 }
2644 
2645 static const HChar *
s390_irgen_ARK(UChar r3,UChar r1,UChar r2)2646 s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2647 {
2648    IRTemp op2 = newTemp(Ity_I32);
2649    IRTemp op3 = newTemp(Ity_I32);
2650    IRTemp result = newTemp(Ity_I32);
2651 
2652    assign(op2, get_gpr_w1(r2));
2653    assign(op3, get_gpr_w1(r3));
2654    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2655    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2656    put_gpr_w1(r1, mkexpr(result));
2657 
2658    return "ark";
2659 }
2660 
2661 static const HChar *
s390_irgen_AGRK(UChar r3,UChar r1,UChar r2)2662 s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2663 {
2664    IRTemp op2 = newTemp(Ity_I64);
2665    IRTemp op3 = newTemp(Ity_I64);
2666    IRTemp result = newTemp(Ity_I64);
2667 
2668    assign(op2, get_gpr_dw0(r2));
2669    assign(op3, get_gpr_dw0(r3));
2670    assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2671    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2672    put_gpr_dw0(r1, mkexpr(result));
2673 
2674    return "agrk";
2675 }
2676 
2677 static const HChar *
s390_irgen_A(UChar r1,IRTemp op2addr)2678 s390_irgen_A(UChar r1, IRTemp op2addr)
2679 {
2680    IRTemp op1 = newTemp(Ity_I32);
2681    IRTemp op2 = newTemp(Ity_I32);
2682    IRTemp result = newTemp(Ity_I32);
2683 
2684    assign(op1, get_gpr_w1(r1));
2685    assign(op2, load(Ity_I32, mkexpr(op2addr)));
2686    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2687    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2688    put_gpr_w1(r1, mkexpr(result));
2689 
2690    return "a";
2691 }
2692 
2693 static const HChar *
s390_irgen_AY(UChar r1,IRTemp op2addr)2694 s390_irgen_AY(UChar r1, IRTemp op2addr)
2695 {
2696    IRTemp op1 = newTemp(Ity_I32);
2697    IRTemp op2 = newTemp(Ity_I32);
2698    IRTemp result = newTemp(Ity_I32);
2699 
2700    assign(op1, get_gpr_w1(r1));
2701    assign(op2, load(Ity_I32, mkexpr(op2addr)));
2702    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2703    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2704    put_gpr_w1(r1, mkexpr(result));
2705 
2706    return "ay";
2707 }
2708 
2709 static const HChar *
s390_irgen_AG(UChar r1,IRTemp op2addr)2710 s390_irgen_AG(UChar r1, IRTemp op2addr)
2711 {
2712    IRTemp op1 = newTemp(Ity_I64);
2713    IRTemp op2 = newTemp(Ity_I64);
2714    IRTemp result = newTemp(Ity_I64);
2715 
2716    assign(op1, get_gpr_dw0(r1));
2717    assign(op2, load(Ity_I64, mkexpr(op2addr)));
2718    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2719    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2720    put_gpr_dw0(r1, mkexpr(result));
2721 
2722    return "ag";
2723 }
2724 
2725 static const HChar *
s390_irgen_AGF(UChar r1,IRTemp op2addr)2726 s390_irgen_AGF(UChar r1, IRTemp op2addr)
2727 {
2728    IRTemp op1 = newTemp(Ity_I64);
2729    IRTemp op2 = newTemp(Ity_I64);
2730    IRTemp result = newTemp(Ity_I64);
2731 
2732    assign(op1, get_gpr_dw0(r1));
2733    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2734    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2735    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2736    put_gpr_dw0(r1, mkexpr(result));
2737 
2738    return "agf";
2739 }
2740 
2741 static const HChar *
s390_irgen_AFI(UChar r1,UInt i2)2742 s390_irgen_AFI(UChar r1, UInt i2)
2743 {
2744    IRTemp op1 = newTemp(Ity_I32);
2745    Int op2;
2746    IRTemp result = newTemp(Ity_I32);
2747 
2748    assign(op1, get_gpr_w1(r1));
2749    op2 = (Int)i2;
2750    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2751    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2752                        mkU32((UInt)op2)));
2753    put_gpr_w1(r1, mkexpr(result));
2754 
2755    return "afi";
2756 }
2757 
2758 static const HChar *
s390_irgen_AGFI(UChar r1,UInt i2)2759 s390_irgen_AGFI(UChar r1, UInt i2)
2760 {
2761    IRTemp op1 = newTemp(Ity_I64);
2762    Long op2;
2763    IRTemp result = newTemp(Ity_I64);
2764 
2765    assign(op1, get_gpr_dw0(r1));
2766    op2 = (Long)(Int)i2;
2767    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2768    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2769                        mkU64((ULong)op2)));
2770    put_gpr_dw0(r1, mkexpr(result));
2771 
2772    return "agfi";
2773 }
2774 
2775 static const HChar *
s390_irgen_AHIK(UChar r1,UChar r3,UShort i2)2776 s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2777 {
2778    Int op2;
2779    IRTemp op3 = newTemp(Ity_I32);
2780    IRTemp result = newTemp(Ity_I32);
2781 
2782    op2 = (Int)(Short)i2;
2783    assign(op3, get_gpr_w1(r3));
2784    assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2785    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2786                        op2)), op3);
2787    put_gpr_w1(r1, mkexpr(result));
2788 
2789    return "ahik";
2790 }
2791 
2792 static const HChar *
s390_irgen_AGHIK(UChar r1,UChar r3,UShort i2)2793 s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2794 {
2795    Long op2;
2796    IRTemp op3 = newTemp(Ity_I64);
2797    IRTemp result = newTemp(Ity_I64);
2798 
2799    op2 = (Long)(Short)i2;
2800    assign(op3, get_gpr_dw0(r3));
2801    assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2802    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2803                        op2)), op3);
2804    put_gpr_dw0(r1, mkexpr(result));
2805 
2806    return "aghik";
2807 }
2808 
2809 static const HChar *
s390_irgen_ASI(UChar i2,IRTemp op1addr)2810 s390_irgen_ASI(UChar i2, IRTemp op1addr)
2811 {
2812    IRTemp op1 = newTemp(Ity_I32);
2813    Int op2;
2814    IRTemp result = newTemp(Ity_I32);
2815 
2816    assign(op1, load(Ity_I32, mkexpr(op1addr)));
2817    op2 = (Int)(Char)i2;
2818    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2819    store(mkexpr(op1addr), mkexpr(result));
2820    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2821                        mkU32((UInt)op2)));
2822 
2823    return "asi";
2824 }
2825 
2826 static const HChar *
s390_irgen_AGSI(UChar i2,IRTemp op1addr)2827 s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2828 {
2829    IRTemp op1 = newTemp(Ity_I64);
2830    Long op2;
2831    IRTemp result = newTemp(Ity_I64);
2832 
2833    assign(op1, load(Ity_I64, mkexpr(op1addr)));
2834    op2 = (Long)(Char)i2;
2835    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2836    store(mkexpr(op1addr), mkexpr(result));
2837    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2838                        mkU64((ULong)op2)));
2839 
2840    return "agsi";
2841 }
2842 
2843 static const HChar *
s390_irgen_AH(UChar r1,IRTemp op2addr)2844 s390_irgen_AH(UChar r1, IRTemp op2addr)
2845 {
2846    IRTemp op1 = newTemp(Ity_I32);
2847    IRTemp op2 = newTemp(Ity_I32);
2848    IRTemp result = newTemp(Ity_I32);
2849 
2850    assign(op1, get_gpr_w1(r1));
2851    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2852    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2853    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2854    put_gpr_w1(r1, mkexpr(result));
2855 
2856    return "ah";
2857 }
2858 
2859 static const HChar *
s390_irgen_AHY(UChar r1,IRTemp op2addr)2860 s390_irgen_AHY(UChar r1, IRTemp op2addr)
2861 {
2862    IRTemp op1 = newTemp(Ity_I32);
2863    IRTemp op2 = newTemp(Ity_I32);
2864    IRTemp result = newTemp(Ity_I32);
2865 
2866    assign(op1, get_gpr_w1(r1));
2867    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2868    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2869    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2870    put_gpr_w1(r1, mkexpr(result));
2871 
2872    return "ahy";
2873 }
2874 
2875 static const HChar *
s390_irgen_AHI(UChar r1,UShort i2)2876 s390_irgen_AHI(UChar r1, UShort i2)
2877 {
2878    IRTemp op1 = newTemp(Ity_I32);
2879    Int op2;
2880    IRTemp result = newTemp(Ity_I32);
2881 
2882    assign(op1, get_gpr_w1(r1));
2883    op2 = (Int)(Short)i2;
2884    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2885    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2886                        mkU32((UInt)op2)));
2887    put_gpr_w1(r1, mkexpr(result));
2888 
2889    return "ahi";
2890 }
2891 
2892 static const HChar *
s390_irgen_AGHI(UChar r1,UShort i2)2893 s390_irgen_AGHI(UChar r1, UShort i2)
2894 {
2895    IRTemp op1 = newTemp(Ity_I64);
2896    Long op2;
2897    IRTemp result = newTemp(Ity_I64);
2898 
2899    assign(op1, get_gpr_dw0(r1));
2900    op2 = (Long)(Short)i2;
2901    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2902    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2903                        mkU64((ULong)op2)));
2904    put_gpr_dw0(r1, mkexpr(result));
2905 
2906    return "aghi";
2907 }
2908 
2909 static const HChar *
s390_irgen_AHHHR(UChar r3,UChar r1,UChar r2)2910 s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2911 {
2912    IRTemp op2 = newTemp(Ity_I32);
2913    IRTemp op3 = newTemp(Ity_I32);
2914    IRTemp result = newTemp(Ity_I32);
2915 
2916    assign(op2, get_gpr_w0(r2));
2917    assign(op3, get_gpr_w0(r3));
2918    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2919    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2920    put_gpr_w0(r1, mkexpr(result));
2921 
2922    return "ahhhr";
2923 }
2924 
2925 static const HChar *
s390_irgen_AHHLR(UChar r3,UChar r1,UChar r2)2926 s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2927 {
2928    IRTemp op2 = newTemp(Ity_I32);
2929    IRTemp op3 = newTemp(Ity_I32);
2930    IRTemp result = newTemp(Ity_I32);
2931 
2932    assign(op2, get_gpr_w0(r2));
2933    assign(op3, get_gpr_w1(r3));
2934    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2935    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2936    put_gpr_w0(r1, mkexpr(result));
2937 
2938    return "ahhlr";
2939 }
2940 
2941 static const HChar *
s390_irgen_AIH(UChar r1,UInt i2)2942 s390_irgen_AIH(UChar r1, UInt i2)
2943 {
2944    IRTemp op1 = newTemp(Ity_I32);
2945    Int op2;
2946    IRTemp result = newTemp(Ity_I32);
2947 
2948    assign(op1, get_gpr_w0(r1));
2949    op2 = (Int)i2;
2950    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2951    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2952                        mkU32((UInt)op2)));
2953    put_gpr_w0(r1, mkexpr(result));
2954 
2955    return "aih";
2956 }
2957 
2958 static const HChar *
s390_irgen_ALR(UChar r1,UChar r2)2959 s390_irgen_ALR(UChar r1, UChar r2)
2960 {
2961    IRTemp op1 = newTemp(Ity_I32);
2962    IRTemp op2 = newTemp(Ity_I32);
2963    IRTemp result = newTemp(Ity_I32);
2964 
2965    assign(op1, get_gpr_w1(r1));
2966    assign(op2, get_gpr_w1(r2));
2967    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2968    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2969    put_gpr_w1(r1, mkexpr(result));
2970 
2971    return "alr";
2972 }
2973 
2974 static const HChar *
s390_irgen_ALGR(UChar r1,UChar r2)2975 s390_irgen_ALGR(UChar r1, UChar r2)
2976 {
2977    IRTemp op1 = newTemp(Ity_I64);
2978    IRTemp op2 = newTemp(Ity_I64);
2979    IRTemp result = newTemp(Ity_I64);
2980 
2981    assign(op1, get_gpr_dw0(r1));
2982    assign(op2, get_gpr_dw0(r2));
2983    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2984    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2985    put_gpr_dw0(r1, mkexpr(result));
2986 
2987    return "algr";
2988 }
2989 
2990 static const HChar *
s390_irgen_ALGFR(UChar r1,UChar r2)2991 s390_irgen_ALGFR(UChar r1, UChar r2)
2992 {
2993    IRTemp op1 = newTemp(Ity_I64);
2994    IRTemp op2 = newTemp(Ity_I64);
2995    IRTemp result = newTemp(Ity_I64);
2996 
2997    assign(op1, get_gpr_dw0(r1));
2998    assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2999    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3000    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3001    put_gpr_dw0(r1, mkexpr(result));
3002 
3003    return "algfr";
3004 }
3005 
3006 static const HChar *
s390_irgen_ALRK(UChar r3,UChar r1,UChar r2)3007 s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
3008 {
3009    IRTemp op2 = newTemp(Ity_I32);
3010    IRTemp op3 = newTemp(Ity_I32);
3011    IRTemp result = newTemp(Ity_I32);
3012 
3013    assign(op2, get_gpr_w1(r2));
3014    assign(op3, get_gpr_w1(r3));
3015    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3016    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3017    put_gpr_w1(r1, mkexpr(result));
3018 
3019    return "alrk";
3020 }
3021 
3022 static const HChar *
s390_irgen_ALGRK(UChar r3,UChar r1,UChar r2)3023 s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
3024 {
3025    IRTemp op2 = newTemp(Ity_I64);
3026    IRTemp op3 = newTemp(Ity_I64);
3027    IRTemp result = newTemp(Ity_I64);
3028 
3029    assign(op2, get_gpr_dw0(r2));
3030    assign(op3, get_gpr_dw0(r3));
3031    assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
3032    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
3033    put_gpr_dw0(r1, mkexpr(result));
3034 
3035    return "algrk";
3036 }
3037 
3038 static const HChar *
s390_irgen_AL(UChar r1,IRTemp op2addr)3039 s390_irgen_AL(UChar r1, IRTemp op2addr)
3040 {
3041    IRTemp op1 = newTemp(Ity_I32);
3042    IRTemp op2 = newTemp(Ity_I32);
3043    IRTemp result = newTemp(Ity_I32);
3044 
3045    assign(op1, get_gpr_w1(r1));
3046    assign(op2, load(Ity_I32, mkexpr(op2addr)));
3047    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3048    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3049    put_gpr_w1(r1, mkexpr(result));
3050 
3051    return "al";
3052 }
3053 
3054 static const HChar *
s390_irgen_ALY(UChar r1,IRTemp op2addr)3055 s390_irgen_ALY(UChar r1, IRTemp op2addr)
3056 {
3057    IRTemp op1 = newTemp(Ity_I32);
3058    IRTemp op2 = newTemp(Ity_I32);
3059    IRTemp result = newTemp(Ity_I32);
3060 
3061    assign(op1, get_gpr_w1(r1));
3062    assign(op2, load(Ity_I32, mkexpr(op2addr)));
3063    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3064    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3065    put_gpr_w1(r1, mkexpr(result));
3066 
3067    return "aly";
3068 }
3069 
3070 static const HChar *
s390_irgen_ALG(UChar r1,IRTemp op2addr)3071 s390_irgen_ALG(UChar r1, IRTemp op2addr)
3072 {
3073    IRTemp op1 = newTemp(Ity_I64);
3074    IRTemp op2 = newTemp(Ity_I64);
3075    IRTemp result = newTemp(Ity_I64);
3076 
3077    assign(op1, get_gpr_dw0(r1));
3078    assign(op2, load(Ity_I64, mkexpr(op2addr)));
3079    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3080    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3081    put_gpr_dw0(r1, mkexpr(result));
3082 
3083    return "alg";
3084 }
3085 
3086 static const HChar *
s390_irgen_ALGF(UChar r1,IRTemp op2addr)3087 s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3088 {
3089    IRTemp op1 = newTemp(Ity_I64);
3090    IRTemp op2 = newTemp(Ity_I64);
3091    IRTemp result = newTemp(Ity_I64);
3092 
3093    assign(op1, get_gpr_dw0(r1));
3094    assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3095    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3096    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3097    put_gpr_dw0(r1, mkexpr(result));
3098 
3099    return "algf";
3100 }
3101 
3102 static const HChar *
s390_irgen_ALFI(UChar r1,UInt i2)3103 s390_irgen_ALFI(UChar r1, UInt i2)
3104 {
3105    IRTemp op1 = newTemp(Ity_I32);
3106    UInt op2;
3107    IRTemp result = newTemp(Ity_I32);
3108 
3109    assign(op1, get_gpr_w1(r1));
3110    op2 = i2;
3111    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3112    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3113                        mkU32(op2)));
3114    put_gpr_w1(r1, mkexpr(result));
3115 
3116    return "alfi";
3117 }
3118 
3119 static const HChar *
s390_irgen_ALGFI(UChar r1,UInt i2)3120 s390_irgen_ALGFI(UChar r1, UInt i2)
3121 {
3122    IRTemp op1 = newTemp(Ity_I64);
3123    ULong op2;
3124    IRTemp result = newTemp(Ity_I64);
3125 
3126    assign(op1, get_gpr_dw0(r1));
3127    op2 = (ULong)i2;
3128    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3129    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3130                        mkU64(op2)));
3131    put_gpr_dw0(r1, mkexpr(result));
3132 
3133    return "algfi";
3134 }
3135 
3136 static const HChar *
s390_irgen_ALHHHR(UChar r3,UChar r1,UChar r2)3137 s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3138 {
3139    IRTemp op2 = newTemp(Ity_I32);
3140    IRTemp op3 = newTemp(Ity_I32);
3141    IRTemp result = newTemp(Ity_I32);
3142 
3143    assign(op2, get_gpr_w0(r2));
3144    assign(op3, get_gpr_w0(r3));
3145    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3146    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3147    put_gpr_w0(r1, mkexpr(result));
3148 
3149    return "alhhhr";
3150 }
3151 
3152 static const HChar *
s390_irgen_ALHHLR(UChar r3,UChar r1,UChar r2)3153 s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3154 {
3155    IRTemp op2 = newTemp(Ity_I32);
3156    IRTemp op3 = newTemp(Ity_I32);
3157    IRTemp result = newTemp(Ity_I32);
3158 
3159    assign(op2, get_gpr_w0(r2));
3160    assign(op3, get_gpr_w1(r3));
3161    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3162    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3163    put_gpr_w0(r1, mkexpr(result));
3164 
3165    return "alhhlr";
3166 }
3167 
3168 static const HChar *
s390_irgen_ALCR(UChar r1,UChar r2)3169 s390_irgen_ALCR(UChar r1, UChar r2)
3170 {
3171    IRTemp op1 = newTemp(Ity_I32);
3172    IRTemp op2 = newTemp(Ity_I32);
3173    IRTemp result = newTemp(Ity_I32);
3174    IRTemp carry_in = newTemp(Ity_I32);
3175 
3176    assign(op1, get_gpr_w1(r1));
3177    assign(op2, get_gpr_w1(r2));
3178    assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3179    assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3180           mkexpr(carry_in)));
3181    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3182    put_gpr_w1(r1, mkexpr(result));
3183 
3184    return "alcr";
3185 }
3186 
3187 static const HChar *
s390_irgen_ALCGR(UChar r1,UChar r2)3188 s390_irgen_ALCGR(UChar r1, UChar r2)
3189 {
3190    IRTemp op1 = newTemp(Ity_I64);
3191    IRTemp op2 = newTemp(Ity_I64);
3192    IRTemp result = newTemp(Ity_I64);
3193    IRTemp carry_in = newTemp(Ity_I64);
3194 
3195    assign(op1, get_gpr_dw0(r1));
3196    assign(op2, get_gpr_dw0(r2));
3197    assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3198           mkU8(1))));
3199    assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3200           mkexpr(carry_in)));
3201    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3202    put_gpr_dw0(r1, mkexpr(result));
3203 
3204    return "alcgr";
3205 }
3206 
3207 static const HChar *
s390_irgen_ALC(UChar r1,IRTemp op2addr)3208 s390_irgen_ALC(UChar r1, IRTemp op2addr)
3209 {
3210    IRTemp op1 = newTemp(Ity_I32);
3211    IRTemp op2 = newTemp(Ity_I32);
3212    IRTemp result = newTemp(Ity_I32);
3213    IRTemp carry_in = newTemp(Ity_I32);
3214 
3215    assign(op1, get_gpr_w1(r1));
3216    assign(op2, load(Ity_I32, mkexpr(op2addr)));
3217    assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3218    assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3219           mkexpr(carry_in)));
3220    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3221    put_gpr_w1(r1, mkexpr(result));
3222 
3223    return "alc";
3224 }
3225 
3226 static const HChar *
s390_irgen_ALCG(UChar r1,IRTemp op2addr)3227 s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3228 {
3229    IRTemp op1 = newTemp(Ity_I64);
3230    IRTemp op2 = newTemp(Ity_I64);
3231    IRTemp result = newTemp(Ity_I64);
3232    IRTemp carry_in = newTemp(Ity_I64);
3233 
3234    assign(op1, get_gpr_dw0(r1));
3235    assign(op2, load(Ity_I64, mkexpr(op2addr)));
3236    assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3237           mkU8(1))));
3238    assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3239           mkexpr(carry_in)));
3240    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3241    put_gpr_dw0(r1, mkexpr(result));
3242 
3243    return "alcg";
3244 }
3245 
3246 static const HChar *
s390_irgen_ALSI(UChar i2,IRTemp op1addr)3247 s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3248 {
3249    IRTemp op1 = newTemp(Ity_I32);
3250    UInt op2;
3251    IRTemp result = newTemp(Ity_I32);
3252 
3253    assign(op1, load(Ity_I32, mkexpr(op1addr)));
3254    op2 = (UInt)(Int)(Char)i2;
3255    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3256    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3257                        mkU32(op2)));
3258    store(mkexpr(op1addr), mkexpr(result));
3259 
3260    return "alsi";
3261 }
3262 
3263 static const HChar *
s390_irgen_ALGSI(UChar i2,IRTemp op1addr)3264 s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3265 {
3266    IRTemp op1 = newTemp(Ity_I64);
3267    ULong op2;
3268    IRTemp result = newTemp(Ity_I64);
3269 
3270    assign(op1, load(Ity_I64, mkexpr(op1addr)));
3271    op2 = (ULong)(Long)(Char)i2;
3272    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3273    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3274                        mkU64(op2)));
3275    store(mkexpr(op1addr), mkexpr(result));
3276 
3277    return "algsi";
3278 }
3279 
3280 static const HChar *
s390_irgen_ALHSIK(UChar r1,UChar r3,UShort i2)3281 s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3282 {
3283    UInt op2;
3284    IRTemp op3 = newTemp(Ity_I32);
3285    IRTemp result = newTemp(Ity_I32);
3286 
3287    op2 = (UInt)(Int)(Short)i2;
3288    assign(op3, get_gpr_w1(r3));
3289    assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3290    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3291                        op3);
3292    put_gpr_w1(r1, mkexpr(result));
3293 
3294    return "alhsik";
3295 }
3296 
3297 static const HChar *
s390_irgen_ALGHSIK(UChar r1,UChar r3,UShort i2)3298 s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3299 {
3300    ULong op2;
3301    IRTemp op3 = newTemp(Ity_I64);
3302    IRTemp result = newTemp(Ity_I64);
3303 
3304    op2 = (ULong)(Long)(Short)i2;
3305    assign(op3, get_gpr_dw0(r3));
3306    assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3307    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3308                        op3);
3309    put_gpr_dw0(r1, mkexpr(result));
3310 
3311    return "alghsik";
3312 }
3313 
3314 static const HChar *
s390_irgen_ALSIH(UChar r1,UInt i2)3315 s390_irgen_ALSIH(UChar r1, UInt i2)
3316 {
3317    IRTemp op1 = newTemp(Ity_I32);
3318    UInt op2;
3319    IRTemp result = newTemp(Ity_I32);
3320 
3321    assign(op1, get_gpr_w0(r1));
3322    op2 = i2;
3323    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3324    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3325                        mkU32(op2)));
3326    put_gpr_w0(r1, mkexpr(result));
3327 
3328    return "alsih";
3329 }
3330 
3331 static const HChar *
s390_irgen_ALSIHN(UChar r1,UInt i2)3332 s390_irgen_ALSIHN(UChar r1, UInt i2)
3333 {
3334    IRTemp op1 = newTemp(Ity_I32);
3335    UInt op2;
3336    IRTemp result = newTemp(Ity_I32);
3337 
3338    assign(op1, get_gpr_w0(r1));
3339    op2 = i2;
3340    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3341    put_gpr_w0(r1, mkexpr(result));
3342 
3343    return "alsihn";
3344 }
3345 
3346 static const HChar *
s390_irgen_NR(UChar r1,UChar r2)3347 s390_irgen_NR(UChar r1, UChar r2)
3348 {
3349    IRTemp op1 = newTemp(Ity_I32);
3350    IRTemp op2 = newTemp(Ity_I32);
3351    IRTemp result = newTemp(Ity_I32);
3352 
3353    assign(op1, get_gpr_w1(r1));
3354    assign(op2, get_gpr_w1(r2));
3355    assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3356    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3357    put_gpr_w1(r1, mkexpr(result));
3358 
3359    return "nr";
3360 }
3361 
3362 static const HChar *
s390_irgen_NGR(UChar r1,UChar r2)3363 s390_irgen_NGR(UChar r1, UChar r2)
3364 {
3365    IRTemp op1 = newTemp(Ity_I64);
3366    IRTemp op2 = newTemp(Ity_I64);
3367    IRTemp result = newTemp(Ity_I64);
3368 
3369    assign(op1, get_gpr_dw0(r1));
3370    assign(op2, get_gpr_dw0(r2));
3371    assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3372    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3373    put_gpr_dw0(r1, mkexpr(result));
3374 
3375    return "ngr";
3376 }
3377 
3378 static const HChar *
s390_irgen_NRK(UChar r3,UChar r1,UChar r2)3379 s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3380 {
3381    IRTemp op2 = newTemp(Ity_I32);
3382    IRTemp op3 = newTemp(Ity_I32);
3383    IRTemp result = newTemp(Ity_I32);
3384 
3385    assign(op2, get_gpr_w1(r2));
3386    assign(op3, get_gpr_w1(r3));
3387    assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3388    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3389    put_gpr_w1(r1, mkexpr(result));
3390 
3391    return "nrk";
3392 }
3393 
3394 static const HChar *
s390_irgen_NGRK(UChar r3,UChar r1,UChar r2)3395 s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3396 {
3397    IRTemp op2 = newTemp(Ity_I64);
3398    IRTemp op3 = newTemp(Ity_I64);
3399    IRTemp result = newTemp(Ity_I64);
3400 
3401    assign(op2, get_gpr_dw0(r2));
3402    assign(op3, get_gpr_dw0(r3));
3403    assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3404    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3405    put_gpr_dw0(r1, mkexpr(result));
3406 
3407    return "ngrk";
3408 }
3409 
3410 static const HChar *
s390_irgen_N(UChar r1,IRTemp op2addr)3411 s390_irgen_N(UChar r1, IRTemp op2addr)
3412 {
3413    IRTemp op1 = newTemp(Ity_I32);
3414    IRTemp op2 = newTemp(Ity_I32);
3415    IRTemp result = newTemp(Ity_I32);
3416 
3417    assign(op1, get_gpr_w1(r1));
3418    assign(op2, load(Ity_I32, mkexpr(op2addr)));
3419    assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3420    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3421    put_gpr_w1(r1, mkexpr(result));
3422 
3423    return "n";
3424 }
3425 
3426 static const HChar *
s390_irgen_NY(UChar r1,IRTemp op2addr)3427 s390_irgen_NY(UChar r1, IRTemp op2addr)
3428 {
3429    IRTemp op1 = newTemp(Ity_I32);
3430    IRTemp op2 = newTemp(Ity_I32);
3431    IRTemp result = newTemp(Ity_I32);
3432 
3433    assign(op1, get_gpr_w1(r1));
3434    assign(op2, load(Ity_I32, mkexpr(op2addr)));
3435    assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3436    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3437    put_gpr_w1(r1, mkexpr(result));
3438 
3439    return "ny";
3440 }
3441 
3442 static const HChar *
s390_irgen_NG(UChar r1,IRTemp op2addr)3443 s390_irgen_NG(UChar r1, IRTemp op2addr)
3444 {
3445    IRTemp op1 = newTemp(Ity_I64);
3446    IRTemp op2 = newTemp(Ity_I64);
3447    IRTemp result = newTemp(Ity_I64);
3448 
3449    assign(op1, get_gpr_dw0(r1));
3450    assign(op2, load(Ity_I64, mkexpr(op2addr)));
3451    assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3452    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3453    put_gpr_dw0(r1, mkexpr(result));
3454 
3455    return "ng";
3456 }
3457 
3458 static const HChar *
s390_irgen_NI(UChar i2,IRTemp op1addr)3459 s390_irgen_NI(UChar i2, IRTemp op1addr)
3460 {
3461    IRTemp op1 = newTemp(Ity_I8);
3462    UChar op2;
3463    IRTemp result = newTemp(Ity_I8);
3464 
3465    assign(op1, load(Ity_I8, mkexpr(op1addr)));
3466    op2 = i2;
3467    assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3468    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3469    store(mkexpr(op1addr), mkexpr(result));
3470 
3471    return "ni";
3472 }
3473 
3474 static const HChar *
s390_irgen_NIY(UChar i2,IRTemp op1addr)3475 s390_irgen_NIY(UChar i2, IRTemp op1addr)
3476 {
3477    IRTemp op1 = newTemp(Ity_I8);
3478    UChar op2;
3479    IRTemp result = newTemp(Ity_I8);
3480 
3481    assign(op1, load(Ity_I8, mkexpr(op1addr)));
3482    op2 = i2;
3483    assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3484    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3485    store(mkexpr(op1addr), mkexpr(result));
3486 
3487    return "niy";
3488 }
3489 
3490 static const HChar *
s390_irgen_NIHF(UChar r1,UInt i2)3491 s390_irgen_NIHF(UChar r1, UInt i2)
3492 {
3493    IRTemp op1 = newTemp(Ity_I32);
3494    UInt op2;
3495    IRTemp result = newTemp(Ity_I32);
3496 
3497    assign(op1, get_gpr_w0(r1));
3498    op2 = i2;
3499    assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3500    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3501    put_gpr_w0(r1, mkexpr(result));
3502 
3503    return "nihf";
3504 }
3505 
3506 static const HChar *
s390_irgen_NIHH(UChar r1,UShort i2)3507 s390_irgen_NIHH(UChar r1, UShort i2)
3508 {
3509    IRTemp op1 = newTemp(Ity_I16);
3510    UShort op2;
3511    IRTemp result = newTemp(Ity_I16);
3512 
3513    assign(op1, get_gpr_hw0(r1));
3514    op2 = i2;
3515    assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3516    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3517    put_gpr_hw0(r1, mkexpr(result));
3518 
3519    return "nihh";
3520 }
3521 
3522 static const HChar *
s390_irgen_NIHL(UChar r1,UShort i2)3523 s390_irgen_NIHL(UChar r1, UShort i2)
3524 {
3525    IRTemp op1 = newTemp(Ity_I16);
3526    UShort op2;
3527    IRTemp result = newTemp(Ity_I16);
3528 
3529    assign(op1, get_gpr_hw1(r1));
3530    op2 = i2;
3531    assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3532    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3533    put_gpr_hw1(r1, mkexpr(result));
3534 
3535    return "nihl";
3536 }
3537 
3538 static const HChar *
s390_irgen_NILF(UChar r1,UInt i2)3539 s390_irgen_NILF(UChar r1, UInt i2)
3540 {
3541    IRTemp op1 = newTemp(Ity_I32);
3542    UInt op2;
3543    IRTemp result = newTemp(Ity_I32);
3544 
3545    assign(op1, get_gpr_w1(r1));
3546    op2 = i2;
3547    assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3548    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3549    put_gpr_w1(r1, mkexpr(result));
3550 
3551    return "nilf";
3552 }
3553 
3554 static const HChar *
s390_irgen_NILH(UChar r1,UShort i2)3555 s390_irgen_NILH(UChar r1, UShort i2)
3556 {
3557    IRTemp op1 = newTemp(Ity_I16);
3558    UShort op2;
3559    IRTemp result = newTemp(Ity_I16);
3560 
3561    assign(op1, get_gpr_hw2(r1));
3562    op2 = i2;
3563    assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3564    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3565    put_gpr_hw2(r1, mkexpr(result));
3566 
3567    return "nilh";
3568 }
3569 
3570 static const HChar *
s390_irgen_NILL(UChar r1,UShort i2)3571 s390_irgen_NILL(UChar r1, UShort i2)
3572 {
3573    IRTemp op1 = newTemp(Ity_I16);
3574    UShort op2;
3575    IRTemp result = newTemp(Ity_I16);
3576 
3577    assign(op1, get_gpr_hw3(r1));
3578    op2 = i2;
3579    assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3580    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3581    put_gpr_hw3(r1, mkexpr(result));
3582 
3583    return "nill";
3584 }
3585 
3586 static const HChar *
s390_irgen_BASR(UChar r1,UChar r2)3587 s390_irgen_BASR(UChar r1, UChar r2)
3588 {
3589    IRTemp target = newTemp(Ity_I64);
3590 
3591    if (r2 == 0) {
3592       put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3593    } else {
3594       if (r1 != r2) {
3595          put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3596          call_function(get_gpr_dw0(r2));
3597       } else {
3598          assign(target, get_gpr_dw0(r2));
3599          put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3600          call_function(mkexpr(target));
3601       }
3602    }
3603 
3604    return "basr";
3605 }
3606 
3607 static const HChar *
s390_irgen_BAS(UChar r1,IRTemp op2addr)3608 s390_irgen_BAS(UChar r1, IRTemp op2addr)
3609 {
3610    IRTemp target = newTemp(Ity_I64);
3611 
3612    put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3613    assign(target, mkexpr(op2addr));
3614    call_function(mkexpr(target));
3615 
3616    return "bas";
3617 }
3618 
3619 static const HChar *
s390_irgen_BCR(UChar r1,UChar r2)3620 s390_irgen_BCR(UChar r1, UChar r2)
3621 {
3622    IRTemp cond = newTemp(Ity_I32);
3623 
3624    if (r2 == 0 && (r1 >= 14)) {    /* serialization */
3625       stmt(IRStmt_MBE(Imbe_Fence));
3626    }
3627 
3628    if ((r2 == 0) || (r1 == 0)) {
3629    } else {
3630       if (r1 == 15) {
3631          return_from_function(get_gpr_dw0(r2));
3632       } else {
3633          assign(cond, s390_call_calculate_cond(r1));
3634          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3635                                     get_gpr_dw0(r2));
3636       }
3637    }
3638    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3639       s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3640 
3641    return "bcr";
3642 }
3643 
3644 static const HChar *
s390_irgen_BC(UChar r1,UChar x2,UChar b2,UShort d2,IRTemp op2addr)3645 s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3646 {
3647    IRTemp cond = newTemp(Ity_I32);
3648 
3649    if (r1 == 0) {
3650    } else {
3651       if (r1 == 15) {
3652          always_goto(mkexpr(op2addr));
3653       } else {
3654          assign(cond, s390_call_calculate_cond(r1));
3655          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3656                                     mkexpr(op2addr));
3657       }
3658    }
3659    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3660       s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3661 
3662    return "bc";
3663 }
3664 
3665 static const HChar *
s390_irgen_BCTR(UChar r1,UChar r2)3666 s390_irgen_BCTR(UChar r1, UChar r2)
3667 {
3668    put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3669    if (r2 != 0) {
3670       if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3671                                  get_gpr_dw0(r2));
3672    }
3673 
3674    return "bctr";
3675 }
3676 
3677 static const HChar *
s390_irgen_BCTGR(UChar r1,UChar r2)3678 s390_irgen_BCTGR(UChar r1, UChar r2)
3679 {
3680    put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3681    if (r2 != 0) {
3682       if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3683                                  get_gpr_dw0(r2));
3684    }
3685 
3686    return "bctgr";
3687 }
3688 
3689 static const HChar *
s390_irgen_BCT(UChar r1,IRTemp op2addr)3690 s390_irgen_BCT(UChar r1, IRTemp op2addr)
3691 {
3692    put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3693    if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3694                               mkexpr(op2addr));
3695 
3696    return "bct";
3697 }
3698 
3699 static const HChar *
s390_irgen_BCTG(UChar r1,IRTemp op2addr)3700 s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3701 {
3702    put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3703    if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3704                               mkexpr(op2addr));
3705 
3706    return "bctg";
3707 }
3708 
3709 static const HChar *
s390_irgen_BXH(UChar r1,UChar r3,IRTemp op2addr)3710 s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3711 {
3712    IRTemp value = newTemp(Ity_I32);
3713 
3714    assign(value, get_gpr_w1(r3 | 1));
3715    put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3716    if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3717                                     get_gpr_w1(r1)), mkexpr(op2addr));
3718 
3719    return "bxh";
3720 }
3721 
3722 static const HChar *
s390_irgen_BXHG(UChar r1,UChar r3,IRTemp op2addr)3723 s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3724 {
3725    IRTemp value = newTemp(Ity_I64);
3726 
3727    assign(value, get_gpr_dw0(r3 | 1));
3728    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3729    if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3730                                     get_gpr_dw0(r1)), mkexpr(op2addr));
3731 
3732    return "bxhg";
3733 }
3734 
3735 static const HChar *
s390_irgen_BXLE(UChar r1,UChar r3,IRTemp op2addr)3736 s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3737 {
3738    IRTemp value = newTemp(Ity_I32);
3739 
3740    assign(value, get_gpr_w1(r3 | 1));
3741    put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3742    if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3743                                     mkexpr(value)), mkexpr(op2addr));
3744 
3745    return "bxle";
3746 }
3747 
3748 static const HChar *
s390_irgen_BXLEG(UChar r1,UChar r3,IRTemp op2addr)3749 s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3750 {
3751    IRTemp value = newTemp(Ity_I64);
3752 
3753    assign(value, get_gpr_dw0(r3 | 1));
3754    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3755    if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3756                                     mkexpr(value)), mkexpr(op2addr));
3757 
3758    return "bxleg";
3759 }
3760 
3761 static const HChar *
s390_irgen_BRAS(UChar r1,UShort i2)3762 s390_irgen_BRAS(UChar r1, UShort i2)
3763 {
3764    put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3765    call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3766 
3767    return "bras";
3768 }
3769 
3770 static const HChar *
s390_irgen_BRASL(UChar r1,UInt i2)3771 s390_irgen_BRASL(UChar r1, UInt i2)
3772 {
3773    put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
3774    call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3775 
3776    return "brasl";
3777 }
3778 
3779 static const HChar *
s390_irgen_BRC(UChar r1,UShort i2)3780 s390_irgen_BRC(UChar r1, UShort i2)
3781 {
3782    IRTemp cond = newTemp(Ity_I32);
3783 
3784    if (r1 == 0) {
3785    } else {
3786       if (r1 == 15) {
3787          always_goto_and_chase(
3788                guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3789       } else {
3790          assign(cond, s390_call_calculate_cond(r1));
3791          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3792                            guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3793 
3794       }
3795    }
3796    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3797       s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3798 
3799    return "brc";
3800 }
3801 
3802 static const HChar *
s390_irgen_BRCL(UChar r1,UInt i2)3803 s390_irgen_BRCL(UChar r1, UInt i2)
3804 {
3805    IRTemp cond = newTemp(Ity_I32);
3806 
3807    if (r1 == 0) {
3808    } else {
3809       if (r1 == 15) {
3810          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3811       } else {
3812          assign(cond, s390_call_calculate_cond(r1));
3813          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3814                            guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3815       }
3816    }
3817    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3818       s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3819 
3820    return "brcl";
3821 }
3822 
3823 static const HChar *
s390_irgen_BRCT(UChar r1,UShort i2)3824 s390_irgen_BRCT(UChar r1, UShort i2)
3825 {
3826    put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3827    if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3828                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3829 
3830    return "brct";
3831 }
3832 
3833 static const HChar *
s390_irgen_BRCTH(UChar r1,UInt i2)3834 s390_irgen_BRCTH(UChar r1, UInt i2)
3835 {
3836    put_gpr_w0(r1, binop(Iop_Sub32, get_gpr_w0(r1), mkU32(1)));
3837    if_condition_goto(binop(Iop_CmpNE32, get_gpr_w0(r1), mkU32(0)),
3838                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3839 
3840    return "brcth";
3841 }
3842 
3843 static const HChar *
s390_irgen_BRCTG(UChar r1,UShort i2)3844 s390_irgen_BRCTG(UChar r1, UShort i2)
3845 {
3846    put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3847    if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3848                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3849 
3850    return "brctg";
3851 }
3852 
3853 static const HChar *
s390_irgen_BRXH(UChar r1,UChar r3,UShort i2)3854 s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3855 {
3856    IRTemp value = newTemp(Ity_I32);
3857 
3858    assign(value, get_gpr_w1(r3 | 1));
3859    put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3860    if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3861                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3862 
3863    return "brxh";
3864 }
3865 
3866 static const HChar *
s390_irgen_BRXHG(UChar r1,UChar r3,UShort i2)3867 s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3868 {
3869    IRTemp value = newTemp(Ity_I64);
3870 
3871    assign(value, get_gpr_dw0(r3 | 1));
3872    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3873    if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3874                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3875 
3876    return "brxhg";
3877 }
3878 
3879 static const HChar *
s390_irgen_BRXLE(UChar r1,UChar r3,UShort i2)3880 s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3881 {
3882    IRTemp value = newTemp(Ity_I32);
3883 
3884    assign(value, get_gpr_w1(r3 | 1));
3885    put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3886    if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3887                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3888 
3889    return "brxle";
3890 }
3891 
3892 static const HChar *
s390_irgen_BRXLG(UChar r1,UChar r3,UShort i2)3893 s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3894 {
3895    IRTemp value = newTemp(Ity_I64);
3896 
3897    assign(value, get_gpr_dw0(r3 | 1));
3898    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3899    if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3900                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3901 
3902    return "brxlg";
3903 }
3904 
3905 static const HChar *
s390_irgen_CR(UChar r1,UChar r2)3906 s390_irgen_CR(UChar r1, UChar r2)
3907 {
3908    IRTemp op1 = newTemp(Ity_I32);
3909    IRTemp op2 = newTemp(Ity_I32);
3910 
3911    assign(op1, get_gpr_w1(r1));
3912    assign(op2, get_gpr_w1(r2));
3913    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3914 
3915    return "cr";
3916 }
3917 
3918 static const HChar *
s390_irgen_CGR(UChar r1,UChar r2)3919 s390_irgen_CGR(UChar r1, UChar r2)
3920 {
3921    IRTemp op1 = newTemp(Ity_I64);
3922    IRTemp op2 = newTemp(Ity_I64);
3923 
3924    assign(op1, get_gpr_dw0(r1));
3925    assign(op2, get_gpr_dw0(r2));
3926    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3927 
3928    return "cgr";
3929 }
3930 
3931 static const HChar *
s390_irgen_CGFR(UChar r1,UChar r2)3932 s390_irgen_CGFR(UChar r1, UChar r2)
3933 {
3934    IRTemp op1 = newTemp(Ity_I64);
3935    IRTemp op2 = newTemp(Ity_I64);
3936 
3937    assign(op1, get_gpr_dw0(r1));
3938    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3939    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3940 
3941    return "cgfr";
3942 }
3943 
3944 static const HChar *
s390_irgen_C(UChar r1,IRTemp op2addr)3945 s390_irgen_C(UChar r1, IRTemp op2addr)
3946 {
3947    IRTemp op1 = newTemp(Ity_I32);
3948    IRTemp op2 = newTemp(Ity_I32);
3949 
3950    assign(op1, get_gpr_w1(r1));
3951    assign(op2, load(Ity_I32, mkexpr(op2addr)));
3952    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3953 
3954    return "c";
3955 }
3956 
3957 static const HChar *
s390_irgen_CY(UChar r1,IRTemp op2addr)3958 s390_irgen_CY(UChar r1, IRTemp op2addr)
3959 {
3960    IRTemp op1 = newTemp(Ity_I32);
3961    IRTemp op2 = newTemp(Ity_I32);
3962 
3963    assign(op1, get_gpr_w1(r1));
3964    assign(op2, load(Ity_I32, mkexpr(op2addr)));
3965    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3966 
3967    return "cy";
3968 }
3969 
3970 static const HChar *
s390_irgen_CG(UChar r1,IRTemp op2addr)3971 s390_irgen_CG(UChar r1, IRTemp op2addr)
3972 {
3973    IRTemp op1 = newTemp(Ity_I64);
3974    IRTemp op2 = newTemp(Ity_I64);
3975 
3976    assign(op1, get_gpr_dw0(r1));
3977    assign(op2, load(Ity_I64, mkexpr(op2addr)));
3978    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3979 
3980    return "cg";
3981 }
3982 
3983 static const HChar *
s390_irgen_CGF(UChar r1,IRTemp op2addr)3984 s390_irgen_CGF(UChar r1, IRTemp op2addr)
3985 {
3986    IRTemp op1 = newTemp(Ity_I64);
3987    IRTemp op2 = newTemp(Ity_I64);
3988 
3989    assign(op1, get_gpr_dw0(r1));
3990    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3991    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3992 
3993    return "cgf";
3994 }
3995 
3996 static const HChar *
s390_irgen_CFI(UChar r1,UInt i2)3997 s390_irgen_CFI(UChar r1, UInt i2)
3998 {
3999    IRTemp op1 = newTemp(Ity_I32);
4000    Int op2;
4001 
4002    assign(op1, get_gpr_w1(r1));
4003    op2 = (Int)i2;
4004    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4005                        mkU32((UInt)op2)));
4006 
4007    return "cfi";
4008 }
4009 
4010 static const HChar *
s390_irgen_CGFI(UChar r1,UInt i2)4011 s390_irgen_CGFI(UChar r1, UInt i2)
4012 {
4013    IRTemp op1 = newTemp(Ity_I64);
4014    Long op2;
4015 
4016    assign(op1, get_gpr_dw0(r1));
4017    op2 = (Long)(Int)i2;
4018    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4019                        mkU64((ULong)op2)));
4020 
4021    return "cgfi";
4022 }
4023 
4024 static const HChar *
s390_irgen_CRL(UChar r1,UInt i2)4025 s390_irgen_CRL(UChar r1, UInt i2)
4026 {
4027    IRTemp op1 = newTemp(Ity_I32);
4028    IRTemp op2 = newTemp(Ity_I32);
4029 
4030    assign(op1, get_gpr_w1(r1));
4031    assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4032           i2 << 1))));
4033    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4034 
4035    return "crl";
4036 }
4037 
4038 static const HChar *
s390_irgen_CGRL(UChar r1,UInt i2)4039 s390_irgen_CGRL(UChar r1, UInt i2)
4040 {
4041    IRTemp op1 = newTemp(Ity_I64);
4042    IRTemp op2 = newTemp(Ity_I64);
4043 
4044    assign(op1, get_gpr_dw0(r1));
4045    assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4046           i2 << 1))));
4047    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4048 
4049    return "cgrl";
4050 }
4051 
4052 static const HChar *
s390_irgen_CGFRL(UChar r1,UInt i2)4053 s390_irgen_CGFRL(UChar r1, UInt i2)
4054 {
4055    IRTemp op1 = newTemp(Ity_I64);
4056    IRTemp op2 = newTemp(Ity_I64);
4057 
4058    assign(op1, get_gpr_dw0(r1));
4059    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4060           ((ULong)(Long)(Int)i2 << 1)))));
4061    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4062 
4063    return "cgfrl";
4064 }
4065 
4066 static const HChar *
s390_irgen_CRB(UChar r1,UChar r2,UChar m3,IRTemp op4addr)4067 s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4068 {
4069    IRTemp op1 = newTemp(Ity_I32);
4070    IRTemp op2 = newTemp(Ity_I32);
4071    IRTemp cond = newTemp(Ity_I32);
4072 
4073    if (m3 == 0) {
4074    } else {
4075       if (m3 == 14) {
4076          always_goto(mkexpr(op4addr));
4077       } else {
4078          assign(op1, get_gpr_w1(r1));
4079          assign(op2, get_gpr_w1(r2));
4080          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4081                                               op1, op2));
4082          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4083                                           mkU32(0)), mkexpr(op4addr));
4084       }
4085    }
4086 
4087    return "crb";
4088 }
4089 
4090 static const HChar *
s390_irgen_CGRB(UChar r1,UChar r2,UChar m3,IRTemp op4addr)4091 s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4092 {
4093    IRTemp op1 = newTemp(Ity_I64);
4094    IRTemp op2 = newTemp(Ity_I64);
4095    IRTemp cond = newTemp(Ity_I32);
4096 
4097    if (m3 == 0) {
4098    } else {
4099       if (m3 == 14) {
4100          always_goto(mkexpr(op4addr));
4101       } else {
4102          assign(op1, get_gpr_dw0(r1));
4103          assign(op2, get_gpr_dw0(r2));
4104          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4105                                               op1, op2));
4106          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4107                                           mkU32(0)), mkexpr(op4addr));
4108       }
4109    }
4110 
4111    return "cgrb";
4112 }
4113 
4114 static const HChar *
s390_irgen_CRJ(UChar r1,UChar r2,UShort i4,UChar m3)4115 s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4116 {
4117    IRTemp op1 = newTemp(Ity_I32);
4118    IRTemp op2 = newTemp(Ity_I32);
4119    IRTemp cond = newTemp(Ity_I32);
4120 
4121    if (m3 == 0) {
4122    } else {
4123       if (m3 == 14) {
4124          always_goto_and_chase(
4125                 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4126       } else {
4127          assign(op1, get_gpr_w1(r1));
4128          assign(op2, get_gpr_w1(r2));
4129          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4130                                               op1, op2));
4131          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4132                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4133 
4134       }
4135    }
4136 
4137    return "crj";
4138 }
4139 
4140 static const HChar *
s390_irgen_CGRJ(UChar r1,UChar r2,UShort i4,UChar m3)4141 s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4142 {
4143    IRTemp op1 = newTemp(Ity_I64);
4144    IRTemp op2 = newTemp(Ity_I64);
4145    IRTemp cond = newTemp(Ity_I32);
4146 
4147    if (m3 == 0) {
4148    } else {
4149       if (m3 == 14) {
4150          always_goto_and_chase(
4151                 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4152       } else {
4153          assign(op1, get_gpr_dw0(r1));
4154          assign(op2, get_gpr_dw0(r2));
4155          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4156                                               op1, op2));
4157          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4158                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4159 
4160       }
4161    }
4162 
4163    return "cgrj";
4164 }
4165 
4166 static const HChar *
s390_irgen_CIB(UChar r1,UChar m3,UChar i2,IRTemp op4addr)4167 s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4168 {
4169    IRTemp op1 = newTemp(Ity_I32);
4170    Int op2;
4171    IRTemp cond = newTemp(Ity_I32);
4172 
4173    if (m3 == 0) {
4174    } else {
4175       if (m3 == 14) {
4176          always_goto(mkexpr(op4addr));
4177       } else {
4178          assign(op1, get_gpr_w1(r1));
4179          op2 = (Int)(Char)i2;
4180          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4181                                               mktemp(Ity_I32, mkU32((UInt)op2))));
4182          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4183                                     mkexpr(op4addr));
4184       }
4185    }
4186 
4187    return "cib";
4188 }
4189 
4190 static const HChar *
s390_irgen_CGIB(UChar r1,UChar m3,UChar i2,IRTemp op4addr)4191 s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4192 {
4193    IRTemp op1 = newTemp(Ity_I64);
4194    Long op2;
4195    IRTemp cond = newTemp(Ity_I32);
4196 
4197    if (m3 == 0) {
4198    } else {
4199       if (m3 == 14) {
4200          always_goto(mkexpr(op4addr));
4201       } else {
4202          assign(op1, get_gpr_dw0(r1));
4203          op2 = (Long)(Char)i2;
4204          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4205                                               mktemp(Ity_I64, mkU64((ULong)op2))));
4206          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4207                                     mkexpr(op4addr));
4208       }
4209    }
4210 
4211    return "cgib";
4212 }
4213 
4214 static const HChar *
s390_irgen_CIJ(UChar r1,UChar m3,UShort i4,UChar i2)4215 s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4216 {
4217    IRTemp op1 = newTemp(Ity_I32);
4218    Int op2;
4219    IRTemp cond = newTemp(Ity_I32);
4220 
4221    if (m3 == 0) {
4222    } else {
4223       if (m3 == 14) {
4224          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4225       } else {
4226          assign(op1, get_gpr_w1(r1));
4227          op2 = (Int)(Char)i2;
4228          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4229                                               mktemp(Ity_I32, mkU32((UInt)op2))));
4230          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4231                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4232 
4233       }
4234    }
4235 
4236    return "cij";
4237 }
4238 
4239 static const HChar *
s390_irgen_CGIJ(UChar r1,UChar m3,UShort i4,UChar i2)4240 s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4241 {
4242    IRTemp op1 = newTemp(Ity_I64);
4243    Long op2;
4244    IRTemp cond = newTemp(Ity_I32);
4245 
4246    if (m3 == 0) {
4247    } else {
4248       if (m3 == 14) {
4249          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4250       } else {
4251          assign(op1, get_gpr_dw0(r1));
4252          op2 = (Long)(Char)i2;
4253          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4254                                               mktemp(Ity_I64, mkU64((ULong)op2))));
4255          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4256                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4257 
4258       }
4259    }
4260 
4261    return "cgij";
4262 }
4263 
4264 static const HChar *
s390_irgen_CH(UChar r1,IRTemp op2addr)4265 s390_irgen_CH(UChar r1, IRTemp op2addr)
4266 {
4267    IRTemp op1 = newTemp(Ity_I32);
4268    IRTemp op2 = newTemp(Ity_I32);
4269 
4270    assign(op1, get_gpr_w1(r1));
4271    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4272    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4273 
4274    return "ch";
4275 }
4276 
4277 static const HChar *
s390_irgen_CHY(UChar r1,IRTemp op2addr)4278 s390_irgen_CHY(UChar r1, IRTemp op2addr)
4279 {
4280    IRTemp op1 = newTemp(Ity_I32);
4281    IRTemp op2 = newTemp(Ity_I32);
4282 
4283    assign(op1, get_gpr_w1(r1));
4284    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4285    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4286 
4287    return "chy";
4288 }
4289 
4290 static const HChar *
s390_irgen_CGH(UChar r1,IRTemp op2addr)4291 s390_irgen_CGH(UChar r1, IRTemp op2addr)
4292 {
4293    IRTemp op1 = newTemp(Ity_I64);
4294    IRTemp op2 = newTemp(Ity_I64);
4295 
4296    assign(op1, get_gpr_dw0(r1));
4297    assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4298    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4299 
4300    return "cgh";
4301 }
4302 
4303 static const HChar *
s390_irgen_CHI(UChar r1,UShort i2)4304 s390_irgen_CHI(UChar r1, UShort i2)
4305 {
4306    IRTemp op1 = newTemp(Ity_I32);
4307    Int op2;
4308 
4309    assign(op1, get_gpr_w1(r1));
4310    op2 = (Int)(Short)i2;
4311    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4312                        mkU32((UInt)op2)));
4313 
4314    return "chi";
4315 }
4316 
4317 static const HChar *
s390_irgen_CGHI(UChar r1,UShort i2)4318 s390_irgen_CGHI(UChar r1, UShort i2)
4319 {
4320    IRTemp op1 = newTemp(Ity_I64);
4321    Long op2;
4322 
4323    assign(op1, get_gpr_dw0(r1));
4324    op2 = (Long)(Short)i2;
4325    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4326                        mkU64((ULong)op2)));
4327 
4328    return "cghi";
4329 }
4330 
4331 static const HChar *
s390_irgen_CHHSI(UShort i2,IRTemp op1addr)4332 s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4333 {
4334    IRTemp op1 = newTemp(Ity_I16);
4335    Short op2;
4336 
4337    assign(op1, load(Ity_I16, mkexpr(op1addr)));
4338    op2 = (Short)i2;
4339    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4340                        mkU16((UShort)op2)));
4341 
4342    return "chhsi";
4343 }
4344 
4345 static const HChar *
s390_irgen_CHSI(UShort i2,IRTemp op1addr)4346 s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4347 {
4348    IRTemp op1 = newTemp(Ity_I32);
4349    Int op2;
4350 
4351    assign(op1, load(Ity_I32, mkexpr(op1addr)));
4352    op2 = (Int)(Short)i2;
4353    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4354                        mkU32((UInt)op2)));
4355 
4356    return "chsi";
4357 }
4358 
4359 static const HChar *
s390_irgen_CGHSI(UShort i2,IRTemp op1addr)4360 s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4361 {
4362    IRTemp op1 = newTemp(Ity_I64);
4363    Long op2;
4364 
4365    assign(op1, load(Ity_I64, mkexpr(op1addr)));
4366    op2 = (Long)(Short)i2;
4367    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4368                        mkU64((ULong)op2)));
4369 
4370    return "cghsi";
4371 }
4372 
4373 static const HChar *
s390_irgen_CHRL(UChar r1,UInt i2)4374 s390_irgen_CHRL(UChar r1, UInt i2)
4375 {
4376    IRTemp op1 = newTemp(Ity_I32);
4377    IRTemp op2 = newTemp(Ity_I32);
4378 
4379    assign(op1, get_gpr_w1(r1));
4380    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4381           ((ULong)(Long)(Int)i2 << 1)))));
4382    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4383 
4384    return "chrl";
4385 }
4386 
4387 static const HChar *
s390_irgen_CGHRL(UChar r1,UInt i2)4388 s390_irgen_CGHRL(UChar r1, UInt i2)
4389 {
4390    IRTemp op1 = newTemp(Ity_I64);
4391    IRTemp op2 = newTemp(Ity_I64);
4392 
4393    assign(op1, get_gpr_dw0(r1));
4394    assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4395           ((ULong)(Long)(Int)i2 << 1)))));
4396    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4397 
4398    return "cghrl";
4399 }
4400 
4401 static const HChar *
s390_irgen_CHHR(UChar r1,UChar r2)4402 s390_irgen_CHHR(UChar r1, UChar r2)
4403 {
4404    IRTemp op1 = newTemp(Ity_I32);
4405    IRTemp op2 = newTemp(Ity_I32);
4406 
4407    assign(op1, get_gpr_w0(r1));
4408    assign(op2, get_gpr_w0(r2));
4409    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4410 
4411    return "chhr";
4412 }
4413 
4414 static const HChar *
s390_irgen_CHLR(UChar r1,UChar r2)4415 s390_irgen_CHLR(UChar r1, UChar r2)
4416 {
4417    IRTemp op1 = newTemp(Ity_I32);
4418    IRTemp op2 = newTemp(Ity_I32);
4419 
4420    assign(op1, get_gpr_w0(r1));
4421    assign(op2, get_gpr_w1(r2));
4422    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4423 
4424    return "chlr";
4425 }
4426 
4427 static const HChar *
s390_irgen_CHF(UChar r1,IRTemp op2addr)4428 s390_irgen_CHF(UChar r1, IRTemp op2addr)
4429 {
4430    IRTemp op1 = newTemp(Ity_I32);
4431    IRTemp op2 = newTemp(Ity_I32);
4432 
4433    assign(op1, get_gpr_w0(r1));
4434    assign(op2, load(Ity_I32, mkexpr(op2addr)));
4435    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4436 
4437    return "chf";
4438 }
4439 
4440 static const HChar *
s390_irgen_CIH(UChar r1,UInt i2)4441 s390_irgen_CIH(UChar r1, UInt i2)
4442 {
4443    IRTemp op1 = newTemp(Ity_I32);
4444    Int op2;
4445 
4446    assign(op1, get_gpr_w0(r1));
4447    op2 = (Int)i2;
4448    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4449                        mkU32((UInt)op2)));
4450 
4451    return "cih";
4452 }
4453 
4454 static const HChar *
s390_irgen_CLR(UChar r1,UChar r2)4455 s390_irgen_CLR(UChar r1, UChar r2)
4456 {
4457    IRTemp op1 = newTemp(Ity_I32);
4458    IRTemp op2 = newTemp(Ity_I32);
4459 
4460    assign(op1, get_gpr_w1(r1));
4461    assign(op2, get_gpr_w1(r2));
4462    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4463 
4464    return "clr";
4465 }
4466 
4467 static const HChar *
s390_irgen_CLGR(UChar r1,UChar r2)4468 s390_irgen_CLGR(UChar r1, UChar r2)
4469 {
4470    IRTemp op1 = newTemp(Ity_I64);
4471    IRTemp op2 = newTemp(Ity_I64);
4472 
4473    assign(op1, get_gpr_dw0(r1));
4474    assign(op2, get_gpr_dw0(r2));
4475    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4476 
4477    return "clgr";
4478 }
4479 
4480 static const HChar *
s390_irgen_CLGFR(UChar r1,UChar r2)4481 s390_irgen_CLGFR(UChar r1, UChar r2)
4482 {
4483    IRTemp op1 = newTemp(Ity_I64);
4484    IRTemp op2 = newTemp(Ity_I64);
4485 
4486    assign(op1, get_gpr_dw0(r1));
4487    assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4488    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4489 
4490    return "clgfr";
4491 }
4492 
4493 static const HChar *
s390_irgen_CL(UChar r1,IRTemp op2addr)4494 s390_irgen_CL(UChar r1, IRTemp op2addr)
4495 {
4496    IRTemp op1 = newTemp(Ity_I32);
4497    IRTemp op2 = newTemp(Ity_I32);
4498 
4499    assign(op1, get_gpr_w1(r1));
4500    assign(op2, load(Ity_I32, mkexpr(op2addr)));
4501    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4502 
4503    return "cl";
4504 }
4505 
4506 static const HChar *
s390_irgen_CLY(UChar r1,IRTemp op2addr)4507 s390_irgen_CLY(UChar r1, IRTemp op2addr)
4508 {
4509    IRTemp op1 = newTemp(Ity_I32);
4510    IRTemp op2 = newTemp(Ity_I32);
4511 
4512    assign(op1, get_gpr_w1(r1));
4513    assign(op2, load(Ity_I32, mkexpr(op2addr)));
4514    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4515 
4516    return "cly";
4517 }
4518 
4519 static const HChar *
s390_irgen_CLG(UChar r1,IRTemp op2addr)4520 s390_irgen_CLG(UChar r1, IRTemp op2addr)
4521 {
4522    IRTemp op1 = newTemp(Ity_I64);
4523    IRTemp op2 = newTemp(Ity_I64);
4524 
4525    assign(op1, get_gpr_dw0(r1));
4526    assign(op2, load(Ity_I64, mkexpr(op2addr)));
4527    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4528 
4529    return "clg";
4530 }
4531 
4532 static const HChar *
s390_irgen_CLGF(UChar r1,IRTemp op2addr)4533 s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4534 {
4535    IRTemp op1 = newTemp(Ity_I64);
4536    IRTemp op2 = newTemp(Ity_I64);
4537 
4538    assign(op1, get_gpr_dw0(r1));
4539    assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4540    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4541 
4542    return "clgf";
4543 }
4544 
4545 static const HChar *
s390_irgen_CLFI(UChar r1,UInt i2)4546 s390_irgen_CLFI(UChar r1, UInt i2)
4547 {
4548    IRTemp op1 = newTemp(Ity_I32);
4549    UInt op2;
4550 
4551    assign(op1, get_gpr_w1(r1));
4552    op2 = i2;
4553    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4554                        mkU32(op2)));
4555 
4556    return "clfi";
4557 }
4558 
4559 static const HChar *
s390_irgen_CLGFI(UChar r1,UInt i2)4560 s390_irgen_CLGFI(UChar r1, UInt i2)
4561 {
4562    IRTemp op1 = newTemp(Ity_I64);
4563    ULong op2;
4564 
4565    assign(op1, get_gpr_dw0(r1));
4566    op2 = (ULong)i2;
4567    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4568                        mkU64(op2)));
4569 
4570    return "clgfi";
4571 }
4572 
4573 static const HChar *
s390_irgen_CLI(UChar i2,IRTemp op1addr)4574 s390_irgen_CLI(UChar i2, IRTemp op1addr)
4575 {
4576    IRTemp op1 = newTemp(Ity_I8);
4577    UChar op2;
4578 
4579    assign(op1, load(Ity_I8, mkexpr(op1addr)));
4580    op2 = i2;
4581    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4582                        mkU8(op2)));
4583 
4584    return "cli";
4585 }
4586 
4587 static const HChar *
s390_irgen_CLIY(UChar i2,IRTemp op1addr)4588 s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4589 {
4590    IRTemp op1 = newTemp(Ity_I8);
4591    UChar op2;
4592 
4593    assign(op1, load(Ity_I8, mkexpr(op1addr)));
4594    op2 = i2;
4595    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4596                        mkU8(op2)));
4597 
4598    return "cliy";
4599 }
4600 
4601 static const HChar *
s390_irgen_CLFHSI(UShort i2,IRTemp op1addr)4602 s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4603 {
4604    IRTemp op1 = newTemp(Ity_I32);
4605    UInt op2;
4606 
4607    assign(op1, load(Ity_I32, mkexpr(op1addr)));
4608    op2 = (UInt)i2;
4609    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4610                        mkU32(op2)));
4611 
4612    return "clfhsi";
4613 }
4614 
4615 static const HChar *
s390_irgen_CLGHSI(UShort i2,IRTemp op1addr)4616 s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4617 {
4618    IRTemp op1 = newTemp(Ity_I64);
4619    ULong op2;
4620 
4621    assign(op1, load(Ity_I64, mkexpr(op1addr)));
4622    op2 = (ULong)i2;
4623    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4624                        mkU64(op2)));
4625 
4626    return "clghsi";
4627 }
4628 
4629 static const HChar *
s390_irgen_CLHHSI(UShort i2,IRTemp op1addr)4630 s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4631 {
4632    IRTemp op1 = newTemp(Ity_I16);
4633    UShort op2;
4634 
4635    assign(op1, load(Ity_I16, mkexpr(op1addr)));
4636    op2 = i2;
4637    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4638                        mkU16(op2)));
4639 
4640    return "clhhsi";
4641 }
4642 
4643 static const HChar *
s390_irgen_CLRL(UChar r1,UInt i2)4644 s390_irgen_CLRL(UChar r1, UInt i2)
4645 {
4646    IRTemp op1 = newTemp(Ity_I32);
4647    IRTemp op2 = newTemp(Ity_I32);
4648 
4649    assign(op1, get_gpr_w1(r1));
4650    assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4651           i2 << 1))));
4652    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4653 
4654    return "clrl";
4655 }
4656 
4657 static const HChar *
s390_irgen_CLGRL(UChar r1,UInt i2)4658 s390_irgen_CLGRL(UChar r1, UInt i2)
4659 {
4660    IRTemp op1 = newTemp(Ity_I64);
4661    IRTemp op2 = newTemp(Ity_I64);
4662 
4663    assign(op1, get_gpr_dw0(r1));
4664    assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4665           i2 << 1))));
4666    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4667 
4668    return "clgrl";
4669 }
4670 
4671 static const HChar *
s390_irgen_CLGFRL(UChar r1,UInt i2)4672 s390_irgen_CLGFRL(UChar r1, UInt i2)
4673 {
4674    IRTemp op1 = newTemp(Ity_I64);
4675    IRTemp op2 = newTemp(Ity_I64);
4676 
4677    assign(op1, get_gpr_dw0(r1));
4678    assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4679           ((ULong)(Long)(Int)i2 << 1)))));
4680    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4681 
4682    return "clgfrl";
4683 }
4684 
4685 static const HChar *
s390_irgen_CLHRL(UChar r1,UInt i2)4686 s390_irgen_CLHRL(UChar r1, UInt i2)
4687 {
4688    IRTemp op1 = newTemp(Ity_I32);
4689    IRTemp op2 = newTemp(Ity_I32);
4690 
4691    assign(op1, get_gpr_w1(r1));
4692    assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4693           ((ULong)(Long)(Int)i2 << 1)))));
4694    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4695 
4696    return "clhrl";
4697 }
4698 
4699 static const HChar *
s390_irgen_CLGHRL(UChar r1,UInt i2)4700 s390_irgen_CLGHRL(UChar r1, UInt i2)
4701 {
4702    IRTemp op1 = newTemp(Ity_I64);
4703    IRTemp op2 = newTemp(Ity_I64);
4704 
4705    assign(op1, get_gpr_dw0(r1));
4706    assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4707           ((ULong)(Long)(Int)i2 << 1)))));
4708    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4709 
4710    return "clghrl";
4711 }
4712 
4713 static const HChar *
s390_irgen_CLRB(UChar r1,UChar r2,UChar m3,IRTemp op4addr)4714 s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4715 {
4716    IRTemp op1 = newTemp(Ity_I32);
4717    IRTemp op2 = newTemp(Ity_I32);
4718    IRTemp cond = newTemp(Ity_I32);
4719 
4720    if (m3 == 0) {
4721    } else {
4722       if (m3 == 14) {
4723          always_goto(mkexpr(op4addr));
4724       } else {
4725          assign(op1, get_gpr_w1(r1));
4726          assign(op2, get_gpr_w1(r2));
4727          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4728                                               op1, op2));
4729          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4730                                     mkexpr(op4addr));
4731       }
4732    }
4733 
4734    return "clrb";
4735 }
4736 
4737 static const HChar *
s390_irgen_CLGRB(UChar r1,UChar r2,UChar m3,IRTemp op4addr)4738 s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4739 {
4740    IRTemp op1 = newTemp(Ity_I64);
4741    IRTemp op2 = newTemp(Ity_I64);
4742    IRTemp cond = newTemp(Ity_I32);
4743 
4744    if (m3 == 0) {
4745    } else {
4746       if (m3 == 14) {
4747          always_goto(mkexpr(op4addr));
4748       } else {
4749          assign(op1, get_gpr_dw0(r1));
4750          assign(op2, get_gpr_dw0(r2));
4751          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4752                                               op1, op2));
4753          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4754                                     mkexpr(op4addr));
4755       }
4756    }
4757 
4758    return "clgrb";
4759 }
4760 
4761 static const HChar *
s390_irgen_CLRJ(UChar r1,UChar r2,UShort i4,UChar m3)4762 s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4763 {
4764    IRTemp op1 = newTemp(Ity_I32);
4765    IRTemp op2 = newTemp(Ity_I32);
4766    IRTemp cond = newTemp(Ity_I32);
4767 
4768    if (m3 == 0) {
4769    } else {
4770       if (m3 == 14) {
4771          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4772       } else {
4773          assign(op1, get_gpr_w1(r1));
4774          assign(op2, get_gpr_w1(r2));
4775          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4776                                               op1, op2));
4777          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4778                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4779 
4780       }
4781    }
4782 
4783    return "clrj";
4784 }
4785 
4786 static const HChar *
s390_irgen_CLGRJ(UChar r1,UChar r2,UShort i4,UChar m3)4787 s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4788 {
4789    IRTemp op1 = newTemp(Ity_I64);
4790    IRTemp op2 = newTemp(Ity_I64);
4791    IRTemp cond = newTemp(Ity_I32);
4792 
4793    if (m3 == 0) {
4794    } else {
4795       if (m3 == 14) {
4796          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4797       } else {
4798          assign(op1, get_gpr_dw0(r1));
4799          assign(op2, get_gpr_dw0(r2));
4800          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4801                                               op1, op2));
4802          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4803                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4804 
4805       }
4806    }
4807 
4808    return "clgrj";
4809 }
4810 
4811 static const HChar *
s390_irgen_CLIB(UChar r1,UChar m3,UChar i2,IRTemp op4addr)4812 s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4813 {
4814    IRTemp op1 = newTemp(Ity_I32);
4815    UInt op2;
4816    IRTemp cond = newTemp(Ity_I32);
4817 
4818    if (m3 == 0) {
4819    } else {
4820       if (m3 == 14) {
4821          always_goto(mkexpr(op4addr));
4822       } else {
4823          assign(op1, get_gpr_w1(r1));
4824          op2 = (UInt)i2;
4825          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4826                                               mktemp(Ity_I32, mkU32(op2))));
4827          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4828                                     mkexpr(op4addr));
4829       }
4830    }
4831 
4832    return "clib";
4833 }
4834 
4835 static const HChar *
s390_irgen_CLGIB(UChar r1,UChar m3,UChar i2,IRTemp op4addr)4836 s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4837 {
4838    IRTemp op1 = newTemp(Ity_I64);
4839    ULong op2;
4840    IRTemp cond = newTemp(Ity_I32);
4841 
4842    if (m3 == 0) {
4843    } else {
4844       if (m3 == 14) {
4845          always_goto(mkexpr(op4addr));
4846       } else {
4847          assign(op1, get_gpr_dw0(r1));
4848          op2 = (ULong)i2;
4849          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4850                                               mktemp(Ity_I64, mkU64(op2))));
4851          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4852                                     mkexpr(op4addr));
4853       }
4854    }
4855 
4856    return "clgib";
4857 }
4858 
4859 static const HChar *
s390_irgen_CLIJ(UChar r1,UChar m3,UShort i4,UChar i2)4860 s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4861 {
4862    IRTemp op1 = newTemp(Ity_I32);
4863    UInt op2;
4864    IRTemp cond = newTemp(Ity_I32);
4865 
4866    if (m3 == 0) {
4867    } else {
4868       if (m3 == 14) {
4869          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4870       } else {
4871          assign(op1, get_gpr_w1(r1));
4872          op2 = (UInt)i2;
4873          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4874                                               mktemp(Ity_I32, mkU32(op2))));
4875          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4876                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4877 
4878       }
4879    }
4880 
4881    return "clij";
4882 }
4883 
4884 static const HChar *
s390_irgen_CLGIJ(UChar r1,UChar m3,UShort i4,UChar i2)4885 s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4886 {
4887    IRTemp op1 = newTemp(Ity_I64);
4888    ULong op2;
4889    IRTemp cond = newTemp(Ity_I32);
4890 
4891    if (m3 == 0) {
4892    } else {
4893       if (m3 == 14) {
4894          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4895       } else {
4896          assign(op1, get_gpr_dw0(r1));
4897          op2 = (ULong)i2;
4898          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4899                                               mktemp(Ity_I64, mkU64(op2))));
4900          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4901                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4902 
4903       }
4904    }
4905 
4906    return "clgij";
4907 }
4908 
4909 static const HChar *
s390_irgen_CLM(UChar r1,UChar r3,IRTemp op2addr)4910 s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4911 {
4912    IRTemp op1 = newTemp(Ity_I32);
4913    IRTemp op2 = newTemp(Ity_I32);
4914    IRTemp b0 = newTemp(Ity_I32);
4915    IRTemp b1 = newTemp(Ity_I32);
4916    IRTemp b2 = newTemp(Ity_I32);
4917    IRTemp b3 = newTemp(Ity_I32);
4918    IRTemp c0 = newTemp(Ity_I32);
4919    IRTemp c1 = newTemp(Ity_I32);
4920    IRTemp c2 = newTemp(Ity_I32);
4921    IRTemp c3 = newTemp(Ity_I32);
4922    UChar n;
4923 
4924    n = 0;
4925    if ((r3 & 8) != 0) {
4926       assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4927       assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4928       n = n + 1;
4929    } else {
4930       assign(b0, mkU32(0));
4931       assign(c0, mkU32(0));
4932    }
4933    if ((r3 & 4) != 0) {
4934       assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4935       assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4936              mkU64(n)))));
4937       n = n + 1;
4938    } else {
4939       assign(b1, mkU32(0));
4940       assign(c1, mkU32(0));
4941    }
4942    if ((r3 & 2) != 0) {
4943       assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4944       assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4945              mkU64(n)))));
4946       n = n + 1;
4947    } else {
4948       assign(b2, mkU32(0));
4949       assign(c2, mkU32(0));
4950    }
4951    if ((r3 & 1) != 0) {
4952       assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4953       assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4954              mkU64(n)))));
4955       n = n + 1;
4956    } else {
4957       assign(b3, mkU32(0));
4958       assign(c3, mkU32(0));
4959    }
4960    assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4961           mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4962           binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4963    assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4964           mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4965           binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4966    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4967 
4968    return "clm";
4969 }
4970 
4971 static const HChar *
s390_irgen_CLMY(UChar r1,UChar r3,IRTemp op2addr)4972 s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4973 {
4974    IRTemp op1 = newTemp(Ity_I32);
4975    IRTemp op2 = newTemp(Ity_I32);
4976    IRTemp b0 = newTemp(Ity_I32);
4977    IRTemp b1 = newTemp(Ity_I32);
4978    IRTemp b2 = newTemp(Ity_I32);
4979    IRTemp b3 = newTemp(Ity_I32);
4980    IRTemp c0 = newTemp(Ity_I32);
4981    IRTemp c1 = newTemp(Ity_I32);
4982    IRTemp c2 = newTemp(Ity_I32);
4983    IRTemp c3 = newTemp(Ity_I32);
4984    UChar n;
4985 
4986    n = 0;
4987    if ((r3 & 8) != 0) {
4988       assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4989       assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4990       n = n + 1;
4991    } else {
4992       assign(b0, mkU32(0));
4993       assign(c0, mkU32(0));
4994    }
4995    if ((r3 & 4) != 0) {
4996       assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4997       assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4998              mkU64(n)))));
4999       n = n + 1;
5000    } else {
5001       assign(b1, mkU32(0));
5002       assign(c1, mkU32(0));
5003    }
5004    if ((r3 & 2) != 0) {
5005       assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
5006       assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5007              mkU64(n)))));
5008       n = n + 1;
5009    } else {
5010       assign(b2, mkU32(0));
5011       assign(c2, mkU32(0));
5012    }
5013    if ((r3 & 1) != 0) {
5014       assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
5015       assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5016              mkU64(n)))));
5017       n = n + 1;
5018    } else {
5019       assign(b3, mkU32(0));
5020       assign(c3, mkU32(0));
5021    }
5022    assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5023           mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5024           binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5025    assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5026           mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5027           binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5028    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5029 
5030    return "clmy";
5031 }
5032 
5033 static const HChar *
s390_irgen_CLMH(UChar r1,UChar r3,IRTemp op2addr)5034 s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5035 {
5036    IRTemp op1 = newTemp(Ity_I32);
5037    IRTemp op2 = newTemp(Ity_I32);
5038    IRTemp b0 = newTemp(Ity_I32);
5039    IRTemp b1 = newTemp(Ity_I32);
5040    IRTemp b2 = newTemp(Ity_I32);
5041    IRTemp b3 = newTemp(Ity_I32);
5042    IRTemp c0 = newTemp(Ity_I32);
5043    IRTemp c1 = newTemp(Ity_I32);
5044    IRTemp c2 = newTemp(Ity_I32);
5045    IRTemp c3 = newTemp(Ity_I32);
5046    UChar n;
5047 
5048    n = 0;
5049    if ((r3 & 8) != 0) {
5050       assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5051       assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5052       n = n + 1;
5053    } else {
5054       assign(b0, mkU32(0));
5055       assign(c0, mkU32(0));
5056    }
5057    if ((r3 & 4) != 0) {
5058       assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5059       assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5060              mkU64(n)))));
5061       n = n + 1;
5062    } else {
5063       assign(b1, mkU32(0));
5064       assign(c1, mkU32(0));
5065    }
5066    if ((r3 & 2) != 0) {
5067       assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5068       assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5069              mkU64(n)))));
5070       n = n + 1;
5071    } else {
5072       assign(b2, mkU32(0));
5073       assign(c2, mkU32(0));
5074    }
5075    if ((r3 & 1) != 0) {
5076       assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5077       assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5078              mkU64(n)))));
5079       n = n + 1;
5080    } else {
5081       assign(b3, mkU32(0));
5082       assign(c3, mkU32(0));
5083    }
5084    assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5085           mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5086           binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5087    assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5088           mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5089           binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5090    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5091 
5092    return "clmh";
5093 }
5094 
5095 static const HChar *
s390_irgen_CLHHR(UChar r1,UChar r2)5096 s390_irgen_CLHHR(UChar r1, UChar r2)
5097 {
5098    IRTemp op1 = newTemp(Ity_I32);
5099    IRTemp op2 = newTemp(Ity_I32);
5100 
5101    assign(op1, get_gpr_w0(r1));
5102    assign(op2, get_gpr_w0(r2));
5103    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5104 
5105    return "clhhr";
5106 }
5107 
5108 static const HChar *
s390_irgen_CLHLR(UChar r1,UChar r2)5109 s390_irgen_CLHLR(UChar r1, UChar r2)
5110 {
5111    IRTemp op1 = newTemp(Ity_I32);
5112    IRTemp op2 = newTemp(Ity_I32);
5113 
5114    assign(op1, get_gpr_w0(r1));
5115    assign(op2, get_gpr_w1(r2));
5116    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5117 
5118    return "clhlr";
5119 }
5120 
5121 static const HChar *
s390_irgen_CLHF(UChar r1,IRTemp op2addr)5122 s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5123 {
5124    IRTemp op1 = newTemp(Ity_I32);
5125    IRTemp op2 = newTemp(Ity_I32);
5126 
5127    assign(op1, get_gpr_w0(r1));
5128    assign(op2, load(Ity_I32, mkexpr(op2addr)));
5129    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5130 
5131    return "clhf";
5132 }
5133 
5134 static const HChar *
s390_irgen_CLIH(UChar r1,UInt i2)5135 s390_irgen_CLIH(UChar r1, UInt i2)
5136 {
5137    IRTemp op1 = newTemp(Ity_I32);
5138    UInt op2;
5139 
5140    assign(op1, get_gpr_w0(r1));
5141    op2 = i2;
5142    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5143                        mkU32(op2)));
5144 
5145    return "clih";
5146 }
5147 
5148 static const HChar *
s390_irgen_CPYA(UChar r1,UChar r2)5149 s390_irgen_CPYA(UChar r1, UChar r2)
5150 {
5151    put_ar_w0(r1, get_ar_w0(r2));
5152    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5153       s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5154 
5155    return "cpya";
5156 }
5157 
5158 static const HChar *
s390_irgen_XR(UChar r1,UChar r2)5159 s390_irgen_XR(UChar r1, UChar r2)
5160 {
5161    IRTemp op1 = newTemp(Ity_I32);
5162    IRTemp op2 = newTemp(Ity_I32);
5163    IRTemp result = newTemp(Ity_I32);
5164 
5165    if (r1 == r2) {
5166       assign(result, mkU32(0));
5167    } else {
5168       assign(op1, get_gpr_w1(r1));
5169       assign(op2, get_gpr_w1(r2));
5170       assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5171    }
5172    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5173    put_gpr_w1(r1, mkexpr(result));
5174 
5175    return "xr";
5176 }
5177 
5178 static const HChar *
s390_irgen_XGR(UChar r1,UChar r2)5179 s390_irgen_XGR(UChar r1, UChar r2)
5180 {
5181    IRTemp op1 = newTemp(Ity_I64);
5182    IRTemp op2 = newTemp(Ity_I64);
5183    IRTemp result = newTemp(Ity_I64);
5184 
5185    if (r1 == r2) {
5186       assign(result, mkU64(0));
5187    } else {
5188       assign(op1, get_gpr_dw0(r1));
5189       assign(op2, get_gpr_dw0(r2));
5190       assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5191    }
5192    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5193    put_gpr_dw0(r1, mkexpr(result));
5194 
5195    return "xgr";
5196 }
5197 
5198 static const HChar *
s390_irgen_XRK(UChar r3,UChar r1,UChar r2)5199 s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5200 {
5201    IRTemp op2 = newTemp(Ity_I32);
5202    IRTemp op3 = newTemp(Ity_I32);
5203    IRTemp result = newTemp(Ity_I32);
5204 
5205    assign(op2, get_gpr_w1(r2));
5206    assign(op3, get_gpr_w1(r3));
5207    assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5208    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5209    put_gpr_w1(r1, mkexpr(result));
5210 
5211    return "xrk";
5212 }
5213 
5214 static const HChar *
s390_irgen_XGRK(UChar r3,UChar r1,UChar r2)5215 s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5216 {
5217    IRTemp op2 = newTemp(Ity_I64);
5218    IRTemp op3 = newTemp(Ity_I64);
5219    IRTemp result = newTemp(Ity_I64);
5220 
5221    assign(op2, get_gpr_dw0(r2));
5222    assign(op3, get_gpr_dw0(r3));
5223    assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5224    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5225    put_gpr_dw0(r1, mkexpr(result));
5226 
5227    return "xgrk";
5228 }
5229 
5230 static const HChar *
s390_irgen_X(UChar r1,IRTemp op2addr)5231 s390_irgen_X(UChar r1, IRTemp op2addr)
5232 {
5233    IRTemp op1 = newTemp(Ity_I32);
5234    IRTemp op2 = newTemp(Ity_I32);
5235    IRTemp result = newTemp(Ity_I32);
5236 
5237    assign(op1, get_gpr_w1(r1));
5238    assign(op2, load(Ity_I32, mkexpr(op2addr)));
5239    assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5240    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5241    put_gpr_w1(r1, mkexpr(result));
5242 
5243    return "x";
5244 }
5245 
5246 static const HChar *
s390_irgen_XY(UChar r1,IRTemp op2addr)5247 s390_irgen_XY(UChar r1, IRTemp op2addr)
5248 {
5249    IRTemp op1 = newTemp(Ity_I32);
5250    IRTemp op2 = newTemp(Ity_I32);
5251    IRTemp result = newTemp(Ity_I32);
5252 
5253    assign(op1, get_gpr_w1(r1));
5254    assign(op2, load(Ity_I32, mkexpr(op2addr)));
5255    assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5256    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5257    put_gpr_w1(r1, mkexpr(result));
5258 
5259    return "xy";
5260 }
5261 
5262 static const HChar *
s390_irgen_XG(UChar r1,IRTemp op2addr)5263 s390_irgen_XG(UChar r1, IRTemp op2addr)
5264 {
5265    IRTemp op1 = newTemp(Ity_I64);
5266    IRTemp op2 = newTemp(Ity_I64);
5267    IRTemp result = newTemp(Ity_I64);
5268 
5269    assign(op1, get_gpr_dw0(r1));
5270    assign(op2, load(Ity_I64, mkexpr(op2addr)));
5271    assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5272    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5273    put_gpr_dw0(r1, mkexpr(result));
5274 
5275    return "xg";
5276 }
5277 
5278 static const HChar *
s390_irgen_XI(UChar i2,IRTemp op1addr)5279 s390_irgen_XI(UChar i2, IRTemp op1addr)
5280 {
5281    IRTemp op1 = newTemp(Ity_I8);
5282    UChar op2;
5283    IRTemp result = newTemp(Ity_I8);
5284 
5285    assign(op1, load(Ity_I8, mkexpr(op1addr)));
5286    op2 = i2;
5287    assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5288    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5289    store(mkexpr(op1addr), mkexpr(result));
5290 
5291    return "xi";
5292 }
5293 
5294 static const HChar *
s390_irgen_XIY(UChar i2,IRTemp op1addr)5295 s390_irgen_XIY(UChar i2, IRTemp op1addr)
5296 {
5297    IRTemp op1 = newTemp(Ity_I8);
5298    UChar op2;
5299    IRTemp result = newTemp(Ity_I8);
5300 
5301    assign(op1, load(Ity_I8, mkexpr(op1addr)));
5302    op2 = i2;
5303    assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5304    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5305    store(mkexpr(op1addr), mkexpr(result));
5306 
5307    return "xiy";
5308 }
5309 
5310 static const HChar *
s390_irgen_XIHF(UChar r1,UInt i2)5311 s390_irgen_XIHF(UChar r1, UInt i2)
5312 {
5313    IRTemp op1 = newTemp(Ity_I32);
5314    UInt op2;
5315    IRTemp result = newTemp(Ity_I32);
5316 
5317    assign(op1, get_gpr_w0(r1));
5318    op2 = i2;
5319    assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5320    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5321    put_gpr_w0(r1, mkexpr(result));
5322 
5323    return "xihf";
5324 }
5325 
5326 static const HChar *
s390_irgen_XILF(UChar r1,UInt i2)5327 s390_irgen_XILF(UChar r1, UInt i2)
5328 {
5329    IRTemp op1 = newTemp(Ity_I32);
5330    UInt op2;
5331    IRTemp result = newTemp(Ity_I32);
5332 
5333    assign(op1, get_gpr_w1(r1));
5334    op2 = i2;
5335    assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5336    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5337    put_gpr_w1(r1, mkexpr(result));
5338 
5339    return "xilf";
5340 }
5341 
5342 static const HChar *
s390_irgen_EAR(UChar r1,UChar r2)5343 s390_irgen_EAR(UChar r1, UChar r2)
5344 {
5345    put_gpr_w1(r1, get_ar_w0(r2));
5346    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5347       s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5348 
5349    return "ear";
5350 }
5351 
5352 static const HChar *
s390_irgen_IC(UChar r1,IRTemp op2addr)5353 s390_irgen_IC(UChar r1, IRTemp op2addr)
5354 {
5355    put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5356 
5357    return "ic";
5358 }
5359 
5360 static const HChar *
s390_irgen_ICY(UChar r1,IRTemp op2addr)5361 s390_irgen_ICY(UChar r1, IRTemp op2addr)
5362 {
5363    put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5364 
5365    return "icy";
5366 }
5367 
5368 static const HChar *
s390_irgen_ICM(UChar r1,UChar r3,IRTemp op2addr)5369 s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5370 {
5371    UChar n;
5372    IRTemp result = newTemp(Ity_I32);
5373    UInt mask;
5374 
5375    n = 0;
5376    mask = (UInt)r3;
5377    if ((mask & 8) != 0) {
5378       put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5379       n = n + 1;
5380    }
5381    if ((mask & 4) != 0) {
5382       put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5383 
5384       n = n + 1;
5385    }
5386    if ((mask & 2) != 0) {
5387       put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5388 
5389       n = n + 1;
5390    }
5391    if ((mask & 1) != 0) {
5392       put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5393 
5394       n = n + 1;
5395    }
5396    assign(result, get_gpr_w1(r1));
5397    s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5398                        mkU32(mask)));
5399 
5400    return "icm";
5401 }
5402 
5403 static const HChar *
s390_irgen_ICMY(UChar r1,UChar r3,IRTemp op2addr)5404 s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5405 {
5406    UChar n;
5407    IRTemp result = newTemp(Ity_I32);
5408    UInt mask;
5409 
5410    n = 0;
5411    mask = (UInt)r3;
5412    if ((mask & 8) != 0) {
5413       put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5414       n = n + 1;
5415    }
5416    if ((mask & 4) != 0) {
5417       put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5418 
5419       n = n + 1;
5420    }
5421    if ((mask & 2) != 0) {
5422       put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5423 
5424       n = n + 1;
5425    }
5426    if ((mask & 1) != 0) {
5427       put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5428 
5429       n = n + 1;
5430    }
5431    assign(result, get_gpr_w1(r1));
5432    s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5433                        mkU32(mask)));
5434 
5435    return "icmy";
5436 }
5437 
5438 static const HChar *
s390_irgen_ICMH(UChar r1,UChar r3,IRTemp op2addr)5439 s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5440 {
5441    UChar n;
5442    IRTemp result = newTemp(Ity_I32);
5443    UInt mask;
5444 
5445    n = 0;
5446    mask = (UInt)r3;
5447    if ((mask & 8) != 0) {
5448       put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5449       n = n + 1;
5450    }
5451    if ((mask & 4) != 0) {
5452       put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5453 
5454       n = n + 1;
5455    }
5456    if ((mask & 2) != 0) {
5457       put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5458 
5459       n = n + 1;
5460    }
5461    if ((mask & 1) != 0) {
5462       put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5463 
5464       n = n + 1;
5465    }
5466    assign(result, get_gpr_w0(r1));
5467    s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5468                        mkU32(mask)));
5469 
5470    return "icmh";
5471 }
5472 
5473 static const HChar *
s390_irgen_IIHF(UChar r1,UInt i2)5474 s390_irgen_IIHF(UChar r1, UInt i2)
5475 {
5476    put_gpr_w0(r1, mkU32(i2));
5477 
5478    return "iihf";
5479 }
5480 
5481 static const HChar *
s390_irgen_IIHH(UChar r1,UShort i2)5482 s390_irgen_IIHH(UChar r1, UShort i2)
5483 {
5484    put_gpr_hw0(r1, mkU16(i2));
5485 
5486    return "iihh";
5487 }
5488 
5489 static const HChar *
s390_irgen_IIHL(UChar r1,UShort i2)5490 s390_irgen_IIHL(UChar r1, UShort i2)
5491 {
5492    put_gpr_hw1(r1, mkU16(i2));
5493 
5494    return "iihl";
5495 }
5496 
5497 static const HChar *
s390_irgen_IILF(UChar r1,UInt i2)5498 s390_irgen_IILF(UChar r1, UInt i2)
5499 {
5500    put_gpr_w1(r1, mkU32(i2));
5501 
5502    return "iilf";
5503 }
5504 
5505 static const HChar *
s390_irgen_IILH(UChar r1,UShort i2)5506 s390_irgen_IILH(UChar r1, UShort i2)
5507 {
5508    put_gpr_hw2(r1, mkU16(i2));
5509 
5510    return "iilh";
5511 }
5512 
5513 static const HChar *
s390_irgen_IILL(UChar r1,UShort i2)5514 s390_irgen_IILL(UChar r1, UShort i2)
5515 {
5516    put_gpr_hw3(r1, mkU16(i2));
5517 
5518    return "iill";
5519 }
5520 
5521 static const HChar *
s390_irgen_LR(UChar r1,UChar r2)5522 s390_irgen_LR(UChar r1, UChar r2)
5523 {
5524    put_gpr_w1(r1, get_gpr_w1(r2));
5525 
5526    return "lr";
5527 }
5528 
5529 static const HChar *
s390_irgen_LGR(UChar r1,UChar r2)5530 s390_irgen_LGR(UChar r1, UChar r2)
5531 {
5532    put_gpr_dw0(r1, get_gpr_dw0(r2));
5533 
5534    return "lgr";
5535 }
5536 
5537 static const HChar *
s390_irgen_LGFR(UChar r1,UChar r2)5538 s390_irgen_LGFR(UChar r1, UChar r2)
5539 {
5540    put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5541 
5542    return "lgfr";
5543 }
5544 
5545 static const HChar *
s390_irgen_L(UChar r1,IRTemp op2addr)5546 s390_irgen_L(UChar r1, IRTemp op2addr)
5547 {
5548    put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5549 
5550    return "l";
5551 }
5552 
5553 static const HChar *
s390_irgen_LY(UChar r1,IRTemp op2addr)5554 s390_irgen_LY(UChar r1, IRTemp op2addr)
5555 {
5556    put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5557 
5558    return "ly";
5559 }
5560 
5561 static const HChar *
s390_irgen_LG(UChar r1,IRTemp op2addr)5562 s390_irgen_LG(UChar r1, IRTemp op2addr)
5563 {
5564    put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5565 
5566    return "lg";
5567 }
5568 
5569 static const HChar *
s390_irgen_LGF(UChar r1,IRTemp op2addr)5570 s390_irgen_LGF(UChar r1, IRTemp op2addr)
5571 {
5572    put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5573 
5574    return "lgf";
5575 }
5576 
5577 static const HChar *
s390_irgen_LGFI(UChar r1,UInt i2)5578 s390_irgen_LGFI(UChar r1, UInt i2)
5579 {
5580    put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5581 
5582    return "lgfi";
5583 }
5584 
5585 static const HChar *
s390_irgen_LRL(UChar r1,UInt i2)5586 s390_irgen_LRL(UChar r1, UInt i2)
5587 {
5588    put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5589               i2 << 1))));
5590 
5591    return "lrl";
5592 }
5593 
5594 static const HChar *
s390_irgen_LGRL(UChar r1,UInt i2)5595 s390_irgen_LGRL(UChar r1, UInt i2)
5596 {
5597    put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5598                i2 << 1))));
5599 
5600    return "lgrl";
5601 }
5602 
5603 static const HChar *
s390_irgen_LGFRL(UChar r1,UInt i2)5604 s390_irgen_LGFRL(UChar r1, UInt i2)
5605 {
5606    put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5607                ((ULong)(Long)(Int)i2 << 1)))));
5608 
5609    return "lgfrl";
5610 }
5611 
5612 static const HChar *
s390_irgen_LA(UChar r1,IRTemp op2addr)5613 s390_irgen_LA(UChar r1, IRTemp op2addr)
5614 {
5615    put_gpr_dw0(r1, mkexpr(op2addr));
5616 
5617    return "la";
5618 }
5619 
5620 static const HChar *
s390_irgen_LAY(UChar r1,IRTemp op2addr)5621 s390_irgen_LAY(UChar r1, IRTemp op2addr)
5622 {
5623    put_gpr_dw0(r1, mkexpr(op2addr));
5624 
5625    return "lay";
5626 }
5627 
5628 static const HChar *
s390_irgen_LAE(UChar r1,IRTemp op2addr)5629 s390_irgen_LAE(UChar r1, IRTemp op2addr)
5630 {
5631    put_gpr_dw0(r1, mkexpr(op2addr));
5632 
5633    return "lae";
5634 }
5635 
5636 static const HChar *
s390_irgen_LAEY(UChar r1,IRTemp op2addr)5637 s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5638 {
5639    put_gpr_dw0(r1, mkexpr(op2addr));
5640 
5641    return "laey";
5642 }
5643 
5644 static const HChar *
s390_irgen_LARL(UChar r1,UInt i2)5645 s390_irgen_LARL(UChar r1, UInt i2)
5646 {
5647    put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5648 
5649    return "larl";
5650 }
5651 
5652 /* The IR representation of LAA and friends is an approximation of what
5653    happens natively. Essentially a loop containing a compare-and-swap is
5654    constructed which will iterate until the CAS succeeds. As a consequence,
5655    instrumenters may see more memory accesses than happen natively. See also
5656    discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
5657 static void
s390_irgen_load_and_add32(UChar r1,UChar r3,IRTemp op2addr,Bool is_signed)5658 s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5659 {
5660    IRCAS *cas;
5661    IRTemp old_mem = newTemp(Ity_I32);
5662    IRTemp op2 = newTemp(Ity_I32);
5663    IRTemp op3 = newTemp(Ity_I32);
5664    IRTemp result = newTemp(Ity_I32);
5665 
5666    assign(op2, load(Ity_I32, mkexpr(op2addr)));
5667    assign(op3, get_gpr_w1(r3));
5668    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5669 
5670    /* Place the addition of second operand and third operand at the
5671       second-operand location everytime */
5672    cas = mkIRCAS(IRTemp_INVALID, old_mem,
5673                  Iend_BE, mkexpr(op2addr),
5674                  NULL, mkexpr(op2), /* expected value */
5675                  NULL, mkexpr(result)  /* new value */);
5676    stmt(IRStmt_CAS(cas));
5677 
5678    /* Set CC according to 32-bit addition */
5679    if (is_signed) {
5680       s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5681    } else {
5682       s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5683    }
5684 
5685    /* If old_mem contains the expected value, then the CAS succeeded.
5686       Otherwise, it did not */
5687    yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5688    put_gpr_w1(r1, mkexpr(old_mem));
5689 }
5690 
5691 static void
s390_irgen_load_and_add64(UChar r1,UChar r3,IRTemp op2addr,Bool is_signed)5692 s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5693 {
5694    IRCAS *cas;
5695    IRTemp old_mem = newTemp(Ity_I64);
5696    IRTemp op2 = newTemp(Ity_I64);
5697    IRTemp op3 = newTemp(Ity_I64);
5698    IRTemp result = newTemp(Ity_I64);
5699 
5700    assign(op2, load(Ity_I64, mkexpr(op2addr)));
5701    assign(op3, get_gpr_dw0(r3));
5702    assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5703 
5704    /* Place the addition of second operand and third operand at the
5705       second-operand location everytime */
5706    cas = mkIRCAS(IRTemp_INVALID, old_mem,
5707                  Iend_BE, mkexpr(op2addr),
5708                  NULL, mkexpr(op2), /* expected value */
5709                  NULL, mkexpr(result)  /* new value */);
5710    stmt(IRStmt_CAS(cas));
5711 
5712    /* Set CC according to 64-bit addition */
5713    if (is_signed) {
5714       s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5715    } else {
5716       s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5717    }
5718 
5719    /* If old_mem contains the expected value, then the CAS succeeded.
5720       Otherwise, it did not */
5721    yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5722    put_gpr_dw0(r1, mkexpr(old_mem));
5723 }
5724 
5725 static void
s390_irgen_load_and_bitwise32(UChar r1,UChar r3,IRTemp op2addr,IROp op)5726 s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5727 {
5728    IRCAS *cas;
5729    IRTemp old_mem = newTemp(Ity_I32);
5730    IRTemp op2 = newTemp(Ity_I32);
5731    IRTemp op3 = newTemp(Ity_I32);
5732    IRTemp result = newTemp(Ity_I32);
5733 
5734    assign(op2, load(Ity_I32, mkexpr(op2addr)));
5735    assign(op3, get_gpr_w1(r3));
5736    assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5737 
5738    /* Place the addition of second operand and third operand at the
5739       second-operand location everytime */
5740    cas = mkIRCAS(IRTemp_INVALID, old_mem,
5741                  Iend_BE, mkexpr(op2addr),
5742                  NULL, mkexpr(op2), /* expected value */
5743                  NULL, mkexpr(result)  /* new value */);
5744    stmt(IRStmt_CAS(cas));
5745 
5746    /* Set CC according to bitwise operation */
5747    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5748 
5749    /* If old_mem contains the expected value, then the CAS succeeded.
5750       Otherwise, it did not */
5751    yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5752    put_gpr_w1(r1, mkexpr(old_mem));
5753 }
5754 
5755 static void
s390_irgen_load_and_bitwise64(UChar r1,UChar r3,IRTemp op2addr,IROp op)5756 s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5757 {
5758    IRCAS *cas;
5759    IRTemp old_mem = newTemp(Ity_I64);
5760    IRTemp op2 = newTemp(Ity_I64);
5761    IRTemp op3 = newTemp(Ity_I64);
5762    IRTemp result = newTemp(Ity_I64);
5763 
5764    assign(op2, load(Ity_I64, mkexpr(op2addr)));
5765    assign(op3, get_gpr_dw0(r3));
5766    assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5767 
5768    /* Place the addition of second operand and third operand at the
5769       second-operand location everytime */
5770    cas = mkIRCAS(IRTemp_INVALID, old_mem,
5771                  Iend_BE, mkexpr(op2addr),
5772                  NULL, mkexpr(op2), /* expected value */
5773                  NULL, mkexpr(result)  /* new value */);
5774    stmt(IRStmt_CAS(cas));
5775 
5776    /* Set CC according to bitwise operation */
5777    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5778 
5779    /* If old_mem contains the expected value, then the CAS succeeded.
5780       Otherwise, it did not */
5781    yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5782    put_gpr_dw0(r1, mkexpr(old_mem));
5783 }
5784 
5785 static const HChar *
s390_irgen_LAA(UChar r1,UChar r3,IRTemp op2addr)5786 s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5787 {
5788    s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
5789 
5790    return "laa";
5791 }
5792 
5793 static const HChar *
s390_irgen_LAAG(UChar r1,UChar r3,IRTemp op2addr)5794 s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5795 {
5796    s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
5797 
5798    return "laag";
5799 }
5800 
5801 static const HChar *
s390_irgen_LAAL(UChar r1,UChar r3,IRTemp op2addr)5802 s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5803 {
5804    s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
5805 
5806    return "laal";
5807 }
5808 
5809 static const HChar *
s390_irgen_LAALG(UChar r1,UChar r3,IRTemp op2addr)5810 s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5811 {
5812    s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
5813 
5814    return "laalg";
5815 }
5816 
5817 static const HChar *
s390_irgen_LAN(UChar r1,UChar r3,IRTemp op2addr)5818 s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5819 {
5820    s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
5821 
5822    return "lan";
5823 }
5824 
5825 static const HChar *
s390_irgen_LANG(UChar r1,UChar r3,IRTemp op2addr)5826 s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5827 {
5828    s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
5829 
5830    return "lang";
5831 }
5832 
5833 static const HChar *
s390_irgen_LAX(UChar r1,UChar r3,IRTemp op2addr)5834 s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5835 {
5836    s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
5837 
5838    return "lax";
5839 }
5840 
5841 static const HChar *
s390_irgen_LAXG(UChar r1,UChar r3,IRTemp op2addr)5842 s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5843 {
5844    s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
5845 
5846    return "laxg";
5847 }
5848 
5849 static const HChar *
s390_irgen_LAO(UChar r1,UChar r3,IRTemp op2addr)5850 s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5851 {
5852    s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
5853 
5854    return "lao";
5855 }
5856 
5857 static const HChar *
s390_irgen_LAOG(UChar r1,UChar r3,IRTemp op2addr)5858 s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5859 {
5860    s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
5861 
5862    return "laog";
5863 }
5864 
5865 static const HChar *
s390_irgen_LTR(UChar r1,UChar r2)5866 s390_irgen_LTR(UChar r1, UChar r2)
5867 {
5868    IRTemp op2 = newTemp(Ity_I32);
5869 
5870    assign(op2, get_gpr_w1(r2));
5871    put_gpr_w1(r1, mkexpr(op2));
5872    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5873 
5874    return "ltr";
5875 }
5876 
5877 static const HChar *
s390_irgen_LTGR(UChar r1,UChar r2)5878 s390_irgen_LTGR(UChar r1, UChar r2)
5879 {
5880    IRTemp op2 = newTemp(Ity_I64);
5881 
5882    assign(op2, get_gpr_dw0(r2));
5883    put_gpr_dw0(r1, mkexpr(op2));
5884    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5885 
5886    return "ltgr";
5887 }
5888 
5889 static const HChar *
s390_irgen_LTGFR(UChar r1,UChar r2)5890 s390_irgen_LTGFR(UChar r1, UChar r2)
5891 {
5892    IRTemp op2 = newTemp(Ity_I64);
5893 
5894    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5895    put_gpr_dw0(r1, mkexpr(op2));
5896    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5897 
5898    return "ltgfr";
5899 }
5900 
5901 static const HChar *
s390_irgen_LT(UChar r1,IRTemp op2addr)5902 s390_irgen_LT(UChar r1, IRTemp op2addr)
5903 {
5904    IRTemp op2 = newTemp(Ity_I32);
5905 
5906    assign(op2, load(Ity_I32, mkexpr(op2addr)));
5907    put_gpr_w1(r1, mkexpr(op2));
5908    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5909 
5910    return "lt";
5911 }
5912 
5913 static const HChar *
s390_irgen_LTG(UChar r1,IRTemp op2addr)5914 s390_irgen_LTG(UChar r1, IRTemp op2addr)
5915 {
5916    IRTemp op2 = newTemp(Ity_I64);
5917 
5918    assign(op2, load(Ity_I64, mkexpr(op2addr)));
5919    put_gpr_dw0(r1, mkexpr(op2));
5920    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5921 
5922    return "ltg";
5923 }
5924 
5925 static const HChar *
s390_irgen_LTGF(UChar r1,IRTemp op2addr)5926 s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5927 {
5928    IRTemp op2 = newTemp(Ity_I64);
5929 
5930    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5931    put_gpr_dw0(r1, mkexpr(op2));
5932    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5933 
5934    return "ltgf";
5935 }
5936 
5937 static const HChar *
s390_irgen_LBR(UChar r1,UChar r2)5938 s390_irgen_LBR(UChar r1, UChar r2)
5939 {
5940    put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5941 
5942    return "lbr";
5943 }
5944 
5945 static const HChar *
s390_irgen_LGBR(UChar r1,UChar r2)5946 s390_irgen_LGBR(UChar r1, UChar r2)
5947 {
5948    put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5949 
5950    return "lgbr";
5951 }
5952 
5953 static const HChar *
s390_irgen_LB(UChar r1,IRTemp op2addr)5954 s390_irgen_LB(UChar r1, IRTemp op2addr)
5955 {
5956    put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5957 
5958    return "lb";
5959 }
5960 
5961 static const HChar *
s390_irgen_LGB(UChar r1,IRTemp op2addr)5962 s390_irgen_LGB(UChar r1, IRTemp op2addr)
5963 {
5964    put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5965 
5966    return "lgb";
5967 }
5968 
5969 static const HChar *
s390_irgen_LBH(UChar r1,IRTemp op2addr)5970 s390_irgen_LBH(UChar r1, IRTemp op2addr)
5971 {
5972    put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5973 
5974    return "lbh";
5975 }
5976 
5977 static const HChar *
s390_irgen_LCR(UChar r1,UChar r2)5978 s390_irgen_LCR(UChar r1, UChar r2)
5979 {
5980    Int op1;
5981    IRTemp op2 = newTemp(Ity_I32);
5982    IRTemp result = newTemp(Ity_I32);
5983 
5984    op1 = 0;
5985    assign(op2, get_gpr_w1(r2));
5986    assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5987    put_gpr_w1(r1, mkexpr(result));
5988    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5989                        op1)), op2);
5990 
5991    return "lcr";
5992 }
5993 
5994 static const HChar *
s390_irgen_LCGR(UChar r1,UChar r2)5995 s390_irgen_LCGR(UChar r1, UChar r2)
5996 {
5997    Long op1;
5998    IRTemp op2 = newTemp(Ity_I64);
5999    IRTemp result = newTemp(Ity_I64);
6000 
6001    op1 = 0ULL;
6002    assign(op2, get_gpr_dw0(r2));
6003    assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6004    put_gpr_dw0(r1, mkexpr(result));
6005    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6006                        op1)), op2);
6007 
6008    return "lcgr";
6009 }
6010 
6011 static const HChar *
s390_irgen_LCGFR(UChar r1,UChar r2)6012 s390_irgen_LCGFR(UChar r1, UChar r2)
6013 {
6014    Long op1;
6015    IRTemp op2 = newTemp(Ity_I64);
6016    IRTemp result = newTemp(Ity_I64);
6017 
6018    op1 = 0ULL;
6019    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6020    assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6021    put_gpr_dw0(r1, mkexpr(result));
6022    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6023                        op1)), op2);
6024 
6025    return "lcgfr";
6026 }
6027 
6028 static const HChar *
s390_irgen_LHR(UChar r1,UChar r2)6029 s390_irgen_LHR(UChar r1, UChar r2)
6030 {
6031    put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
6032 
6033    return "lhr";
6034 }
6035 
6036 static const HChar *
s390_irgen_LGHR(UChar r1,UChar r2)6037 s390_irgen_LGHR(UChar r1, UChar r2)
6038 {
6039    put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6040 
6041    return "lghr";
6042 }
6043 
6044 static const HChar *
s390_irgen_LH(UChar r1,IRTemp op2addr)6045 s390_irgen_LH(UChar r1, IRTemp op2addr)
6046 {
6047    put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6048 
6049    return "lh";
6050 }
6051 
6052 static const HChar *
s390_irgen_LHY(UChar r1,IRTemp op2addr)6053 s390_irgen_LHY(UChar r1, IRTemp op2addr)
6054 {
6055    put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6056 
6057    return "lhy";
6058 }
6059 
6060 static const HChar *
s390_irgen_LGH(UChar r1,IRTemp op2addr)6061 s390_irgen_LGH(UChar r1, IRTemp op2addr)
6062 {
6063    put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6064 
6065    return "lgh";
6066 }
6067 
6068 static const HChar *
s390_irgen_LHI(UChar r1,UShort i2)6069 s390_irgen_LHI(UChar r1, UShort i2)
6070 {
6071    put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6072 
6073    return "lhi";
6074 }
6075 
6076 static const HChar *
s390_irgen_LGHI(UChar r1,UShort i2)6077 s390_irgen_LGHI(UChar r1, UShort i2)
6078 {
6079    put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6080 
6081    return "lghi";
6082 }
6083 
6084 static const HChar *
s390_irgen_LHRL(UChar r1,UInt i2)6085 s390_irgen_LHRL(UChar r1, UInt i2)
6086 {
6087    put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6088               ((ULong)(Long)(Int)i2 << 1)))));
6089 
6090    return "lhrl";
6091 }
6092 
6093 static const HChar *
s390_irgen_LGHRL(UChar r1,UInt i2)6094 s390_irgen_LGHRL(UChar r1, UInt i2)
6095 {
6096    put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6097                ((ULong)(Long)(Int)i2 << 1)))));
6098 
6099    return "lghrl";
6100 }
6101 
6102 static const HChar *
s390_irgen_LHH(UChar r1,IRTemp op2addr)6103 s390_irgen_LHH(UChar r1, IRTemp op2addr)
6104 {
6105    put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6106 
6107    return "lhh";
6108 }
6109 
6110 static const HChar *
s390_irgen_LFH(UChar r1,IRTemp op2addr)6111 s390_irgen_LFH(UChar r1, IRTemp op2addr)
6112 {
6113    put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6114 
6115    return "lfh";
6116 }
6117 
6118 static const HChar *
s390_irgen_LLGFR(UChar r1,UChar r2)6119 s390_irgen_LLGFR(UChar r1, UChar r2)
6120 {
6121    put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6122 
6123    return "llgfr";
6124 }
6125 
6126 static const HChar *
s390_irgen_LLGF(UChar r1,IRTemp op2addr)6127 s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6128 {
6129    put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6130 
6131    return "llgf";
6132 }
6133 
6134 static const HChar *
s390_irgen_LLGFRL(UChar r1,UInt i2)6135 s390_irgen_LLGFRL(UChar r1, UInt i2)
6136 {
6137    put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6138                ((ULong)(Long)(Int)i2 << 1)))));
6139 
6140    return "llgfrl";
6141 }
6142 
6143 static const HChar *
s390_irgen_LLCR(UChar r1,UChar r2)6144 s390_irgen_LLCR(UChar r1, UChar r2)
6145 {
6146    put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6147 
6148    return "llcr";
6149 }
6150 
6151 static const HChar *
s390_irgen_LLGCR(UChar r1,UChar r2)6152 s390_irgen_LLGCR(UChar r1, UChar r2)
6153 {
6154    put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6155 
6156    return "llgcr";
6157 }
6158 
6159 static const HChar *
s390_irgen_LLC(UChar r1,IRTemp op2addr)6160 s390_irgen_LLC(UChar r1, IRTemp op2addr)
6161 {
6162    put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6163 
6164    return "llc";
6165 }
6166 
6167 static const HChar *
s390_irgen_LLGC(UChar r1,IRTemp op2addr)6168 s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6169 {
6170    put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6171 
6172    return "llgc";
6173 }
6174 
6175 static const HChar *
s390_irgen_LLCH(UChar r1,IRTemp op2addr)6176 s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6177 {
6178    put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6179 
6180    return "llch";
6181 }
6182 
6183 static const HChar *
s390_irgen_LLHR(UChar r1,UChar r2)6184 s390_irgen_LLHR(UChar r1, UChar r2)
6185 {
6186    put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6187 
6188    return "llhr";
6189 }
6190 
6191 static const HChar *
s390_irgen_LLGHR(UChar r1,UChar r2)6192 s390_irgen_LLGHR(UChar r1, UChar r2)
6193 {
6194    put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6195 
6196    return "llghr";
6197 }
6198 
6199 static const HChar *
s390_irgen_LLH(UChar r1,IRTemp op2addr)6200 s390_irgen_LLH(UChar r1, IRTemp op2addr)
6201 {
6202    put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6203 
6204    return "llh";
6205 }
6206 
6207 static const HChar *
s390_irgen_LLGH(UChar r1,IRTemp op2addr)6208 s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6209 {
6210    put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6211 
6212    return "llgh";
6213 }
6214 
6215 static const HChar *
s390_irgen_LLHRL(UChar r1,UInt i2)6216 s390_irgen_LLHRL(UChar r1, UInt i2)
6217 {
6218    put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6219               ((ULong)(Long)(Int)i2 << 1)))));
6220 
6221    return "llhrl";
6222 }
6223 
6224 static const HChar *
s390_irgen_LLGHRL(UChar r1,UInt i2)6225 s390_irgen_LLGHRL(UChar r1, UInt i2)
6226 {
6227    put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6228                ((ULong)(Long)(Int)i2 << 1)))));
6229 
6230    return "llghrl";
6231 }
6232 
6233 static const HChar *
s390_irgen_LLHH(UChar r1,IRTemp op2addr)6234 s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6235 {
6236    put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6237 
6238    return "llhh";
6239 }
6240 
6241 static const HChar *
s390_irgen_LLIHF(UChar r1,UInt i2)6242 s390_irgen_LLIHF(UChar r1, UInt i2)
6243 {
6244    put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6245 
6246    return "llihf";
6247 }
6248 
6249 static const HChar *
s390_irgen_LLIHH(UChar r1,UShort i2)6250 s390_irgen_LLIHH(UChar r1, UShort i2)
6251 {
6252    put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6253 
6254    return "llihh";
6255 }
6256 
6257 static const HChar *
s390_irgen_LLIHL(UChar r1,UShort i2)6258 s390_irgen_LLIHL(UChar r1, UShort i2)
6259 {
6260    put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6261 
6262    return "llihl";
6263 }
6264 
6265 static const HChar *
s390_irgen_LLILF(UChar r1,UInt i2)6266 s390_irgen_LLILF(UChar r1, UInt i2)
6267 {
6268    put_gpr_dw0(r1, mkU64(i2));
6269 
6270    return "llilf";
6271 }
6272 
6273 static const HChar *
s390_irgen_LLILH(UChar r1,UShort i2)6274 s390_irgen_LLILH(UChar r1, UShort i2)
6275 {
6276    put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6277 
6278    return "llilh";
6279 }
6280 
6281 static const HChar *
s390_irgen_LLILL(UChar r1,UShort i2)6282 s390_irgen_LLILL(UChar r1, UShort i2)
6283 {
6284    put_gpr_dw0(r1, mkU64(i2));
6285 
6286    return "llill";
6287 }
6288 
6289 static const HChar *
s390_irgen_LLGTR(UChar r1,UChar r2)6290 s390_irgen_LLGTR(UChar r1, UChar r2)
6291 {
6292    put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6293                mkU32(2147483647))));
6294 
6295    return "llgtr";
6296 }
6297 
6298 static const HChar *
s390_irgen_LLGT(UChar r1,IRTemp op2addr)6299 s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6300 {
6301    put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6302                mkexpr(op2addr)), mkU32(2147483647))));
6303 
6304    return "llgt";
6305 }
6306 
6307 static const HChar *
s390_irgen_LNR(UChar r1,UChar r2)6308 s390_irgen_LNR(UChar r1, UChar r2)
6309 {
6310    IRTemp op2 = newTemp(Ity_I32);
6311    IRTemp result = newTemp(Ity_I32);
6312 
6313    assign(op2, get_gpr_w1(r2));
6314    assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6315           binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6316    put_gpr_w1(r1, mkexpr(result));
6317    s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6318 
6319    return "lnr";
6320 }
6321 
6322 static const HChar *
s390_irgen_LNGR(UChar r1,UChar r2)6323 s390_irgen_LNGR(UChar r1, UChar r2)
6324 {
6325    IRTemp op2 = newTemp(Ity_I64);
6326    IRTemp result = newTemp(Ity_I64);
6327 
6328    assign(op2, get_gpr_dw0(r2));
6329    assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6330           binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6331    put_gpr_dw0(r1, mkexpr(result));
6332    s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6333 
6334    return "lngr";
6335 }
6336 
6337 static const HChar *
s390_irgen_LNGFR(UChar r1,UChar r2)6338 s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6339 {
6340    IRTemp op2 = newTemp(Ity_I64);
6341    IRTemp result = newTemp(Ity_I64);
6342 
6343    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6344    assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6345           binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6346    put_gpr_dw0(r1, mkexpr(result));
6347    s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6348 
6349    return "lngfr";
6350 }
6351 
6352 static const HChar *
s390_irgen_LOCR(UChar m3,UChar r1,UChar r2)6353 s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6354 {
6355    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
6356    put_gpr_w1(r1, get_gpr_w1(r2));
6357 
6358    return "locr";
6359 }
6360 
6361 static const HChar *
s390_irgen_LOCGR(UChar m3,UChar r1,UChar r2)6362 s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6363 {
6364    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
6365    put_gpr_dw0(r1, get_gpr_dw0(r2));
6366 
6367    return "locgr";
6368 }
6369 
6370 static const HChar *
s390_irgen_LOC(UChar r1,IRTemp op2addr)6371 s390_irgen_LOC(UChar r1, IRTemp op2addr)
6372 {
6373    /* condition is checked in format handler */
6374    put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6375 
6376    return "loc";
6377 }
6378 
6379 static const HChar *
s390_irgen_LOCG(UChar r1,IRTemp op2addr)6380 s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6381 {
6382    /* condition is checked in format handler */
6383    put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6384 
6385    return "locg";
6386 }
6387 
6388 static const HChar *
s390_irgen_LPQ(UChar r1,IRTemp op2addr)6389 s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6390 {
6391    put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6392    put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6393                ));
6394 
6395    return "lpq";
6396 }
6397 
6398 static const HChar *
s390_irgen_LPR(UChar r1,UChar r2)6399 s390_irgen_LPR(UChar r1, UChar r2)
6400 {
6401    IRTemp op2 = newTemp(Ity_I32);
6402    IRTemp result = newTemp(Ity_I32);
6403 
6404    assign(op2, get_gpr_w1(r2));
6405    assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6406           binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6407    put_gpr_w1(r1, mkexpr(result));
6408    s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6409 
6410    return "lpr";
6411 }
6412 
6413 static const HChar *
s390_irgen_LPGR(UChar r1,UChar r2)6414 s390_irgen_LPGR(UChar r1, UChar r2)
6415 {
6416    IRTemp op2 = newTemp(Ity_I64);
6417    IRTemp result = newTemp(Ity_I64);
6418 
6419    assign(op2, get_gpr_dw0(r2));
6420    assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6421           binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6422    put_gpr_dw0(r1, mkexpr(result));
6423    s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6424 
6425    return "lpgr";
6426 }
6427 
6428 static const HChar *
s390_irgen_LPGFR(UChar r1,UChar r2)6429 s390_irgen_LPGFR(UChar r1, UChar r2)
6430 {
6431    IRTemp op2 = newTemp(Ity_I64);
6432    IRTemp result = newTemp(Ity_I64);
6433 
6434    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6435    assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6436           binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6437    put_gpr_dw0(r1, mkexpr(result));
6438    s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6439 
6440    return "lpgfr";
6441 }
6442 
6443 static const HChar *
s390_irgen_LRVR(UChar r1,UChar r2)6444 s390_irgen_LRVR(UChar r1, UChar r2)
6445 {
6446    IRTemp b0 = newTemp(Ity_I8);
6447    IRTemp b1 = newTemp(Ity_I8);
6448    IRTemp b2 = newTemp(Ity_I8);
6449    IRTemp b3 = newTemp(Ity_I8);
6450 
6451    assign(b3, get_gpr_b7(r2));
6452    assign(b2, get_gpr_b6(r2));
6453    assign(b1, get_gpr_b5(r2));
6454    assign(b0, get_gpr_b4(r2));
6455    put_gpr_b4(r1, mkexpr(b3));
6456    put_gpr_b5(r1, mkexpr(b2));
6457    put_gpr_b6(r1, mkexpr(b1));
6458    put_gpr_b7(r1, mkexpr(b0));
6459 
6460    return "lrvr";
6461 }
6462 
6463 static const HChar *
s390_irgen_LRVGR(UChar r1,UChar r2)6464 s390_irgen_LRVGR(UChar r1, UChar r2)
6465 {
6466    IRTemp b0 = newTemp(Ity_I8);
6467    IRTemp b1 = newTemp(Ity_I8);
6468    IRTemp b2 = newTemp(Ity_I8);
6469    IRTemp b3 = newTemp(Ity_I8);
6470    IRTemp b4 = newTemp(Ity_I8);
6471    IRTemp b5 = newTemp(Ity_I8);
6472    IRTemp b6 = newTemp(Ity_I8);
6473    IRTemp b7 = newTemp(Ity_I8);
6474 
6475    assign(b7, get_gpr_b7(r2));
6476    assign(b6, get_gpr_b6(r2));
6477    assign(b5, get_gpr_b5(r2));
6478    assign(b4, get_gpr_b4(r2));
6479    assign(b3, get_gpr_b3(r2));
6480    assign(b2, get_gpr_b2(r2));
6481    assign(b1, get_gpr_b1(r2));
6482    assign(b0, get_gpr_b0(r2));
6483    put_gpr_b0(r1, mkexpr(b7));
6484    put_gpr_b1(r1, mkexpr(b6));
6485    put_gpr_b2(r1, mkexpr(b5));
6486    put_gpr_b3(r1, mkexpr(b4));
6487    put_gpr_b4(r1, mkexpr(b3));
6488    put_gpr_b5(r1, mkexpr(b2));
6489    put_gpr_b6(r1, mkexpr(b1));
6490    put_gpr_b7(r1, mkexpr(b0));
6491 
6492    return "lrvgr";
6493 }
6494 
6495 static const HChar *
s390_irgen_LRVH(UChar r1,IRTemp op2addr)6496 s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6497 {
6498    IRTemp op2 = newTemp(Ity_I16);
6499 
6500    assign(op2, load(Ity_I16, mkexpr(op2addr)));
6501    put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6502    put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6503 
6504    return "lrvh";
6505 }
6506 
6507 static const HChar *
s390_irgen_LRV(UChar r1,IRTemp op2addr)6508 s390_irgen_LRV(UChar r1, IRTemp op2addr)
6509 {
6510    IRTemp op2 = newTemp(Ity_I32);
6511 
6512    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6513    put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6514    put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6515               mkU8(8)), mkU32(255))));
6516    put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6517               mkU8(16)), mkU32(255))));
6518    put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6519               mkU8(24)), mkU32(255))));
6520 
6521    return "lrv";
6522 }
6523 
6524 static const HChar *
s390_irgen_LRVG(UChar r1,IRTemp op2addr)6525 s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6526 {
6527    IRTemp op2 = newTemp(Ity_I64);
6528 
6529    assign(op2, load(Ity_I64, mkexpr(op2addr)));
6530    put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6531    put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6532               mkU8(8)), mkU64(255))));
6533    put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6534               mkU8(16)), mkU64(255))));
6535    put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6536               mkU8(24)), mkU64(255))));
6537    put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6538               mkU8(32)), mkU64(255))));
6539    put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6540               mkU8(40)), mkU64(255))));
6541    put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6542               mkU8(48)), mkU64(255))));
6543    put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6544               mkU8(56)), mkU64(255))));
6545 
6546    return "lrvg";
6547 }
6548 
6549 static const HChar *
s390_irgen_MVHHI(UShort i2,IRTemp op1addr)6550 s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6551 {
6552    store(mkexpr(op1addr), mkU16(i2));
6553 
6554    return "mvhhi";
6555 }
6556 
6557 static const HChar *
s390_irgen_MVHI(UShort i2,IRTemp op1addr)6558 s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6559 {
6560    store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6561 
6562    return "mvhi";
6563 }
6564 
6565 static const HChar *
s390_irgen_MVGHI(UShort i2,IRTemp op1addr)6566 s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6567 {
6568    store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6569 
6570    return "mvghi";
6571 }
6572 
6573 static const HChar *
s390_irgen_MVI(UChar i2,IRTemp op1addr)6574 s390_irgen_MVI(UChar i2, IRTemp op1addr)
6575 {
6576    store(mkexpr(op1addr), mkU8(i2));
6577 
6578    return "mvi";
6579 }
6580 
6581 static const HChar *
s390_irgen_MVIY(UChar i2,IRTemp op1addr)6582 s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6583 {
6584    store(mkexpr(op1addr), mkU8(i2));
6585 
6586    return "mviy";
6587 }
6588 
6589 static const HChar *
s390_irgen_MR(UChar r1,UChar r2)6590 s390_irgen_MR(UChar r1, UChar r2)
6591 {
6592    IRTemp op1 = newTemp(Ity_I32);
6593    IRTemp op2 = newTemp(Ity_I32);
6594    IRTemp result = newTemp(Ity_I64);
6595 
6596    assign(op1, get_gpr_w1(r1 + 1));
6597    assign(op2, get_gpr_w1(r2));
6598    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6599    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6600    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6601 
6602    return "mr";
6603 }
6604 
6605 static const HChar *
s390_irgen_M(UChar r1,IRTemp op2addr)6606 s390_irgen_M(UChar r1, IRTemp op2addr)
6607 {
6608    IRTemp op1 = newTemp(Ity_I32);
6609    IRTemp op2 = newTemp(Ity_I32);
6610    IRTemp result = newTemp(Ity_I64);
6611 
6612    assign(op1, get_gpr_w1(r1 + 1));
6613    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6614    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6615    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6616    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6617 
6618    return "m";
6619 }
6620 
6621 static const HChar *
s390_irgen_MFY(UChar r1,IRTemp op2addr)6622 s390_irgen_MFY(UChar r1, IRTemp op2addr)
6623 {
6624    IRTemp op1 = newTemp(Ity_I32);
6625    IRTemp op2 = newTemp(Ity_I32);
6626    IRTemp result = newTemp(Ity_I64);
6627 
6628    assign(op1, get_gpr_w1(r1 + 1));
6629    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6630    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6631    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6632    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6633 
6634    return "mfy";
6635 }
6636 
6637 static const HChar *
s390_irgen_MH(UChar r1,IRTemp op2addr)6638 s390_irgen_MH(UChar r1, IRTemp op2addr)
6639 {
6640    IRTemp op1 = newTemp(Ity_I32);
6641    IRTemp op2 = newTemp(Ity_I16);
6642    IRTemp result = newTemp(Ity_I64);
6643 
6644    assign(op1, get_gpr_w1(r1));
6645    assign(op2, load(Ity_I16, mkexpr(op2addr)));
6646    assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6647           ));
6648    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6649 
6650    return "mh";
6651 }
6652 
6653 static const HChar *
s390_irgen_MHY(UChar r1,IRTemp op2addr)6654 s390_irgen_MHY(UChar r1, IRTemp op2addr)
6655 {
6656    IRTemp op1 = newTemp(Ity_I32);
6657    IRTemp op2 = newTemp(Ity_I16);
6658    IRTemp result = newTemp(Ity_I64);
6659 
6660    assign(op1, get_gpr_w1(r1));
6661    assign(op2, load(Ity_I16, mkexpr(op2addr)));
6662    assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6663           ));
6664    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6665 
6666    return "mhy";
6667 }
6668 
6669 static const HChar *
s390_irgen_MHI(UChar r1,UShort i2)6670 s390_irgen_MHI(UChar r1, UShort i2)
6671 {
6672    IRTemp op1 = newTemp(Ity_I32);
6673    Short op2;
6674    IRTemp result = newTemp(Ity_I64);
6675 
6676    assign(op1, get_gpr_w1(r1));
6677    op2 = (Short)i2;
6678    assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6679           mkU16((UShort)op2))));
6680    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6681 
6682    return "mhi";
6683 }
6684 
6685 static const HChar *
s390_irgen_MGHI(UChar r1,UShort i2)6686 s390_irgen_MGHI(UChar r1, UShort i2)
6687 {
6688    IRTemp op1 = newTemp(Ity_I64);
6689    Short op2;
6690    IRTemp result = newTemp(Ity_I128);
6691 
6692    assign(op1, get_gpr_dw0(r1));
6693    op2 = (Short)i2;
6694    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6695           mkU16((UShort)op2))));
6696    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6697 
6698    return "mghi";
6699 }
6700 
6701 static const HChar *
s390_irgen_MLR(UChar r1,UChar r2)6702 s390_irgen_MLR(UChar r1, UChar r2)
6703 {
6704    IRTemp op1 = newTemp(Ity_I32);
6705    IRTemp op2 = newTemp(Ity_I32);
6706    IRTemp result = newTemp(Ity_I64);
6707 
6708    assign(op1, get_gpr_w1(r1 + 1));
6709    assign(op2, get_gpr_w1(r2));
6710    assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6711    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6712    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6713 
6714    return "mlr";
6715 }
6716 
6717 static const HChar *
s390_irgen_MLGR(UChar r1,UChar r2)6718 s390_irgen_MLGR(UChar r1, UChar r2)
6719 {
6720    IRTemp op1 = newTemp(Ity_I64);
6721    IRTemp op2 = newTemp(Ity_I64);
6722    IRTemp result = newTemp(Ity_I128);
6723 
6724    assign(op1, get_gpr_dw0(r1 + 1));
6725    assign(op2, get_gpr_dw0(r2));
6726    assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6727    put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6728    put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6729 
6730    return "mlgr";
6731 }
6732 
6733 static const HChar *
s390_irgen_ML(UChar r1,IRTemp op2addr)6734 s390_irgen_ML(UChar r1, IRTemp op2addr)
6735 {
6736    IRTemp op1 = newTemp(Ity_I32);
6737    IRTemp op2 = newTemp(Ity_I32);
6738    IRTemp result = newTemp(Ity_I64);
6739 
6740    assign(op1, get_gpr_w1(r1 + 1));
6741    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6742    assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6743    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6744    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6745 
6746    return "ml";
6747 }
6748 
6749 static const HChar *
s390_irgen_MLG(UChar r1,IRTemp op2addr)6750 s390_irgen_MLG(UChar r1, IRTemp op2addr)
6751 {
6752    IRTemp op1 = newTemp(Ity_I64);
6753    IRTemp op2 = newTemp(Ity_I64);
6754    IRTemp result = newTemp(Ity_I128);
6755 
6756    assign(op1, get_gpr_dw0(r1 + 1));
6757    assign(op2, load(Ity_I64, mkexpr(op2addr)));
6758    assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6759    put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6760    put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6761 
6762    return "mlg";
6763 }
6764 
6765 static const HChar *
s390_irgen_MSR(UChar r1,UChar r2)6766 s390_irgen_MSR(UChar r1, UChar r2)
6767 {
6768    IRTemp op1 = newTemp(Ity_I32);
6769    IRTemp op2 = newTemp(Ity_I32);
6770    IRTemp result = newTemp(Ity_I64);
6771 
6772    assign(op1, get_gpr_w1(r1));
6773    assign(op2, get_gpr_w1(r2));
6774    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6775    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6776 
6777    return "msr";
6778 }
6779 
6780 static const HChar *
s390_irgen_MSGR(UChar r1,UChar r2)6781 s390_irgen_MSGR(UChar r1, UChar r2)
6782 {
6783    IRTemp op1 = newTemp(Ity_I64);
6784    IRTemp op2 = newTemp(Ity_I64);
6785    IRTemp result = newTemp(Ity_I128);
6786 
6787    assign(op1, get_gpr_dw0(r1));
6788    assign(op2, get_gpr_dw0(r2));
6789    assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6790    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6791 
6792    return "msgr";
6793 }
6794 
6795 static const HChar *
s390_irgen_MSGFR(UChar r1,UChar r2)6796 s390_irgen_MSGFR(UChar r1, UChar r2)
6797 {
6798    IRTemp op1 = newTemp(Ity_I64);
6799    IRTemp op2 = newTemp(Ity_I32);
6800    IRTemp result = newTemp(Ity_I128);
6801 
6802    assign(op1, get_gpr_dw0(r1));
6803    assign(op2, get_gpr_w1(r2));
6804    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6805           ));
6806    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6807 
6808    return "msgfr";
6809 }
6810 
6811 static const HChar *
s390_irgen_MS(UChar r1,IRTemp op2addr)6812 s390_irgen_MS(UChar r1, IRTemp op2addr)
6813 {
6814    IRTemp op1 = newTemp(Ity_I32);
6815    IRTemp op2 = newTemp(Ity_I32);
6816    IRTemp result = newTemp(Ity_I64);
6817 
6818    assign(op1, get_gpr_w1(r1));
6819    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6820    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6821    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6822 
6823    return "ms";
6824 }
6825 
6826 static const HChar *
s390_irgen_MSY(UChar r1,IRTemp op2addr)6827 s390_irgen_MSY(UChar r1, IRTemp op2addr)
6828 {
6829    IRTemp op1 = newTemp(Ity_I32);
6830    IRTemp op2 = newTemp(Ity_I32);
6831    IRTemp result = newTemp(Ity_I64);
6832 
6833    assign(op1, get_gpr_w1(r1));
6834    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6835    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6836    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6837 
6838    return "msy";
6839 }
6840 
6841 static const HChar *
s390_irgen_MSG(UChar r1,IRTemp op2addr)6842 s390_irgen_MSG(UChar r1, IRTemp op2addr)
6843 {
6844    IRTemp op1 = newTemp(Ity_I64);
6845    IRTemp op2 = newTemp(Ity_I64);
6846    IRTemp result = newTemp(Ity_I128);
6847 
6848    assign(op1, get_gpr_dw0(r1));
6849    assign(op2, load(Ity_I64, mkexpr(op2addr)));
6850    assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6851    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6852 
6853    return "msg";
6854 }
6855 
6856 static const HChar *
s390_irgen_MSGF(UChar r1,IRTemp op2addr)6857 s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6858 {
6859    IRTemp op1 = newTemp(Ity_I64);
6860    IRTemp op2 = newTemp(Ity_I32);
6861    IRTemp result = newTemp(Ity_I128);
6862 
6863    assign(op1, get_gpr_dw0(r1));
6864    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6865    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6866           ));
6867    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6868 
6869    return "msgf";
6870 }
6871 
6872 static const HChar *
s390_irgen_MSFI(UChar r1,UInt i2)6873 s390_irgen_MSFI(UChar r1, UInt i2)
6874 {
6875    IRTemp op1 = newTemp(Ity_I32);
6876    Int op2;
6877    IRTemp result = newTemp(Ity_I64);
6878 
6879    assign(op1, get_gpr_w1(r1));
6880    op2 = (Int)i2;
6881    assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6882    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6883 
6884    return "msfi";
6885 }
6886 
6887 static const HChar *
s390_irgen_MSGFI(UChar r1,UInt i2)6888 s390_irgen_MSGFI(UChar r1, UInt i2)
6889 {
6890    IRTemp op1 = newTemp(Ity_I64);
6891    Int op2;
6892    IRTemp result = newTemp(Ity_I128);
6893 
6894    assign(op1, get_gpr_dw0(r1));
6895    op2 = (Int)i2;
6896    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6897           op2))));
6898    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6899 
6900    return "msgfi";
6901 }
6902 
6903 static const HChar *
s390_irgen_OR(UChar r1,UChar r2)6904 s390_irgen_OR(UChar r1, UChar r2)
6905 {
6906    IRTemp op1 = newTemp(Ity_I32);
6907    IRTemp op2 = newTemp(Ity_I32);
6908    IRTemp result = newTemp(Ity_I32);
6909 
6910    assign(op1, get_gpr_w1(r1));
6911    assign(op2, get_gpr_w1(r2));
6912    assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6913    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6914    put_gpr_w1(r1, mkexpr(result));
6915 
6916    return "or";
6917 }
6918 
6919 static const HChar *
s390_irgen_OGR(UChar r1,UChar r2)6920 s390_irgen_OGR(UChar r1, UChar r2)
6921 {
6922    IRTemp op1 = newTemp(Ity_I64);
6923    IRTemp op2 = newTemp(Ity_I64);
6924    IRTemp result = newTemp(Ity_I64);
6925 
6926    assign(op1, get_gpr_dw0(r1));
6927    assign(op2, get_gpr_dw0(r2));
6928    assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6929    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6930    put_gpr_dw0(r1, mkexpr(result));
6931 
6932    return "ogr";
6933 }
6934 
6935 static const HChar *
s390_irgen_ORK(UChar r3,UChar r1,UChar r2)6936 s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6937 {
6938    IRTemp op2 = newTemp(Ity_I32);
6939    IRTemp op3 = newTemp(Ity_I32);
6940    IRTemp result = newTemp(Ity_I32);
6941 
6942    assign(op2, get_gpr_w1(r2));
6943    assign(op3, get_gpr_w1(r3));
6944    assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6945    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6946    put_gpr_w1(r1, mkexpr(result));
6947 
6948    return "ork";
6949 }
6950 
6951 static const HChar *
s390_irgen_OGRK(UChar r3,UChar r1,UChar r2)6952 s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6953 {
6954    IRTemp op2 = newTemp(Ity_I64);
6955    IRTemp op3 = newTemp(Ity_I64);
6956    IRTemp result = newTemp(Ity_I64);
6957 
6958    assign(op2, get_gpr_dw0(r2));
6959    assign(op3, get_gpr_dw0(r3));
6960    assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6961    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6962    put_gpr_dw0(r1, mkexpr(result));
6963 
6964    return "ogrk";
6965 }
6966 
6967 static const HChar *
s390_irgen_O(UChar r1,IRTemp op2addr)6968 s390_irgen_O(UChar r1, IRTemp op2addr)
6969 {
6970    IRTemp op1 = newTemp(Ity_I32);
6971    IRTemp op2 = newTemp(Ity_I32);
6972    IRTemp result = newTemp(Ity_I32);
6973 
6974    assign(op1, get_gpr_w1(r1));
6975    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6976    assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6977    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6978    put_gpr_w1(r1, mkexpr(result));
6979 
6980    return "o";
6981 }
6982 
6983 static const HChar *
s390_irgen_OY(UChar r1,IRTemp op2addr)6984 s390_irgen_OY(UChar r1, IRTemp op2addr)
6985 {
6986    IRTemp op1 = newTemp(Ity_I32);
6987    IRTemp op2 = newTemp(Ity_I32);
6988    IRTemp result = newTemp(Ity_I32);
6989 
6990    assign(op1, get_gpr_w1(r1));
6991    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6992    assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6993    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6994    put_gpr_w1(r1, mkexpr(result));
6995 
6996    return "oy";
6997 }
6998 
6999 static const HChar *
s390_irgen_OG(UChar r1,IRTemp op2addr)7000 s390_irgen_OG(UChar r1, IRTemp op2addr)
7001 {
7002    IRTemp op1 = newTemp(Ity_I64);
7003    IRTemp op2 = newTemp(Ity_I64);
7004    IRTemp result = newTemp(Ity_I64);
7005 
7006    assign(op1, get_gpr_dw0(r1));
7007    assign(op2, load(Ity_I64, mkexpr(op2addr)));
7008    assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
7009    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7010    put_gpr_dw0(r1, mkexpr(result));
7011 
7012    return "og";
7013 }
7014 
7015 static const HChar *
s390_irgen_OI(UChar i2,IRTemp op1addr)7016 s390_irgen_OI(UChar i2, IRTemp op1addr)
7017 {
7018    IRTemp op1 = newTemp(Ity_I8);
7019    UChar op2;
7020    IRTemp result = newTemp(Ity_I8);
7021 
7022    assign(op1, load(Ity_I8, mkexpr(op1addr)));
7023    op2 = i2;
7024    assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7025    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7026    store(mkexpr(op1addr), mkexpr(result));
7027 
7028    return "oi";
7029 }
7030 
7031 static const HChar *
s390_irgen_OIY(UChar i2,IRTemp op1addr)7032 s390_irgen_OIY(UChar i2, IRTemp op1addr)
7033 {
7034    IRTemp op1 = newTemp(Ity_I8);
7035    UChar op2;
7036    IRTemp result = newTemp(Ity_I8);
7037 
7038    assign(op1, load(Ity_I8, mkexpr(op1addr)));
7039    op2 = i2;
7040    assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7041    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7042    store(mkexpr(op1addr), mkexpr(result));
7043 
7044    return "oiy";
7045 }
7046 
7047 static const HChar *
s390_irgen_OIHF(UChar r1,UInt i2)7048 s390_irgen_OIHF(UChar r1, UInt i2)
7049 {
7050    IRTemp op1 = newTemp(Ity_I32);
7051    UInt op2;
7052    IRTemp result = newTemp(Ity_I32);
7053 
7054    assign(op1, get_gpr_w0(r1));
7055    op2 = i2;
7056    assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7057    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7058    put_gpr_w0(r1, mkexpr(result));
7059 
7060    return "oihf";
7061 }
7062 
7063 static const HChar *
s390_irgen_OIHH(UChar r1,UShort i2)7064 s390_irgen_OIHH(UChar r1, UShort i2)
7065 {
7066    IRTemp op1 = newTemp(Ity_I16);
7067    UShort op2;
7068    IRTemp result = newTemp(Ity_I16);
7069 
7070    assign(op1, get_gpr_hw0(r1));
7071    op2 = i2;
7072    assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7073    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7074    put_gpr_hw0(r1, mkexpr(result));
7075 
7076    return "oihh";
7077 }
7078 
7079 static const HChar *
s390_irgen_OIHL(UChar r1,UShort i2)7080 s390_irgen_OIHL(UChar r1, UShort i2)
7081 {
7082    IRTemp op1 = newTemp(Ity_I16);
7083    UShort op2;
7084    IRTemp result = newTemp(Ity_I16);
7085 
7086    assign(op1, get_gpr_hw1(r1));
7087    op2 = i2;
7088    assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7089    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7090    put_gpr_hw1(r1, mkexpr(result));
7091 
7092    return "oihl";
7093 }
7094 
7095 static const HChar *
s390_irgen_OILF(UChar r1,UInt i2)7096 s390_irgen_OILF(UChar r1, UInt i2)
7097 {
7098    IRTemp op1 = newTemp(Ity_I32);
7099    UInt op2;
7100    IRTemp result = newTemp(Ity_I32);
7101 
7102    assign(op1, get_gpr_w1(r1));
7103    op2 = i2;
7104    assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7105    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7106    put_gpr_w1(r1, mkexpr(result));
7107 
7108    return "oilf";
7109 }
7110 
7111 static const HChar *
s390_irgen_OILH(UChar r1,UShort i2)7112 s390_irgen_OILH(UChar r1, UShort i2)
7113 {
7114    IRTemp op1 = newTemp(Ity_I16);
7115    UShort op2;
7116    IRTemp result = newTemp(Ity_I16);
7117 
7118    assign(op1, get_gpr_hw2(r1));
7119    op2 = i2;
7120    assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7121    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7122    put_gpr_hw2(r1, mkexpr(result));
7123 
7124    return "oilh";
7125 }
7126 
7127 static const HChar *
s390_irgen_OILL(UChar r1,UShort i2)7128 s390_irgen_OILL(UChar r1, UShort i2)
7129 {
7130    IRTemp op1 = newTemp(Ity_I16);
7131    UShort op2;
7132    IRTemp result = newTemp(Ity_I16);
7133 
7134    assign(op1, get_gpr_hw3(r1));
7135    op2 = i2;
7136    assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7137    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7138    put_gpr_hw3(r1, mkexpr(result));
7139 
7140    return "oill";
7141 }
7142 
7143 static const HChar *
s390_irgen_PFD(void)7144 s390_irgen_PFD(void)
7145 {
7146 
7147    return "pfd";
7148 }
7149 
7150 static const HChar *
s390_irgen_PFDRL(void)7151 s390_irgen_PFDRL(void)
7152 {
7153 
7154    return "pfdrl";
7155 }
7156 
7157 static IRExpr *
get_rounding_mode_from_gr0(void)7158 get_rounding_mode_from_gr0(void)
7159 {
7160    IRTemp rm_bits = newTemp(Ity_I32);
7161    IRExpr *s390rm;
7162    IRExpr *irrm;
7163 
7164    /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7165       when PFPO insn is called. So, extract the bits at [60:63] */
7166    assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7167    s390rm = mkexpr(rm_bits);
7168    irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7169             mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7170             mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7171               mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7172               mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7173                 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7174                 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7175                   mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7176                   mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7177                     mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7178                     mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7179                       mkexpr(encode_dfp_rounding_mode(
7180                                S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7181                       mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7182                         mkexpr(encode_dfp_rounding_mode(
7183                                  S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7184                         mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7185                           mkexpr(encode_dfp_rounding_mode(
7186                                    S390_DFP_ROUND_AWAY_0)),
7187                           mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7188                             mkexpr(encode_dfp_rounding_mode(
7189                                      S390_DFP_ROUND_PREPARE_SHORT_15)),
7190                                 /* if rounding mode is 0 or invalid (2-7)
7191                                    set S390_DFP_ROUND_PER_FPC_0 */
7192                             mkexpr(encode_dfp_rounding_mode(
7193                                      S390_DFP_ROUND_PER_FPC_0)))))))))));
7194 
7195    return irrm;
7196 }
7197 
7198 static IRExpr *
s390_call_pfpo_helper(IRExpr * gr0)7199 s390_call_pfpo_helper(IRExpr *gr0)
7200 {
7201    IRExpr **args, *call;
7202 
7203    args = mkIRExprVec_1(gr0);
7204    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7205                         "s390_do_pfpo", &s390_do_pfpo, args);
7206    /* Nothing is excluded from definedness checking. */
7207    call->Iex.CCall.cee->mcx_mask = 0;
7208 
7209    return call;
7210 }
7211 
7212 static const HChar *
s390_irgen_PFPO(void)7213 s390_irgen_PFPO(void)
7214 {
7215    IRTemp gr0 = newTemp(Ity_I32);     /* word 1 [32:63] of GR 0 */
7216    IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7217    IRTemp fn = newTemp(Ity_I32);       /* [33:55] of GR 0 - function code */
7218    IRTemp ef = newTemp(Ity_I32);       /* Emulation Failure */
7219    IRTemp src1 = newTemp(Ity_F32);
7220    IRTemp dst1 = newTemp(Ity_D32);
7221    IRTemp src2 = newTemp(Ity_F32);
7222    IRTemp dst2 = newTemp(Ity_D64);
7223    IRTemp src3 = newTemp(Ity_F32);
7224    IRTemp dst3 = newTemp(Ity_D128);
7225    IRTemp src4 = newTemp(Ity_F64);
7226    IRTemp dst4 = newTemp(Ity_D32);
7227    IRTemp src5 = newTemp(Ity_F64);
7228    IRTemp dst5 = newTemp(Ity_D64);
7229    IRTemp src6 = newTemp(Ity_F64);
7230    IRTemp dst6 = newTemp(Ity_D128);
7231    IRTemp src7 = newTemp(Ity_F128);
7232    IRTemp dst7 = newTemp(Ity_D32);
7233    IRTemp src8 = newTemp(Ity_F128);
7234    IRTemp dst8 = newTemp(Ity_D64);
7235    IRTemp src9 = newTemp(Ity_F128);
7236    IRTemp dst9 = newTemp(Ity_D128);
7237    IRTemp src10 = newTemp(Ity_D32);
7238    IRTemp dst10 = newTemp(Ity_F32);
7239    IRTemp src11 = newTemp(Ity_D32);
7240    IRTemp dst11 = newTemp(Ity_F64);
7241    IRTemp src12 = newTemp(Ity_D32);
7242    IRTemp dst12 = newTemp(Ity_F128);
7243    IRTemp src13 = newTemp(Ity_D64);
7244    IRTemp dst13 = newTemp(Ity_F32);
7245    IRTemp src14 = newTemp(Ity_D64);
7246    IRTemp dst14 = newTemp(Ity_F64);
7247    IRTemp src15 = newTemp(Ity_D64);
7248    IRTemp dst15 = newTemp(Ity_F128);
7249    IRTemp src16 = newTemp(Ity_D128);
7250    IRTemp dst16 = newTemp(Ity_F32);
7251    IRTemp src17 = newTemp(Ity_D128);
7252    IRTemp dst17 = newTemp(Ity_F64);
7253    IRTemp src18 = newTemp(Ity_D128);
7254    IRTemp dst18 = newTemp(Ity_F128);
7255    IRExpr *irrm;
7256 
7257    if (! s390_host_has_pfpo) {
7258       emulation_failure(EmFail_S390X_pfpo);
7259       goto done;
7260    }
7261 
7262    assign(gr0, get_gpr_w1(0));
7263    /* get function code */
7264    assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7265                     mkU32(0x7fffff)));
7266    /* get validity test bit */
7267    assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7268                           mkU32(0x1)));
7269    irrm = get_rounding_mode_from_gr0();
7270 
7271    /* test_bit is 1 */
7272    assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
7273    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7274 
7275    /* Return code set in GR1 is usually 0. Non-zero value is set only
7276       when exceptions are raised. See Programming Notes point 5 in the
7277       instrcution description of pfpo in POP. Since valgrind does not
7278       model exception, it might be safe to just set 0 to GR 1. */
7279    put_gpr_w1(1, mkU32(0x0));
7280    next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7281 
7282    /* Check validity of function code in GR 0 */
7283    assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
7284    emulation_failure_with_expr(mkexpr(ef));
7285 
7286    stmt(
7287         IRStmt_Exit(
7288                     binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7289                     Ijk_EmFail,
7290                     IRConst_U64(guest_IA_next_instr),
7291                     S390X_GUEST_OFFSET(guest_IA)
7292                     )
7293         );
7294 
7295    /* F32 -> D32 */
7296    /* get source from FPR 4,6 - already set in src1 */
7297    assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
7298    put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
7299    put_gpr_w1(1, mkU32(0x0));
7300    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
7301    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
7302 
7303    /* F32 -> D64 */
7304    assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
7305    assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
7306    put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
7307    put_gpr_w1(1, mkU32(0x0));
7308    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
7309    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
7310 
7311    /* F32 -> D128 */
7312    assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
7313    assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
7314    put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7315    put_gpr_w1(1, mkU32(0x0));
7316    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
7317    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
7318 
7319    /* F64 -> D32 */
7320    assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7321    assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
7322    put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7323    put_gpr_w1(1, mkU32(0x0));
7324    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
7325    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
7326 
7327    /* F64 -> D64 */
7328    assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7329    assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
7330    put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7331    put_gpr_w1(1, mkU32(0x0));
7332    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
7333    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7334 
7335    /* F64 -> D128 */
7336    assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7337    assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
7338    put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7339    put_gpr_w1(1, mkU32(0x0));
7340    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
7341    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7342 
7343    /* F128 -> D32 */
7344    assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
7345    assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
7346    put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
7347    put_gpr_w1(1, mkU32(0x0));
7348    s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
7349    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
7350 
7351    /* F128 -> D64 */
7352    assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
7353    assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
7354    put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
7355    put_gpr_w1(1, mkU32(0x0));
7356    s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
7357    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
7358 
7359    /* F128 -> D128 */
7360    assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
7361    assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
7362    put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
7363    put_gpr_w1(1, mkU32(0x0));
7364    s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
7365    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7366 
7367    /* D32 -> F32 */
7368    assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
7369    assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
7370    put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
7371    put_gpr_w1(1, mkU32(0x0));
7372    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
7373    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
7374 
7375    /* D32 -> F64 */
7376    assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
7377    assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
7378    put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
7379    put_gpr_w1(1, mkU32(0x0));
7380    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
7381    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
7382 
7383    /* D32 -> F128 */
7384    assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
7385    assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
7386    put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
7387    put_gpr_w1(1, mkU32(0x0));
7388    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
7389    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
7390 
7391    /* D64 -> F32 */
7392    assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7393    assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
7394    put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
7395    put_gpr_w1(1, mkU32(0x0));
7396    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
7397    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
7398 
7399    /* D64 -> F64 */
7400    assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7401    assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
7402    put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
7403    put_gpr_w1(1, mkU32(0x0));
7404    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
7405    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7406 
7407    /* D64 -> F128 */
7408    assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7409    assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
7410    put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
7411    put_gpr_w1(1, mkU32(0x0));
7412    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
7413    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
7414 
7415    /* D128 -> F32 */
7416    assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
7417    assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
7418    put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
7419    put_gpr_w1(1, mkU32(0x0));
7420    s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
7421    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
7422 
7423    /* D128 -> F64 */
7424    assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
7425    assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
7426    put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
7427    put_gpr_w1(1, mkU32(0x0));
7428    s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
7429    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7430 
7431    /* D128 -> F128 */
7432    assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
7433    assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
7434    put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
7435    put_gpr_w1(1, mkU32(0x0));
7436    s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
7437    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7438 
7439  done:
7440    return "pfpo";
7441 }
7442 
7443 static const HChar *
s390_irgen_RLL(UChar r1,UChar r3,IRTemp op2addr)7444 s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7445 {
7446    IRTemp amount = newTemp(Ity_I64);
7447    IRTemp op = newTemp(Ity_I32);
7448 
7449    assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7450    assign(op, get_gpr_w1(r3));
7451    put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7452               mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7453               binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7454 
7455    return "rll";
7456 }
7457 
7458 static const HChar *
s390_irgen_RLLG(UChar r1,UChar r3,IRTemp op2addr)7459 s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7460 {
7461    IRTemp amount = newTemp(Ity_I64);
7462    IRTemp op = newTemp(Ity_I64);
7463 
7464    assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7465    assign(op, get_gpr_dw0(r3));
7466    put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7467                mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7468                binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7469 
7470    return "rllg";
7471 }
7472 
7473 static const HChar *
s390_irgen_RNSBG(UChar r1,UChar r2,UChar i3,UChar i4,UChar i5)7474 s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7475 {
7476    UChar from;
7477    UChar to;
7478    UChar rot;
7479    UChar t_bit;
7480    ULong mask;
7481    ULong maskc;
7482    IRTemp result = newTemp(Ity_I64);
7483    IRTemp op2 = newTemp(Ity_I64);
7484 
7485    from = i3 & 63;
7486    to = i4 & 63;
7487    rot = i5 & 63;
7488    t_bit = i3 & 128;
7489    assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7490           get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7491           mkU8(64 - rot))));
7492    if (from <= to) {
7493       mask = ~0ULL;
7494       mask = (mask >> from) & (mask << (63 - to));
7495       maskc = ~mask;
7496    } else {
7497       maskc = ~0ULL;
7498       maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7499       mask = ~maskc;
7500    }
7501    assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7502           ), mkU64(mask)));
7503    if (t_bit == 0) {
7504       put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7505                   mkU64(maskc)), mkexpr(result)));
7506    }
7507    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7508 
7509    return "rnsbg";
7510 }
7511 
7512 static const HChar *
s390_irgen_RXSBG(UChar r1,UChar r2,UChar i3,UChar i4,UChar i5)7513 s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7514 {
7515    UChar from;
7516    UChar to;
7517    UChar rot;
7518    UChar t_bit;
7519    ULong mask;
7520    ULong maskc;
7521    IRTemp result = newTemp(Ity_I64);
7522    IRTemp op2 = newTemp(Ity_I64);
7523 
7524    from = i3 & 63;
7525    to = i4 & 63;
7526    rot = i5 & 63;
7527    t_bit = i3 & 128;
7528    assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7529           get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7530           mkU8(64 - rot))));
7531    if (from <= to) {
7532       mask = ~0ULL;
7533       mask = (mask >> from) & (mask << (63 - to));
7534       maskc = ~mask;
7535    } else {
7536       maskc = ~0ULL;
7537       maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7538       mask = ~maskc;
7539    }
7540    assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7541           ), mkU64(mask)));
7542    if (t_bit == 0) {
7543       put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7544                   mkU64(maskc)), mkexpr(result)));
7545    }
7546    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7547 
7548    return "rxsbg";
7549 }
7550 
7551 static const HChar *
s390_irgen_ROSBG(UChar r1,UChar r2,UChar i3,UChar i4,UChar i5)7552 s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7553 {
7554    UChar from;
7555    UChar to;
7556    UChar rot;
7557    UChar t_bit;
7558    ULong mask;
7559    ULong maskc;
7560    IRTemp result = newTemp(Ity_I64);
7561    IRTemp op2 = newTemp(Ity_I64);
7562 
7563    from = i3 & 63;
7564    to = i4 & 63;
7565    rot = i5 & 63;
7566    t_bit = i3 & 128;
7567    assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7568           get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7569           mkU8(64 - rot))));
7570    if (from <= to) {
7571       mask = ~0ULL;
7572       mask = (mask >> from) & (mask << (63 - to));
7573       maskc = ~mask;
7574    } else {
7575       maskc = ~0ULL;
7576       maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7577       mask = ~maskc;
7578    }
7579    assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7580           ), mkU64(mask)));
7581    if (t_bit == 0) {
7582       put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7583                   mkU64(maskc)), mkexpr(result)));
7584    }
7585    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7586 
7587    return "rosbg";
7588 }
7589 
7590 static const HChar *
s390_irgen_RISBGx(UChar r1,UChar r2,UChar i3,UChar i4,UChar i5,Bool set_cc)7591 s390_irgen_RISBGx(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
7592                   Bool set_cc)
7593 {
7594    UChar from;
7595    UChar to;
7596    UChar rot;
7597    UChar z_bit;
7598    ULong mask;
7599    ULong maskc;
7600    IRTemp op2 = newTemp(Ity_I64);
7601    IRTemp result = newTemp(Ity_I64);
7602 
7603    from = i3 & 63;
7604    to = i4 & 63;
7605    rot = i5 & 63;
7606    z_bit = i4 & 128;
7607    assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7608           get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7609           mkU8(64 - rot))));
7610    if (from <= to) {
7611       mask = ~0ULL;
7612       mask = (mask >> from) & (mask << (63 - to));
7613       maskc = ~mask;
7614    } else {
7615       maskc = ~0ULL;
7616       maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7617       mask = ~maskc;
7618    }
7619    if (z_bit == 0) {
7620       put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7621                   mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7622    } else {
7623       put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7624    }
7625    assign(result, get_gpr_dw0(r1));
7626    if (set_cc) {
7627       s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7628       return "risbg";
7629    }
7630 
7631    return "risbgn";
7632 }
7633 
7634 static const HChar *
s390_irgen_RISBG(UChar r1,UChar r2,UChar i3,UChar i4,UChar i5)7635 s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7636 {
7637    return s390_irgen_RISBGx(r1, r2, i3, i4, i5, True);
7638 }
7639 
7640 static const HChar *
s390_irgen_RISBGN(UChar r1,UChar r2,UChar i3,UChar i4,UChar i5)7641 s390_irgen_RISBGN(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7642 {
7643    return s390_irgen_RISBGx(r1, r2, i3, i4, i5, False);
7644 }
7645 
7646 static IRExpr *
s390_irgen_RISBxG(UChar r1,UChar r2,UChar i3,UChar i4,UChar i5,Bool high)7647 s390_irgen_RISBxG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
7648                   Bool high)
7649 {
7650    UChar from;
7651    UChar to;
7652    UChar rot;
7653    UChar z_bit;
7654    UInt mask;
7655    UInt maskc;
7656    IRTemp op2 = newTemp(Ity_I32);
7657 
7658    from = i3 & 31;
7659    to = i4 & 31;
7660    rot = i5 & 63;
7661    z_bit = i4 & 128;
7662    if (rot == 0) {
7663       assign(op2, high ? get_gpr_w0(r2) : get_gpr_w1(r2));
7664    } else if (rot == 32) {
7665       assign(op2, high ? get_gpr_w1(r2) : get_gpr_w0(r2));
7666    } else {
7667       assign(op2,
7668              unop(high ? Iop_64HIto32 : Iop_64to32,
7669                   binop(Iop_Or64,
7670                         binop(Iop_Shl64, get_gpr_dw0(r2), mkU8(rot)),
7671                         binop(Iop_Shr64, get_gpr_dw0(r2), mkU8(64 - rot)))));
7672    }
7673    if (from <= to) {
7674       mask = ~0U;
7675       mask = (mask >> from) & (mask << (31 - to));
7676       maskc = ~mask;
7677    } else {
7678       maskc = ~0U;
7679       maskc = (maskc >> (to + 1)) & (maskc << (32 - from));
7680       mask = ~maskc;
7681    }
7682    if (z_bit) {
7683       return binop(Iop_And32, mkexpr(op2), mkU32(mask));
7684    }
7685    return binop(Iop_Or32,
7686                 binop(Iop_And32, high ? get_gpr_w0(r1) : get_gpr_w1(r1),
7687                       mkU32(maskc)),
7688                 binop(Iop_And32, mkexpr(op2), mkU32(mask)));
7689 }
7690 
7691 static const HChar *
s390_irgen_RISBHG(UChar r1,UChar r2,UChar i3,UChar i4,UChar i5)7692 s390_irgen_RISBHG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7693 {
7694    put_gpr_w0(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, True));
7695    return "risbhg";
7696 }
7697 
7698 static const HChar *
s390_irgen_RISBLG(UChar r1,UChar r2,UChar i3,UChar i4,UChar i5)7699 s390_irgen_RISBLG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7700 {
7701    put_gpr_w1(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, False));
7702    return "risblg";
7703 }
7704 
7705 static const HChar *
s390_irgen_SAR(UChar r1,UChar r2)7706 s390_irgen_SAR(UChar r1, UChar r2)
7707 {
7708    put_ar_w0(r1, get_gpr_w1(r2));
7709    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
7710       s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7711 
7712    return "sar";
7713 }
7714 
7715 static const HChar *
s390_irgen_SLDA(UChar r1,IRTemp op2addr)7716 s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7717 {
7718    IRTemp p1 = newTemp(Ity_I64);
7719    IRTemp p2 = newTemp(Ity_I64);
7720    IRTemp op = newTemp(Ity_I64);
7721    IRTemp result = newTemp(Ity_I64);
7722    ULong sign_mask;
7723    IRTemp shift_amount = newTemp(Ity_I64);
7724 
7725    assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7726    assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7727    assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7728           ));
7729    sign_mask = 1ULL << 63;
7730    assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7731    assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
7732           unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7733           binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
7734    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7735    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7736    s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7737 
7738    return "slda";
7739 }
7740 
7741 static const HChar *
s390_irgen_SLDL(UChar r1,IRTemp op2addr)7742 s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7743 {
7744    IRTemp p1 = newTemp(Ity_I64);
7745    IRTemp p2 = newTemp(Ity_I64);
7746    IRTemp result = newTemp(Ity_I64);
7747 
7748    assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7749    assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7750    assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7751           mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7752           mkexpr(op2addr), mkU64(63)))));
7753    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7754    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7755 
7756    return "sldl";
7757 }
7758 
7759 static const HChar *
s390_irgen_SLA(UChar r1,IRTemp op2addr)7760 s390_irgen_SLA(UChar r1, IRTemp op2addr)
7761 {
7762    IRTemp uop = newTemp(Ity_I32);
7763    IRTemp result = newTemp(Ity_I32);
7764    UInt sign_mask;
7765    IRTemp shift_amount = newTemp(Ity_I64);
7766    IRTemp op = newTemp(Ity_I32);
7767 
7768    assign(op, get_gpr_w1(r1));
7769    assign(uop, get_gpr_w1(r1));
7770    sign_mask = 2147483648U;
7771    assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7772    assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7773           unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7774           binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7775    put_gpr_w1(r1, mkexpr(result));
7776    s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7777 
7778    return "sla";
7779 }
7780 
7781 static const HChar *
s390_irgen_SLAK(UChar r1,UChar r3,IRTemp op2addr)7782 s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7783 {
7784    IRTemp uop = newTemp(Ity_I32);
7785    IRTemp result = newTemp(Ity_I32);
7786    UInt sign_mask;
7787    IRTemp shift_amount = newTemp(Ity_I64);
7788    IRTemp op = newTemp(Ity_I32);
7789 
7790    assign(op, get_gpr_w1(r3));
7791    assign(uop, get_gpr_w1(r3));
7792    sign_mask = 2147483648U;
7793    assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7794    assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7795           unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7796           binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7797    put_gpr_w1(r1, mkexpr(result));
7798    s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7799 
7800    return "slak";
7801 }
7802 
7803 static const HChar *
s390_irgen_SLAG(UChar r1,UChar r3,IRTemp op2addr)7804 s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7805 {
7806    IRTemp uop = newTemp(Ity_I64);
7807    IRTemp result = newTemp(Ity_I64);
7808    ULong sign_mask;
7809    IRTemp shift_amount = newTemp(Ity_I64);
7810    IRTemp op = newTemp(Ity_I64);
7811 
7812    assign(op, get_gpr_dw0(r3));
7813    assign(uop, get_gpr_dw0(r3));
7814    sign_mask = 9223372036854775808ULL;
7815    assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7816    assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7817           unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7818           binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7819    put_gpr_dw0(r1, mkexpr(result));
7820    s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7821 
7822    return "slag";
7823 }
7824 
7825 static const HChar *
s390_irgen_SLL(UChar r1,IRTemp op2addr)7826 s390_irgen_SLL(UChar r1, IRTemp op2addr)
7827 {
7828    put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7829               binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7830 
7831    return "sll";
7832 }
7833 
7834 static const HChar *
s390_irgen_SLLK(UChar r1,UChar r3,IRTemp op2addr)7835 s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7836 {
7837    put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7838               binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7839 
7840    return "sllk";
7841 }
7842 
7843 static const HChar *
s390_irgen_SLLG(UChar r1,UChar r3,IRTemp op2addr)7844 s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7845 {
7846    put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7847                binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7848 
7849    return "sllg";
7850 }
7851 
7852 static const HChar *
s390_irgen_SRDA(UChar r1,IRTemp op2addr)7853 s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7854 {
7855    IRTemp p1 = newTemp(Ity_I64);
7856    IRTemp p2 = newTemp(Ity_I64);
7857    IRTemp result = newTemp(Ity_I64);
7858 
7859    assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7860    assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7861    assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7862           mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7863           mkexpr(op2addr), mkU64(63)))));
7864    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7865    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7866    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7867 
7868    return "srda";
7869 }
7870 
7871 static const HChar *
s390_irgen_SRDL(UChar r1,IRTemp op2addr)7872 s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7873 {
7874    IRTemp p1 = newTemp(Ity_I64);
7875    IRTemp p2 = newTemp(Ity_I64);
7876    IRTemp result = newTemp(Ity_I64);
7877 
7878    assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7879    assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7880    assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7881           mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7882           mkexpr(op2addr), mkU64(63)))));
7883    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7884    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7885 
7886    return "srdl";
7887 }
7888 
7889 static const HChar *
s390_irgen_SRA(UChar r1,IRTemp op2addr)7890 s390_irgen_SRA(UChar r1, IRTemp op2addr)
7891 {
7892    IRTemp result = newTemp(Ity_I32);
7893    IRTemp op = newTemp(Ity_I32);
7894 
7895    assign(op, get_gpr_w1(r1));
7896    assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7897           mkexpr(op2addr), mkU64(63)))));
7898    put_gpr_w1(r1, mkexpr(result));
7899    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7900 
7901    return "sra";
7902 }
7903 
7904 static const HChar *
s390_irgen_SRAK(UChar r1,UChar r3,IRTemp op2addr)7905 s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7906 {
7907    IRTemp result = newTemp(Ity_I32);
7908    IRTemp op = newTemp(Ity_I32);
7909 
7910    assign(op, get_gpr_w1(r3));
7911    assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7912           mkexpr(op2addr), mkU64(63)))));
7913    put_gpr_w1(r1, mkexpr(result));
7914    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7915 
7916    return "srak";
7917 }
7918 
7919 static const HChar *
s390_irgen_SRAG(UChar r1,UChar r3,IRTemp op2addr)7920 s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7921 {
7922    IRTemp result = newTemp(Ity_I64);
7923    IRTemp op = newTemp(Ity_I64);
7924 
7925    assign(op, get_gpr_dw0(r3));
7926    assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7927           mkexpr(op2addr), mkU64(63)))));
7928    put_gpr_dw0(r1, mkexpr(result));
7929    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7930 
7931    return "srag";
7932 }
7933 
7934 static const HChar *
s390_irgen_SRL(UChar r1,IRTemp op2addr)7935 s390_irgen_SRL(UChar r1, IRTemp op2addr)
7936 {
7937    IRTemp op = newTemp(Ity_I32);
7938 
7939    assign(op, get_gpr_w1(r1));
7940    put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7941               mkexpr(op2addr), mkU64(63)))));
7942 
7943    return "srl";
7944 }
7945 
7946 static const HChar *
s390_irgen_SRLK(UChar r1,UChar r3,IRTemp op2addr)7947 s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7948 {
7949    IRTemp op = newTemp(Ity_I32);
7950 
7951    assign(op, get_gpr_w1(r3));
7952    put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7953               mkexpr(op2addr), mkU64(63)))));
7954 
7955    return "srlk";
7956 }
7957 
7958 static const HChar *
s390_irgen_SRLG(UChar r1,UChar r3,IRTemp op2addr)7959 s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7960 {
7961    IRTemp op = newTemp(Ity_I64);
7962 
7963    assign(op, get_gpr_dw0(r3));
7964    put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7965                mkexpr(op2addr), mkU64(63)))));
7966 
7967    return "srlg";
7968 }
7969 
7970 static const HChar *
s390_irgen_ST(UChar r1,IRTemp op2addr)7971 s390_irgen_ST(UChar r1, IRTemp op2addr)
7972 {
7973    store(mkexpr(op2addr), get_gpr_w1(r1));
7974 
7975    return "st";
7976 }
7977 
7978 static const HChar *
s390_irgen_STY(UChar r1,IRTemp op2addr)7979 s390_irgen_STY(UChar r1, IRTemp op2addr)
7980 {
7981    store(mkexpr(op2addr), get_gpr_w1(r1));
7982 
7983    return "sty";
7984 }
7985 
7986 static const HChar *
s390_irgen_STG(UChar r1,IRTemp op2addr)7987 s390_irgen_STG(UChar r1, IRTemp op2addr)
7988 {
7989    store(mkexpr(op2addr), get_gpr_dw0(r1));
7990 
7991    return "stg";
7992 }
7993 
7994 static const HChar *
s390_irgen_STRL(UChar r1,UInt i2)7995 s390_irgen_STRL(UChar r1, UInt i2)
7996 {
7997    store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7998          get_gpr_w1(r1));
7999 
8000    return "strl";
8001 }
8002 
8003 static const HChar *
s390_irgen_STGRL(UChar r1,UInt i2)8004 s390_irgen_STGRL(UChar r1, UInt i2)
8005 {
8006    store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8007          get_gpr_dw0(r1));
8008 
8009    return "stgrl";
8010 }
8011 
8012 static const HChar *
s390_irgen_STC(UChar r1,IRTemp op2addr)8013 s390_irgen_STC(UChar r1, IRTemp op2addr)
8014 {
8015    store(mkexpr(op2addr), get_gpr_b7(r1));
8016 
8017    return "stc";
8018 }
8019 
8020 static const HChar *
s390_irgen_STCY(UChar r1,IRTemp op2addr)8021 s390_irgen_STCY(UChar r1, IRTemp op2addr)
8022 {
8023    store(mkexpr(op2addr), get_gpr_b7(r1));
8024 
8025    return "stcy";
8026 }
8027 
8028 static const HChar *
s390_irgen_STCH(UChar r1,IRTemp op2addr)8029 s390_irgen_STCH(UChar r1, IRTemp op2addr)
8030 {
8031    store(mkexpr(op2addr), get_gpr_b3(r1));
8032 
8033    return "stch";
8034 }
8035 
8036 static const HChar *
s390_irgen_STCM(UChar r1,UChar r3,IRTemp op2addr)8037 s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
8038 {
8039    UChar mask;
8040    UChar n;
8041 
8042    mask = (UChar)r3;
8043    n = 0;
8044    if ((mask & 8) != 0) {
8045       store(mkexpr(op2addr), get_gpr_b4(r1));
8046       n = n + 1;
8047    }
8048    if ((mask & 4) != 0) {
8049       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
8050       n = n + 1;
8051    }
8052    if ((mask & 2) != 0) {
8053       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
8054       n = n + 1;
8055    }
8056    if ((mask & 1) != 0) {
8057       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
8058    }
8059 
8060    return "stcm";
8061 }
8062 
8063 static const HChar *
s390_irgen_STCMY(UChar r1,UChar r3,IRTemp op2addr)8064 s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
8065 {
8066    UChar mask;
8067    UChar n;
8068 
8069    mask = (UChar)r3;
8070    n = 0;
8071    if ((mask & 8) != 0) {
8072       store(mkexpr(op2addr), get_gpr_b4(r1));
8073       n = n + 1;
8074    }
8075    if ((mask & 4) != 0) {
8076       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
8077       n = n + 1;
8078    }
8079    if ((mask & 2) != 0) {
8080       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
8081       n = n + 1;
8082    }
8083    if ((mask & 1) != 0) {
8084       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
8085    }
8086 
8087    return "stcmy";
8088 }
8089 
8090 static const HChar *
s390_irgen_STCMH(UChar r1,UChar r3,IRTemp op2addr)8091 s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
8092 {
8093    UChar mask;
8094    UChar n;
8095 
8096    mask = (UChar)r3;
8097    n = 0;
8098    if ((mask & 8) != 0) {
8099       store(mkexpr(op2addr), get_gpr_b0(r1));
8100       n = n + 1;
8101    }
8102    if ((mask & 4) != 0) {
8103       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
8104       n = n + 1;
8105    }
8106    if ((mask & 2) != 0) {
8107       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
8108       n = n + 1;
8109    }
8110    if ((mask & 1) != 0) {
8111       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
8112    }
8113 
8114    return "stcmh";
8115 }
8116 
8117 static const HChar *
s390_irgen_STH(UChar r1,IRTemp op2addr)8118 s390_irgen_STH(UChar r1, IRTemp op2addr)
8119 {
8120    store(mkexpr(op2addr), get_gpr_hw3(r1));
8121 
8122    return "sth";
8123 }
8124 
8125 static const HChar *
s390_irgen_STHY(UChar r1,IRTemp op2addr)8126 s390_irgen_STHY(UChar r1, IRTemp op2addr)
8127 {
8128    store(mkexpr(op2addr), get_gpr_hw3(r1));
8129 
8130    return "sthy";
8131 }
8132 
8133 static const HChar *
s390_irgen_STHRL(UChar r1,UInt i2)8134 s390_irgen_STHRL(UChar r1, UInt i2)
8135 {
8136    store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8137          get_gpr_hw3(r1));
8138 
8139    return "sthrl";
8140 }
8141 
8142 static const HChar *
s390_irgen_STHH(UChar r1,IRTemp op2addr)8143 s390_irgen_STHH(UChar r1, IRTemp op2addr)
8144 {
8145    store(mkexpr(op2addr), get_gpr_hw1(r1));
8146 
8147    return "sthh";
8148 }
8149 
8150 static const HChar *
s390_irgen_STFH(UChar r1,IRTemp op2addr)8151 s390_irgen_STFH(UChar r1, IRTemp op2addr)
8152 {
8153    store(mkexpr(op2addr), get_gpr_w0(r1));
8154 
8155    return "stfh";
8156 }
8157 
8158 static const HChar *
s390_irgen_STOC(UChar r1,IRTemp op2addr)8159 s390_irgen_STOC(UChar r1, IRTemp op2addr)
8160 {
8161    /* condition is checked in format handler */
8162    store(mkexpr(op2addr), get_gpr_w1(r1));
8163 
8164    return "stoc";
8165 }
8166 
8167 static const HChar *
s390_irgen_STOCG(UChar r1,IRTemp op2addr)8168 s390_irgen_STOCG(UChar r1, IRTemp op2addr)
8169 {
8170    /* condition is checked in format handler */
8171    store(mkexpr(op2addr), get_gpr_dw0(r1));
8172 
8173    return "stocg";
8174 }
8175 
8176 static const HChar *
s390_irgen_STPQ(UChar r1,IRTemp op2addr)8177 s390_irgen_STPQ(UChar r1, IRTemp op2addr)
8178 {
8179    store(mkexpr(op2addr), get_gpr_dw0(r1));
8180    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
8181 
8182    return "stpq";
8183 }
8184 
8185 static const HChar *
s390_irgen_STRVH(UChar r1,IRTemp op2addr)8186 s390_irgen_STRVH(UChar r1, IRTemp op2addr)
8187 {
8188    store(mkexpr(op2addr), get_gpr_b7(r1));
8189    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8190 
8191    return "strvh";
8192 }
8193 
8194 static const HChar *
s390_irgen_STRV(UChar r1,IRTemp op2addr)8195 s390_irgen_STRV(UChar r1, IRTemp op2addr)
8196 {
8197    store(mkexpr(op2addr), get_gpr_b7(r1));
8198    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8199    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8200    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8201 
8202    return "strv";
8203 }
8204 
8205 static const HChar *
s390_irgen_STRVG(UChar r1,IRTemp op2addr)8206 s390_irgen_STRVG(UChar r1, IRTemp op2addr)
8207 {
8208    store(mkexpr(op2addr), get_gpr_b7(r1));
8209    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8210    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8211    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8212    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
8213    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
8214    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
8215    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
8216 
8217    return "strvg";
8218 }
8219 
8220 static const HChar *
s390_irgen_SR(UChar r1,UChar r2)8221 s390_irgen_SR(UChar r1, UChar r2)
8222 {
8223    IRTemp op1 = newTemp(Ity_I32);
8224    IRTemp op2 = newTemp(Ity_I32);
8225    IRTemp result = newTemp(Ity_I32);
8226 
8227    assign(op1, get_gpr_w1(r1));
8228    assign(op2, get_gpr_w1(r2));
8229    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8230    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8231    put_gpr_w1(r1, mkexpr(result));
8232 
8233    return "sr";
8234 }
8235 
8236 static const HChar *
s390_irgen_SGR(UChar r1,UChar r2)8237 s390_irgen_SGR(UChar r1, UChar r2)
8238 {
8239    IRTemp op1 = newTemp(Ity_I64);
8240    IRTemp op2 = newTemp(Ity_I64);
8241    IRTemp result = newTemp(Ity_I64);
8242 
8243    assign(op1, get_gpr_dw0(r1));
8244    assign(op2, get_gpr_dw0(r2));
8245    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8246    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8247    put_gpr_dw0(r1, mkexpr(result));
8248 
8249    return "sgr";
8250 }
8251 
8252 static const HChar *
s390_irgen_SGFR(UChar r1,UChar r2)8253 s390_irgen_SGFR(UChar r1, UChar r2)
8254 {
8255    IRTemp op1 = newTemp(Ity_I64);
8256    IRTemp op2 = newTemp(Ity_I64);
8257    IRTemp result = newTemp(Ity_I64);
8258 
8259    assign(op1, get_gpr_dw0(r1));
8260    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8261    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8262    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8263    put_gpr_dw0(r1, mkexpr(result));
8264 
8265    return "sgfr";
8266 }
8267 
8268 static const HChar *
s390_irgen_SRK(UChar r3,UChar r1,UChar r2)8269 s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8270 {
8271    IRTemp op2 = newTemp(Ity_I32);
8272    IRTemp op3 = newTemp(Ity_I32);
8273    IRTemp result = newTemp(Ity_I32);
8274 
8275    assign(op2, get_gpr_w1(r2));
8276    assign(op3, get_gpr_w1(r3));
8277    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8278    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8279    put_gpr_w1(r1, mkexpr(result));
8280 
8281    return "srk";
8282 }
8283 
8284 static const HChar *
s390_irgen_SGRK(UChar r3,UChar r1,UChar r2)8285 s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8286 {
8287    IRTemp op2 = newTemp(Ity_I64);
8288    IRTemp op3 = newTemp(Ity_I64);
8289    IRTemp result = newTemp(Ity_I64);
8290 
8291    assign(op2, get_gpr_dw0(r2));
8292    assign(op3, get_gpr_dw0(r3));
8293    assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8294    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8295    put_gpr_dw0(r1, mkexpr(result));
8296 
8297    return "sgrk";
8298 }
8299 
8300 static const HChar *
s390_irgen_S(UChar r1,IRTemp op2addr)8301 s390_irgen_S(UChar r1, IRTemp op2addr)
8302 {
8303    IRTemp op1 = newTemp(Ity_I32);
8304    IRTemp op2 = newTemp(Ity_I32);
8305    IRTemp result = newTemp(Ity_I32);
8306 
8307    assign(op1, get_gpr_w1(r1));
8308    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8309    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8310    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8311    put_gpr_w1(r1, mkexpr(result));
8312 
8313    return "s";
8314 }
8315 
8316 static const HChar *
s390_irgen_SY(UChar r1,IRTemp op2addr)8317 s390_irgen_SY(UChar r1, IRTemp op2addr)
8318 {
8319    IRTemp op1 = newTemp(Ity_I32);
8320    IRTemp op2 = newTemp(Ity_I32);
8321    IRTemp result = newTemp(Ity_I32);
8322 
8323    assign(op1, get_gpr_w1(r1));
8324    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8325    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8326    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8327    put_gpr_w1(r1, mkexpr(result));
8328 
8329    return "sy";
8330 }
8331 
8332 static const HChar *
s390_irgen_SG(UChar r1,IRTemp op2addr)8333 s390_irgen_SG(UChar r1, IRTemp op2addr)
8334 {
8335    IRTemp op1 = newTemp(Ity_I64);
8336    IRTemp op2 = newTemp(Ity_I64);
8337    IRTemp result = newTemp(Ity_I64);
8338 
8339    assign(op1, get_gpr_dw0(r1));
8340    assign(op2, load(Ity_I64, mkexpr(op2addr)));
8341    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8342    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8343    put_gpr_dw0(r1, mkexpr(result));
8344 
8345    return "sg";
8346 }
8347 
8348 static const HChar *
s390_irgen_SGF(UChar r1,IRTemp op2addr)8349 s390_irgen_SGF(UChar r1, IRTemp op2addr)
8350 {
8351    IRTemp op1 = newTemp(Ity_I64);
8352    IRTemp op2 = newTemp(Ity_I64);
8353    IRTemp result = newTemp(Ity_I64);
8354 
8355    assign(op1, get_gpr_dw0(r1));
8356    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8357    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8358    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8359    put_gpr_dw0(r1, mkexpr(result));
8360 
8361    return "sgf";
8362 }
8363 
8364 static const HChar *
s390_irgen_SH(UChar r1,IRTemp op2addr)8365 s390_irgen_SH(UChar r1, IRTemp op2addr)
8366 {
8367    IRTemp op1 = newTemp(Ity_I32);
8368    IRTemp op2 = newTemp(Ity_I32);
8369    IRTemp result = newTemp(Ity_I32);
8370 
8371    assign(op1, get_gpr_w1(r1));
8372    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8373    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8374    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8375    put_gpr_w1(r1, mkexpr(result));
8376 
8377    return "sh";
8378 }
8379 
8380 static const HChar *
s390_irgen_SHY(UChar r1,IRTemp op2addr)8381 s390_irgen_SHY(UChar r1, IRTemp op2addr)
8382 {
8383    IRTemp op1 = newTemp(Ity_I32);
8384    IRTemp op2 = newTemp(Ity_I32);
8385    IRTemp result = newTemp(Ity_I32);
8386 
8387    assign(op1, get_gpr_w1(r1));
8388    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8389    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8390    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8391    put_gpr_w1(r1, mkexpr(result));
8392 
8393    return "shy";
8394 }
8395 
8396 static const HChar *
s390_irgen_SHHHR(UChar r3,UChar r1,UChar r2)8397 s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8398 {
8399    IRTemp op2 = newTemp(Ity_I32);
8400    IRTemp op3 = newTemp(Ity_I32);
8401    IRTemp result = newTemp(Ity_I32);
8402 
8403    assign(op2, get_gpr_w0(r1));
8404    assign(op3, get_gpr_w0(r2));
8405    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8406    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8407    put_gpr_w0(r1, mkexpr(result));
8408 
8409    return "shhhr";
8410 }
8411 
8412 static const HChar *
s390_irgen_SHHLR(UChar r3,UChar r1,UChar r2)8413 s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8414 {
8415    IRTemp op2 = newTemp(Ity_I32);
8416    IRTemp op3 = newTemp(Ity_I32);
8417    IRTemp result = newTemp(Ity_I32);
8418 
8419    assign(op2, get_gpr_w0(r1));
8420    assign(op3, get_gpr_w1(r2));
8421    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8422    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8423    put_gpr_w0(r1, mkexpr(result));
8424 
8425    return "shhlr";
8426 }
8427 
8428 static const HChar *
s390_irgen_SLR(UChar r1,UChar r2)8429 s390_irgen_SLR(UChar r1, UChar r2)
8430 {
8431    IRTemp op1 = newTemp(Ity_I32);
8432    IRTemp op2 = newTemp(Ity_I32);
8433    IRTemp result = newTemp(Ity_I32);
8434 
8435    assign(op1, get_gpr_w1(r1));
8436    assign(op2, get_gpr_w1(r2));
8437    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8438    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8439    put_gpr_w1(r1, mkexpr(result));
8440 
8441    return "slr";
8442 }
8443 
8444 static const HChar *
s390_irgen_SLGR(UChar r1,UChar r2)8445 s390_irgen_SLGR(UChar r1, UChar r2)
8446 {
8447    IRTemp op1 = newTemp(Ity_I64);
8448    IRTemp op2 = newTemp(Ity_I64);
8449    IRTemp result = newTemp(Ity_I64);
8450 
8451    assign(op1, get_gpr_dw0(r1));
8452    assign(op2, get_gpr_dw0(r2));
8453    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8454    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8455    put_gpr_dw0(r1, mkexpr(result));
8456 
8457    return "slgr";
8458 }
8459 
8460 static const HChar *
s390_irgen_SLGFR(UChar r1,UChar r2)8461 s390_irgen_SLGFR(UChar r1, UChar r2)
8462 {
8463    IRTemp op1 = newTemp(Ity_I64);
8464    IRTemp op2 = newTemp(Ity_I64);
8465    IRTemp result = newTemp(Ity_I64);
8466 
8467    assign(op1, get_gpr_dw0(r1));
8468    assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8469    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8470    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8471    put_gpr_dw0(r1, mkexpr(result));
8472 
8473    return "slgfr";
8474 }
8475 
8476 static const HChar *
s390_irgen_SLRK(UChar r3,UChar r1,UChar r2)8477 s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8478 {
8479    IRTemp op2 = newTemp(Ity_I32);
8480    IRTemp op3 = newTemp(Ity_I32);
8481    IRTemp result = newTemp(Ity_I32);
8482 
8483    assign(op2, get_gpr_w1(r2));
8484    assign(op3, get_gpr_w1(r3));
8485    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8486    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8487    put_gpr_w1(r1, mkexpr(result));
8488 
8489    return "slrk";
8490 }
8491 
8492 static const HChar *
s390_irgen_SLGRK(UChar r3,UChar r1,UChar r2)8493 s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8494 {
8495    IRTemp op2 = newTemp(Ity_I64);
8496    IRTemp op3 = newTemp(Ity_I64);
8497    IRTemp result = newTemp(Ity_I64);
8498 
8499    assign(op2, get_gpr_dw0(r2));
8500    assign(op3, get_gpr_dw0(r3));
8501    assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8502    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8503    put_gpr_dw0(r1, mkexpr(result));
8504 
8505    return "slgrk";
8506 }
8507 
8508 static const HChar *
s390_irgen_SL(UChar r1,IRTemp op2addr)8509 s390_irgen_SL(UChar r1, IRTemp op2addr)
8510 {
8511    IRTemp op1 = newTemp(Ity_I32);
8512    IRTemp op2 = newTemp(Ity_I32);
8513    IRTemp result = newTemp(Ity_I32);
8514 
8515    assign(op1, get_gpr_w1(r1));
8516    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8517    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8518    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8519    put_gpr_w1(r1, mkexpr(result));
8520 
8521    return "sl";
8522 }
8523 
8524 static const HChar *
s390_irgen_SLY(UChar r1,IRTemp op2addr)8525 s390_irgen_SLY(UChar r1, IRTemp op2addr)
8526 {
8527    IRTemp op1 = newTemp(Ity_I32);
8528    IRTemp op2 = newTemp(Ity_I32);
8529    IRTemp result = newTemp(Ity_I32);
8530 
8531    assign(op1, get_gpr_w1(r1));
8532    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8533    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8534    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8535    put_gpr_w1(r1, mkexpr(result));
8536 
8537    return "sly";
8538 }
8539 
8540 static const HChar *
s390_irgen_SLG(UChar r1,IRTemp op2addr)8541 s390_irgen_SLG(UChar r1, IRTemp op2addr)
8542 {
8543    IRTemp op1 = newTemp(Ity_I64);
8544    IRTemp op2 = newTemp(Ity_I64);
8545    IRTemp result = newTemp(Ity_I64);
8546 
8547    assign(op1, get_gpr_dw0(r1));
8548    assign(op2, load(Ity_I64, mkexpr(op2addr)));
8549    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8550    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8551    put_gpr_dw0(r1, mkexpr(result));
8552 
8553    return "slg";
8554 }
8555 
8556 static const HChar *
s390_irgen_SLGF(UChar r1,IRTemp op2addr)8557 s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8558 {
8559    IRTemp op1 = newTemp(Ity_I64);
8560    IRTemp op2 = newTemp(Ity_I64);
8561    IRTemp result = newTemp(Ity_I64);
8562 
8563    assign(op1, get_gpr_dw0(r1));
8564    assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8565    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8566    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8567    put_gpr_dw0(r1, mkexpr(result));
8568 
8569    return "slgf";
8570 }
8571 
8572 static const HChar *
s390_irgen_SLFI(UChar r1,UInt i2)8573 s390_irgen_SLFI(UChar r1, UInt i2)
8574 {
8575    IRTemp op1 = newTemp(Ity_I32);
8576    UInt op2;
8577    IRTemp result = newTemp(Ity_I32);
8578 
8579    assign(op1, get_gpr_w1(r1));
8580    op2 = i2;
8581    assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8582    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8583                        mkU32(op2)));
8584    put_gpr_w1(r1, mkexpr(result));
8585 
8586    return "slfi";
8587 }
8588 
8589 static const HChar *
s390_irgen_SLGFI(UChar r1,UInt i2)8590 s390_irgen_SLGFI(UChar r1, UInt i2)
8591 {
8592    IRTemp op1 = newTemp(Ity_I64);
8593    ULong op2;
8594    IRTemp result = newTemp(Ity_I64);
8595 
8596    assign(op1, get_gpr_dw0(r1));
8597    op2 = (ULong)i2;
8598    assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8599    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8600                        mkU64(op2)));
8601    put_gpr_dw0(r1, mkexpr(result));
8602 
8603    return "slgfi";
8604 }
8605 
8606 static const HChar *
s390_irgen_SLHHHR(UChar r3,UChar r1,UChar r2)8607 s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8608 {
8609    IRTemp op2 = newTemp(Ity_I32);
8610    IRTemp op3 = newTemp(Ity_I32);
8611    IRTemp result = newTemp(Ity_I32);
8612 
8613    assign(op2, get_gpr_w0(r1));
8614    assign(op3, get_gpr_w0(r2));
8615    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8616    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8617    put_gpr_w0(r1, mkexpr(result));
8618 
8619    return "slhhhr";
8620 }
8621 
8622 static const HChar *
s390_irgen_SLHHLR(UChar r3,UChar r1,UChar r2)8623 s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8624 {
8625    IRTemp op2 = newTemp(Ity_I32);
8626    IRTemp op3 = newTemp(Ity_I32);
8627    IRTemp result = newTemp(Ity_I32);
8628 
8629    assign(op2, get_gpr_w0(r1));
8630    assign(op3, get_gpr_w1(r2));
8631    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8632    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8633    put_gpr_w0(r1, mkexpr(result));
8634 
8635    return "slhhlr";
8636 }
8637 
8638 static const HChar *
s390_irgen_SLBR(UChar r1,UChar r2)8639 s390_irgen_SLBR(UChar r1, UChar r2)
8640 {
8641    IRTemp op1 = newTemp(Ity_I32);
8642    IRTemp op2 = newTemp(Ity_I32);
8643    IRTemp result = newTemp(Ity_I32);
8644    IRTemp borrow_in = newTemp(Ity_I32);
8645 
8646    assign(op1, get_gpr_w1(r1));
8647    assign(op2, get_gpr_w1(r2));
8648    assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8649           s390_call_calculate_cc(), mkU8(1))));
8650    assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8651           mkexpr(borrow_in)));
8652    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8653    put_gpr_w1(r1, mkexpr(result));
8654 
8655    return "slbr";
8656 }
8657 
8658 static const HChar *
s390_irgen_SLBGR(UChar r1,UChar r2)8659 s390_irgen_SLBGR(UChar r1, UChar r2)
8660 {
8661    IRTemp op1 = newTemp(Ity_I64);
8662    IRTemp op2 = newTemp(Ity_I64);
8663    IRTemp result = newTemp(Ity_I64);
8664    IRTemp borrow_in = newTemp(Ity_I64);
8665 
8666    assign(op1, get_gpr_dw0(r1));
8667    assign(op2, get_gpr_dw0(r2));
8668    assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8669           binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8670    assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8671           mkexpr(borrow_in)));
8672    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8673    put_gpr_dw0(r1, mkexpr(result));
8674 
8675    return "slbgr";
8676 }
8677 
8678 static const HChar *
s390_irgen_SLB(UChar r1,IRTemp op2addr)8679 s390_irgen_SLB(UChar r1, IRTemp op2addr)
8680 {
8681    IRTemp op1 = newTemp(Ity_I32);
8682    IRTemp op2 = newTemp(Ity_I32);
8683    IRTemp result = newTemp(Ity_I32);
8684    IRTemp borrow_in = newTemp(Ity_I32);
8685 
8686    assign(op1, get_gpr_w1(r1));
8687    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8688    assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8689           s390_call_calculate_cc(), mkU8(1))));
8690    assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8691           mkexpr(borrow_in)));
8692    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8693    put_gpr_w1(r1, mkexpr(result));
8694 
8695    return "slb";
8696 }
8697 
8698 static const HChar *
s390_irgen_SLBG(UChar r1,IRTemp op2addr)8699 s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8700 {
8701    IRTemp op1 = newTemp(Ity_I64);
8702    IRTemp op2 = newTemp(Ity_I64);
8703    IRTemp result = newTemp(Ity_I64);
8704    IRTemp borrow_in = newTemp(Ity_I64);
8705 
8706    assign(op1, get_gpr_dw0(r1));
8707    assign(op2, load(Ity_I64, mkexpr(op2addr)));
8708    assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8709           binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8710    assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8711           mkexpr(borrow_in)));
8712    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8713    put_gpr_dw0(r1, mkexpr(result));
8714 
8715    return "slbg";
8716 }
8717 
8718 static const HChar *
s390_irgen_SVC(UChar i)8719 s390_irgen_SVC(UChar i)
8720 {
8721    IRTemp sysno = newTemp(Ity_I64);
8722 
8723    if (i != 0) {
8724       assign(sysno, mkU64(i));
8725    } else {
8726       assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8727    }
8728    system_call(mkexpr(sysno));
8729 
8730    return "svc";
8731 }
8732 
8733 static const HChar *
s390_irgen_TM(UChar i2,IRTemp op1addr)8734 s390_irgen_TM(UChar i2, IRTemp op1addr)
8735 {
8736    UChar mask;
8737    IRTemp value = newTemp(Ity_I8);
8738 
8739    mask = i2;
8740    assign(value, load(Ity_I8, mkexpr(op1addr)));
8741    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8742                        mkU8(mask)));
8743 
8744    return "tm";
8745 }
8746 
8747 static const HChar *
s390_irgen_TMY(UChar i2,IRTemp op1addr)8748 s390_irgen_TMY(UChar i2, IRTemp op1addr)
8749 {
8750    UChar mask;
8751    IRTemp value = newTemp(Ity_I8);
8752 
8753    mask = i2;
8754    assign(value, load(Ity_I8, mkexpr(op1addr)));
8755    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8756                        mkU8(mask)));
8757 
8758    return "tmy";
8759 }
8760 
8761 static const HChar *
s390_irgen_TMHH(UChar r1,UShort i2)8762 s390_irgen_TMHH(UChar r1, UShort i2)
8763 {
8764    UShort mask;
8765    IRTemp value = newTemp(Ity_I16);
8766 
8767    mask = i2;
8768    assign(value, get_gpr_hw0(r1));
8769    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8770                        mkU16(mask)));
8771 
8772    return "tmhh";
8773 }
8774 
8775 static const HChar *
s390_irgen_TMHL(UChar r1,UShort i2)8776 s390_irgen_TMHL(UChar r1, UShort i2)
8777 {
8778    UShort mask;
8779    IRTemp value = newTemp(Ity_I16);
8780 
8781    mask = i2;
8782    assign(value, get_gpr_hw1(r1));
8783    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8784                        mkU16(mask)));
8785 
8786    return "tmhl";
8787 }
8788 
8789 static const HChar *
s390_irgen_TMLH(UChar r1,UShort i2)8790 s390_irgen_TMLH(UChar r1, UShort i2)
8791 {
8792    UShort mask;
8793    IRTemp value = newTemp(Ity_I16);
8794 
8795    mask = i2;
8796    assign(value, get_gpr_hw2(r1));
8797    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8798                        mkU16(mask)));
8799 
8800    return "tmlh";
8801 }
8802 
8803 static const HChar *
s390_irgen_TMLL(UChar r1,UShort i2)8804 s390_irgen_TMLL(UChar r1, UShort i2)
8805 {
8806    UShort mask;
8807    IRTemp value = newTemp(Ity_I16);
8808 
8809    mask = i2;
8810    assign(value, get_gpr_hw3(r1));
8811    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8812                        mkU16(mask)));
8813 
8814    return "tmll";
8815 }
8816 
8817 static const HChar *
s390_irgen_EFPC(UChar r1)8818 s390_irgen_EFPC(UChar r1)
8819 {
8820    put_gpr_w1(r1, get_fpc_w0());
8821 
8822    return "efpc";
8823 }
8824 
8825 static const HChar *
s390_irgen_LER(UChar r1,UChar r2)8826 s390_irgen_LER(UChar r1, UChar r2)
8827 {
8828    put_fpr_w0(r1, get_fpr_w0(r2));
8829 
8830    return "ler";
8831 }
8832 
8833 static const HChar *
s390_irgen_LDR(UChar r1,UChar r2)8834 s390_irgen_LDR(UChar r1, UChar r2)
8835 {
8836    put_fpr_dw0(r1, get_fpr_dw0(r2));
8837 
8838    return "ldr";
8839 }
8840 
8841 static const HChar *
s390_irgen_LDER(UChar r1,UChar r2)8842 s390_irgen_LDER(UChar r1, UChar r2)
8843 {
8844    put_fpr_dw0(r1, mkF64i(0x0));
8845    put_fpr_w0(r1, get_fpr_w0(r2));
8846 
8847    return "lder";
8848 }
8849 
8850 static const HChar *
s390_irgen_LXR(UChar r1,UChar r2)8851 s390_irgen_LXR(UChar r1, UChar r2)
8852 {
8853    put_fpr_dw0(r1, get_fpr_dw0(r2));
8854    put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8855 
8856    return "lxr";
8857 }
8858 
8859 static const HChar *
s390_irgen_LE(UChar r1,IRTemp op2addr)8860 s390_irgen_LE(UChar r1, IRTemp op2addr)
8861 {
8862    put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8863 
8864    return "le";
8865 }
8866 
8867 static const HChar *
s390_irgen_LD(UChar r1,IRTemp op2addr)8868 s390_irgen_LD(UChar r1, IRTemp op2addr)
8869 {
8870    put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8871 
8872    return "ld";
8873 }
8874 
8875 static const HChar *
s390_irgen_LDE(UChar r1,IRTemp op2addr)8876 s390_irgen_LDE(UChar r1, IRTemp op2addr)
8877 {
8878    put_fpr_dw0(r1, mkF64i(0x0));
8879    put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8880 
8881    return "lde";
8882 }
8883 
8884 static const HChar *
s390_irgen_LEY(UChar r1,IRTemp op2addr)8885 s390_irgen_LEY(UChar r1, IRTemp op2addr)
8886 {
8887    put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8888 
8889    return "ley";
8890 }
8891 
8892 static const HChar *
s390_irgen_LDY(UChar r1,IRTemp op2addr)8893 s390_irgen_LDY(UChar r1, IRTemp op2addr)
8894 {
8895    put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8896 
8897    return "ldy";
8898 }
8899 
8900 static const HChar *
s390_irgen_LFPC(IRTemp op2addr)8901 s390_irgen_LFPC(IRTemp op2addr)
8902 {
8903    put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8904 
8905    return "lfpc";
8906 }
8907 
8908 static const HChar *
s390_irgen_LZER(UChar r1)8909 s390_irgen_LZER(UChar r1)
8910 {
8911    put_fpr_w0(r1, mkF32i(0x0));
8912 
8913    return "lzer";
8914 }
8915 
8916 static const HChar *
s390_irgen_LZDR(UChar r1)8917 s390_irgen_LZDR(UChar r1)
8918 {
8919    put_fpr_dw0(r1, mkF64i(0x0));
8920 
8921    return "lzdr";
8922 }
8923 
8924 static const HChar *
s390_irgen_LZXR(UChar r1)8925 s390_irgen_LZXR(UChar r1)
8926 {
8927    put_fpr_dw0(r1, mkF64i(0x0));
8928    put_fpr_dw0(r1 + 2, mkF64i(0x0));
8929 
8930    return "lzxr";
8931 }
8932 
8933 static const HChar *
s390_irgen_SRNM(IRTemp op2addr)8934 s390_irgen_SRNM(IRTemp op2addr)
8935 {
8936    UInt input_mask, fpc_mask;
8937 
8938    input_mask = 3;
8939    fpc_mask = s390_host_has_fpext ? 7 : 3;
8940 
8941    put_fpc_w0(binop(Iop_Or32,
8942                     binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8943                     binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8944                           mkU32(input_mask))));
8945    return "srnm";
8946 }
8947 
8948 static const HChar *
s390_irgen_SRNMB(IRTemp op2addr)8949 s390_irgen_SRNMB(IRTemp op2addr)
8950 {
8951    UInt input_mask, fpc_mask;
8952 
8953    input_mask = 7;
8954    fpc_mask = 7;
8955 
8956    put_fpc_w0(binop(Iop_Or32,
8957                     binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8958                     binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8959                           mkU32(input_mask))));
8960    return "srnmb";
8961 }
8962 
8963 static void
s390_irgen_srnmb_wrapper(UChar b2,UShort d2)8964 s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8965 {
8966    if (b2 == 0) {  /* This is the typical case */
8967       if (d2 > 3) {
8968          if (s390_host_has_fpext && d2 == 7) {
8969             /* ok */
8970          } else {
8971             emulation_warning(EmWarn_S390X_invalid_rounding);
8972             d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
8973          }
8974       }
8975    }
8976 
8977    s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8978 }
8979 
8980 /* Wrapper to validate the parameter as in SRNMB is not required, as all
8981    the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8982 static const HChar *
s390_irgen_SRNMT(IRTemp op2addr)8983 s390_irgen_SRNMT(IRTemp op2addr)
8984 {
8985    UInt input_mask, fpc_mask;
8986 
8987    input_mask = 7;
8988    fpc_mask = 0x70;
8989 
8990    /* fpc[25:27] <- op2addr[61:63]
8991       fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8992    put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8993                     binop(Iop_Shl32, binop(Iop_And32,
8994                                            unop(Iop_64to32, mkexpr(op2addr)),
8995                                            mkU32(input_mask)), mkU8(4))));
8996    return "srnmt";
8997 }
8998 
8999 
9000 static const HChar *
s390_irgen_SFPC(UChar r1)9001 s390_irgen_SFPC(UChar r1)
9002 {
9003    put_fpc_w0(get_gpr_w1(r1));
9004 
9005    return "sfpc";
9006 }
9007 
9008 static const HChar *
s390_irgen_STE(UChar r1,IRTemp op2addr)9009 s390_irgen_STE(UChar r1, IRTemp op2addr)
9010 {
9011    store(mkexpr(op2addr), get_fpr_w0(r1));
9012 
9013    return "ste";
9014 }
9015 
9016 static const HChar *
s390_irgen_STD(UChar r1,IRTemp op2addr)9017 s390_irgen_STD(UChar r1, IRTemp op2addr)
9018 {
9019    store(mkexpr(op2addr), get_fpr_dw0(r1));
9020 
9021    return "std";
9022 }
9023 
9024 static const HChar *
s390_irgen_STEY(UChar r1,IRTemp op2addr)9025 s390_irgen_STEY(UChar r1, IRTemp op2addr)
9026 {
9027    store(mkexpr(op2addr), get_fpr_w0(r1));
9028 
9029    return "stey";
9030 }
9031 
9032 static const HChar *
s390_irgen_STDY(UChar r1,IRTemp op2addr)9033 s390_irgen_STDY(UChar r1, IRTemp op2addr)
9034 {
9035    store(mkexpr(op2addr), get_fpr_dw0(r1));
9036 
9037    return "stdy";
9038 }
9039 
9040 static const HChar *
s390_irgen_STFPC(IRTemp op2addr)9041 s390_irgen_STFPC(IRTemp op2addr)
9042 {
9043    store(mkexpr(op2addr), get_fpc_w0());
9044 
9045    return "stfpc";
9046 }
9047 
9048 static const HChar *
s390_irgen_AEBR(UChar r1,UChar r2)9049 s390_irgen_AEBR(UChar r1, UChar r2)
9050 {
9051    IRTemp op1 = newTemp(Ity_F32);
9052    IRTemp op2 = newTemp(Ity_F32);
9053    IRTemp result = newTemp(Ity_F32);
9054    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9055 
9056    assign(op1, get_fpr_w0(r1));
9057    assign(op2, get_fpr_w0(r2));
9058    assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
9059           mkexpr(op2)));
9060    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9061    put_fpr_w0(r1, mkexpr(result));
9062 
9063    return "aebr";
9064 }
9065 
9066 static const HChar *
s390_irgen_ADBR(UChar r1,UChar r2)9067 s390_irgen_ADBR(UChar r1, UChar r2)
9068 {
9069    IRTemp op1 = newTemp(Ity_F64);
9070    IRTemp op2 = newTemp(Ity_F64);
9071    IRTemp result = newTemp(Ity_F64);
9072    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9073 
9074    assign(op1, get_fpr_dw0(r1));
9075    assign(op2, get_fpr_dw0(r2));
9076    assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
9077           mkexpr(op2)));
9078    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9079    put_fpr_dw0(r1, mkexpr(result));
9080 
9081    return "adbr";
9082 }
9083 
9084 static const HChar *
s390_irgen_AEB(UChar r1,IRTemp op2addr)9085 s390_irgen_AEB(UChar r1, IRTemp op2addr)
9086 {
9087    IRTemp op1 = newTemp(Ity_F32);
9088    IRTemp op2 = newTemp(Ity_F32);
9089    IRTemp result = newTemp(Ity_F32);
9090    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9091 
9092    assign(op1, get_fpr_w0(r1));
9093    assign(op2, load(Ity_F32, mkexpr(op2addr)));
9094    assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
9095           mkexpr(op2)));
9096    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9097    put_fpr_w0(r1, mkexpr(result));
9098 
9099    return "aeb";
9100 }
9101 
9102 static const HChar *
s390_irgen_ADB(UChar r1,IRTemp op2addr)9103 s390_irgen_ADB(UChar r1, IRTemp op2addr)
9104 {
9105    IRTemp op1 = newTemp(Ity_F64);
9106    IRTemp op2 = newTemp(Ity_F64);
9107    IRTemp result = newTemp(Ity_F64);
9108    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9109 
9110    assign(op1, get_fpr_dw0(r1));
9111    assign(op2, load(Ity_F64, mkexpr(op2addr)));
9112    assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
9113           mkexpr(op2)));
9114    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9115    put_fpr_dw0(r1, mkexpr(result));
9116 
9117    return "adb";
9118 }
9119 
9120 static const HChar *
s390_irgen_CEFBR(UChar m3,UChar m4,UChar r1,UChar r2)9121 s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
9122                  UChar r1, UChar r2)
9123 {
9124    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9125       emulation_warning(EmWarn_S390X_fpext_rounding);
9126       m3 = S390_BFP_ROUND_PER_FPC;
9127    }
9128    IRTemp op2 = newTemp(Ity_I32);
9129 
9130    assign(op2, get_gpr_w1(r2));
9131    put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9132                         mkexpr(op2)));
9133 
9134    return "cefbr";
9135 }
9136 
9137 static const HChar *
s390_irgen_CDFBR(UChar m3,UChar m4,UChar r1,UChar r2)9138 s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
9139                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9140 {
9141    IRTemp op2 = newTemp(Ity_I32);
9142 
9143    assign(op2, get_gpr_w1(r2));
9144    put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
9145 
9146    return "cdfbr";
9147 }
9148 
9149 static const HChar *
s390_irgen_CEGBR(UChar m3,UChar m4,UChar r1,UChar r2)9150 s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
9151                  UChar r1, UChar r2)
9152 {
9153    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9154       emulation_warning(EmWarn_S390X_fpext_rounding);
9155       m3 = S390_BFP_ROUND_PER_FPC;
9156    }
9157    IRTemp op2 = newTemp(Ity_I64);
9158 
9159    assign(op2, get_gpr_dw0(r2));
9160    put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9161                         mkexpr(op2)));
9162 
9163    return "cegbr";
9164 }
9165 
9166 static const HChar *
s390_irgen_CDGBR(UChar m3,UChar m4,UChar r1,UChar r2)9167 s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
9168                  UChar r1, UChar r2)
9169 {
9170    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9171       emulation_warning(EmWarn_S390X_fpext_rounding);
9172       m3 = S390_BFP_ROUND_PER_FPC;
9173    }
9174    IRTemp op2 = newTemp(Ity_I64);
9175 
9176    assign(op2, get_gpr_dw0(r2));
9177    put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
9178                          mkexpr(op2)));
9179 
9180    return "cdgbr";
9181 }
9182 
9183 static const HChar *
s390_irgen_CELFBR(UChar m3,UChar m4,UChar r1,UChar r2)9184 s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
9185                   UChar r1, UChar r2)
9186 {
9187    if (! s390_host_has_fpext) {
9188       emulation_failure(EmFail_S390X_fpext);
9189    } else {
9190       IRTemp op2 = newTemp(Ity_I32);
9191 
9192       assign(op2, get_gpr_w1(r2));
9193       put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9194                            mkexpr(op2)));
9195    }
9196    return "celfbr";
9197 }
9198 
9199 static const HChar *
s390_irgen_CDLFBR(UChar m3,UChar m4,UChar r1,UChar r2)9200 s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
9201                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9202 {
9203    if (! s390_host_has_fpext) {
9204       emulation_failure(EmFail_S390X_fpext);
9205    } else {
9206       IRTemp op2 = newTemp(Ity_I32);
9207 
9208       assign(op2, get_gpr_w1(r2));
9209       put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
9210    }
9211    return "cdlfbr";
9212 }
9213 
9214 static const HChar *
s390_irgen_CELGBR(UChar m3,UChar m4,UChar r1,UChar r2)9215 s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
9216                   UChar r1, UChar r2)
9217 {
9218    if (! s390_host_has_fpext) {
9219       emulation_failure(EmFail_S390X_fpext);
9220    } else {
9221       IRTemp op2 = newTemp(Ity_I64);
9222 
9223       assign(op2, get_gpr_dw0(r2));
9224       put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9225                            mkexpr(op2)));
9226    }
9227    return "celgbr";
9228 }
9229 
9230 static const HChar *
s390_irgen_CDLGBR(UChar m3,UChar m4,UChar r1,UChar r2)9231 s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
9232                   UChar r1, UChar r2)
9233 {
9234    if (! s390_host_has_fpext) {
9235       emulation_failure(EmFail_S390X_fpext);
9236    } else {
9237       IRTemp op2 = newTemp(Ity_I64);
9238 
9239       assign(op2, get_gpr_dw0(r2));
9240       put_fpr_dw0(r1, binop(Iop_I64UtoF64,
9241                             mkexpr(encode_bfp_rounding_mode(m3)),
9242                             mkexpr(op2)));
9243    }
9244    return "cdlgbr";
9245 }
9246 
9247 static const HChar *
s390_irgen_CLFEBR(UChar m3,UChar m4,UChar r1,UChar r2)9248 s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9249                   UChar r1, UChar r2)
9250 {
9251    if (! s390_host_has_fpext) {
9252       emulation_failure(EmFail_S390X_fpext);
9253    } else {
9254       IRTemp op = newTemp(Ity_F32);
9255       IRTemp result = newTemp(Ity_I32);
9256       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9257 
9258       assign(op, get_fpr_w0(r2));
9259       assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
9260                            mkexpr(op)));
9261       put_gpr_w1(r1, mkexpr(result));
9262       s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
9263    }
9264    return "clfebr";
9265 }
9266 
9267 static const HChar *
s390_irgen_CLFDBR(UChar m3,UChar m4,UChar r1,UChar r2)9268 s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9269                   UChar r1, UChar r2)
9270 {
9271    if (! s390_host_has_fpext) {
9272       emulation_failure(EmFail_S390X_fpext);
9273    } else {
9274       IRTemp op = newTemp(Ity_F64);
9275       IRTemp result = newTemp(Ity_I32);
9276       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9277 
9278       assign(op, get_fpr_dw0(r2));
9279       assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
9280                            mkexpr(op)));
9281       put_gpr_w1(r1, mkexpr(result));
9282       s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
9283    }
9284    return "clfdbr";
9285 }
9286 
9287 static const HChar *
s390_irgen_CLGEBR(UChar m3,UChar m4,UChar r1,UChar r2)9288 s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9289                   UChar r1, UChar r2)
9290 {
9291    if (! s390_host_has_fpext) {
9292       emulation_failure(EmFail_S390X_fpext);
9293    } else {
9294       IRTemp op = newTemp(Ity_F32);
9295       IRTemp result = newTemp(Ity_I64);
9296       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9297 
9298       assign(op, get_fpr_w0(r2));
9299       assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
9300                            mkexpr(op)));
9301       put_gpr_dw0(r1, mkexpr(result));
9302       s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
9303    }
9304    return "clgebr";
9305 }
9306 
9307 static const HChar *
s390_irgen_CLGDBR(UChar m3,UChar m4,UChar r1,UChar r2)9308 s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9309                   UChar r1, UChar r2)
9310 {
9311    if (! s390_host_has_fpext) {
9312       emulation_failure(EmFail_S390X_fpext);
9313    } else {
9314       IRTemp op = newTemp(Ity_F64);
9315       IRTemp result = newTemp(Ity_I64);
9316       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9317 
9318       assign(op, get_fpr_dw0(r2));
9319       assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
9320                            mkexpr(op)));
9321       put_gpr_dw0(r1, mkexpr(result));
9322       s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
9323    }
9324    return "clgdbr";
9325 }
9326 
9327 static const HChar *
s390_irgen_CFEBR(UChar m3,UChar m4,UChar r1,UChar r2)9328 s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9329                  UChar r1, UChar r2)
9330 {
9331    IRTemp op = newTemp(Ity_F32);
9332    IRTemp result = newTemp(Ity_I32);
9333    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9334 
9335    assign(op, get_fpr_w0(r2));
9336    assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
9337           mkexpr(op)));
9338    put_gpr_w1(r1, mkexpr(result));
9339    s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
9340 
9341    return "cfebr";
9342 }
9343 
9344 static const HChar *
s390_irgen_CFDBR(UChar m3,UChar m4,UChar r1,UChar r2)9345 s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9346                  UChar r1, UChar r2)
9347 {
9348    IRTemp op = newTemp(Ity_F64);
9349    IRTemp result = newTemp(Ity_I32);
9350    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9351 
9352    assign(op, get_fpr_dw0(r2));
9353    assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
9354           mkexpr(op)));
9355    put_gpr_w1(r1, mkexpr(result));
9356    s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
9357 
9358    return "cfdbr";
9359 }
9360 
9361 static const HChar *
s390_irgen_CGEBR(UChar m3,UChar m4,UChar r1,UChar r2)9362 s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9363                  UChar r1, UChar r2)
9364 {
9365    IRTemp op = newTemp(Ity_F32);
9366    IRTemp result = newTemp(Ity_I64);
9367    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9368 
9369    assign(op, get_fpr_w0(r2));
9370    assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
9371           mkexpr(op)));
9372    put_gpr_dw0(r1, mkexpr(result));
9373    s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
9374 
9375    return "cgebr";
9376 }
9377 
9378 static const HChar *
s390_irgen_CGDBR(UChar m3,UChar m4,UChar r1,UChar r2)9379 s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9380                  UChar r1, UChar r2)
9381 {
9382    IRTemp op = newTemp(Ity_F64);
9383    IRTemp result = newTemp(Ity_I64);
9384    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9385 
9386    assign(op, get_fpr_dw0(r2));
9387    assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
9388           mkexpr(op)));
9389    put_gpr_dw0(r1, mkexpr(result));
9390    s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
9391 
9392    return "cgdbr";
9393 }
9394 
9395 static const HChar *
s390_irgen_DEBR(UChar r1,UChar r2)9396 s390_irgen_DEBR(UChar r1, UChar r2)
9397 {
9398    IRTemp op1 = newTemp(Ity_F32);
9399    IRTemp op2 = newTemp(Ity_F32);
9400    IRTemp result = newTemp(Ity_F32);
9401    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9402 
9403    assign(op1, get_fpr_w0(r1));
9404    assign(op2, get_fpr_w0(r2));
9405    assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
9406           mkexpr(op2)));
9407    put_fpr_w0(r1, mkexpr(result));
9408 
9409    return "debr";
9410 }
9411 
9412 static const HChar *
s390_irgen_DDBR(UChar r1,UChar r2)9413 s390_irgen_DDBR(UChar r1, UChar r2)
9414 {
9415    IRTemp op1 = newTemp(Ity_F64);
9416    IRTemp op2 = newTemp(Ity_F64);
9417    IRTemp result = newTemp(Ity_F64);
9418    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9419 
9420    assign(op1, get_fpr_dw0(r1));
9421    assign(op2, get_fpr_dw0(r2));
9422    assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
9423           mkexpr(op2)));
9424    put_fpr_dw0(r1, mkexpr(result));
9425 
9426    return "ddbr";
9427 }
9428 
9429 static const HChar *
s390_irgen_DEB(UChar r1,IRTemp op2addr)9430 s390_irgen_DEB(UChar r1, IRTemp op2addr)
9431 {
9432    IRTemp op1 = newTemp(Ity_F32);
9433    IRTemp op2 = newTemp(Ity_F32);
9434    IRTemp result = newTemp(Ity_F32);
9435    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9436 
9437    assign(op1, get_fpr_w0(r1));
9438    assign(op2, load(Ity_F32, mkexpr(op2addr)));
9439    assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
9440           mkexpr(op2)));
9441    put_fpr_w0(r1, mkexpr(result));
9442 
9443    return "deb";
9444 }
9445 
9446 static const HChar *
s390_irgen_DDB(UChar r1,IRTemp op2addr)9447 s390_irgen_DDB(UChar r1, IRTemp op2addr)
9448 {
9449    IRTemp op1 = newTemp(Ity_F64);
9450    IRTemp op2 = newTemp(Ity_F64);
9451    IRTemp result = newTemp(Ity_F64);
9452    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9453 
9454    assign(op1, get_fpr_dw0(r1));
9455    assign(op2, load(Ity_F64, mkexpr(op2addr)));
9456    assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
9457           mkexpr(op2)));
9458    put_fpr_dw0(r1, mkexpr(result));
9459 
9460    return "ddb";
9461 }
9462 
9463 static const HChar *
s390_irgen_LTEBR(UChar r1,UChar r2)9464 s390_irgen_LTEBR(UChar r1, UChar r2)
9465 {
9466    IRTemp result = newTemp(Ity_F32);
9467 
9468    assign(result, get_fpr_w0(r2));
9469    put_fpr_w0(r1, mkexpr(result));
9470    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9471 
9472    return "ltebr";
9473 }
9474 
9475 static const HChar *
s390_irgen_LTDBR(UChar r1,UChar r2)9476 s390_irgen_LTDBR(UChar r1, UChar r2)
9477 {
9478    IRTemp result = newTemp(Ity_F64);
9479 
9480    assign(result, get_fpr_dw0(r2));
9481    put_fpr_dw0(r1, mkexpr(result));
9482    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9483 
9484    return "ltdbr";
9485 }
9486 
9487 static const HChar *
s390_irgen_LCEBR(UChar r1,UChar r2)9488 s390_irgen_LCEBR(UChar r1, UChar r2)
9489 {
9490    IRTemp result = newTemp(Ity_F32);
9491 
9492    assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9493    put_fpr_w0(r1, mkexpr(result));
9494    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9495 
9496    return "lcebr";
9497 }
9498 
9499 static const HChar *
s390_irgen_LCDBR(UChar r1,UChar r2)9500 s390_irgen_LCDBR(UChar r1, UChar r2)
9501 {
9502    IRTemp result = newTemp(Ity_F64);
9503 
9504    assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9505    put_fpr_dw0(r1, mkexpr(result));
9506    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9507 
9508    return "lcdbr";
9509 }
9510 
9511 static const HChar *
s390_irgen_LDEBR(UChar r1,UChar r2)9512 s390_irgen_LDEBR(UChar r1, UChar r2)
9513 {
9514    IRTemp op = newTemp(Ity_F32);
9515 
9516    assign(op, get_fpr_w0(r2));
9517    put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9518 
9519    return "ldebr";
9520 }
9521 
9522 static const HChar *
s390_irgen_LDEB(UChar r1,IRTemp op2addr)9523 s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9524 {
9525    IRTemp op = newTemp(Ity_F32);
9526 
9527    assign(op, load(Ity_F32, mkexpr(op2addr)));
9528    put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9529 
9530    return "ldeb";
9531 }
9532 
9533 static const HChar *
s390_irgen_LEDBR(UChar m3,UChar m4,UChar r1,UChar r2)9534 s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9535                  UChar r1, UChar r2)
9536 {
9537    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9538       emulation_warning(EmWarn_S390X_fpext_rounding);
9539       m3 = S390_BFP_ROUND_PER_FPC;
9540    }
9541    IRTemp op = newTemp(Ity_F64);
9542 
9543    assign(op, get_fpr_dw0(r2));
9544    put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
9545                         mkexpr(op)));
9546 
9547    return "ledbr";
9548 }
9549 
9550 static const HChar *
s390_irgen_MEEBR(UChar r1,UChar r2)9551 s390_irgen_MEEBR(UChar r1, UChar r2)
9552 {
9553    IRTemp op1 = newTemp(Ity_F32);
9554    IRTemp op2 = newTemp(Ity_F32);
9555    IRTemp result = newTemp(Ity_F32);
9556    IRRoundingMode rounding_mode =
9557       encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9558 
9559    assign(op1, get_fpr_w0(r1));
9560    assign(op2, get_fpr_w0(r2));
9561    assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
9562           mkexpr(op2)));
9563    put_fpr_w0(r1, mkexpr(result));
9564 
9565    return "meebr";
9566 }
9567 
9568 static const HChar *
s390_irgen_MDBR(UChar r1,UChar r2)9569 s390_irgen_MDBR(UChar r1, UChar r2)
9570 {
9571    IRTemp op1 = newTemp(Ity_F64);
9572    IRTemp op2 = newTemp(Ity_F64);
9573    IRTemp result = newTemp(Ity_F64);
9574    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9575 
9576    assign(op1, get_fpr_dw0(r1));
9577    assign(op2, get_fpr_dw0(r2));
9578    assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
9579           mkexpr(op2)));
9580    put_fpr_dw0(r1, mkexpr(result));
9581 
9582    return "mdbr";
9583 }
9584 
9585 static const HChar *
s390_irgen_MEEB(UChar r1,IRTemp op2addr)9586 s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9587 {
9588    IRTemp op1 = newTemp(Ity_F32);
9589    IRTemp op2 = newTemp(Ity_F32);
9590    IRTemp result = newTemp(Ity_F32);
9591    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9592 
9593    assign(op1, get_fpr_w0(r1));
9594    assign(op2, load(Ity_F32, mkexpr(op2addr)));
9595    assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
9596           mkexpr(op2)));
9597    put_fpr_w0(r1, mkexpr(result));
9598 
9599    return "meeb";
9600 }
9601 
9602 static const HChar *
s390_irgen_MDB(UChar r1,IRTemp op2addr)9603 s390_irgen_MDB(UChar r1, IRTemp op2addr)
9604 {
9605    IRTemp op1 = newTemp(Ity_F64);
9606    IRTemp op2 = newTemp(Ity_F64);
9607    IRTemp result = newTemp(Ity_F64);
9608    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9609 
9610    assign(op1, get_fpr_dw0(r1));
9611    assign(op2, load(Ity_F64, mkexpr(op2addr)));
9612    assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
9613           mkexpr(op2)));
9614    put_fpr_dw0(r1, mkexpr(result));
9615 
9616    return "mdb";
9617 }
9618 
9619 static const HChar *
s390_irgen_SEBR(UChar r1,UChar r2)9620 s390_irgen_SEBR(UChar r1, UChar r2)
9621 {
9622    IRTemp op1 = newTemp(Ity_F32);
9623    IRTemp op2 = newTemp(Ity_F32);
9624    IRTemp result = newTemp(Ity_F32);
9625    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9626 
9627    assign(op1, get_fpr_w0(r1));
9628    assign(op2, get_fpr_w0(r2));
9629    assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
9630           mkexpr(op2)));
9631    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9632    put_fpr_w0(r1, mkexpr(result));
9633 
9634    return "sebr";
9635 }
9636 
9637 static const HChar *
s390_irgen_SDBR(UChar r1,UChar r2)9638 s390_irgen_SDBR(UChar r1, UChar r2)
9639 {
9640    IRTemp op1 = newTemp(Ity_F64);
9641    IRTemp op2 = newTemp(Ity_F64);
9642    IRTemp result = newTemp(Ity_F64);
9643    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9644 
9645    assign(op1, get_fpr_dw0(r1));
9646    assign(op2, get_fpr_dw0(r2));
9647    assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
9648           mkexpr(op2)));
9649    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9650    put_fpr_dw0(r1, mkexpr(result));
9651 
9652    return "sdbr";
9653 }
9654 
9655 static const HChar *
s390_irgen_SEB(UChar r1,IRTemp op2addr)9656 s390_irgen_SEB(UChar r1, IRTemp op2addr)
9657 {
9658    IRTemp op1 = newTemp(Ity_F32);
9659    IRTemp op2 = newTemp(Ity_F32);
9660    IRTemp result = newTemp(Ity_F32);
9661    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9662 
9663    assign(op1, get_fpr_w0(r1));
9664    assign(op2, load(Ity_F32, mkexpr(op2addr)));
9665    assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
9666           mkexpr(op2)));
9667    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9668    put_fpr_w0(r1, mkexpr(result));
9669 
9670    return "seb";
9671 }
9672 
9673 static const HChar *
s390_irgen_SDB(UChar r1,IRTemp op2addr)9674 s390_irgen_SDB(UChar r1, IRTemp op2addr)
9675 {
9676    IRTemp op1 = newTemp(Ity_F64);
9677    IRTemp op2 = newTemp(Ity_F64);
9678    IRTemp result = newTemp(Ity_F64);
9679    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9680 
9681    assign(op1, get_fpr_dw0(r1));
9682    assign(op2, load(Ity_F64, mkexpr(op2addr)));
9683    assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
9684           mkexpr(op2)));
9685    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9686    put_fpr_dw0(r1, mkexpr(result));
9687 
9688    return "sdb";
9689 }
9690 
9691 static const HChar *
s390_irgen_ADTRA(UChar r3,UChar m4,UChar r1,UChar r2)9692 s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9693 {
9694    if (! s390_host_has_dfp) {
9695       emulation_failure(EmFail_S390X_DFP_insn);
9696    } else {
9697       IRTemp op1 = newTemp(Ity_D64);
9698       IRTemp op2 = newTemp(Ity_D64);
9699       IRTemp result = newTemp(Ity_D64);
9700       IRTemp rounding_mode;
9701 
9702       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9703          emulation_warning(EmWarn_S390X_fpext_rounding);
9704          m4 = S390_DFP_ROUND_PER_FPC_0;
9705       }
9706 
9707       rounding_mode = encode_dfp_rounding_mode(m4);
9708       assign(op1, get_dpr_dw0(r2));
9709       assign(op2, get_dpr_dw0(r3));
9710       assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9711                            mkexpr(op2)));
9712       s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9713       put_dpr_dw0(r1, mkexpr(result));
9714    }
9715    return (m4 == 0) ? "adtr" : "adtra";
9716 }
9717 
9718 static const HChar *
s390_irgen_AXTRA(UChar r3,UChar m4,UChar r1,UChar r2)9719 s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9720 {
9721    if (! s390_host_has_dfp) {
9722       emulation_failure(EmFail_S390X_DFP_insn);
9723    } else {
9724       IRTemp op1 = newTemp(Ity_D128);
9725       IRTemp op2 = newTemp(Ity_D128);
9726       IRTemp result = newTemp(Ity_D128);
9727       IRTemp rounding_mode;
9728 
9729       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9730          emulation_warning(EmWarn_S390X_fpext_rounding);
9731          m4 = S390_DFP_ROUND_PER_FPC_0;
9732       }
9733 
9734       rounding_mode = encode_dfp_rounding_mode(m4);
9735       assign(op1, get_dpr_pair(r2));
9736       assign(op2, get_dpr_pair(r3));
9737       assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9738                            mkexpr(op2)));
9739       put_dpr_pair(r1, mkexpr(result));
9740 
9741       s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9742    }
9743    return (m4 == 0) ? "axtr" : "axtra";
9744 }
9745 
9746 static const HChar *
s390_irgen_CDTR(UChar r1,UChar r2)9747 s390_irgen_CDTR(UChar r1, UChar r2)
9748 {
9749    IRTemp op1 = newTemp(Ity_D64);
9750    IRTemp op2 = newTemp(Ity_D64);
9751    IRTemp cc_vex  = newTemp(Ity_I32);
9752    IRTemp cc_s390 = newTemp(Ity_I32);
9753 
9754    assign(op1, get_dpr_dw0(r1));
9755    assign(op2, get_dpr_dw0(r2));
9756    assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9757 
9758    assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9759    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9760 
9761    return "cdtr";
9762 }
9763 
9764 static const HChar *
s390_irgen_CXTR(UChar r1,UChar r2)9765 s390_irgen_CXTR(UChar r1, UChar r2)
9766 {
9767    IRTemp op1 = newTemp(Ity_D128);
9768    IRTemp op2 = newTemp(Ity_D128);
9769    IRTemp cc_vex  = newTemp(Ity_I32);
9770    IRTemp cc_s390 = newTemp(Ity_I32);
9771 
9772    assign(op1, get_dpr_pair(r1));
9773    assign(op2, get_dpr_pair(r2));
9774    assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9775 
9776    assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9777    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9778 
9779    return "cxtr";
9780 }
9781 
9782 static const HChar *
s390_irgen_CDFTR(UChar m3,UChar m4,UChar r1,UChar r2)9783 s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9784                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9785 {
9786    if (! s390_host_has_dfp) {
9787       emulation_failure(EmFail_S390X_DFP_insn);
9788    } else {
9789       if (! s390_host_has_fpext) {
9790          emulation_failure(EmFail_S390X_fpext);
9791       } else {
9792          IRTemp op2 = newTemp(Ity_I32);
9793 
9794          assign(op2, get_gpr_w1(r2));
9795          put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9796       }
9797    }
9798    return "cdftr";
9799 }
9800 
9801 static const HChar *
s390_irgen_CXFTR(UChar m3,UChar m4,UChar r1,UChar r2)9802 s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9803                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9804 {
9805    if (! s390_host_has_dfp) {
9806       emulation_failure(EmFail_S390X_DFP_insn);
9807    } else {
9808       if (! s390_host_has_fpext) {
9809          emulation_failure(EmFail_S390X_fpext);
9810       } else {
9811          IRTemp op2 = newTemp(Ity_I32);
9812 
9813          assign(op2, get_gpr_w1(r2));
9814          put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9815       }
9816    }
9817    return "cxftr";
9818 }
9819 
9820 static const HChar *
s390_irgen_CDGTRA(UChar m3,UChar m4,UChar r1,UChar r2)9821 s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9822                   UChar r1, UChar r2)
9823 {
9824    if (! s390_host_has_dfp) {
9825       emulation_failure(EmFail_S390X_DFP_insn);
9826    } else {
9827       IRTemp op2 = newTemp(Ity_I64);
9828 
9829       if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9830          emulation_warning(EmWarn_S390X_fpext_rounding);
9831          m3 = S390_DFP_ROUND_PER_FPC_0;
9832       }
9833 
9834       assign(op2, get_gpr_dw0(r2));
9835       put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9836                             mkexpr(op2)));
9837    }
9838    return (m3 == 0) ? "cdgtr" : "cdgtra";
9839 }
9840 
9841 static const HChar *
s390_irgen_CXGTR(UChar m3,UChar m4,UChar r1,UChar r2)9842 s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9843                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9844 {
9845    if (! s390_host_has_dfp) {
9846       emulation_failure(EmFail_S390X_DFP_insn);
9847    } else {
9848       IRTemp op2 = newTemp(Ity_I64);
9849 
9850       /* No emulation warning here about an non-zero m3 on hosts without
9851          floating point extension facility. No rounding is performed */
9852 
9853       assign(op2, get_gpr_dw0(r2));
9854       put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9855    }
9856    return "cxgtr";
9857 }
9858 
9859 static const HChar *
s390_irgen_CDLFTR(UChar m3,UChar m4,UChar r1,UChar r2)9860 s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9861                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9862 {
9863    if (! s390_host_has_dfp) {
9864       emulation_failure(EmFail_S390X_DFP_insn);
9865    } else {
9866       if (! s390_host_has_fpext) {
9867          emulation_failure(EmFail_S390X_fpext);
9868       } else {
9869          IRTemp op2 = newTemp(Ity_I32);
9870 
9871          assign(op2, get_gpr_w1(r2));
9872          put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9873       }
9874    }
9875    return "cdlftr";
9876 }
9877 
9878 static const HChar *
s390_irgen_CXLFTR(UChar m3,UChar m4,UChar r1,UChar r2)9879 s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9880                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9881 {
9882    if (! s390_host_has_dfp) {
9883       emulation_failure(EmFail_S390X_DFP_insn);
9884    } else {
9885       if (! s390_host_has_fpext) {
9886          emulation_failure(EmFail_S390X_fpext);
9887       } else {
9888          IRTemp op2 = newTemp(Ity_I32);
9889 
9890          assign(op2, get_gpr_w1(r2));
9891          put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9892       }
9893    }
9894    return "cxlftr";
9895 }
9896 
9897 static const HChar *
s390_irgen_CDLGTR(UChar m3,UChar m4,UChar r1,UChar r2)9898 s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9899                   UChar r1, UChar r2)
9900 {
9901    if (! s390_host_has_dfp) {
9902       emulation_failure(EmFail_S390X_DFP_insn);
9903    } else {
9904       if (! s390_host_has_fpext) {
9905          emulation_failure(EmFail_S390X_fpext);
9906       } else {
9907          IRTemp op2 = newTemp(Ity_I64);
9908 
9909          assign(op2, get_gpr_dw0(r2));
9910          put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9911                                mkexpr(encode_dfp_rounding_mode(m3)),
9912                                mkexpr(op2)));
9913       }
9914    }
9915    return "cdlgtr";
9916 }
9917 
9918 static const HChar *
s390_irgen_CXLGTR(UChar m3,UChar m4,UChar r1,UChar r2)9919 s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9920                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9921 {
9922    if (! s390_host_has_dfp) {
9923       emulation_failure(EmFail_S390X_DFP_insn);
9924    } else {
9925       if (! s390_host_has_fpext) {
9926          emulation_failure(EmFail_S390X_fpext);
9927       } else {
9928          IRTemp op2 = newTemp(Ity_I64);
9929 
9930          assign(op2, get_gpr_dw0(r2));
9931          put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9932       }
9933    }
9934    return "cxlgtr";
9935 }
9936 
9937 static const HChar *
s390_irgen_CFDTR(UChar m3,UChar m4,UChar r1,UChar r2)9938 s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9939                  UChar r1, UChar r2)
9940 {
9941    if (! s390_host_has_dfp) {
9942       emulation_failure(EmFail_S390X_DFP_insn);
9943    } else {
9944       if (! s390_host_has_fpext) {
9945          emulation_failure(EmFail_S390X_fpext);
9946       } else {
9947          IRTemp op = newTemp(Ity_D64);
9948          IRTemp result = newTemp(Ity_I32);
9949          IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9950 
9951          assign(op, get_dpr_dw0(r2));
9952          assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9953                               mkexpr(op)));
9954          put_gpr_w1(r1, mkexpr(result));
9955          s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9956       }
9957    }
9958    return "cfdtr";
9959 }
9960 
9961 static const HChar *
s390_irgen_CFXTR(UChar m3,UChar m4,UChar r1,UChar r2)9962 s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9963                  UChar r1, UChar r2)
9964 {
9965    if (! s390_host_has_dfp) {
9966       emulation_failure(EmFail_S390X_DFP_insn);
9967    } else {
9968       if (! s390_host_has_fpext) {
9969          emulation_failure(EmFail_S390X_fpext);
9970       } else {
9971          IRTemp op = newTemp(Ity_D128);
9972          IRTemp result = newTemp(Ity_I32);
9973          IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9974 
9975          assign(op, get_dpr_pair(r2));
9976          assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9977                               mkexpr(op)));
9978          put_gpr_w1(r1, mkexpr(result));
9979          s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op,
9980                                  rounding_mode);
9981       }
9982    }
9983    return "cfxtr";
9984 }
9985 
9986 static const HChar *
s390_irgen_CGDTR(UChar m3,UChar m4,UChar r1,UChar r2)9987 s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9988                  UChar r1, UChar r2)
9989 {
9990    if (! s390_host_has_dfp) {
9991       emulation_failure(EmFail_S390X_DFP_insn);
9992    } else {
9993       IRTemp op = newTemp(Ity_D64);
9994       IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9995 
9996       /* If fpext is not installed and m3 is in 1:7,
9997          rounding mode performed is unpredictable */
9998       if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9999          emulation_warning(EmWarn_S390X_fpext_rounding);
10000          m3 = S390_DFP_ROUND_PER_FPC_0;
10001       }
10002 
10003       assign(op, get_dpr_dw0(r2));
10004       put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
10005       s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
10006    }
10007    return "cgdtr";
10008 }
10009 
10010 static const HChar *
s390_irgen_CGXTR(UChar m3,UChar m4,UChar r1,UChar r2)10011 s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
10012                  UChar r1, UChar r2)
10013 {
10014    if (! s390_host_has_dfp) {
10015       emulation_failure(EmFail_S390X_DFP_insn);
10016    } else {
10017       IRTemp op = newTemp(Ity_D128);
10018       IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10019 
10020       /* If fpext is not installed and m3 is in 1:7,
10021          rounding mode performed is unpredictable */
10022       if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10023          emulation_warning(EmWarn_S390X_fpext_rounding);
10024          m3 = S390_DFP_ROUND_PER_FPC_0;
10025       }
10026       assign(op, get_dpr_pair(r2));
10027       put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
10028       s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
10029    }
10030    return "cgxtr";
10031 }
10032 
10033 static const HChar *
s390_irgen_CEDTR(UChar r1,UChar r2)10034 s390_irgen_CEDTR(UChar r1, UChar r2)
10035 {
10036    if (! s390_host_has_dfp) {
10037       emulation_failure(EmFail_S390X_DFP_insn);
10038    } else {
10039       IRTemp op1 = newTemp(Ity_D64);
10040       IRTemp op2 = newTemp(Ity_D64);
10041       IRTemp cc_vex  = newTemp(Ity_I32);
10042       IRTemp cc_s390 = newTemp(Ity_I32);
10043 
10044       assign(op1, get_dpr_dw0(r1));
10045       assign(op2, get_dpr_dw0(r2));
10046       assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
10047 
10048       assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
10049       s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10050    }
10051    return "cedtr";
10052 }
10053 
10054 static const HChar *
s390_irgen_CEXTR(UChar r1,UChar r2)10055 s390_irgen_CEXTR(UChar r1, UChar r2)
10056 {
10057    if (! s390_host_has_dfp) {
10058       emulation_failure(EmFail_S390X_DFP_insn);
10059    } else {
10060       IRTemp op1 = newTemp(Ity_D128);
10061       IRTemp op2 = newTemp(Ity_D128);
10062       IRTemp cc_vex  = newTemp(Ity_I32);
10063       IRTemp cc_s390 = newTemp(Ity_I32);
10064 
10065       assign(op1, get_dpr_pair(r1));
10066       assign(op2, get_dpr_pair(r2));
10067       assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
10068 
10069       assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
10070       s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10071    }
10072    return "cextr";
10073 }
10074 
10075 static const HChar *
s390_irgen_CLFDTR(UChar m3,UChar m4,UChar r1,UChar r2)10076 s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
10077                   UChar r1, UChar r2)
10078 {
10079    if (! s390_host_has_dfp) {
10080       emulation_failure(EmFail_S390X_DFP_insn);
10081    } else {
10082       if (! s390_host_has_fpext) {
10083          emulation_failure(EmFail_S390X_fpext);
10084       } else {
10085          IRTemp op = newTemp(Ity_D64);
10086          IRTemp result = newTemp(Ity_I32);
10087          IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10088 
10089          assign(op, get_dpr_dw0(r2));
10090          assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
10091                               mkexpr(op)));
10092          put_gpr_w1(r1, mkexpr(result));
10093          s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
10094       }
10095    }
10096    return "clfdtr";
10097 }
10098 
10099 static const HChar *
s390_irgen_CLFXTR(UChar m3,UChar m4,UChar r1,UChar r2)10100 s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
10101                   UChar r1, UChar r2)
10102 {
10103    if (! s390_host_has_dfp) {
10104       emulation_failure(EmFail_S390X_DFP_insn);
10105    } else {
10106       if (! s390_host_has_fpext) {
10107          emulation_failure(EmFail_S390X_fpext);
10108       } else {
10109          IRTemp op = newTemp(Ity_D128);
10110          IRTemp result = newTemp(Ity_I32);
10111          IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10112 
10113          assign(op, get_dpr_pair(r2));
10114          assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
10115                               mkexpr(op)));
10116          put_gpr_w1(r1, mkexpr(result));
10117          s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op,
10118                                  rounding_mode);
10119       }
10120    }
10121    return "clfxtr";
10122 }
10123 
10124 static const HChar *
s390_irgen_CLGDTR(UChar m3,UChar m4,UChar r1,UChar r2)10125 s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
10126                   UChar r1, UChar r2)
10127 {
10128    if (! s390_host_has_dfp) {
10129       emulation_failure(EmFail_S390X_DFP_insn);
10130    } else {
10131       if (! s390_host_has_fpext) {
10132          emulation_failure(EmFail_S390X_fpext);
10133       } else {
10134          IRTemp op = newTemp(Ity_D64);
10135          IRTemp result = newTemp(Ity_I64);
10136          IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10137 
10138          assign(op, get_dpr_dw0(r2));
10139          assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
10140                               mkexpr(op)));
10141          put_gpr_dw0(r1, mkexpr(result));
10142          s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
10143       }
10144    }
10145    return "clgdtr";
10146 }
10147 
10148 static const HChar *
s390_irgen_CLGXTR(UChar m3,UChar m4,UChar r1,UChar r2)10149 s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
10150                   UChar r1, UChar r2)
10151 {
10152    if (! s390_host_has_dfp) {
10153       emulation_failure(EmFail_S390X_DFP_insn);
10154    } else {
10155       if (! s390_host_has_fpext) {
10156          emulation_failure(EmFail_S390X_fpext);
10157       } else {
10158          IRTemp op = newTemp(Ity_D128);
10159          IRTemp result = newTemp(Ity_I64);
10160          IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10161 
10162          assign(op, get_dpr_pair(r2));
10163          assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
10164                               mkexpr(op)));
10165          put_gpr_dw0(r1, mkexpr(result));
10166          s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
10167                                  rounding_mode);
10168       }
10169    }
10170    return "clgxtr";
10171 }
10172 
10173 static const HChar *
s390_irgen_DDTRA(UChar r3,UChar m4,UChar r1,UChar r2)10174 s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10175 {
10176    if (! s390_host_has_dfp) {
10177       emulation_failure(EmFail_S390X_DFP_insn);
10178    } else {
10179       IRTemp op1 = newTemp(Ity_D64);
10180       IRTemp op2 = newTemp(Ity_D64);
10181       IRTemp result = newTemp(Ity_D64);
10182       IRTemp rounding_mode;
10183 
10184       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10185          emulation_warning(EmWarn_S390X_fpext_rounding);
10186          m4 = S390_DFP_ROUND_PER_FPC_0;
10187       }
10188 
10189       rounding_mode = encode_dfp_rounding_mode(m4);
10190       assign(op1, get_dpr_dw0(r2));
10191       assign(op2, get_dpr_dw0(r3));
10192       assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
10193                            mkexpr(op2)));
10194       put_dpr_dw0(r1, mkexpr(result));
10195    }
10196    return (m4 == 0) ? "ddtr" : "ddtra";
10197 }
10198 
10199 static const HChar *
s390_irgen_DXTRA(UChar r3,UChar m4,UChar r1,UChar r2)10200 s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10201 {
10202    if (! s390_host_has_dfp) {
10203       emulation_failure(EmFail_S390X_DFP_insn);
10204    } else {
10205       IRTemp op1 = newTemp(Ity_D128);
10206       IRTemp op2 = newTemp(Ity_D128);
10207       IRTemp result = newTemp(Ity_D128);
10208       IRTemp rounding_mode;
10209 
10210       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10211          emulation_warning(EmWarn_S390X_fpext_rounding);
10212          m4 = S390_DFP_ROUND_PER_FPC_0;
10213       }
10214 
10215       rounding_mode = encode_dfp_rounding_mode(m4);
10216       assign(op1, get_dpr_pair(r2));
10217       assign(op2, get_dpr_pair(r3));
10218       assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
10219                            mkexpr(op2)));
10220       put_dpr_pair(r1, mkexpr(result));
10221    }
10222    return (m4 == 0) ? "dxtr" : "dxtra";
10223 }
10224 
10225 static const HChar *
s390_irgen_EEDTR(UChar r1,UChar r2)10226 s390_irgen_EEDTR(UChar r1, UChar r2)
10227 {
10228    if (! s390_host_has_dfp) {
10229       emulation_failure(EmFail_S390X_DFP_insn);
10230    } else {
10231       put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
10232    }
10233    return "eedtr";
10234 }
10235 
10236 static const HChar *
s390_irgen_EEXTR(UChar r1,UChar r2)10237 s390_irgen_EEXTR(UChar r1, UChar r2)
10238 {
10239    if (! s390_host_has_dfp) {
10240       emulation_failure(EmFail_S390X_DFP_insn);
10241    } else {
10242       put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
10243    }
10244    return "eextr";
10245 }
10246 
10247 static const HChar *
s390_irgen_ESDTR(UChar r1,UChar r2)10248 s390_irgen_ESDTR(UChar r1, UChar r2)
10249 {
10250    if (! s390_host_has_dfp) {
10251       emulation_failure(EmFail_S390X_DFP_insn);
10252    } else {
10253       put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
10254    }
10255    return "esdtr";
10256 }
10257 
10258 static const HChar *
s390_irgen_ESXTR(UChar r1,UChar r2)10259 s390_irgen_ESXTR(UChar r1, UChar r2)
10260 {
10261    if (! s390_host_has_dfp) {
10262       emulation_failure(EmFail_S390X_DFP_insn);
10263    } else {
10264       put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
10265    }
10266    return "esxtr";
10267 }
10268 
10269 static const HChar *
s390_irgen_IEDTR(UChar r3,UChar r1,UChar r2)10270 s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
10271 {
10272    if (! s390_host_has_dfp) {
10273       emulation_failure(EmFail_S390X_DFP_insn);
10274    } else {
10275       IRTemp op1 = newTemp(Ity_I64);
10276       IRTemp op2 = newTemp(Ity_D64);
10277       IRTemp result = newTemp(Ity_D64);
10278 
10279       assign(op1, get_gpr_dw0(r2));
10280       assign(op2, get_dpr_dw0(r3));
10281       assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
10282       put_dpr_dw0(r1, mkexpr(result));
10283    }
10284    return "iedtr";
10285 }
10286 
10287 static const HChar *
s390_irgen_IEXTR(UChar r3,UChar r1,UChar r2)10288 s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
10289 {
10290    if (! s390_host_has_dfp) {
10291       emulation_failure(EmFail_S390X_DFP_insn);
10292    } else {
10293       IRTemp op1 = newTemp(Ity_I64);
10294       IRTemp op2 = newTemp(Ity_D128);
10295       IRTemp result = newTemp(Ity_D128);
10296 
10297       assign(op1, get_gpr_dw0(r2));
10298       assign(op2, get_dpr_pair(r3));
10299       assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10300       put_dpr_pair(r1, mkexpr(result));
10301    }
10302    return "iextr";
10303 }
10304 
10305 static const HChar *
s390_irgen_LDETR(UChar m4,UChar r1,UChar r2)10306 s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10307 {
10308    if (! s390_host_has_dfp) {
10309       emulation_failure(EmFail_S390X_DFP_insn);
10310    } else {
10311       IRTemp op = newTemp(Ity_D32);
10312 
10313       assign(op, get_dpr_w0(r2));
10314       put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10315    }
10316    return "ldetr";
10317 }
10318 
10319 static const HChar *
s390_irgen_LXDTR(UChar m4,UChar r1,UChar r2)10320 s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10321 {
10322    IRTemp op = newTemp(Ity_D64);
10323 
10324    assign(op, get_dpr_dw0(r2));
10325    put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10326 
10327    return "lxdtr";
10328 }
10329 
10330 static const HChar *
s390_irgen_LDXTR(UChar m3,UChar m4,UChar r1,UChar r2)10331 s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10332                  UChar r1, UChar r2)
10333 {
10334    if (! s390_host_has_dfp) {
10335       emulation_failure(EmFail_S390X_DFP_insn);
10336    } else {
10337       /* If fpext is not installed and m3 is in 1:7,
10338          rounding mode performed is unpredictable */
10339       if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10340          emulation_warning(EmWarn_S390X_fpext_rounding);
10341          m3 = S390_DFP_ROUND_PER_FPC_0;
10342       }
10343       IRTemp result = newTemp(Ity_D64);
10344 
10345       assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10346                            get_dpr_pair(r2)));
10347       put_dpr_dw0(r1, mkexpr(result));
10348    }
10349    return "ldxtr";
10350 }
10351 
10352 static const HChar *
s390_irgen_LEDTR(UChar m3,UChar m4,UChar r1,UChar r2)10353 s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10354                  UChar r1, UChar r2)
10355 {
10356    if (! s390_host_has_dfp) {
10357       emulation_failure(EmFail_S390X_DFP_insn);
10358    } else {
10359       /* If fpext is not installed and m3 is in 1:7,
10360          rounding mode performed is unpredictable */
10361       if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10362          emulation_warning(EmWarn_S390X_fpext_rounding);
10363          m3 = S390_DFP_ROUND_PER_FPC_0;
10364       }
10365       IRTemp op = newTemp(Ity_D64);
10366 
10367       assign(op, get_dpr_dw0(r2));
10368       put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10369                            mkexpr(op)));
10370    }
10371    return "ledtr";
10372 }
10373 
10374 static const HChar *
s390_irgen_LTDTR(UChar r1,UChar r2)10375 s390_irgen_LTDTR(UChar r1, UChar r2)
10376 {
10377    IRTemp result = newTemp(Ity_D64);
10378 
10379    assign(result, get_dpr_dw0(r2));
10380    put_dpr_dw0(r1, mkexpr(result));
10381    s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10382 
10383    return "ltdtr";
10384 }
10385 
10386 static const HChar *
s390_irgen_LTXTR(UChar r1,UChar r2)10387 s390_irgen_LTXTR(UChar r1, UChar r2)
10388 {
10389    IRTemp result = newTemp(Ity_D128);
10390 
10391    assign(result, get_dpr_pair(r2));
10392    put_dpr_pair(r1, mkexpr(result));
10393    s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10394 
10395    return "ltxtr";
10396 }
10397 
10398 static const HChar *
s390_irgen_MDTRA(UChar r3,UChar m4,UChar r1,UChar r2)10399 s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10400 {
10401    if (! s390_host_has_dfp) {
10402       emulation_failure(EmFail_S390X_DFP_insn);
10403    } else {
10404       IRTemp op1 = newTemp(Ity_D64);
10405       IRTemp op2 = newTemp(Ity_D64);
10406       IRTemp result = newTemp(Ity_D64);
10407       IRTemp rounding_mode;
10408 
10409       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10410          emulation_warning(EmWarn_S390X_fpext_rounding);
10411          m4 = S390_DFP_ROUND_PER_FPC_0;
10412       }
10413 
10414       rounding_mode = encode_dfp_rounding_mode(m4);
10415       assign(op1, get_dpr_dw0(r2));
10416       assign(op2, get_dpr_dw0(r3));
10417       assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10418                            mkexpr(op2)));
10419       put_dpr_dw0(r1, mkexpr(result));
10420    }
10421    return (m4 == 0) ? "mdtr" : "mdtra";
10422 }
10423 
10424 static const HChar *
s390_irgen_MXTRA(UChar r3,UChar m4,UChar r1,UChar r2)10425 s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10426 {
10427    if (! s390_host_has_dfp) {
10428       emulation_failure(EmFail_S390X_DFP_insn);
10429    } else {
10430       IRTemp op1 = newTemp(Ity_D128);
10431       IRTemp op2 = newTemp(Ity_D128);
10432       IRTemp result = newTemp(Ity_D128);
10433       IRTemp rounding_mode;
10434 
10435       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10436          emulation_warning(EmWarn_S390X_fpext_rounding);
10437          m4 = S390_DFP_ROUND_PER_FPC_0;
10438       }
10439 
10440       rounding_mode = encode_dfp_rounding_mode(m4);
10441       assign(op1, get_dpr_pair(r2));
10442       assign(op2, get_dpr_pair(r3));
10443       assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10444                            mkexpr(op2)));
10445       put_dpr_pair(r1, mkexpr(result));
10446    }
10447    return (m4 == 0) ? "mxtr" : "mxtra";
10448 }
10449 
10450 static const HChar *
s390_irgen_QADTR(UChar r3,UChar m4,UChar r1,UChar r2)10451 s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10452 {
10453    if (! s390_host_has_dfp) {
10454       emulation_failure(EmFail_S390X_DFP_insn);
10455    } else {
10456       IRTemp op1 = newTemp(Ity_D64);
10457       IRTemp op2 = newTemp(Ity_D64);
10458       IRTemp result = newTemp(Ity_D64);
10459       IRTemp rounding_mode;
10460 
10461       /* If fpext is not installed and m4 is in 1:7,
10462          rounding mode performed is unpredictable */
10463       if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10464          emulation_warning(EmWarn_S390X_fpext_rounding);
10465          m4 = S390_DFP_ROUND_PER_FPC_0;
10466       }
10467 
10468       rounding_mode = encode_dfp_rounding_mode(m4);
10469       assign(op1, get_dpr_dw0(r2));
10470       assign(op2, get_dpr_dw0(r3));
10471       assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10472                            mkexpr(op2)));
10473       put_dpr_dw0(r1, mkexpr(result));
10474    }
10475    return "qadtr";
10476 }
10477 
10478 static const HChar *
s390_irgen_QAXTR(UChar r3,UChar m4,UChar r1,UChar r2)10479 s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10480 {
10481    if (! s390_host_has_dfp) {
10482       emulation_failure(EmFail_S390X_DFP_insn);
10483    } else {
10484       IRTemp op1 = newTemp(Ity_D128);
10485       IRTemp op2 = newTemp(Ity_D128);
10486       IRTemp result = newTemp(Ity_D128);
10487       IRTemp rounding_mode;
10488 
10489       /* If fpext is not installed and m4 is in 1:7,
10490          rounding mode performed is unpredictable */
10491       if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10492          emulation_warning(EmWarn_S390X_fpext_rounding);
10493          m4 = S390_DFP_ROUND_PER_FPC_0;
10494       }
10495 
10496       rounding_mode = encode_dfp_rounding_mode(m4);
10497       assign(op1, get_dpr_pair(r2));
10498       assign(op2, get_dpr_pair(r3));
10499       assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10500                            mkexpr(op2)));
10501       put_dpr_pair(r1, mkexpr(result));
10502    }
10503    return "qaxtr";
10504 }
10505 
10506 static const HChar *
s390_irgen_RRDTR(UChar r3,UChar m4,UChar r1,UChar r2)10507 s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10508 {
10509    if (! s390_host_has_dfp) {
10510       emulation_failure(EmFail_S390X_DFP_insn);
10511    } else {
10512       IRTemp op1 = newTemp(Ity_I8);
10513       IRTemp op2 = newTemp(Ity_D64);
10514       IRTemp result = newTemp(Ity_D64);
10515       IRTemp rounding_mode;
10516 
10517       /* If fpext is not installed and m4 is in 1:7,
10518          rounding mode performed is unpredictable */
10519       if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10520          emulation_warning(EmWarn_S390X_fpext_rounding);
10521          m4 = S390_DFP_ROUND_PER_FPC_0;
10522       }
10523 
10524       rounding_mode = encode_dfp_rounding_mode(m4);
10525       assign(op1, get_gpr_b7(r2));
10526       assign(op2, get_dpr_dw0(r3));
10527       assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10528                            mkexpr(op1), mkexpr(op2)));
10529       put_dpr_dw0(r1, mkexpr(result));
10530    }
10531    return "rrdtr";
10532 }
10533 
10534 static const HChar *
s390_irgen_RRXTR(UChar r3,UChar m4,UChar r1,UChar r2)10535 s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10536 {
10537    if (! s390_host_has_dfp) {
10538       emulation_failure(EmFail_S390X_DFP_insn);
10539    } else {
10540       IRTemp op1 = newTemp(Ity_I8);
10541       IRTemp op2 = newTemp(Ity_D128);
10542       IRTemp result = newTemp(Ity_D128);
10543       IRTemp rounding_mode;
10544 
10545       /* If fpext is not installed and m4 is in 1:7,
10546          rounding mode performed is unpredictable */
10547       if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10548          emulation_warning(EmWarn_S390X_fpext_rounding);
10549          m4 = S390_DFP_ROUND_PER_FPC_0;
10550       }
10551 
10552       rounding_mode = encode_dfp_rounding_mode(m4);
10553       assign(op1, get_gpr_b7(r2));
10554       assign(op2, get_dpr_pair(r3));
10555       assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10556                            mkexpr(op1), mkexpr(op2)));
10557       put_dpr_pair(r1, mkexpr(result));
10558    }
10559    return "rrxtr";
10560 }
10561 
10562 static const HChar *
s390_irgen_SDTRA(UChar r3,UChar m4,UChar r1,UChar r2)10563 s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10564 {
10565    if (! s390_host_has_dfp) {
10566       emulation_failure(EmFail_S390X_DFP_insn);
10567    } else {
10568       IRTemp op1 = newTemp(Ity_D64);
10569       IRTemp op2 = newTemp(Ity_D64);
10570       IRTemp result = newTemp(Ity_D64);
10571       IRTemp rounding_mode;
10572 
10573       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10574          emulation_warning(EmWarn_S390X_fpext_rounding);
10575          m4 = S390_DFP_ROUND_PER_FPC_0;
10576       }
10577 
10578       rounding_mode = encode_dfp_rounding_mode(m4);
10579       assign(op1, get_dpr_dw0(r2));
10580       assign(op2, get_dpr_dw0(r3));
10581       assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10582                            mkexpr(op2)));
10583       s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10584       put_dpr_dw0(r1, mkexpr(result));
10585    }
10586    return (m4 == 0) ? "sdtr" : "sdtra";
10587 }
10588 
10589 static const HChar *
s390_irgen_SXTRA(UChar r3,UChar m4,UChar r1,UChar r2)10590 s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10591 {
10592    if (! s390_host_has_dfp) {
10593       emulation_failure(EmFail_S390X_DFP_insn);
10594    } else {
10595       IRTemp op1 = newTemp(Ity_D128);
10596       IRTemp op2 = newTemp(Ity_D128);
10597       IRTemp result = newTemp(Ity_D128);
10598       IRTemp rounding_mode;
10599 
10600       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10601          emulation_warning(EmWarn_S390X_fpext_rounding);
10602          m4 = S390_DFP_ROUND_PER_FPC_0;
10603       }
10604 
10605       rounding_mode = encode_dfp_rounding_mode(m4);
10606       assign(op1, get_dpr_pair(r2));
10607       assign(op2, get_dpr_pair(r3));
10608       assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10609                            mkexpr(op2)));
10610       put_dpr_pair(r1, mkexpr(result));
10611 
10612       s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10613    }
10614    return (m4 == 0) ? "sxtr" : "sxtra";
10615 }
10616 
10617 static const HChar *
s390_irgen_SLDT(UChar r3,IRTemp op2addr,UChar r1)10618 s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10619 {
10620    if (! s390_host_has_dfp) {
10621       emulation_failure(EmFail_S390X_DFP_insn);
10622    } else {
10623       IRTemp op = newTemp(Ity_D64);
10624 
10625       assign(op, get_dpr_dw0(r3));
10626       put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op),
10627                             unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10628                                                   mkU64(63)))));
10629    }
10630    return "sldt";
10631 }
10632 
10633 static const HChar *
s390_irgen_SLXT(UChar r3,IRTemp op2addr,UChar r1)10634 s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10635 {
10636    if (! s390_host_has_dfp) {
10637       emulation_failure(EmFail_S390X_DFP_insn);
10638    } else {
10639       IRTemp op = newTemp(Ity_D128);
10640 
10641       assign(op, get_dpr_pair(r3));
10642       put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op),
10643                              unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10644                                                    mkU64(63)))));
10645    }
10646    return "slxt";
10647 }
10648 
10649 static const HChar *
s390_irgen_SRDT(UChar r3,IRTemp op2addr,UChar r1)10650 s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10651 {
10652    if (! s390_host_has_dfp) {
10653       emulation_failure(EmFail_S390X_DFP_insn);
10654    } else {
10655       IRTemp op = newTemp(Ity_D64);
10656 
10657       assign(op, get_dpr_dw0(r3));
10658       put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op),
10659                             unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10660                                                   mkU64(63)))));
10661    }
10662    return "srdt";
10663 }
10664 
10665 static const HChar *
s390_irgen_SRXT(UChar r3,IRTemp op2addr,UChar r1)10666 s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10667 {
10668    if (! s390_host_has_dfp) {
10669       emulation_failure(EmFail_S390X_DFP_insn);
10670    } else {
10671       IRTemp op = newTemp(Ity_D128);
10672 
10673       assign(op, get_dpr_pair(r3));
10674       put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op),
10675                              unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10676                                                    mkU64(63)))));
10677    }
10678    return "srxt";
10679 }
10680 
10681 static const HChar *
s390_irgen_TDCET(UChar r1,IRTemp op2addr)10682 s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10683 {
10684    if (! s390_host_has_dfp) {
10685       emulation_failure(EmFail_S390X_DFP_insn);
10686    } else {
10687       IRTemp value = newTemp(Ity_D32);
10688 
10689       assign(value, get_dpr_w0(r1));
10690 
10691       s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10692    }
10693    return "tdcet";
10694 }
10695 
10696 static const HChar *
s390_irgen_TDCDT(UChar r1,IRTemp op2addr)10697 s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10698 {
10699    if (! s390_host_has_dfp) {
10700       emulation_failure(EmFail_S390X_DFP_insn);
10701    } else {
10702       IRTemp value = newTemp(Ity_D64);
10703 
10704       assign(value, get_dpr_dw0(r1));
10705 
10706       s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10707    }
10708    return "tdcdt";
10709 }
10710 
10711 static const HChar *
s390_irgen_TDCXT(UChar r1,IRTemp op2addr)10712 s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10713 {
10714    if (! s390_host_has_dfp) {
10715       emulation_failure(EmFail_S390X_DFP_insn);
10716    } else {
10717       IRTemp value = newTemp(Ity_D128);
10718 
10719       assign(value, get_dpr_pair(r1));
10720 
10721       s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10722    }
10723    return "tdcxt";
10724 }
10725 
10726 static const HChar *
s390_irgen_TDGET(UChar r1,IRTemp op2addr)10727 s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10728 {
10729    if (! s390_host_has_dfp) {
10730       emulation_failure(EmFail_S390X_DFP_insn);
10731    } else {
10732       IRTemp value = newTemp(Ity_D32);
10733 
10734       assign(value, get_dpr_w0(r1));
10735 
10736       s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10737    }
10738    return "tdget";
10739 }
10740 
10741 static const HChar *
s390_irgen_TDGDT(UChar r1,IRTemp op2addr)10742 s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10743 {
10744    if (! s390_host_has_dfp) {
10745       emulation_failure(EmFail_S390X_DFP_insn);
10746    } else {
10747       IRTemp value = newTemp(Ity_D64);
10748 
10749       assign(value, get_dpr_dw0(r1));
10750 
10751       s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10752    }
10753    return "tdgdt";
10754 }
10755 
10756 static const HChar *
s390_irgen_TDGXT(UChar r1,IRTemp op2addr)10757 s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10758 {
10759    if (! s390_host_has_dfp) {
10760       emulation_failure(EmFail_S390X_DFP_insn);
10761    } else {
10762       IRTemp value = newTemp(Ity_D128);
10763 
10764       assign(value, get_dpr_pair(r1));
10765 
10766       s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10767    }
10768    return "tdgxt";
10769 }
10770 
10771 static const HChar *
s390_irgen_CLC(UChar length,IRTemp start1,IRTemp start2)10772 s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10773 {
10774    IRTemp len = newTemp(Ity_I64);
10775 
10776    assign(len, mkU64(length));
10777    s390_irgen_CLC_EX(len, start1, start2);
10778 
10779    return "clc";
10780 }
10781 
10782 static const HChar *
s390_irgen_CLCL(UChar r1,UChar r2)10783 s390_irgen_CLCL(UChar r1, UChar r2)
10784 {
10785    IRTemp addr1 = newTemp(Ity_I64);
10786    IRTemp addr2 = newTemp(Ity_I64);
10787    IRTemp addr1_load = newTemp(Ity_I64);
10788    IRTemp addr2_load = newTemp(Ity_I64);
10789    IRTemp len1 = newTemp(Ity_I32);
10790    IRTemp len2 = newTemp(Ity_I32);
10791    IRTemp r1p1 = newTemp(Ity_I32);   /* contents of r1 + 1 */
10792    IRTemp r2p1 = newTemp(Ity_I32);   /* contents of r2 + 1 */
10793    IRTemp single1 = newTemp(Ity_I8);
10794    IRTemp single2 = newTemp(Ity_I8);
10795    IRTemp pad = newTemp(Ity_I8);
10796 
10797    assign(addr1, get_gpr_dw0(r1));
10798    assign(r1p1, get_gpr_w1(r1 + 1));
10799    assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10800    assign(addr2, get_gpr_dw0(r2));
10801    assign(r2p1, get_gpr_w1(r2 + 1));
10802    assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10803    assign(pad, get_gpr_b4(r2 + 1));
10804 
10805    /* len1 == 0 and len2 == 0? Exit */
10806    s390_cc_set(0);
10807    next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10808                                          mkexpr(len2)), mkU32(0)));
10809 
10810    /* Because mkite evaluates both the then-clause and the else-clause
10811       we cannot load directly from addr1 here. If len1 is 0, then adddr1
10812       may be NULL and loading from there would segfault. So we provide a
10813       valid dummy address in that case. Loading from there does no harm and
10814       the value will be discarded at runtime. */
10815    assign(addr1_load,
10816           mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10817                 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10818    assign(single1,
10819           mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10820                 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10821 
10822    assign(addr2_load,
10823           mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10824                 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10825    assign(single2,
10826           mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10827                 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10828 
10829    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10830    /* Fields differ ? */
10831    next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
10832 
10833    /* Update len1 and addr1, unless len1 == 0. */
10834    put_gpr_dw0(r1,
10835                mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10836                      mkexpr(addr1),
10837                      binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10838 
10839    /* When updating len1 we must not modify bits (r1+1)[0:39] */
10840    put_gpr_w1(r1 + 1,
10841               mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10842                     binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10843                     binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10844 
10845    /* Update len2 and addr2, unless len2 == 0. */
10846    put_gpr_dw0(r2,
10847                mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10848                      mkexpr(addr2),
10849                      binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10850 
10851    /* When updating len2 we must not modify bits (r2+1)[0:39] */
10852    put_gpr_w1(r2 + 1,
10853               mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10854                     binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10855                     binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10856 
10857    iterate();
10858 
10859    return "clcl";
10860 }
10861 
10862 static const HChar *
s390_irgen_CLCLE(UChar r1,UChar r3,IRTemp pad2)10863 s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10864 {
10865    IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10866 
10867    addr1 = newTemp(Ity_I64);
10868    addr3 = newTemp(Ity_I64);
10869    addr1_load = newTemp(Ity_I64);
10870    addr3_load = newTemp(Ity_I64);
10871    len1 = newTemp(Ity_I64);
10872    len3 = newTemp(Ity_I64);
10873    single1 = newTemp(Ity_I8);
10874    single3 = newTemp(Ity_I8);
10875 
10876    assign(addr1, get_gpr_dw0(r1));
10877    assign(len1, get_gpr_dw0(r1 + 1));
10878    assign(addr3, get_gpr_dw0(r3));
10879    assign(len3, get_gpr_dw0(r3 + 1));
10880 
10881    /* len1 == 0 and len3 == 0? Exit */
10882    s390_cc_set(0);
10883    next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10884                                         mkexpr(len3)), mkU64(0)));
10885 
10886    /* A mux requires both ways to be possible. This is a way to prevent clcle
10887       from reading from addr1 if it should read from the pad. Since the pad
10888       has no address, just read from the instruction, we discard that anyway */
10889    assign(addr1_load,
10890           mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10891                 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10892 
10893    /* same for addr3 */
10894    assign(addr3_load,
10895           mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10896                 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
10897 
10898    assign(single1,
10899           mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10900                 unop(Iop_64to8, mkexpr(pad2)),
10901                 load(Ity_I8, mkexpr(addr1_load))));
10902 
10903    assign(single3,
10904           mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10905                 unop(Iop_64to8, mkexpr(pad2)),
10906                 load(Ity_I8, mkexpr(addr3_load))));
10907 
10908    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10909    /* Both fields differ ? */
10910    next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
10911 
10912    /* If a length in 0 we must not change this length and the address */
10913    put_gpr_dw0(r1,
10914                mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10915                      mkexpr(addr1),
10916                      binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10917 
10918    put_gpr_dw0(r1 + 1,
10919                mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10920                      mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
10921 
10922    put_gpr_dw0(r3,
10923                mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10924                      mkexpr(addr3),
10925                      binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
10926 
10927    put_gpr_dw0(r3 + 1,
10928                mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10929                      mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
10930 
10931    iterate();
10932 
10933    return "clcle";
10934 }
10935 
10936 
10937 static void
s390_irgen_XC_EX(IRTemp length,IRTemp start1,IRTemp start2)10938 s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10939 {
10940    s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10941 }
10942 
10943 
10944 static void
s390_irgen_NC_EX(IRTemp length,IRTemp start1,IRTemp start2)10945 s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10946 {
10947    s390_irgen_xonc(Iop_And8, length, start1, start2);
10948 }
10949 
10950 
10951 static void
s390_irgen_OC_EX(IRTemp length,IRTemp start1,IRTemp start2)10952 s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10953 {
10954    s390_irgen_xonc(Iop_Or8, length, start1, start2);
10955 }
10956 
10957 
10958 static void
s390_irgen_CLC_EX(IRTemp length,IRTemp start1,IRTemp start2)10959 s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10960 {
10961    IRTemp current1 = newTemp(Ity_I8);
10962    IRTemp current2 = newTemp(Ity_I8);
10963    IRTemp counter = newTemp(Ity_I64);
10964 
10965    assign(counter, get_counter_dw0());
10966    put_counter_dw0(mkU64(0));
10967 
10968    assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10969                                        mkexpr(counter))));
10970    assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10971                                        mkexpr(counter))));
10972    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10973                       False);
10974 
10975    /* Both fields differ ? */
10976    next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
10977 
10978    /* Check for end of field */
10979    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10980    iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
10981    put_counter_dw0(mkU64(0));
10982 }
10983 
10984 static void
s390_irgen_MVC_EX(IRTemp length,IRTemp start1,IRTemp start2)10985 s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10986 {
10987    IRTemp counter = newTemp(Ity_I64);
10988 
10989    assign(counter, get_counter_dw0());
10990 
10991    store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10992          load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10993 
10994    /* Check for end of field */
10995    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10996    iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
10997    put_counter_dw0(mkU64(0));
10998 }
10999 
11000 static void
s390_irgen_MVCIN_EX(IRTemp length,IRTemp start1,IRTemp start2)11001 s390_irgen_MVCIN_EX(IRTemp length, IRTemp start1, IRTemp start2)
11002 {
11003    IRTemp counter = newTemp(Ity_I64);
11004 
11005    assign(counter, get_counter_dw0());
11006 
11007    store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
11008          load(Ity_I8, binop(Iop_Sub64, mkexpr(start2), mkexpr(counter))));
11009 
11010    /* Check for end of field */
11011    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11012    iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
11013    put_counter_dw0(mkU64(0));
11014 }
11015 
11016 static void
s390_irgen_TR_EX(IRTemp length,IRTemp start1,IRTemp start2)11017 s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
11018 {
11019    IRTemp op = newTemp(Ity_I8);
11020    IRTemp op1 = newTemp(Ity_I8);
11021    IRTemp result = newTemp(Ity_I64);
11022    IRTemp counter = newTemp(Ity_I64);
11023 
11024    assign(counter, get_counter_dw0());
11025 
11026    assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
11027 
11028    assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
11029 
11030    assign(op1, load(Ity_I8, mkexpr(result)));
11031    store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
11032 
11033    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11034    iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
11035    put_counter_dw0(mkU64(0));
11036 }
11037 
11038 
11039 static void
s390_irgen_EX_SS(UChar r,IRTemp addr2,void (* irgen)(IRTemp length,IRTemp start1,IRTemp start2),UInt lensize)11040 s390_irgen_EX_SS(UChar r, IRTemp addr2,
11041                  void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
11042                  UInt lensize)
11043 {
11044    struct SS {
11045       unsigned int op :  8;
11046       unsigned int l  :  8;
11047       unsigned int b1 :  4;
11048       unsigned int d1 : 12;
11049       unsigned int b2 :  4;
11050       unsigned int d2 : 12;
11051    };
11052    union {
11053       struct SS dec;
11054       unsigned long bytes;
11055    } ss;
11056    IRTemp cond;
11057    IRDirty *d;
11058    IRTemp torun;
11059 
11060    IRTemp start1 = newTemp(Ity_I64);
11061    IRTemp start2 = newTemp(Ity_I64);
11062    IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
11063    cond = newTemp(Ity_I1);
11064    torun = newTemp(Ity_I64);
11065 
11066    assign(torun, load(Ity_I64, mkexpr(addr2)));
11067    /* Start with a check that the saved code is still correct */
11068    assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
11069    /* If not, save the new value */
11070    d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
11071                           mkIRExprVec_1(mkexpr(torun)));
11072    d->guard = mkexpr(cond);
11073    stmt(IRStmt_Dirty(d));
11074 
11075    /* and restart */
11076    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
11077                    mkU64(guest_IA_curr_instr)));
11078    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
11079    restart_if(mkexpr(cond));
11080 
11081    ss.bytes = last_execute_target;
11082    assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
11083           ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
11084    assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
11085           ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
11086    assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
11087           r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
11088    irgen(len, start1, start2);
11089 
11090    last_execute_target = 0;
11091 }
11092 
11093 static const HChar *
s390_irgen_EX(UChar r1,IRTemp addr2)11094 s390_irgen_EX(UChar r1, IRTemp addr2)
11095 {
11096    switch(last_execute_target & 0xff00000000000000ULL) {
11097    case 0:
11098    {
11099       /* no code information yet */
11100       IRDirty *d;
11101 
11102       /* so safe the code... */
11103       d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
11104                              mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
11105       stmt(IRStmt_Dirty(d));
11106       /* and restart */
11107       stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
11108                       mkU64(guest_IA_curr_instr)));
11109       stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
11110       restart_if(IRExpr_Const(IRConst_U1(True)));
11111 
11112       /* we know that this will be invalidated */
11113       put_IA(mkaddr_expr(guest_IA_next_instr));
11114       dis_res->whatNext = Dis_StopHere;
11115       dis_res->jk_StopHere = Ijk_InvalICache;
11116       break;
11117    }
11118 
11119    case 0xd200000000000000ULL:
11120       /* special case MVC */
11121       s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
11122       return "ex@mvc";
11123 
11124    case 0xd500000000000000ULL:
11125       /* special case CLC */
11126       s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
11127       return "ex@clc";
11128 
11129    case 0xd700000000000000ULL:
11130       /* special case XC */
11131       s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
11132       return "ex@xc";
11133 
11134    case 0xd600000000000000ULL:
11135       /* special case OC */
11136       s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
11137       return "ex@oc";
11138 
11139    case 0xd400000000000000ULL:
11140       /* special case NC */
11141       s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
11142       return "ex@nc";
11143 
11144    case 0xdc00000000000000ULL:
11145       /* special case TR */
11146       s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
11147       return "ex@tr";
11148 
11149    case 0xe800000000000000ULL:
11150       /* special case MVCIN */
11151       s390_irgen_EX_SS(r1, addr2, s390_irgen_MVCIN_EX, 64);
11152       return "ex@mvcin";
11153 
11154    default:
11155    {
11156       /* everything else will get a self checking prefix that also checks the
11157          register content */
11158       IRDirty *d;
11159       UChar *bytes;
11160       IRTemp cond;
11161       IRTemp orperand;
11162       IRTemp torun;
11163 
11164       cond = newTemp(Ity_I1);
11165       orperand = newTemp(Ity_I64);
11166       torun = newTemp(Ity_I64);
11167 
11168       if (r1 == 0)
11169          assign(orperand, mkU64(0));
11170       else
11171          assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
11172       /* This code is going to be translated */
11173       assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
11174              binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
11175 
11176       /* Start with a check that saved code is still correct */
11177       assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
11178              mkU64(last_execute_target)));
11179       /* If not, save the new value */
11180       d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
11181                              mkIRExprVec_1(mkexpr(torun)));
11182       d->guard = mkexpr(cond);
11183       stmt(IRStmt_Dirty(d));
11184 
11185       /* and restart */
11186       stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART), mkU64(guest_IA_curr_instr)));
11187       stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
11188       restart_if(mkexpr(cond));
11189 
11190       /* Now comes the actual translation */
11191       bytes = (UChar *) &last_execute_target;
11192       s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
11193                             dis_res);
11194       if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
11195          vex_printf("    which was executed by\n");
11196       /* dont make useless translations in the next execute */
11197       last_execute_target = 0;
11198    }
11199    }
11200    return "ex";
11201 }
11202 
11203 static const HChar *
s390_irgen_EXRL(UChar r1,UInt offset)11204 s390_irgen_EXRL(UChar r1, UInt offset)
11205 {
11206    IRTemp addr = newTemp(Ity_I64);
11207    /* we might save one round trip because we know the target */
11208    if (!last_execute_target)
11209       last_execute_target = *(ULong *)(HWord)
11210                              (guest_IA_curr_instr + offset * 2UL);
11211    assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
11212    s390_irgen_EX(r1, addr);
11213    return "exrl";
11214 }
11215 
11216 static const HChar *
s390_irgen_IPM(UChar r1)11217 s390_irgen_IPM(UChar r1)
11218 {
11219    // As long as we dont support SPM, lets just assume 0 as program mask
11220    put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
11221                        binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
11222 
11223    return "ipm";
11224 }
11225 
11226 
11227 static const HChar *
s390_irgen_SRST(UChar r1,UChar r2)11228 s390_irgen_SRST(UChar r1, UChar r2)
11229 {
11230    IRTemp address = newTemp(Ity_I64);
11231    IRTemp next = newTemp(Ity_I64);
11232    IRTemp delim = newTemp(Ity_I8);
11233    IRTemp counter = newTemp(Ity_I64);
11234    IRTemp byte = newTemp(Ity_I8);
11235 
11236    assign(address, get_gpr_dw0(r2));
11237    assign(next, get_gpr_dw0(r1));
11238 
11239    assign(counter, get_counter_dw0());
11240    put_counter_dw0(mkU64(0));
11241 
11242    // start = next?  CC=2 and out r1 and r2 unchanged
11243    s390_cc_set(2);
11244    put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
11245    next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
11246 
11247    assign(byte, load(Ity_I8, mkexpr(address)));
11248    assign(delim, get_gpr_b7(0));
11249 
11250    // byte = delim? CC=1, R1=address
11251    s390_cc_set(1);
11252    put_gpr_dw0(r1,  mkexpr(address));
11253    next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
11254 
11255    // else: all equal, no end yet, loop
11256    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11257    put_gpr_dw0(r1, mkexpr(next));
11258    put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
11259 
11260    iterate();
11261 
11262    return "srst";
11263 }
11264 
11265 static const HChar *
s390_irgen_CLST(UChar r1,UChar r2)11266 s390_irgen_CLST(UChar r1, UChar r2)
11267 {
11268    IRTemp address1 = newTemp(Ity_I64);
11269    IRTemp address2 = newTemp(Ity_I64);
11270    IRTemp end = newTemp(Ity_I8);
11271    IRTemp counter = newTemp(Ity_I64);
11272    IRTemp byte1 = newTemp(Ity_I8);
11273    IRTemp byte2 = newTemp(Ity_I8);
11274 
11275    assign(address1, get_gpr_dw0(r1));
11276    assign(address2, get_gpr_dw0(r2));
11277    assign(end, get_gpr_b7(0));
11278    assign(counter, get_counter_dw0());
11279    put_counter_dw0(mkU64(0));
11280    assign(byte1, load(Ity_I8, mkexpr(address1)));
11281    assign(byte2, load(Ity_I8, mkexpr(address2)));
11282 
11283    // end in both? all equal, reset r1 and r2 to start values
11284    s390_cc_set(0);
11285    put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
11286    put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
11287    next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
11288                       binop(Iop_Or8,
11289                             binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
11290                             binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
11291 
11292    put_gpr_dw0(r1, mkexpr(address1));
11293    put_gpr_dw0(r2, mkexpr(address2));
11294 
11295    // End found in string1
11296    s390_cc_set(1);
11297    next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
11298 
11299    // End found in string2
11300    s390_cc_set(2);
11301    next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
11302 
11303    // string1 < string2
11304    s390_cc_set(1);
11305    next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
11306                       unop(Iop_8Uto32, mkexpr(byte2))));
11307 
11308    // string2 < string1
11309    s390_cc_set(2);
11310    next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
11311                       unop(Iop_8Uto32, mkexpr(byte1))));
11312 
11313    // else: all equal, no end yet, loop
11314    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11315    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
11316    put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
11317 
11318    iterate();
11319 
11320    return "clst";
11321 }
11322 
11323 static void
s390_irgen_load_multiple_32bit(UChar r1,UChar r3,IRTemp op2addr)11324 s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11325 {
11326    UChar reg;
11327    IRTemp addr = newTemp(Ity_I64);
11328 
11329    assign(addr, mkexpr(op2addr));
11330    reg = r1;
11331    do {
11332       IRTemp old = addr;
11333 
11334       reg %= 16;
11335       put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
11336       addr = newTemp(Ity_I64);
11337       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11338       reg++;
11339    } while (reg != (r3 + 1));
11340 }
11341 
11342 static const HChar *
s390_irgen_LM(UChar r1,UChar r3,IRTemp op2addr)11343 s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
11344 {
11345    s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11346 
11347    return "lm";
11348 }
11349 
11350 static const HChar *
s390_irgen_LMY(UChar r1,UChar r3,IRTemp op2addr)11351 s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11352 {
11353    s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11354 
11355    return "lmy";
11356 }
11357 
11358 static const HChar *
s390_irgen_LMH(UChar r1,UChar r3,IRTemp op2addr)11359 s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11360 {
11361    UChar reg;
11362    IRTemp addr = newTemp(Ity_I64);
11363 
11364    assign(addr, mkexpr(op2addr));
11365    reg = r1;
11366    do {
11367       IRTemp old = addr;
11368 
11369       reg %= 16;
11370       put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11371       addr = newTemp(Ity_I64);
11372       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11373       reg++;
11374    } while (reg != (r3 + 1));
11375 
11376    return "lmh";
11377 }
11378 
11379 static const HChar *
s390_irgen_LMG(UChar r1,UChar r3,IRTemp op2addr)11380 s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11381 {
11382    UChar reg;
11383    IRTemp addr = newTemp(Ity_I64);
11384 
11385    assign(addr, mkexpr(op2addr));
11386    reg = r1;
11387    do {
11388       IRTemp old = addr;
11389 
11390       reg %= 16;
11391       put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11392       addr = newTemp(Ity_I64);
11393       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11394       reg++;
11395    } while (reg != (r3 + 1));
11396 
11397    return "lmg";
11398 }
11399 
11400 static void
s390_irgen_store_multiple_32bit(UChar r1,UChar r3,IRTemp op2addr)11401 s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11402 {
11403    UChar reg;
11404    IRTemp addr = newTemp(Ity_I64);
11405 
11406    assign(addr, mkexpr(op2addr));
11407    reg = r1;
11408    do {
11409       IRTemp old = addr;
11410 
11411       reg %= 16;
11412       store(mkexpr(addr), get_gpr_w1(reg));
11413       addr = newTemp(Ity_I64);
11414       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11415       reg++;
11416    } while( reg != (r3 + 1));
11417 }
11418 
11419 static const HChar *
s390_irgen_STM(UChar r1,UChar r3,IRTemp op2addr)11420 s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11421 {
11422    s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11423 
11424    return "stm";
11425 }
11426 
11427 static const HChar *
s390_irgen_STMY(UChar r1,UChar r3,IRTemp op2addr)11428 s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11429 {
11430    s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11431 
11432    return "stmy";
11433 }
11434 
11435 static const HChar *
s390_irgen_STMH(UChar r1,UChar r3,IRTemp op2addr)11436 s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11437 {
11438    UChar reg;
11439    IRTemp addr = newTemp(Ity_I64);
11440 
11441    assign(addr, mkexpr(op2addr));
11442    reg = r1;
11443    do {
11444       IRTemp old = addr;
11445 
11446       reg %= 16;
11447       store(mkexpr(addr), get_gpr_w0(reg));
11448       addr = newTemp(Ity_I64);
11449       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11450       reg++;
11451    } while( reg != (r3 + 1));
11452 
11453    return "stmh";
11454 }
11455 
11456 static const HChar *
s390_irgen_STMG(UChar r1,UChar r3,IRTemp op2addr)11457 s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11458 {
11459    UChar reg;
11460    IRTemp addr = newTemp(Ity_I64);
11461 
11462    assign(addr, mkexpr(op2addr));
11463    reg = r1;
11464    do {
11465       IRTemp old = addr;
11466 
11467       reg %= 16;
11468       store(mkexpr(addr), get_gpr_dw0(reg));
11469       addr = newTemp(Ity_I64);
11470       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11471       reg++;
11472    } while( reg != (r3 + 1));
11473 
11474    return "stmg";
11475 }
11476 
11477 static void
s390_irgen_xonc(IROp op,IRTemp length,IRTemp start1,IRTemp start2)11478 s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
11479 {
11480    IRTemp old1 = newTemp(Ity_I8);
11481    IRTemp old2 = newTemp(Ity_I8);
11482    IRTemp new1 = newTemp(Ity_I8);
11483    IRTemp counter = newTemp(Ity_I32);
11484    IRTemp addr1 = newTemp(Ity_I64);
11485 
11486    assign(counter, get_counter_w0());
11487 
11488    assign(addr1, binop(Iop_Add64, mkexpr(start1),
11489                        unop(Iop_32Uto64, mkexpr(counter))));
11490 
11491    assign(old1, load(Ity_I8, mkexpr(addr1)));
11492    assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11493                                    unop(Iop_32Uto64,mkexpr(counter)))));
11494    assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11495 
11496    /* Special case: xc is used to zero memory */
11497    if (op == Iop_Xor8) {
11498       store(mkexpr(addr1),
11499             mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11500                   mkU8(0), mkexpr(new1)));
11501    } else
11502       store(mkexpr(addr1), mkexpr(new1));
11503    put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11504                         get_counter_w1()));
11505 
11506    /* Check for end of field */
11507    put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
11508    iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
11509    s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11510                       False);
11511    put_counter_dw0(mkU64(0));
11512 }
11513 
11514 static const HChar *
s390_irgen_XC(UChar length,IRTemp start1,IRTemp start2)11515 s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11516 {
11517    IRTemp len = newTemp(Ity_I32);
11518 
11519    assign(len, mkU32(length));
11520    s390_irgen_xonc(Iop_Xor8, len, start1, start2);
11521 
11522    return "xc";
11523 }
11524 
11525 static void
s390_irgen_XC_sameloc(UChar length,UChar b,UShort d)11526 s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11527 {
11528    IRTemp counter = newTemp(Ity_I32);
11529    IRTemp start = newTemp(Ity_I64);
11530    IRTemp addr  = newTemp(Ity_I64);
11531 
11532    assign(start,
11533           binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11534 
11535    if (length < 8) {
11536       UInt i;
11537 
11538       for (i = 0; i <= length; ++i) {
11539          store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11540       }
11541    } else {
11542      assign(counter, get_counter_w0());
11543 
11544      assign(addr, binop(Iop_Add64, mkexpr(start),
11545                         unop(Iop_32Uto64, mkexpr(counter))));
11546 
11547      store(mkexpr(addr), mkU8(0));
11548 
11549      /* Check for end of field */
11550      put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
11551      iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
11552 
11553      /* Reset counter */
11554      put_counter_dw0(mkU64(0));
11555    }
11556 
11557    s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11558 
11559    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
11560       s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11561 }
11562 
11563 static const HChar *
s390_irgen_NC(UChar length,IRTemp start1,IRTemp start2)11564 s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11565 {
11566    IRTemp len = newTemp(Ity_I32);
11567 
11568    assign(len, mkU32(length));
11569    s390_irgen_xonc(Iop_And8, len, start1, start2);
11570 
11571    return "nc";
11572 }
11573 
11574 static const HChar *
s390_irgen_OC(UChar length,IRTemp start1,IRTemp start2)11575 s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11576 {
11577    IRTemp len = newTemp(Ity_I32);
11578 
11579    assign(len, mkU32(length));
11580    s390_irgen_xonc(Iop_Or8, len, start1, start2);
11581 
11582    return "oc";
11583 }
11584 
11585 
11586 static const HChar *
s390_irgen_MVC(UChar length,IRTemp start1,IRTemp start2)11587 s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11588 {
11589    IRTemp len = newTemp(Ity_I64);
11590 
11591    assign(len, mkU64(length));
11592    s390_irgen_MVC_EX(len, start1, start2);
11593 
11594    return "mvc";
11595 }
11596 
11597 static const HChar *
s390_irgen_MVCIN(UChar length,IRTemp start1,IRTemp start2)11598 s390_irgen_MVCIN(UChar length, IRTemp start1, IRTemp start2)
11599 {
11600    IRTemp len = newTemp(Ity_I64);
11601 
11602    assign(len, mkU64(length));
11603    s390_irgen_MVCIN_EX(len, start1, start2);
11604 
11605    return "mvcin";
11606 }
11607 
11608 static const HChar *
s390_irgen_MVCL(UChar r1,UChar r2)11609 s390_irgen_MVCL(UChar r1, UChar r2)
11610 {
11611    IRTemp addr1 = newTemp(Ity_I64);
11612    IRTemp addr2 = newTemp(Ity_I64);
11613    IRTemp addr2_load = newTemp(Ity_I64);
11614    IRTemp r1p1 = newTemp(Ity_I32);   /* contents of r1 + 1 */
11615    IRTemp r2p1 = newTemp(Ity_I32);   /* contents of r2 + 1 */
11616    IRTemp len1 = newTemp(Ity_I32);
11617    IRTemp len2 = newTemp(Ity_I32);
11618    IRTemp pad = newTemp(Ity_I8);
11619    IRTemp single = newTemp(Ity_I8);
11620 
11621    assign(addr1, get_gpr_dw0(r1));
11622    assign(r1p1, get_gpr_w1(r1 + 1));
11623    assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11624    assign(addr2, get_gpr_dw0(r2));
11625    assign(r2p1, get_gpr_w1(r2 + 1));
11626    assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11627    assign(pad, get_gpr_b4(r2 + 1));
11628 
11629    /* len1 == 0 ? */
11630    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
11631    next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
11632 
11633    /* Check for destructive overlap:
11634       addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11635    s390_cc_set(3);
11636    IRTemp cond1 = newTemp(Ity_I32);
11637    assign(cond1, unop(Iop_1Uto32,
11638                       binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11639    IRTemp cond2 = newTemp(Ity_I32);
11640    assign(cond2, unop(Iop_1Uto32,
11641                       binop(Iop_CmpLT64U, mkexpr(addr1),
11642                             binop(Iop_Add64, mkexpr(addr2),
11643                                   unop(Iop_32Uto64, mkexpr(len1))))));
11644    IRTemp cond3 = newTemp(Ity_I32);
11645    assign(cond3, unop(Iop_1Uto32,
11646                       binop(Iop_CmpLT64U,
11647                             mkexpr(addr1),
11648                             binop(Iop_Add64, mkexpr(addr2),
11649                                   unop(Iop_32Uto64, mkexpr(len2))))));
11650 
11651    next_insn_if(binop(Iop_CmpEQ32,
11652                       binop(Iop_And32,
11653                             binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11654                             mkexpr(cond3)),
11655                       mkU32(1)));
11656 
11657    /* See s390_irgen_CLCL for explanation why we cannot load directly
11658       and need two steps. */
11659    assign(addr2_load,
11660           mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11661                 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11662    assign(single,
11663           mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11664                 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11665 
11666    store(mkexpr(addr1), mkexpr(single));
11667 
11668    /* Update addr1 and len1 */
11669    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11670    put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11671 
11672    /* Update addr2 and len2 */
11673    put_gpr_dw0(r2,
11674                mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11675                      mkexpr(addr2),
11676                      binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11677 
11678    /* When updating len2 we must not modify bits (r2+1)[0:39] */
11679    put_gpr_w1(r2 + 1,
11680               mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11681                     binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11682                     binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11683 
11684    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
11685    iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
11686 
11687    return "mvcl";
11688 }
11689 
11690 
11691 static const HChar *
s390_irgen_MVCLE(UChar r1,UChar r3,IRTemp pad2)11692 s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11693 {
11694    IRTemp addr1, addr3, addr3_load, len1, len3, single;
11695 
11696    addr1 = newTemp(Ity_I64);
11697    addr3 = newTemp(Ity_I64);
11698    addr3_load = newTemp(Ity_I64);
11699    len1 = newTemp(Ity_I64);
11700    len3 = newTemp(Ity_I64);
11701    single = newTemp(Ity_I8);
11702 
11703    assign(addr1, get_gpr_dw0(r1));
11704    assign(len1, get_gpr_dw0(r1 + 1));
11705    assign(addr3, get_gpr_dw0(r3));
11706    assign(len3, get_gpr_dw0(r3 + 1));
11707 
11708    // len1 == 0 ?
11709    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
11710    next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
11711 
11712    /* This is a hack to prevent mvcle from reading from addr3 if it
11713       should read from the pad. Since the pad has no address, just
11714       read from the instruction, we discard that anyway */
11715    assign(addr3_load,
11716           mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11717                 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
11718 
11719    assign(single,
11720           mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11721                 unop(Iop_64to8, mkexpr(pad2)),
11722                 load(Ity_I8, mkexpr(addr3_load))));
11723    store(mkexpr(addr1), mkexpr(single));
11724 
11725    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11726 
11727    put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11728 
11729    put_gpr_dw0(r3,
11730                mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11731                      mkexpr(addr3),
11732                      binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
11733 
11734    put_gpr_dw0(r3 + 1,
11735                mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11736                      mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
11737 
11738    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
11739    iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
11740 
11741    return "mvcle";
11742 }
11743 
11744 static const HChar *
s390_irgen_MVST(UChar r1,UChar r2)11745 s390_irgen_MVST(UChar r1, UChar r2)
11746 {
11747    IRTemp addr1 = newTemp(Ity_I64);
11748    IRTemp addr2 = newTemp(Ity_I64);
11749    IRTemp end = newTemp(Ity_I8);
11750    IRTemp byte = newTemp(Ity_I8);
11751    IRTemp counter = newTemp(Ity_I64);
11752 
11753    assign(addr1, get_gpr_dw0(r1));
11754    assign(addr2, get_gpr_dw0(r2));
11755    assign(counter, get_counter_dw0());
11756    assign(end, get_gpr_b7(0));
11757    assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11758    store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11759 
11760    // We use unlimited as cpu-determined number
11761    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11762    iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
11763 
11764    // and always set cc=1 at the end + update r1
11765    s390_cc_set(1);
11766    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11767    put_counter_dw0(mkU64(0));
11768 
11769    return "mvst";
11770 }
11771 
11772 static void
s390_irgen_divide_64to32(IROp op,UChar r1,IRTemp op2)11773 s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11774 {
11775    IRTemp op1 = newTemp(Ity_I64);
11776    IRTemp result = newTemp(Ity_I64);
11777 
11778    assign(op1, binop(Iop_32HLto64,
11779                      get_gpr_w1(r1),         // high 32 bits
11780                      get_gpr_w1(r1 + 1)));   // low  32 bits
11781    assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11782    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));   // remainder
11783    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11784 }
11785 
11786 static void
s390_irgen_divide_128to64(IROp op,UChar r1,IRTemp op2)11787 s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11788 {
11789    IRTemp op1 = newTemp(Ity_I128);
11790    IRTemp result = newTemp(Ity_I128);
11791 
11792    assign(op1, binop(Iop_64HLto128,
11793                      get_gpr_dw0(r1),         // high 64 bits
11794                      get_gpr_dw0(r1 + 1)));   // low  64 bits
11795    assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11796    put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));   // remainder
11797    put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11798 }
11799 
11800 static void
s390_irgen_divide_64to64(IROp op,UChar r1,IRTemp op2)11801 s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11802 {
11803    IRTemp op1 = newTemp(Ity_I64);
11804    IRTemp result = newTemp(Ity_I128);
11805 
11806    assign(op1, get_gpr_dw0(r1 + 1));
11807    assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11808    put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));   // remainder
11809    put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11810 }
11811 
11812 static const HChar *
s390_irgen_DR(UChar r1,UChar r2)11813 s390_irgen_DR(UChar r1, UChar r2)
11814 {
11815    IRTemp op2 = newTemp(Ity_I32);
11816 
11817    assign(op2, get_gpr_w1(r2));
11818 
11819    s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11820 
11821    return "dr";
11822 }
11823 
11824 static const HChar *
s390_irgen_D(UChar r1,IRTemp op2addr)11825 s390_irgen_D(UChar r1, IRTemp op2addr)
11826 {
11827    IRTemp op2 = newTemp(Ity_I32);
11828 
11829    assign(op2, load(Ity_I32, mkexpr(op2addr)));
11830 
11831    s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11832 
11833    return "d";
11834 }
11835 
11836 static const HChar *
s390_irgen_DLR(UChar r1,UChar r2)11837 s390_irgen_DLR(UChar r1, UChar r2)
11838 {
11839    IRTemp op2 = newTemp(Ity_I32);
11840 
11841    assign(op2, get_gpr_w1(r2));
11842 
11843    s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11844 
11845    return "dlr";
11846 }
11847 
11848 static const HChar *
s390_irgen_DL(UChar r1,IRTemp op2addr)11849 s390_irgen_DL(UChar r1, IRTemp op2addr)
11850 {
11851    IRTemp op2 = newTemp(Ity_I32);
11852 
11853    assign(op2, load(Ity_I32, mkexpr(op2addr)));
11854 
11855    s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11856 
11857    return "dl";
11858 }
11859 
11860 static const HChar *
s390_irgen_DLG(UChar r1,IRTemp op2addr)11861 s390_irgen_DLG(UChar r1, IRTemp op2addr)
11862 {
11863    IRTemp op2 = newTemp(Ity_I64);
11864 
11865    assign(op2, load(Ity_I64, mkexpr(op2addr)));
11866 
11867    s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11868 
11869    return "dlg";
11870 }
11871 
11872 static const HChar *
s390_irgen_DLGR(UChar r1,UChar r2)11873 s390_irgen_DLGR(UChar r1, UChar r2)
11874 {
11875    IRTemp op2 = newTemp(Ity_I64);
11876 
11877    assign(op2, get_gpr_dw0(r2));
11878 
11879    s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11880 
11881    return "dlgr";
11882 }
11883 
11884 static const HChar *
s390_irgen_DSGR(UChar r1,UChar r2)11885 s390_irgen_DSGR(UChar r1, UChar r2)
11886 {
11887    IRTemp op2 = newTemp(Ity_I64);
11888 
11889    assign(op2, get_gpr_dw0(r2));
11890 
11891    s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11892 
11893    return "dsgr";
11894 }
11895 
11896 static const HChar *
s390_irgen_DSG(UChar r1,IRTemp op2addr)11897 s390_irgen_DSG(UChar r1, IRTemp op2addr)
11898 {
11899    IRTemp op2 = newTemp(Ity_I64);
11900 
11901    assign(op2, load(Ity_I64, mkexpr(op2addr)));
11902 
11903    s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11904 
11905    return "dsg";
11906 }
11907 
11908 static const HChar *
s390_irgen_DSGFR(UChar r1,UChar r2)11909 s390_irgen_DSGFR(UChar r1, UChar r2)
11910 {
11911    IRTemp op2 = newTemp(Ity_I64);
11912 
11913    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11914 
11915    s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11916 
11917    return "dsgfr";
11918 }
11919 
11920 static const HChar *
s390_irgen_DSGF(UChar r1,IRTemp op2addr)11921 s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11922 {
11923    IRTemp op2 = newTemp(Ity_I64);
11924 
11925    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11926 
11927    s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11928 
11929    return "dsgf";
11930 }
11931 
11932 static void
s390_irgen_load_ar_multiple(UChar r1,UChar r3,IRTemp op2addr)11933 s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11934 {
11935    UChar reg;
11936    IRTemp addr = newTemp(Ity_I64);
11937 
11938    assign(addr, mkexpr(op2addr));
11939    reg = r1;
11940    do {
11941       IRTemp old = addr;
11942 
11943       reg %= 16;
11944       put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11945       addr = newTemp(Ity_I64);
11946       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11947       reg++;
11948    } while (reg != (r3 + 1));
11949 }
11950 
11951 static const HChar *
s390_irgen_LAM(UChar r1,UChar r3,IRTemp op2addr)11952 s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11953 {
11954    s390_irgen_load_ar_multiple(r1, r3, op2addr);
11955 
11956    return "lam";
11957 }
11958 
11959 static const HChar *
s390_irgen_LAMY(UChar r1,UChar r3,IRTemp op2addr)11960 s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11961 {
11962    s390_irgen_load_ar_multiple(r1, r3, op2addr);
11963 
11964    return "lamy";
11965 }
11966 
11967 static void
s390_irgen_store_ar_multiple(UChar r1,UChar r3,IRTemp op2addr)11968 s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11969 {
11970    UChar reg;
11971    IRTemp addr = newTemp(Ity_I64);
11972 
11973    assign(addr, mkexpr(op2addr));
11974    reg = r1;
11975    do {
11976       IRTemp old = addr;
11977 
11978       reg %= 16;
11979       store(mkexpr(addr), get_ar_w0(reg));
11980       addr = newTemp(Ity_I64);
11981       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11982       reg++;
11983    } while (reg != (r3 + 1));
11984 }
11985 
11986 static const HChar *
s390_irgen_STAM(UChar r1,UChar r3,IRTemp op2addr)11987 s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11988 {
11989    s390_irgen_store_ar_multiple(r1, r3, op2addr);
11990 
11991    return "stam";
11992 }
11993 
11994 static const HChar *
s390_irgen_STAMY(UChar r1,UChar r3,IRTemp op2addr)11995 s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11996 {
11997    s390_irgen_store_ar_multiple(r1, r3, op2addr);
11998 
11999    return "stamy";
12000 }
12001 
12002 
12003 /* Implementation for 32-bit compare-and-swap */
12004 static void
s390_irgen_cas_32(UChar r1,UChar r3,IRTemp op2addr)12005 s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
12006 {
12007    IRCAS *cas;
12008    IRTemp op1 = newTemp(Ity_I32);
12009    IRTemp old_mem = newTemp(Ity_I32);
12010    IRTemp op3 = newTemp(Ity_I32);
12011    IRTemp result = newTemp(Ity_I32);
12012    IRTemp nequal = newTemp(Ity_I1);
12013 
12014    assign(op1, get_gpr_w1(r1));
12015    assign(op3, get_gpr_w1(r3));
12016 
12017    /* The first and second operands are compared. If they are equal,
12018       the third operand is stored at the second- operand location. */
12019    cas = mkIRCAS(IRTemp_INVALID, old_mem,
12020                  Iend_BE, mkexpr(op2addr),
12021                  NULL, mkexpr(op1), /* expected value */
12022                  NULL, mkexpr(op3)  /* new value */);
12023    stmt(IRStmt_CAS(cas));
12024 
12025    /* Set CC. Operands compared equal -> 0, else 1. */
12026    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
12027    s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12028 
12029    /* If operands were equal (cc == 0) just store the old value op1 in r1.
12030       Otherwise, store the old_value from memory in r1 and yield. */
12031    assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12032    put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
12033    yield_if(mkexpr(nequal));
12034 }
12035 
12036 static const HChar *
s390_irgen_CS(UChar r1,UChar r3,IRTemp op2addr)12037 s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
12038 {
12039    s390_irgen_cas_32(r1, r3, op2addr);
12040 
12041    return "cs";
12042 }
12043 
12044 static const HChar *
s390_irgen_CSY(UChar r1,UChar r3,IRTemp op2addr)12045 s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
12046 {
12047    s390_irgen_cas_32(r1, r3, op2addr);
12048 
12049    return "csy";
12050 }
12051 
12052 static const HChar *
s390_irgen_CSG(UChar r1,UChar r3,IRTemp op2addr)12053 s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
12054 {
12055    IRCAS *cas;
12056    IRTemp op1 = newTemp(Ity_I64);
12057    IRTemp old_mem = newTemp(Ity_I64);
12058    IRTemp op3 = newTemp(Ity_I64);
12059    IRTemp result = newTemp(Ity_I64);
12060    IRTemp nequal = newTemp(Ity_I1);
12061 
12062    assign(op1, get_gpr_dw0(r1));
12063    assign(op3, get_gpr_dw0(r3));
12064 
12065    /* The first and second operands are compared. If they are equal,
12066       the third operand is stored at the second- operand location. */
12067    cas = mkIRCAS(IRTemp_INVALID, old_mem,
12068                  Iend_BE, mkexpr(op2addr),
12069                  NULL, mkexpr(op1), /* expected value */
12070                  NULL, mkexpr(op3)  /* new value */);
12071    stmt(IRStmt_CAS(cas));
12072 
12073    /* Set CC. Operands compared equal -> 0, else 1. */
12074    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
12075    s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12076 
12077    /* If operands were equal (cc == 0) just store the old value op1 in r1.
12078       Otherwise, store the old_value from memory in r1 and yield. */
12079    assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12080    put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
12081    yield_if(mkexpr(nequal));
12082 
12083    return "csg";
12084 }
12085 
12086 /* Implementation for 32-bit compare-double-and-swap */
12087 static void
s390_irgen_cdas_32(UChar r1,UChar r3,IRTemp op2addr)12088 s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
12089 {
12090    IRCAS *cas;
12091    IRTemp op1_high = newTemp(Ity_I32);
12092    IRTemp op1_low  = newTemp(Ity_I32);
12093    IRTemp old_mem_high = newTemp(Ity_I32);
12094    IRTemp old_mem_low  = newTemp(Ity_I32);
12095    IRTemp op3_high = newTemp(Ity_I32);
12096    IRTemp op3_low  = newTemp(Ity_I32);
12097    IRTemp result = newTemp(Ity_I32);
12098    IRTemp nequal = newTemp(Ity_I1);
12099 
12100    assign(op1_high, get_gpr_w1(r1));
12101    assign(op1_low,  get_gpr_w1(r1+1));
12102    assign(op3_high, get_gpr_w1(r3));
12103    assign(op3_low,  get_gpr_w1(r3+1));
12104 
12105    /* The first and second operands are compared. If they are equal,
12106       the third operand is stored at the second-operand location. */
12107    cas = mkIRCAS(old_mem_high, old_mem_low,
12108                  Iend_BE, mkexpr(op2addr),
12109                  mkexpr(op1_high), mkexpr(op1_low), /* expected value */
12110                  mkexpr(op3_high), mkexpr(op3_low)  /* new value */);
12111    stmt(IRStmt_CAS(cas));
12112 
12113    /* Set CC. Operands compared equal -> 0, else 1. */
12114    assign(result, unop(Iop_1Uto32,
12115           binop(Iop_CmpNE32,
12116                 binop(Iop_Or32,
12117                       binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
12118                       binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
12119                 mkU32(0))));
12120 
12121    s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12122 
12123    /* If operands were equal (cc == 0) just store the old value op1 in r1.
12124       Otherwise, store the old_value from memory in r1 and yield. */
12125    assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12126    put_gpr_w1(r1,   mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
12127    put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low),  mkexpr(op1_low)));
12128    yield_if(mkexpr(nequal));
12129 }
12130 
12131 static const HChar *
s390_irgen_CDS(UChar r1,UChar r3,IRTemp op2addr)12132 s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
12133 {
12134    s390_irgen_cdas_32(r1, r3, op2addr);
12135 
12136    return "cds";
12137 }
12138 
12139 static const HChar *
s390_irgen_CDSY(UChar r1,UChar r3,IRTemp op2addr)12140 s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
12141 {
12142    s390_irgen_cdas_32(r1, r3, op2addr);
12143 
12144    return "cdsy";
12145 }
12146 
12147 static const HChar *
s390_irgen_CDSG(UChar r1,UChar r3,IRTemp op2addr)12148 s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
12149 {
12150    IRCAS *cas;
12151    IRTemp op1_high = newTemp(Ity_I64);
12152    IRTemp op1_low  = newTemp(Ity_I64);
12153    IRTemp old_mem_high = newTemp(Ity_I64);
12154    IRTemp old_mem_low  = newTemp(Ity_I64);
12155    IRTemp op3_high = newTemp(Ity_I64);
12156    IRTemp op3_low  = newTemp(Ity_I64);
12157    IRTemp result = newTemp(Ity_I64);
12158    IRTemp nequal = newTemp(Ity_I1);
12159 
12160    assign(op1_high, get_gpr_dw0(r1));
12161    assign(op1_low,  get_gpr_dw0(r1+1));
12162    assign(op3_high, get_gpr_dw0(r3));
12163    assign(op3_low,  get_gpr_dw0(r3+1));
12164 
12165    /* The first and second operands are compared. If they are equal,
12166       the third operand is stored at the second-operand location. */
12167    cas = mkIRCAS(old_mem_high, old_mem_low,
12168                  Iend_BE, mkexpr(op2addr),
12169                  mkexpr(op1_high), mkexpr(op1_low), /* expected value */
12170                  mkexpr(op3_high), mkexpr(op3_low)  /* new value */);
12171    stmt(IRStmt_CAS(cas));
12172 
12173    /* Set CC. Operands compared equal -> 0, else 1. */
12174    assign(result, unop(Iop_1Uto64,
12175           binop(Iop_CmpNE64,
12176                 binop(Iop_Or64,
12177                       binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
12178                       binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
12179                 mkU64(0))));
12180 
12181    s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12182 
12183    /* If operands were equal (cc == 0) just store the old value op1 in r1.
12184       Otherwise, store the old_value from memory in r1 and yield. */
12185    assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12186    put_gpr_dw0(r1,   mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
12187    put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low),  mkexpr(op1_low)));
12188    yield_if(mkexpr(nequal));
12189 
12190    return "cdsg";
12191 }
12192 
12193 
12194 /* Binary floating point */
12195 
12196 static const HChar *
s390_irgen_AXBR(UChar r1,UChar r2)12197 s390_irgen_AXBR(UChar r1, UChar r2)
12198 {
12199    IRTemp op1 = newTemp(Ity_F128);
12200    IRTemp op2 = newTemp(Ity_F128);
12201    IRTemp result = newTemp(Ity_F128);
12202    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12203 
12204    assign(op1, get_fpr_pair(r1));
12205    assign(op2, get_fpr_pair(r2));
12206    assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
12207                         mkexpr(op2)));
12208    put_fpr_pair(r1, mkexpr(result));
12209 
12210    s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12211 
12212    return "axbr";
12213 }
12214 
12215 static const HChar *
s390_irgen_CEBR(UChar r1,UChar r2)12216 s390_irgen_CEBR(UChar r1, UChar r2)
12217 {
12218    IRTemp op1 = newTemp(Ity_F32);
12219    IRTemp op2 = newTemp(Ity_F32);
12220    IRTemp cc_vex  = newTemp(Ity_I32);
12221    IRTemp cc_s390 = newTemp(Ity_I32);
12222 
12223    assign(op1, get_fpr_w0(r1));
12224    assign(op2, get_fpr_w0(r2));
12225    assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12226 
12227    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12228    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12229 
12230    return "cebr";
12231 }
12232 
12233 static const HChar *
s390_irgen_CDBR(UChar r1,UChar r2)12234 s390_irgen_CDBR(UChar r1, UChar r2)
12235 {
12236    IRTemp op1 = newTemp(Ity_F64);
12237    IRTemp op2 = newTemp(Ity_F64);
12238    IRTemp cc_vex  = newTemp(Ity_I32);
12239    IRTemp cc_s390 = newTemp(Ity_I32);
12240 
12241    assign(op1, get_fpr_dw0(r1));
12242    assign(op2, get_fpr_dw0(r2));
12243    assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12244 
12245    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12246    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12247 
12248    return "cdbr";
12249 }
12250 
12251 static const HChar *
s390_irgen_CXBR(UChar r1,UChar r2)12252 s390_irgen_CXBR(UChar r1, UChar r2)
12253 {
12254    IRTemp op1 = newTemp(Ity_F128);
12255    IRTemp op2 = newTemp(Ity_F128);
12256    IRTemp cc_vex  = newTemp(Ity_I32);
12257    IRTemp cc_s390 = newTemp(Ity_I32);
12258 
12259    assign(op1, get_fpr_pair(r1));
12260    assign(op2, get_fpr_pair(r2));
12261    assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
12262 
12263    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12264    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12265 
12266    return "cxbr";
12267 }
12268 
12269 static const HChar *
s390_irgen_CEB(UChar r1,IRTemp op2addr)12270 s390_irgen_CEB(UChar r1, IRTemp op2addr)
12271 {
12272    IRTemp op1 = newTemp(Ity_F32);
12273    IRTemp op2 = newTemp(Ity_F32);
12274    IRTemp cc_vex  = newTemp(Ity_I32);
12275    IRTemp cc_s390 = newTemp(Ity_I32);
12276 
12277    assign(op1, get_fpr_w0(r1));
12278    assign(op2, load(Ity_F32, mkexpr(op2addr)));
12279    assign(cc_vex,  binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12280 
12281    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12282    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12283 
12284    return "ceb";
12285 }
12286 
12287 static const HChar *
s390_irgen_CDB(UChar r1,IRTemp op2addr)12288 s390_irgen_CDB(UChar r1, IRTemp op2addr)
12289 {
12290    IRTemp op1 = newTemp(Ity_F64);
12291    IRTemp op2 = newTemp(Ity_F64);
12292    IRTemp cc_vex  = newTemp(Ity_I32);
12293    IRTemp cc_s390 = newTemp(Ity_I32);
12294 
12295    assign(op1, get_fpr_dw0(r1));
12296    assign(op2, load(Ity_F64, mkexpr(op2addr)));
12297    assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12298 
12299    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12300    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12301 
12302    return "cdb";
12303 }
12304 
12305 static const HChar *
s390_irgen_CXFBR(UChar m3,UChar m4,UChar r1,UChar r2)12306 s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
12307                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12308 {
12309    IRTemp op2 = newTemp(Ity_I32);
12310 
12311    assign(op2, get_gpr_w1(r2));
12312    put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
12313 
12314    return "cxfbr";
12315 }
12316 
12317 static const HChar *
s390_irgen_CXLFBR(UChar m3,UChar m4,UChar r1,UChar r2)12318 s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
12319                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12320 {
12321    if (! s390_host_has_fpext) {
12322       emulation_failure(EmFail_S390X_fpext);
12323    } else {
12324       IRTemp op2 = newTemp(Ity_I32);
12325 
12326       assign(op2, get_gpr_w1(r2));
12327       put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
12328    }
12329    return "cxlfbr";
12330 }
12331 
12332 
12333 static const HChar *
s390_irgen_CXGBR(UChar m3,UChar m4,UChar r1,UChar r2)12334 s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
12335                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12336 {
12337    IRTemp op2 = newTemp(Ity_I64);
12338 
12339    assign(op2, get_gpr_dw0(r2));
12340    put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
12341 
12342    return "cxgbr";
12343 }
12344 
12345 static const HChar *
s390_irgen_CXLGBR(UChar m3,UChar m4,UChar r1,UChar r2)12346 s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
12347                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12348 {
12349    if (! s390_host_has_fpext) {
12350       emulation_failure(EmFail_S390X_fpext);
12351    } else {
12352       IRTemp op2 = newTemp(Ity_I64);
12353 
12354       assign(op2, get_gpr_dw0(r2));
12355       put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
12356    }
12357    return "cxlgbr";
12358 }
12359 
12360 static const HChar *
s390_irgen_CFXBR(UChar m3,UChar m4,UChar r1,UChar r2)12361 s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
12362                  UChar r1, UChar r2)
12363 {
12364    IRTemp op = newTemp(Ity_F128);
12365    IRTemp result = newTemp(Ity_I32);
12366    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12367 
12368    assign(op, get_fpr_pair(r2));
12369    assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
12370                         mkexpr(op)));
12371    put_gpr_w1(r1, mkexpr(result));
12372    s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
12373 
12374    return "cfxbr";
12375 }
12376 
12377 static const HChar *
s390_irgen_CLFXBR(UChar m3,UChar m4,UChar r1,UChar r2)12378 s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12379                   UChar r1, UChar r2)
12380 {
12381    if (! s390_host_has_fpext) {
12382       emulation_failure(EmFail_S390X_fpext);
12383    } else {
12384       IRTemp op = newTemp(Ity_F128);
12385       IRTemp result = newTemp(Ity_I32);
12386       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12387 
12388       assign(op, get_fpr_pair(r2));
12389       assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
12390                            mkexpr(op)));
12391       put_gpr_w1(r1, mkexpr(result));
12392       s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
12393    }
12394    return "clfxbr";
12395 }
12396 
12397 
12398 static const HChar *
s390_irgen_CGXBR(UChar m3,UChar m4,UChar r1,UChar r2)12399 s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12400                  UChar r1, UChar r2)
12401 {
12402    IRTemp op = newTemp(Ity_F128);
12403    IRTemp result = newTemp(Ity_I64);
12404    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12405 
12406    assign(op, get_fpr_pair(r2));
12407    assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
12408                         mkexpr(op)));
12409    put_gpr_dw0(r1, mkexpr(result));
12410    s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
12411 
12412    return "cgxbr";
12413 }
12414 
12415 static const HChar *
s390_irgen_CLGXBR(UChar m3,UChar m4,UChar r1,UChar r2)12416 s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12417                   UChar r1, UChar r2)
12418 {
12419    if (! s390_host_has_fpext) {
12420       emulation_failure(EmFail_S390X_fpext);
12421    } else {
12422       IRTemp op = newTemp(Ity_F128);
12423       IRTemp result = newTemp(Ity_I64);
12424       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12425 
12426       assign(op, get_fpr_pair(r2));
12427       assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
12428                            mkexpr(op)));
12429       put_gpr_dw0(r1, mkexpr(result));
12430       s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12431                               rounding_mode);
12432    }
12433    return "clgxbr";
12434 }
12435 
12436 static const HChar *
s390_irgen_DXBR(UChar r1,UChar r2)12437 s390_irgen_DXBR(UChar r1, UChar r2)
12438 {
12439    IRTemp op1 = newTemp(Ity_F128);
12440    IRTemp op2 = newTemp(Ity_F128);
12441    IRTemp result = newTemp(Ity_F128);
12442    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12443 
12444    assign(op1, get_fpr_pair(r1));
12445    assign(op2, get_fpr_pair(r2));
12446    assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
12447                         mkexpr(op2)));
12448    put_fpr_pair(r1, mkexpr(result));
12449 
12450    return "dxbr";
12451 }
12452 
12453 static const HChar *
s390_irgen_LTXBR(UChar r1,UChar r2)12454 s390_irgen_LTXBR(UChar r1, UChar r2)
12455 {
12456    IRTemp result = newTemp(Ity_F128);
12457 
12458    assign(result, get_fpr_pair(r2));
12459    put_fpr_pair(r1, mkexpr(result));
12460    s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12461 
12462    return "ltxbr";
12463 }
12464 
12465 static const HChar *
s390_irgen_LCXBR(UChar r1,UChar r2)12466 s390_irgen_LCXBR(UChar r1, UChar r2)
12467 {
12468    IRTemp result = newTemp(Ity_F128);
12469 
12470    assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
12471    put_fpr_pair(r1, mkexpr(result));
12472    s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12473 
12474    return "lcxbr";
12475 }
12476 
12477 static const HChar *
s390_irgen_LXDBR(UChar r1,UChar r2)12478 s390_irgen_LXDBR(UChar r1, UChar r2)
12479 {
12480    IRTemp op = newTemp(Ity_F64);
12481 
12482    assign(op, get_fpr_dw0(r2));
12483    put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12484 
12485    return "lxdbr";
12486 }
12487 
12488 static const HChar *
s390_irgen_LXEBR(UChar r1,UChar r2)12489 s390_irgen_LXEBR(UChar r1, UChar r2)
12490 {
12491    IRTemp op = newTemp(Ity_F32);
12492 
12493    assign(op, get_fpr_w0(r2));
12494    put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12495 
12496    return "lxebr";
12497 }
12498 
12499 static const HChar *
s390_irgen_LXDB(UChar r1,IRTemp op2addr)12500 s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12501 {
12502    IRTemp op = newTemp(Ity_F64);
12503 
12504    assign(op, load(Ity_F64, mkexpr(op2addr)));
12505    put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12506 
12507    return "lxdb";
12508 }
12509 
12510 static const HChar *
s390_irgen_LXEB(UChar r1,IRTemp op2addr)12511 s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12512 {
12513    IRTemp op = newTemp(Ity_F32);
12514 
12515    assign(op, load(Ity_F32, mkexpr(op2addr)));
12516    put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12517 
12518    return "lxeb";
12519 }
12520 
12521 static const HChar *
s390_irgen_FIEBRA(UChar m3,UChar m4,UChar r1,UChar r2)12522 s390_irgen_FIEBRA(UChar m3, UChar m4 __attribute__((unused)),
12523                   UChar r1, UChar r2)
12524 {
12525    IRTemp result = newTemp(Ity_F32);
12526 
12527    assign(result, binop(Iop_RoundF32toInt, mkexpr(encode_bfp_rounding_mode(m3)),
12528                         get_fpr_w0(r2)));
12529    put_fpr_w0(r1, mkexpr(result));
12530 
12531    return "fiebra";
12532 }
12533 
12534 static const HChar *
s390_irgen_FIDBRA(UChar m3,UChar m4,UChar r1,UChar r2)12535 s390_irgen_FIDBRA(UChar m3, UChar m4 __attribute__((unused)),
12536                   UChar r1, UChar r2)
12537 {
12538    IRTemp result = newTemp(Ity_F64);
12539 
12540    assign(result, binop(Iop_RoundF64toInt, mkexpr(encode_bfp_rounding_mode(m3)),
12541                         get_fpr_dw0(r2)));
12542    put_fpr_dw0(r1, mkexpr(result));
12543 
12544    return "fidbra";
12545 }
12546 
12547 static const HChar *
s390_irgen_FIXBRA(UChar m3,UChar m4,UChar r1,UChar r2)12548 s390_irgen_FIXBRA(UChar m3, UChar m4 __attribute__((unused)),
12549                   UChar r1, UChar r2)
12550 {
12551    IRTemp result = newTemp(Ity_F128);
12552 
12553    assign(result, binop(Iop_RoundF128toInt, mkexpr(encode_bfp_rounding_mode(m3)),
12554                         get_fpr_pair(r2)));
12555    put_fpr_pair(r1, mkexpr(result));
12556 
12557    return "fixbra";
12558 }
12559 
12560 static const HChar *
s390_irgen_LNEBR(UChar r1,UChar r2)12561 s390_irgen_LNEBR(UChar r1, UChar r2)
12562 {
12563    IRTemp result = newTemp(Ity_F32);
12564 
12565    assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12566    put_fpr_w0(r1, mkexpr(result));
12567    s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12568 
12569    return "lnebr";
12570 }
12571 
12572 static const HChar *
s390_irgen_LNDBR(UChar r1,UChar r2)12573 s390_irgen_LNDBR(UChar r1, UChar r2)
12574 {
12575    IRTemp result = newTemp(Ity_F64);
12576 
12577    assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12578    put_fpr_dw0(r1, mkexpr(result));
12579    s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12580 
12581    return "lndbr";
12582 }
12583 
12584 static const HChar *
s390_irgen_LNXBR(UChar r1,UChar r2)12585 s390_irgen_LNXBR(UChar r1, UChar r2)
12586 {
12587    IRTemp result = newTemp(Ity_F128);
12588 
12589    assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12590    put_fpr_pair(r1, mkexpr(result));
12591    s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12592 
12593    return "lnxbr";
12594 }
12595 
12596 static const HChar *
s390_irgen_LPEBR(UChar r1,UChar r2)12597 s390_irgen_LPEBR(UChar r1, UChar r2)
12598 {
12599    IRTemp result = newTemp(Ity_F32);
12600 
12601    assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12602    put_fpr_w0(r1, mkexpr(result));
12603    s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12604 
12605    return "lpebr";
12606 }
12607 
12608 static const HChar *
s390_irgen_LPDBR(UChar r1,UChar r2)12609 s390_irgen_LPDBR(UChar r1, UChar r2)
12610 {
12611    IRTemp result = newTemp(Ity_F64);
12612 
12613    assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12614    put_fpr_dw0(r1, mkexpr(result));
12615    s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12616 
12617    return "lpdbr";
12618 }
12619 
12620 static const HChar *
s390_irgen_LPXBR(UChar r1,UChar r2)12621 s390_irgen_LPXBR(UChar r1, UChar r2)
12622 {
12623    IRTemp result = newTemp(Ity_F128);
12624 
12625    assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12626    put_fpr_pair(r1, mkexpr(result));
12627    s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12628 
12629    return "lpxbr";
12630 }
12631 
12632 static const HChar *
s390_irgen_LDXBR(UChar m3,UChar m4,UChar r1,UChar r2)12633 s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12634                  UChar r1, UChar r2)
12635 {
12636    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
12637       emulation_warning(EmWarn_S390X_fpext_rounding);
12638       m3 = S390_BFP_ROUND_PER_FPC;
12639    }
12640    IRTemp result = newTemp(Ity_F64);
12641 
12642    assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
12643                         get_fpr_pair(r2)));
12644    put_fpr_dw0(r1, mkexpr(result));
12645 
12646    return "ldxbr";
12647 }
12648 
12649 static const HChar *
s390_irgen_LEXBR(UChar m3,UChar m4,UChar r1,UChar r2)12650 s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12651                  UChar r1, UChar r2)
12652 {
12653    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
12654       emulation_warning(EmWarn_S390X_fpext_rounding);
12655       m3 = S390_BFP_ROUND_PER_FPC;
12656    }
12657    IRTemp result = newTemp(Ity_F32);
12658 
12659    assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
12660                         get_fpr_pair(r2)));
12661    put_fpr_w0(r1, mkexpr(result));
12662 
12663    return "lexbr";
12664 }
12665 
12666 static const HChar *
s390_irgen_MXBR(UChar r1,UChar r2)12667 s390_irgen_MXBR(UChar r1, UChar r2)
12668 {
12669    IRTemp op1 = newTemp(Ity_F128);
12670    IRTemp op2 = newTemp(Ity_F128);
12671    IRTemp result = newTemp(Ity_F128);
12672    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12673 
12674    assign(op1, get_fpr_pair(r1));
12675    assign(op2, get_fpr_pair(r2));
12676    assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
12677                         mkexpr(op2)));
12678    put_fpr_pair(r1, mkexpr(result));
12679 
12680    return "mxbr";
12681 }
12682 
12683 static const HChar *
s390_irgen_MAEBR(UChar r1,UChar r3,UChar r2)12684 s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12685 {
12686    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12687 
12688    put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
12689                       get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
12690 
12691    return "maebr";
12692 }
12693 
12694 static const HChar *
s390_irgen_MADBR(UChar r1,UChar r3,UChar r2)12695 s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12696 {
12697    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12698 
12699    put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
12700                        get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
12701 
12702    return "madbr";
12703 }
12704 
12705 static const HChar *
s390_irgen_MAEB(UChar r3,IRTemp op2addr,UChar r1)12706 s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12707 {
12708    IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
12709    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12710 
12711    put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
12712                       get_fpr_w0(r3), op2, get_fpr_w0(r1)));
12713 
12714    return "maeb";
12715 }
12716 
12717 static const HChar *
s390_irgen_MADB(UChar r3,IRTemp op2addr,UChar r1)12718 s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12719 {
12720    IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
12721    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12722 
12723    put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
12724                        get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
12725 
12726    return "madb";
12727 }
12728 
12729 static const HChar *
s390_irgen_MSEBR(UChar r1,UChar r3,UChar r2)12730 s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12731 {
12732    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12733 
12734    put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
12735                       get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
12736 
12737    return "msebr";
12738 }
12739 
12740 static const HChar *
s390_irgen_MSDBR(UChar r1,UChar r3,UChar r2)12741 s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12742 {
12743    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12744 
12745    put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
12746                        get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
12747 
12748    return "msdbr";
12749 }
12750 
12751 static const HChar *
s390_irgen_MSEB(UChar r3,IRTemp op2addr,UChar r1)12752 s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12753 {
12754    IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
12755    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12756 
12757    put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
12758                       get_fpr_w0(r3), op2, get_fpr_w0(r1)));
12759 
12760    return "mseb";
12761 }
12762 
12763 static const HChar *
s390_irgen_MSDB(UChar r3,IRTemp op2addr,UChar r1)12764 s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12765 {
12766    IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
12767    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12768 
12769    put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
12770                        get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
12771 
12772    return "msdb";
12773 }
12774 
12775 static const HChar *
s390_irgen_SQEBR(UChar r1,UChar r2)12776 s390_irgen_SQEBR(UChar r1, UChar r2)
12777 {
12778    IRTemp result = newTemp(Ity_F32);
12779    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12780 
12781    assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
12782    put_fpr_w0(r1, mkexpr(result));
12783 
12784    return "sqebr";
12785 }
12786 
12787 static const HChar *
s390_irgen_SQDBR(UChar r1,UChar r2)12788 s390_irgen_SQDBR(UChar r1, UChar r2)
12789 {
12790    IRTemp result = newTemp(Ity_F64);
12791    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12792 
12793    assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
12794    put_fpr_dw0(r1, mkexpr(result));
12795 
12796    return "sqdbr";
12797 }
12798 
12799 static const HChar *
s390_irgen_SQXBR(UChar r1,UChar r2)12800 s390_irgen_SQXBR(UChar r1, UChar r2)
12801 {
12802    IRTemp result = newTemp(Ity_F128);
12803    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12804 
12805    assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12806                         get_fpr_pair(r2)));
12807    put_fpr_pair(r1, mkexpr(result));
12808 
12809    return "sqxbr";
12810 }
12811 
12812 static const HChar *
s390_irgen_SQEB(UChar r1,IRTemp op2addr)12813 s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12814 {
12815    IRTemp op = newTemp(Ity_F32);
12816    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12817 
12818    assign(op, load(Ity_F32, mkexpr(op2addr)));
12819    put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
12820 
12821    return "sqeb";
12822 }
12823 
12824 static const HChar *
s390_irgen_SQDB(UChar r1,IRTemp op2addr)12825 s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12826 {
12827    IRTemp op = newTemp(Ity_F64);
12828    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12829 
12830    assign(op, load(Ity_F64, mkexpr(op2addr)));
12831    put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
12832 
12833    return "sqdb";
12834 }
12835 
12836 static const HChar *
s390_irgen_SXBR(UChar r1,UChar r2)12837 s390_irgen_SXBR(UChar r1, UChar r2)
12838 {
12839    IRTemp op1 = newTemp(Ity_F128);
12840    IRTemp op2 = newTemp(Ity_F128);
12841    IRTemp result = newTemp(Ity_F128);
12842    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12843 
12844    assign(op1, get_fpr_pair(r1));
12845    assign(op2, get_fpr_pair(r2));
12846    assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
12847                         mkexpr(op2)));
12848    put_fpr_pair(r1, mkexpr(result));
12849    s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12850 
12851    return "sxbr";
12852 }
12853 
12854 static const HChar *
s390_irgen_TCEB(UChar r1,IRTemp op2addr)12855 s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12856 {
12857    IRTemp value = newTemp(Ity_F32);
12858 
12859    assign(value, get_fpr_w0(r1));
12860 
12861    s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12862 
12863    return "tceb";
12864 }
12865 
12866 static const HChar *
s390_irgen_TCDB(UChar r1,IRTemp op2addr)12867 s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12868 {
12869    IRTemp value = newTemp(Ity_F64);
12870 
12871    assign(value, get_fpr_dw0(r1));
12872 
12873    s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12874 
12875    return "tcdb";
12876 }
12877 
12878 static const HChar *
s390_irgen_TCXB(UChar r1,IRTemp op2addr)12879 s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12880 {
12881    IRTemp value = newTemp(Ity_F128);
12882 
12883    assign(value, get_fpr_pair(r1));
12884 
12885    s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12886 
12887    return "tcxb";
12888 }
12889 
12890 static const HChar *
s390_irgen_LCDFR(UChar r1,UChar r2)12891 s390_irgen_LCDFR(UChar r1, UChar r2)
12892 {
12893    IRTemp result = newTemp(Ity_F64);
12894 
12895    assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12896    put_fpr_dw0(r1, mkexpr(result));
12897 
12898    return "lcdfr";
12899 }
12900 
12901 static const HChar *
s390_irgen_LNDFR(UChar r1,UChar r2)12902 s390_irgen_LNDFR(UChar r1, UChar r2)
12903 {
12904    IRTemp result = newTemp(Ity_F64);
12905 
12906    assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12907    put_fpr_dw0(r1, mkexpr(result));
12908 
12909    return "lndfr";
12910 }
12911 
12912 static const HChar *
s390_irgen_LPDFR(UChar r1,UChar r2)12913 s390_irgen_LPDFR(UChar r1, UChar r2)
12914 {
12915    IRTemp result = newTemp(Ity_F64);
12916 
12917    assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12918    put_fpr_dw0(r1, mkexpr(result));
12919 
12920    return "lpdfr";
12921 }
12922 
12923 static const HChar *
s390_irgen_LDGR(UChar r1,UChar r2)12924 s390_irgen_LDGR(UChar r1, UChar r2)
12925 {
12926    put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12927 
12928    return "ldgr";
12929 }
12930 
12931 static const HChar *
s390_irgen_LGDR(UChar r1,UChar r2)12932 s390_irgen_LGDR(UChar r1, UChar r2)
12933 {
12934    put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12935 
12936    return "lgdr";
12937 }
12938 
12939 
12940 static const HChar *
s390_irgen_CPSDR(UChar r3,UChar r1,UChar r2)12941 s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12942 {
12943    IRTemp sign  = newTemp(Ity_I64);
12944    IRTemp value = newTemp(Ity_I64);
12945 
12946    assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12947                       mkU64(1ULL << 63)));
12948    assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12949                        mkU64((1ULL << 63) - 1)));
12950    put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12951                                                     mkexpr(sign))));
12952 
12953    return "cpsdr";
12954 }
12955 
12956 
12957 static IRExpr *
s390_call_cvb(IRExpr * in)12958 s390_call_cvb(IRExpr *in)
12959 {
12960    IRExpr **args, *call;
12961 
12962    args = mkIRExprVec_1(in);
12963    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12964                         "s390_do_cvb", &s390_do_cvb, args);
12965 
12966    /* Nothing is excluded from definedness checking. */
12967    call->Iex.CCall.cee->mcx_mask = 0;
12968 
12969    return call;
12970 }
12971 
12972 static const HChar *
s390_irgen_CVB(UChar r1,IRTemp op2addr)12973 s390_irgen_CVB(UChar r1, IRTemp op2addr)
12974 {
12975    put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12976 
12977    return "cvb";
12978 }
12979 
12980 static const HChar *
s390_irgen_CVBY(UChar r1,IRTemp op2addr)12981 s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12982 {
12983    put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12984 
12985    return "cvby";
12986 }
12987 
12988 
12989 static IRExpr *
s390_call_cvd(IRExpr * in)12990 s390_call_cvd(IRExpr *in)
12991 {
12992    IRExpr **args, *call;
12993 
12994    args = mkIRExprVec_1(in);
12995    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12996                         "s390_do_cvd", &s390_do_cvd, args);
12997 
12998    /* Nothing is excluded from definedness checking. */
12999    call->Iex.CCall.cee->mcx_mask = 0;
13000 
13001    return call;
13002 }
13003 
13004 static const HChar *
s390_irgen_CVD(UChar r1,IRTemp op2addr)13005 s390_irgen_CVD(UChar r1, IRTemp op2addr)
13006 {
13007    store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
13008 
13009    return "cvd";
13010 }
13011 
13012 static const HChar *
s390_irgen_CVDY(UChar r1,IRTemp op2addr)13013 s390_irgen_CVDY(UChar r1, IRTemp op2addr)
13014 {
13015    store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
13016 
13017    return "cvdy";
13018 }
13019 
13020 static const HChar *
s390_irgen_FLOGR(UChar r1,UChar r2)13021 s390_irgen_FLOGR(UChar r1, UChar r2)
13022 {
13023    IRTemp input    = newTemp(Ity_I64);
13024    IRTemp not_zero = newTemp(Ity_I64);
13025    IRTemp tmpnum   = newTemp(Ity_I64);
13026    IRTemp num      = newTemp(Ity_I64);
13027    IRTemp shift_amount = newTemp(Ity_I8);
13028 
13029    /* We use the "count leading zeroes" operator because the number of
13030       leading zeroes is identical with the bit position of the first '1' bit.
13031       However, that operator does not work when the input value is zero.
13032       Therefore, we set the LSB of the input value to 1 and use Clz64 on
13033       the modified value. If input == 0, then the result is 64. Otherwise,
13034       the result of Clz64 is what we want. */
13035 
13036    assign(input, get_gpr_dw0(r2));
13037    assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
13038    assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
13039 
13040    /* num = (input == 0) ? 64 : tmpnum */
13041    assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
13042                      /* == 0 */ mkU64(64),
13043                      /* != 0 */ mkexpr(tmpnum)));
13044 
13045    put_gpr_dw0(r1, mkexpr(num));
13046 
13047    /* Set the leftmost '1' bit of the input value to zero. The general scheme
13048       is to first shift the input value by NUM + 1 bits to the left which
13049       causes the leftmost '1' bit to disappear. Then we shift logically to
13050       the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
13051       Iop_Shr64 are undefined if the shift-amount is greater than or equal to
13052       the width of the value-to-be-shifted, we need to special case
13053       NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
13054       For both such INPUT values the result will be 0. */
13055 
13056    assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
13057                           mkU64(1))));
13058 
13059    put_gpr_dw0(r1 + 1,
13060                mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
13061                      /* == 0 || == 1*/ mkU64(0),
13062                      /* otherwise */
13063                      binop(Iop_Shr64,
13064                            binop(Iop_Shl64, mkexpr(input),
13065                                  mkexpr(shift_amount)),
13066                            mkexpr(shift_amount))));
13067 
13068    /* Compare the original value as an unsigned integer with 0. */
13069    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
13070                       mktemp(Ity_I64, mkU64(0)), False);
13071 
13072    return "flogr";
13073 }
13074 
13075 static const HChar *
s390_irgen_POPCNT(UChar r1,UChar r2)13076 s390_irgen_POPCNT(UChar r1, UChar r2)
13077 {
13078    Int i;
13079    IRTemp val = newTemp(Ity_I64);
13080    IRTemp mask[3];
13081 
13082    assign(val, get_gpr_dw0(r2));
13083    for (i = 0; i < 3; i++) {
13084       mask[i] = newTemp(Ity_I64);
13085    }
13086    assign(mask[0], mkU64(0x5555555555555555ULL));
13087    assign(mask[1], mkU64(0x3333333333333333ULL));
13088    assign(mask[2], mkU64(0x0F0F0F0F0F0F0F0FULL));
13089    for (i = 0; i < 3; i++) {
13090       IRTemp tmp = newTemp(Ity_I64);
13091 
13092       assign(tmp,
13093              binop(Iop_Add64,
13094                    binop(Iop_And64,
13095                          mkexpr(val),
13096                          mkexpr(mask[i])),
13097                    binop(Iop_And64,
13098                          binop(Iop_Shr64, mkexpr(val), mkU8(1 << i)),
13099                          mkexpr(mask[i]))));
13100       val = tmp;
13101    }
13102    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, val);
13103    put_gpr_dw0(r1, mkexpr(val));
13104    return "popcnt";
13105 }
13106 
13107 static const HChar *
s390_irgen_STCK(IRTemp op2addr)13108 s390_irgen_STCK(IRTemp op2addr)
13109 {
13110    IRDirty *d;
13111    IRTemp cc = newTemp(Ity_I64);
13112 
13113    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
13114                          &s390x_dirtyhelper_STCK,
13115                          mkIRExprVec_1(mkexpr(op2addr)));
13116    d->mFx   = Ifx_Write;
13117    d->mAddr = mkexpr(op2addr);
13118    d->mSize = 8;
13119    stmt(IRStmt_Dirty(d));
13120    s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
13121                       mkexpr(cc), mkU64(0), mkU64(0));
13122    return "stck";
13123 }
13124 
13125 static const HChar *
s390_irgen_STCKF(IRTemp op2addr)13126 s390_irgen_STCKF(IRTemp op2addr)
13127 {
13128    if (! s390_host_has_stckf) {
13129       emulation_failure(EmFail_S390X_stckf);
13130    } else {
13131       IRTemp cc = newTemp(Ity_I64);
13132 
13133       IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
13134                                      &s390x_dirtyhelper_STCKF,
13135                                      mkIRExprVec_1(mkexpr(op2addr)));
13136       d->mFx   = Ifx_Write;
13137       d->mAddr = mkexpr(op2addr);
13138       d->mSize = 8;
13139       stmt(IRStmt_Dirty(d));
13140       s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
13141                          mkexpr(cc), mkU64(0), mkU64(0));
13142    }
13143    return "stckf";
13144 }
13145 
13146 static const HChar *
s390_irgen_STCKE(IRTemp op2addr)13147 s390_irgen_STCKE(IRTemp op2addr)
13148 {
13149    IRDirty *d;
13150    IRTemp cc = newTemp(Ity_I64);
13151 
13152    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
13153                          &s390x_dirtyhelper_STCKE,
13154                          mkIRExprVec_1(mkexpr(op2addr)));
13155    d->mFx   = Ifx_Write;
13156    d->mAddr = mkexpr(op2addr);
13157    d->mSize = 16;
13158    stmt(IRStmt_Dirty(d));
13159    s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
13160                       mkexpr(cc), mkU64(0), mkU64(0));
13161    return "stcke";
13162 }
13163 
13164 static const HChar *
s390_irgen_STFLE(IRTemp op2addr)13165 s390_irgen_STFLE(IRTemp op2addr)
13166 {
13167    if (! s390_host_has_stfle) {
13168       emulation_failure(EmFail_S390X_stfle);
13169       return "stfle";
13170    }
13171 
13172    IRDirty *d;
13173    IRTemp cc = newTemp(Ity_I64);
13174 
13175    /* IRExpr_GSPTR() => Need to pass pointer to guest state to helper */
13176    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
13177                          &s390x_dirtyhelper_STFLE,
13178                          mkIRExprVec_2(IRExpr_GSPTR(), mkexpr(op2addr)));
13179 
13180    d->nFxState = 1;
13181    vex_bzero(&d->fxState, sizeof(d->fxState));
13182 
13183    d->fxState[0].fx     = Ifx_Modify;  /* read then write */
13184    d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
13185    d->fxState[0].size   = sizeof(ULong);
13186 
13187    d->mAddr = mkexpr(op2addr);
13188    /* Pretend all double words are written */
13189    d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
13190    d->mFx   = Ifx_Write;
13191 
13192    stmt(IRStmt_Dirty(d));
13193 
13194    s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
13195 
13196    return "stfle";
13197 }
13198 
13199 static const HChar *
s390_irgen_CKSM(UChar r1,UChar r2)13200 s390_irgen_CKSM(UChar r1,UChar r2)
13201 {
13202    IRTemp addr = newTemp(Ity_I64);
13203    IRTemp op = newTemp(Ity_I32);
13204    IRTemp len = newTemp(Ity_I64);
13205    IRTemp oldval = newTemp(Ity_I32);
13206    IRTemp mask = newTemp(Ity_I32);
13207    IRTemp newop = newTemp(Ity_I32);
13208    IRTemp result = newTemp(Ity_I32);
13209    IRTemp result1 = newTemp(Ity_I32);
13210    IRTemp inc = newTemp(Ity_I64);
13211 
13212    assign(oldval, get_gpr_w1(r1));
13213    assign(addr, get_gpr_dw0(r2));
13214    assign(len, get_gpr_dw0(r2+1));
13215 
13216    /* Condition code is always zero. */
13217    s390_cc_set(0);
13218 
13219    /* If length is zero, there is no need to calculate the checksum */
13220    next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
13221 
13222    /* Assiging the increment variable to adjust address and length
13223       later on. */
13224    assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
13225                            mkexpr(len), mkU64(4)));
13226 
13227    /* If length < 4 the final 4-byte 2nd operand value is computed by
13228       appending the remaining bytes to the right with 0. This is done
13229       by AND'ing the 4 bytes loaded from memory with an appropriate
13230       mask. If length >= 4, that mask is simply 0xffffffff. */
13231 
13232    assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
13233                       /* Mask computation when len < 4:
13234                          0xffffffff << (32 - (len % 4)*8) */
13235                       binop(Iop_Shl32, mkU32(0xffffffff),
13236                             unop(Iop_32to8,
13237                                  binop(Iop_Sub32, mkU32(32),
13238                                        binop(Iop_Shl32,
13239                                              unop(Iop_64to32,
13240                                                   binop(Iop_And64,
13241                                                         mkexpr(len), mkU64(3))),
13242                                              mkU8(3))))),
13243                       mkU32(0xffffffff)));
13244 
13245    assign(op, load(Ity_I32, mkexpr(addr)));
13246    assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
13247    assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
13248 
13249    /* Checking for carry */
13250    assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
13251                          binop(Iop_Add32, mkexpr(result), mkU32(1)),
13252                          mkexpr(result)));
13253 
13254    put_gpr_w1(r1, mkexpr(result1));
13255    put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
13256    put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
13257 
13258    iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
13259 
13260    return "cksm";
13261 }
13262 
13263 static const HChar *
s390_irgen_TROO(UChar m3,UChar r1,UChar r2)13264 s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
13265 {
13266    IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13267    src_addr = newTemp(Ity_I64);
13268    des_addr = newTemp(Ity_I64);
13269    tab_addr = newTemp(Ity_I64);
13270    test_byte = newTemp(Ity_I8);
13271    src_len = newTemp(Ity_I64);
13272 
13273    assign(src_addr, get_gpr_dw0(r2));
13274    assign(des_addr, get_gpr_dw0(r1));
13275    assign(tab_addr, get_gpr_dw0(1));
13276    assign(src_len, get_gpr_dw0(r1+1));
13277    assign(test_byte, get_gpr_b7(0));
13278 
13279    IRTemp op = newTemp(Ity_I8);
13280    IRTemp op1 = newTemp(Ity_I8);
13281    IRTemp result = newTemp(Ity_I64);
13282 
13283    /* End of source string? We're done; proceed to next insn */
13284    s390_cc_set(0);
13285    next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13286 
13287    /* Load character from source string, index translation table and
13288       store translated character in op1. */
13289    assign(op, load(Ity_I8, mkexpr(src_addr)));
13290 
13291    assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13292                         mkexpr(tab_addr)));
13293    assign(op1, load(Ity_I8, mkexpr(result)));
13294 
13295    if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13296       s390_cc_set(1);
13297       next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
13298    }
13299    store(get_gpr_dw0(r1), mkexpr(op1));
13300 
13301    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13302    put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13303    put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13304 
13305    iterate();
13306 
13307    return "troo";
13308 }
13309 
13310 static const HChar *
s390_irgen_TRTO(UChar m3,UChar r1,UChar r2)13311 s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
13312 {
13313    IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13314    src_addr = newTemp(Ity_I64);
13315    des_addr = newTemp(Ity_I64);
13316    tab_addr = newTemp(Ity_I64);
13317    test_byte = newTemp(Ity_I8);
13318    src_len = newTemp(Ity_I64);
13319 
13320    assign(src_addr, get_gpr_dw0(r2));
13321    assign(des_addr, get_gpr_dw0(r1));
13322    assign(tab_addr, get_gpr_dw0(1));
13323    assign(src_len, get_gpr_dw0(r1+1));
13324    assign(test_byte, get_gpr_b7(0));
13325 
13326    IRTemp op = newTemp(Ity_I16);
13327    IRTemp op1 = newTemp(Ity_I8);
13328    IRTemp result = newTemp(Ity_I64);
13329 
13330    /* End of source string? We're done; proceed to next insn */
13331    s390_cc_set(0);
13332    next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13333 
13334    /* Load character from source string, index translation table and
13335       store translated character in op1. */
13336    assign(op, load(Ity_I16, mkexpr(src_addr)));
13337 
13338    assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13339                         mkexpr(tab_addr)));
13340 
13341    assign(op1, load(Ity_I8, mkexpr(result)));
13342 
13343    if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13344       s390_cc_set(1);
13345       next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
13346    }
13347    store(get_gpr_dw0(r1), mkexpr(op1));
13348 
13349    put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13350    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13351    put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13352 
13353    iterate();
13354 
13355    return "trto";
13356 }
13357 
13358 static const HChar *
s390_irgen_TROT(UChar m3,UChar r1,UChar r2)13359 s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
13360 {
13361    IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13362    src_addr = newTemp(Ity_I64);
13363    des_addr = newTemp(Ity_I64);
13364    tab_addr = newTemp(Ity_I64);
13365    test_byte = newTemp(Ity_I16);
13366    src_len = newTemp(Ity_I64);
13367 
13368    assign(src_addr, get_gpr_dw0(r2));
13369    assign(des_addr, get_gpr_dw0(r1));
13370    assign(tab_addr, get_gpr_dw0(1));
13371    assign(src_len, get_gpr_dw0(r1+1));
13372    assign(test_byte, get_gpr_hw3(0));
13373 
13374    IRTemp op = newTemp(Ity_I8);
13375    IRTemp op1 = newTemp(Ity_I16);
13376    IRTemp result = newTemp(Ity_I64);
13377 
13378    /* End of source string? We're done; proceed to next insn */
13379    s390_cc_set(0);
13380    next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13381 
13382    /* Load character from source string, index translation table and
13383       store translated character in op1. */
13384    assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
13385 
13386    assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13387                         mkexpr(tab_addr)));
13388    assign(op1, load(Ity_I16, mkexpr(result)));
13389 
13390    if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13391       s390_cc_set(1);
13392       next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
13393    }
13394    store(get_gpr_dw0(r1), mkexpr(op1));
13395 
13396    put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13397    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13398    put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13399 
13400    iterate();
13401 
13402    return "trot";
13403 }
13404 
13405 static const HChar *
s390_irgen_TRTT(UChar m3,UChar r1,UChar r2)13406 s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
13407 {
13408    IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13409    src_addr = newTemp(Ity_I64);
13410    des_addr = newTemp(Ity_I64);
13411    tab_addr = newTemp(Ity_I64);
13412    test_byte = newTemp(Ity_I16);
13413    src_len = newTemp(Ity_I64);
13414 
13415    assign(src_addr, get_gpr_dw0(r2));
13416    assign(des_addr, get_gpr_dw0(r1));
13417    assign(tab_addr, get_gpr_dw0(1));
13418    assign(src_len, get_gpr_dw0(r1+1));
13419    assign(test_byte, get_gpr_hw3(0));
13420 
13421    IRTemp op = newTemp(Ity_I16);
13422    IRTemp op1 = newTemp(Ity_I16);
13423    IRTemp result = newTemp(Ity_I64);
13424 
13425    /* End of source string? We're done; proceed to next insn */
13426    s390_cc_set(0);
13427    next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13428 
13429    /* Load character from source string, index translation table and
13430       store translated character in op1. */
13431    assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
13432 
13433    assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13434                         mkexpr(tab_addr)));
13435    assign(op1, load(Ity_I16, mkexpr(result)));
13436 
13437    if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13438       s390_cc_set(1);
13439       next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
13440    }
13441 
13442    store(get_gpr_dw0(r1), mkexpr(op1));
13443 
13444    put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13445    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13446    put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13447 
13448    iterate();
13449 
13450    return "trtt";
13451 }
13452 
13453 static const HChar *
s390_irgen_TR(UChar length,IRTemp start1,IRTemp start2)13454 s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13455 {
13456    IRTemp len = newTemp(Ity_I64);
13457 
13458    assign(len, mkU64(length));
13459    s390_irgen_TR_EX(len, start1, start2);
13460 
13461    return "tr";
13462 }
13463 
13464 static const HChar *
s390_irgen_TRE(UChar r1,UChar r2)13465 s390_irgen_TRE(UChar r1,UChar r2)
13466 {
13467    IRTemp src_addr, tab_addr, src_len, test_byte;
13468    src_addr = newTemp(Ity_I64);
13469    tab_addr = newTemp(Ity_I64);
13470    src_len = newTemp(Ity_I64);
13471    test_byte = newTemp(Ity_I8);
13472 
13473    assign(src_addr, get_gpr_dw0(r1));
13474    assign(src_len, get_gpr_dw0(r1+1));
13475    assign(tab_addr, get_gpr_dw0(r2));
13476    assign(test_byte, get_gpr_b7(0));
13477 
13478    IRTemp op = newTemp(Ity_I8);
13479    IRTemp op1 = newTemp(Ity_I8);
13480    IRTemp result = newTemp(Ity_I64);
13481 
13482    /* End of source string? We're done; proceed to next insn */
13483    s390_cc_set(0);
13484    next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13485 
13486    /* Load character from source string and compare with test byte */
13487    assign(op, load(Ity_I8, mkexpr(src_addr)));
13488 
13489    s390_cc_set(1);
13490    next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
13491 
13492    assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13493 			mkexpr(tab_addr)));
13494 
13495    assign(op1, load(Ity_I8, mkexpr(result)));
13496 
13497    store(get_gpr_dw0(r1), mkexpr(op1));
13498    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13499    put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13500 
13501    iterate();
13502 
13503    return "tre";
13504 }
13505 
13506 static IRExpr *
s390_call_cu21(IRExpr * srcval,IRExpr * low_surrogate)13507 s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13508 {
13509    IRExpr **args, *call;
13510    args = mkIRExprVec_2(srcval, low_surrogate);
13511    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13512                        "s390_do_cu21", &s390_do_cu21, args);
13513 
13514    /* Nothing is excluded from definedness checking. */
13515    call->Iex.CCall.cee->mcx_mask = 0;
13516 
13517    return call;
13518 }
13519 
13520 static const HChar *
s390_irgen_CU21(UChar m3,UChar r1,UChar r2)13521 s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13522 {
13523    IRTemp addr1 = newTemp(Ity_I64);
13524    IRTemp addr2 = newTemp(Ity_I64);
13525    IRTemp len1 = newTemp(Ity_I64);
13526    IRTemp len2 = newTemp(Ity_I64);
13527 
13528    assign(addr1, get_gpr_dw0(r1));
13529    assign(addr2, get_gpr_dw0(r2));
13530    assign(len1, get_gpr_dw0(r1 + 1));
13531    assign(len2, get_gpr_dw0(r2 + 1));
13532 
13533    /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13534       there are less than 2 bytes left, then the 2nd operand is exhausted
13535       and we're done here. cc = 0 */
13536    s390_cc_set(0);
13537    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
13538 
13539    /* There are at least two bytes there. Read them. */
13540    IRTemp srcval = newTemp(Ity_I32);
13541    assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13542 
13543    /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13544       inside the interval [0xd800 - 0xdbff] */
13545    IRTemp  is_high_surrogate = newTemp(Ity_I32);
13546    IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13547                          mkU32(1), mkU32(0));
13548    IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13549                          mkU32(1), mkU32(0));
13550    assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13551 
13552    /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13553       then the 2nd operand is exhausted and we're done here. cc = 0 */
13554    IRExpr *not_enough_bytes =
13555       mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13556 
13557    next_insn_if(binop(Iop_CmpEQ32,
13558                       binop(Iop_And32, mkexpr(is_high_surrogate),
13559                             not_enough_bytes), mkU32(1)));
13560 
13561    /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13562       surrogate, read the next two bytes (low surrogate). */
13563    IRTemp  low_surrogate = newTemp(Ity_I32);
13564    IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13565 
13566    assign(low_surrogate,
13567           mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13568                 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13569                 mkU32(0)));  // any value is fine; it will not be used
13570 
13571    /* Call the helper */
13572    IRTemp retval = newTemp(Ity_I64);
13573    assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13574                                  unop(Iop_32Uto64, mkexpr(low_surrogate))));
13575 
13576    /* Before we can test whether the 1st operand is exhausted we need to
13577       test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13578    if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13579       IRExpr *invalid_low_surrogate =
13580          binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13581 
13582       s390_cc_set(2);
13583       next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
13584    }
13585 
13586    /* Now test whether the 1st operand is exhausted */
13587    IRTemp num_bytes = newTemp(Ity_I64);
13588    assign(num_bytes, binop(Iop_And64,
13589                            binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13590                            mkU64(0xff)));
13591    s390_cc_set(1);
13592    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13593 
13594    /* Extract the bytes to be stored at addr1 */
13595    IRTemp data = newTemp(Ity_I64);
13596    assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13597 
13598    /* To store the bytes construct 4 dirty helper calls. The helper calls
13599       are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13600       one of them will be called at runtime. */
13601    UInt i;
13602    for (i = 1; i <= 4; ++i) {
13603       IRDirty *d;
13604 
13605       d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13606                             &s390x_dirtyhelper_CUxy,
13607                             mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13608                                           mkexpr(num_bytes)));
13609       d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13610       d->mFx   = Ifx_Write;
13611       d->mAddr = mkexpr(addr1);
13612       d->mSize = i;
13613       stmt(IRStmt_Dirty(d));
13614    }
13615 
13616    /* Update source address and length */
13617    IRTemp num_src_bytes = newTemp(Ity_I64);
13618    assign(num_src_bytes,
13619           mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13620                 mkU64(4), mkU64(2)));
13621    put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13622    put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
13623 
13624    /* Update destination address and length */
13625    put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13626    put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13627 
13628    iterate();
13629 
13630    return "cu21";
13631 }
13632 
13633 static IRExpr *
s390_call_cu24(IRExpr * srcval,IRExpr * low_surrogate)13634 s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13635 {
13636    IRExpr **args, *call;
13637    args = mkIRExprVec_2(srcval, low_surrogate);
13638    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13639                        "s390_do_cu24", &s390_do_cu24, args);
13640 
13641    /* Nothing is excluded from definedness checking. */
13642    call->Iex.CCall.cee->mcx_mask = 0;
13643 
13644    return call;
13645 }
13646 
13647 static const HChar *
s390_irgen_CU24(UChar m3,UChar r1,UChar r2)13648 s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13649 {
13650    IRTemp addr1 = newTemp(Ity_I64);
13651    IRTemp addr2 = newTemp(Ity_I64);
13652    IRTemp len1 = newTemp(Ity_I64);
13653    IRTemp len2 = newTemp(Ity_I64);
13654 
13655    assign(addr1, get_gpr_dw0(r1));
13656    assign(addr2, get_gpr_dw0(r2));
13657    assign(len1, get_gpr_dw0(r1 + 1));
13658    assign(len2, get_gpr_dw0(r2 + 1));
13659 
13660    /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13661       there are less than 2 bytes left, then the 2nd operand is exhausted
13662       and we're done here. cc = 0 */
13663    s390_cc_set(0);
13664    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
13665 
13666    /* There are at least two bytes there. Read them. */
13667    IRTemp srcval = newTemp(Ity_I32);
13668    assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13669 
13670    /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13671       inside the interval [0xd800 - 0xdbff] */
13672    IRTemp  is_high_surrogate = newTemp(Ity_I32);
13673    IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13674                          mkU32(1), mkU32(0));
13675    IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13676                          mkU32(1), mkU32(0));
13677    assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13678 
13679    /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13680       then the 2nd operand is exhausted and we're done here. cc = 0 */
13681    IRExpr *not_enough_bytes =
13682       mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13683 
13684    next_insn_if(binop(Iop_CmpEQ32,
13685                       binop(Iop_And32, mkexpr(is_high_surrogate),
13686                             not_enough_bytes),
13687                       mkU32(1)));
13688 
13689    /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13690       surrogate, read the next two bytes (low surrogate). */
13691    IRTemp  low_surrogate = newTemp(Ity_I32);
13692    IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13693 
13694    assign(low_surrogate,
13695           mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13696                 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13697                 mkU32(0)));  // any value is fine; it will not be used
13698 
13699    /* Call the helper */
13700    IRTemp retval = newTemp(Ity_I64);
13701    assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13702                                  unop(Iop_32Uto64, mkexpr(low_surrogate))));
13703 
13704    /* Before we can test whether the 1st operand is exhausted we need to
13705       test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13706    if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13707       IRExpr *invalid_low_surrogate =
13708          binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13709 
13710       s390_cc_set(2);
13711       next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
13712    }
13713 
13714    /* Now test whether the 1st operand is exhausted */
13715    s390_cc_set(1);
13716    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
13717 
13718    /* Extract the bytes to be stored at addr1 */
13719    IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13720 
13721    store(mkexpr(addr1), data);
13722 
13723    /* Update source address and length */
13724    IRTemp num_src_bytes = newTemp(Ity_I64);
13725    assign(num_src_bytes,
13726           mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13727                 mkU64(4), mkU64(2)));
13728    put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13729    put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
13730 
13731    /* Update destination address and length */
13732    put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13733    put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkU64(4)));
13734 
13735    iterate();
13736 
13737    return "cu24";
13738 }
13739 
13740 static IRExpr *
s390_call_cu42(IRExpr * srcval)13741 s390_call_cu42(IRExpr *srcval)
13742 {
13743    IRExpr **args, *call;
13744    args = mkIRExprVec_1(srcval);
13745    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13746                        "s390_do_cu42", &s390_do_cu42, args);
13747 
13748    /* Nothing is excluded from definedness checking. */
13749    call->Iex.CCall.cee->mcx_mask = 0;
13750 
13751    return call;
13752 }
13753 
13754 static const HChar *
s390_irgen_CU42(UChar r1,UChar r2)13755 s390_irgen_CU42(UChar r1, UChar r2)
13756 {
13757    IRTemp addr1 = newTemp(Ity_I64);
13758    IRTemp addr2 = newTemp(Ity_I64);
13759    IRTemp len1 = newTemp(Ity_I64);
13760    IRTemp len2 = newTemp(Ity_I64);
13761 
13762    assign(addr1, get_gpr_dw0(r1));
13763    assign(addr2, get_gpr_dw0(r2));
13764    assign(len1, get_gpr_dw0(r1 + 1));
13765    assign(len2, get_gpr_dw0(r2 + 1));
13766 
13767    /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13768       there are less than 4 bytes left, then the 2nd operand is exhausted
13769       and we're done here. cc = 0 */
13770    s390_cc_set(0);
13771    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13772 
13773    /* Read the 2nd operand. */
13774    IRTemp srcval = newTemp(Ity_I32);
13775    assign(srcval, load(Ity_I32, mkexpr(addr2)));
13776 
13777    /* Call the helper */
13778    IRTemp retval = newTemp(Ity_I64);
13779    assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
13780 
13781    /* If the UTF-32 character was invalid, set cc=2 and we're done.
13782       cc=2 outranks cc=1 (1st operand exhausted) */
13783    IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13784 
13785    s390_cc_set(2);
13786    next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13787 
13788    /* Now test whether the 1st operand is exhausted */
13789    IRTemp num_bytes = newTemp(Ity_I64);
13790    assign(num_bytes, binop(Iop_And64,
13791                            binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13792                            mkU64(0xff)));
13793    s390_cc_set(1);
13794    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13795 
13796    /* Extract the bytes to be stored at addr1 */
13797    IRTemp data = newTemp(Ity_I64);
13798    assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13799 
13800    /* To store the bytes construct 2 dirty helper calls. The helper calls
13801       are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13802       that only one of them will be called at runtime. */
13803 
13804    Int i;
13805    for (i = 2; i <= 4; ++i) {
13806       IRDirty *d;
13807 
13808       if (i == 3) continue;  // skip this one
13809 
13810       d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13811                             &s390x_dirtyhelper_CUxy,
13812                             mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13813                                           mkexpr(num_bytes)));
13814       d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13815       d->mFx   = Ifx_Write;
13816       d->mAddr = mkexpr(addr1);
13817       d->mSize = i;
13818       stmt(IRStmt_Dirty(d));
13819    }
13820 
13821    /* Update source address and length */
13822    put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13823    put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkU64(4)));
13824 
13825    /* Update destination address and length */
13826    put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13827    put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13828 
13829    iterate();
13830 
13831    return "cu42";
13832 }
13833 
13834 static IRExpr *
s390_call_cu41(IRExpr * srcval)13835 s390_call_cu41(IRExpr *srcval)
13836 {
13837    IRExpr **args, *call;
13838    args = mkIRExprVec_1(srcval);
13839    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13840                        "s390_do_cu41", &s390_do_cu41, args);
13841 
13842    /* Nothing is excluded from definedness checking. */
13843    call->Iex.CCall.cee->mcx_mask = 0;
13844 
13845    return call;
13846 }
13847 
13848 static const HChar *
s390_irgen_CU41(UChar r1,UChar r2)13849 s390_irgen_CU41(UChar r1, UChar r2)
13850 {
13851    IRTemp addr1 = newTemp(Ity_I64);
13852    IRTemp addr2 = newTemp(Ity_I64);
13853    IRTemp len1 = newTemp(Ity_I64);
13854    IRTemp len2 = newTemp(Ity_I64);
13855 
13856    assign(addr1, get_gpr_dw0(r1));
13857    assign(addr2, get_gpr_dw0(r2));
13858    assign(len1, get_gpr_dw0(r1 + 1));
13859    assign(len2, get_gpr_dw0(r2 + 1));
13860 
13861    /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13862       there are less than 4 bytes left, then the 2nd operand is exhausted
13863       and we're done here. cc = 0 */
13864    s390_cc_set(0);
13865    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13866 
13867    /* Read the 2nd operand. */
13868    IRTemp srcval = newTemp(Ity_I32);
13869    assign(srcval, load(Ity_I32, mkexpr(addr2)));
13870 
13871    /* Call the helper */
13872    IRTemp retval = newTemp(Ity_I64);
13873    assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
13874 
13875    /* If the UTF-32 character was invalid, set cc=2 and we're done.
13876       cc=2 outranks cc=1 (1st operand exhausted) */
13877    IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13878 
13879    s390_cc_set(2);
13880    next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13881 
13882    /* Now test whether the 1st operand is exhausted */
13883    IRTemp num_bytes = newTemp(Ity_I64);
13884    assign(num_bytes, binop(Iop_And64,
13885                            binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13886                            mkU64(0xff)));
13887    s390_cc_set(1);
13888    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13889 
13890    /* Extract the bytes to be stored at addr1 */
13891    IRTemp data = newTemp(Ity_I64);
13892    assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13893 
13894    /* To store the bytes construct 4 dirty helper calls. The helper calls
13895       are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13896       one of them will be called at runtime. */
13897    UInt i;
13898    for (i = 1; i <= 4; ++i) {
13899       IRDirty *d;
13900 
13901       d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13902                             &s390x_dirtyhelper_CUxy,
13903                             mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13904                                           mkexpr(num_bytes)));
13905       d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13906       d->mFx   = Ifx_Write;
13907       d->mAddr = mkexpr(addr1);
13908       d->mSize = i;
13909       stmt(IRStmt_Dirty(d));
13910    }
13911 
13912    /* Update source address and length */
13913    put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13914    put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkU64(4)));
13915 
13916    /* Update destination address and length */
13917    put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13918    put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13919 
13920    iterate();
13921 
13922    return "cu41";
13923 }
13924 
13925 static IRExpr *
s390_call_cu12_cu14_helper1(IRExpr * byte1,IRExpr * etf3_and_m3_is_1)13926 s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
13927 {
13928    IRExpr **args, *call;
13929    args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
13930    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13931                         &s390_do_cu12_cu14_helper1, args);
13932 
13933    /* Nothing is excluded from definedness checking. */
13934    call->Iex.CCall.cee->mcx_mask = 0;
13935 
13936    return call;
13937 }
13938 
13939 static IRExpr *
s390_call_cu12_helper2(IRExpr * byte1,IRExpr * byte2,IRExpr * byte3,IRExpr * byte4,IRExpr * stuff)13940 s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13941                        IRExpr *byte4, IRExpr *stuff)
13942 {
13943    IRExpr **args, *call;
13944    args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13945    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13946                         "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13947 
13948    /* Nothing is excluded from definedness checking. */
13949    call->Iex.CCall.cee->mcx_mask = 0;
13950 
13951    return call;
13952 }
13953 
13954 static IRExpr *
s390_call_cu14_helper2(IRExpr * byte1,IRExpr * byte2,IRExpr * byte3,IRExpr * byte4,IRExpr * stuff)13955 s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13956                        IRExpr *byte4, IRExpr *stuff)
13957 {
13958    IRExpr **args, *call;
13959    args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13960    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13961                         "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13962 
13963    /* Nothing is excluded from definedness checking. */
13964    call->Iex.CCall.cee->mcx_mask = 0;
13965 
13966    return call;
13967 }
13968 
13969 static void
s390_irgen_cu12_cu14(UChar m3,UChar r1,UChar r2,Bool is_cu12)13970 s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
13971 {
13972    IRTemp addr1 = newTemp(Ity_I64);
13973    IRTemp addr2 = newTemp(Ity_I64);
13974    IRTemp len1 = newTemp(Ity_I64);
13975    IRTemp len2 = newTemp(Ity_I64);
13976 
13977    assign(addr1, get_gpr_dw0(r1));
13978    assign(addr2, get_gpr_dw0(r2));
13979    assign(len1, get_gpr_dw0(r1 + 1));
13980    assign(len2, get_gpr_dw0(r2 + 1));
13981 
13982    UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13983 
13984    /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13985       there is less than 1 byte left, then the 2nd operand is exhausted
13986       and we're done here. cc = 0 */
13987    s390_cc_set(0);
13988    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13989 
13990    /* There is at least one byte there. Read it. */
13991    IRTemp byte1 = newTemp(Ity_I64);
13992    assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
13993 
13994    /* Call the helper to get number of bytes and invalid byte indicator */
13995    IRTemp retval1 = newTemp(Ity_I64);
13996    assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
13997                                                mkU64(extended_checking)));
13998 
13999    /* Check for invalid 1st byte */
14000    IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
14001    s390_cc_set(2);
14002    next_insn_if(is_invalid);
14003 
14004    /* How many bytes do we have to read? */
14005    IRTemp num_src_bytes = newTemp(Ity_I64);
14006    assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
14007 
14008    /* Now test whether the 2nd operand is exhausted */
14009    s390_cc_set(0);
14010    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
14011 
14012    /* Read the remaining bytes */
14013    IRExpr *cond, *addr, *byte2, *byte3, *byte4;
14014 
14015    cond  = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
14016    addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
14017    byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
14018    cond  = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
14019    addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
14020    byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
14021    cond  = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
14022    addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
14023    byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
14024 
14025    /* Call the helper to get the converted value and invalid byte indicator.
14026       We can pass at most 5 arguments; therefore some encoding is needed
14027       here */
14028    IRExpr *stuff = binop(Iop_Or64,
14029                          binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
14030                          mkU64(extended_checking));
14031    IRTemp retval2 = newTemp(Ity_I64);
14032 
14033    if (is_cu12) {
14034       assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
14035                                              byte4, stuff));
14036    } else {
14037       assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
14038                                              byte4, stuff));
14039    }
14040 
14041    /* Check for invalid character */
14042    s390_cc_set(2);
14043    is_invalid = unop(Iop_64to1, mkexpr(retval2));
14044    next_insn_if(is_invalid);
14045 
14046    /* Now test whether the 1st operand is exhausted */
14047    IRTemp num_bytes = newTemp(Ity_I64);
14048    assign(num_bytes, binop(Iop_And64,
14049                            binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
14050                            mkU64(0xff)));
14051    s390_cc_set(1);
14052    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
14053 
14054    /* Extract the bytes to be stored at addr1 */
14055    IRTemp data = newTemp(Ity_I64);
14056    assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
14057 
14058    if (is_cu12) {
14059       /* To store the bytes construct 2 dirty helper calls. The helper calls
14060          are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
14061          that only one of them will be called at runtime. */
14062 
14063       Int i;
14064       for (i = 2; i <= 4; ++i) {
14065          IRDirty *d;
14066 
14067          if (i == 3) continue;  // skip this one
14068 
14069          d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
14070                                &s390x_dirtyhelper_CUxy,
14071                                mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
14072                                              mkexpr(num_bytes)));
14073          d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
14074          d->mFx   = Ifx_Write;
14075          d->mAddr = mkexpr(addr1);
14076          d->mSize = i;
14077          stmt(IRStmt_Dirty(d));
14078       }
14079    } else {
14080       // cu14
14081       store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
14082    }
14083 
14084    /* Update source address and length */
14085    put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
14086    put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
14087 
14088    /* Update destination address and length */
14089    put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
14090    put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
14091 
14092    iterate();
14093 }
14094 
14095 static const HChar *
s390_irgen_CU12(UChar m3,UChar r1,UChar r2)14096 s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
14097 {
14098    s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
14099 
14100    return "cu12";
14101 }
14102 
14103 static const HChar *
s390_irgen_CU14(UChar m3,UChar r1,UChar r2)14104 s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
14105 {
14106    s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
14107 
14108    return "cu14";
14109 }
14110 
14111 static IRExpr *
s390_call_ecag(IRExpr * op2addr)14112 s390_call_ecag(IRExpr *op2addr)
14113 {
14114    IRExpr **args, *call;
14115 
14116    args = mkIRExprVec_1(op2addr);
14117    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
14118                         "s390_do_ecag", &s390_do_ecag, args);
14119 
14120    /* Nothing is excluded from definedness checking. */
14121    call->Iex.CCall.cee->mcx_mask = 0;
14122 
14123    return call;
14124 }
14125 
14126 static const HChar *
s390_irgen_ECAG(UChar r1,UChar r3,IRTemp op2addr)14127 s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
14128 {
14129    if (! s390_host_has_gie) {
14130       emulation_failure(EmFail_S390X_ecag);
14131    } else {
14132       put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
14133    }
14134 
14135    return "ecag";
14136 }
14137 
14138 
14139 /* New insns are added here.
14140    If an insn is contingent on a facility being installed also
14141    check whether the list of supported facilities in function
14142    s390x_dirtyhelper_STFLE needs updating */
14143 
14144 /*------------------------------------------------------------*/
14145 /*--- Build IR for special instructions                    ---*/
14146 /*------------------------------------------------------------*/
14147 
14148 static void
s390_irgen_client_request(void)14149 s390_irgen_client_request(void)
14150 {
14151    if (0)
14152       vex_printf("%%R3 = client_request ( %%R2 )\n");
14153 
14154    Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
14155                                      + S390_SPECIAL_OP_SIZE;
14156 
14157    dis_res->jk_StopHere = Ijk_ClientReq;
14158    dis_res->whatNext = Dis_StopHere;
14159 
14160    put_IA(mkaddr_expr(next));
14161 }
14162 
14163 static void
s390_irgen_guest_NRADDR(void)14164 s390_irgen_guest_NRADDR(void)
14165 {
14166    if (0)
14167       vex_printf("%%R3 = guest_NRADDR\n");
14168 
14169    put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
14170 }
14171 
14172 static void
s390_irgen_call_noredir(void)14173 s390_irgen_call_noredir(void)
14174 {
14175    Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
14176                                      + S390_SPECIAL_OP_SIZE;
14177 
14178    /* Continue after special op */
14179    put_gpr_dw0(14, mkaddr_expr(next));
14180 
14181    /* The address is in REG1, all parameters are in the right (guest) places */
14182    put_IA(get_gpr_dw0(1));
14183 
14184    dis_res->whatNext = Dis_StopHere;
14185    dis_res->jk_StopHere = Ijk_NoRedir;
14186 }
14187 
14188 /* Force proper alignment for the structures below. */
14189 #pragma pack(1)
14190 
14191 
14192 static s390_decode_t
s390_decode_2byte_and_irgen(const UChar * bytes)14193 s390_decode_2byte_and_irgen(const UChar *bytes)
14194 {
14195    typedef union {
14196       struct {
14197          unsigned int op : 16;
14198       } E;
14199       struct {
14200          unsigned int op :  8;
14201          unsigned int i  :  8;
14202       } I;
14203       struct {
14204          unsigned int op :  8;
14205          unsigned int r1 :  4;
14206          unsigned int r2 :  4;
14207       } RR;
14208    } formats;
14209    union {
14210       formats fmt;
14211       UShort value;
14212    } ovl;
14213 
14214    vassert(sizeof(formats) == 2);
14215 
14216    ((UChar *)(&ovl.value))[0] = bytes[0];
14217    ((UChar *)(&ovl.value))[1] = bytes[1];
14218 
14219    switch (ovl.value & 0xffff) {
14220    case 0x0101: /* PR */ goto unimplemented;
14221    case 0x0102: /* UPT */ goto unimplemented;
14222    case 0x0104: /* PTFF */ goto unimplemented;
14223    case 0x0107: /* SCKPF */ goto unimplemented;
14224    case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
14225    case 0x010b: /* TAM */ goto unimplemented;
14226    case 0x010c: /* SAM24 */ goto unimplemented;
14227    case 0x010d: /* SAM31 */ goto unimplemented;
14228    case 0x010e: /* SAM64 */ goto unimplemented;
14229    case 0x01ff: /* TRAP2 */ goto unimplemented;
14230    }
14231 
14232    switch ((ovl.value & 0xff00) >> 8) {
14233    case 0x04: /* SPM */ goto unimplemented;
14234    case 0x05: /* BALR */ goto unimplemented;
14235    case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14236                                 goto ok;
14237    case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14238                              goto ok;
14239    case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i);  goto ok;
14240    case 0x0b: /* BSM */ goto unimplemented;
14241    case 0x0c: /* BASSM */ goto unimplemented;
14242    case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14243                                 goto ok;
14244    case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14245                              goto ok;
14246    case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14247                              goto ok;
14248    case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14249                                 goto ok;
14250    case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14251                                 goto ok;
14252    case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14253                                 goto ok;
14254    case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14255                                 goto ok;
14256    case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14257                                 goto ok;
14258    case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14259                                 goto ok;
14260    case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14261                                 goto ok;
14262    case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14263                                 goto ok;
14264    case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14265                                 goto ok;
14266    case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14267                                 goto ok;
14268    case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14269                                 goto ok;
14270    case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14271                                 goto ok;
14272    case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14273                                 goto ok;
14274    case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14275                                 goto ok;
14276    case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14277                                 goto ok;
14278    case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14279                                 goto ok;
14280    case 0x20: /* LPDR */ goto unimplemented;
14281    case 0x21: /* LNDR */ goto unimplemented;
14282    case 0x22: /* LTDR */ goto unimplemented;
14283    case 0x23: /* LCDR */ goto unimplemented;
14284    case 0x24: /* HDR */ goto unimplemented;
14285    case 0x25: /* LDXR */ goto unimplemented;
14286    case 0x26: /* MXR */ goto unimplemented;
14287    case 0x27: /* MXDR */ goto unimplemented;
14288    case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14289                                 goto ok;
14290    case 0x29: /* CDR */ goto unimplemented;
14291    case 0x2a: /* ADR */ goto unimplemented;
14292    case 0x2b: /* SDR */ goto unimplemented;
14293    case 0x2c: /* MDR */ goto unimplemented;
14294    case 0x2d: /* DDR */ goto unimplemented;
14295    case 0x2e: /* AWR */ goto unimplemented;
14296    case 0x2f: /* SWR */ goto unimplemented;
14297    case 0x30: /* LPER */ goto unimplemented;
14298    case 0x31: /* LNER */ goto unimplemented;
14299    case 0x32: /* LTER */ goto unimplemented;
14300    case 0x33: /* LCER */ goto unimplemented;
14301    case 0x34: /* HER */ goto unimplemented;
14302    case 0x35: /* LEDR */ goto unimplemented;
14303    case 0x36: /* AXR */ goto unimplemented;
14304    case 0x37: /* SXR */ goto unimplemented;
14305    case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14306                                 goto ok;
14307    case 0x39: /* CER */ goto unimplemented;
14308    case 0x3a: /* AER */ goto unimplemented;
14309    case 0x3b: /* SER */ goto unimplemented;
14310    case 0x3c: /* MDER */ goto unimplemented;
14311    case 0x3d: /* DER */ goto unimplemented;
14312    case 0x3e: /* AUR */ goto unimplemented;
14313    case 0x3f: /* SUR */ goto unimplemented;
14314    }
14315 
14316    return S390_DECODE_UNKNOWN_INSN;
14317 
14318 ok:
14319    return S390_DECODE_OK;
14320 
14321 unimplemented:
14322    return S390_DECODE_UNIMPLEMENTED_INSN;
14323 }
14324 
14325 static s390_decode_t
s390_decode_4byte_and_irgen(const UChar * bytes)14326 s390_decode_4byte_and_irgen(const UChar *bytes)
14327 {
14328    typedef union {
14329       struct {
14330          unsigned int op1 :  8;
14331          unsigned int r1  :  4;
14332          unsigned int op2 :  4;
14333          unsigned int i2  : 16;
14334       } RI;
14335       struct {
14336          unsigned int op : 16;
14337          unsigned int    :  8;
14338          unsigned int r1 :  4;
14339          unsigned int r2 :  4;
14340       } RRE;
14341       struct {
14342          unsigned int op : 16;
14343          unsigned int r1 :  4;
14344          unsigned int    :  4;
14345          unsigned int r3 :  4;
14346          unsigned int r2 :  4;
14347       } RRF;
14348       struct {
14349          unsigned int op : 16;
14350          unsigned int m3 :  4;
14351          unsigned int m4 :  4;
14352          unsigned int r1 :  4;
14353          unsigned int r2 :  4;
14354       } RRF2;
14355       struct {
14356          unsigned int op : 16;
14357          unsigned int r3 :  4;
14358          unsigned int    :  4;
14359          unsigned int r1 :  4;
14360          unsigned int r2 :  4;
14361       } RRF3;
14362       struct {
14363          unsigned int op : 16;
14364          unsigned int r3 :  4;
14365          unsigned int    :  4;
14366          unsigned int r1 :  4;
14367          unsigned int r2 :  4;
14368       } RRR;
14369       struct {
14370          unsigned int op : 16;
14371          unsigned int r3 :  4;
14372          unsigned int m4 :  4;
14373          unsigned int r1 :  4;
14374          unsigned int r2 :  4;
14375       } RRF4;
14376       struct {
14377          unsigned int op : 16;
14378          unsigned int    :  4;
14379          unsigned int m4 :  4;
14380          unsigned int r1 :  4;
14381          unsigned int r2 :  4;
14382       } RRF5;
14383       struct {
14384          unsigned int op :  8;
14385          unsigned int r1 :  4;
14386          unsigned int r3 :  4;
14387          unsigned int b2 :  4;
14388          unsigned int d2 : 12;
14389       } RS;
14390       struct {
14391          unsigned int op :  8;
14392          unsigned int r1 :  4;
14393          unsigned int r3 :  4;
14394          unsigned int i2 : 16;
14395       } RSI;
14396       struct {
14397          unsigned int op :  8;
14398          unsigned int r1 :  4;
14399          unsigned int x2 :  4;
14400          unsigned int b2 :  4;
14401          unsigned int d2 : 12;
14402       } RX;
14403       struct {
14404          unsigned int op : 16;
14405          unsigned int b2 :  4;
14406          unsigned int d2 : 12;
14407       } S;
14408       struct {
14409          unsigned int op :  8;
14410          unsigned int i2 :  8;
14411          unsigned int b1 :  4;
14412          unsigned int d1 : 12;
14413       } SI;
14414    } formats;
14415    union {
14416       formats fmt;
14417       UInt value;
14418    } ovl;
14419 
14420    vassert(sizeof(formats) == 4);
14421 
14422    ((UChar *)(&ovl.value))[0] = bytes[0];
14423    ((UChar *)(&ovl.value))[1] = bytes[1];
14424    ((UChar *)(&ovl.value))[2] = bytes[2];
14425    ((UChar *)(&ovl.value))[3] = bytes[3];
14426 
14427    switch ((ovl.value & 0xff0f0000) >> 16) {
14428    case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
14429                                   ovl.fmt.RI.i2);  goto ok;
14430    case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
14431                                   ovl.fmt.RI.i2);  goto ok;
14432    case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14433                                   ovl.fmt.RI.i2);  goto ok;
14434    case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14435                                   ovl.fmt.RI.i2);  goto ok;
14436    case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14437                                   ovl.fmt.RI.i2);  goto ok;
14438    case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14439                                   ovl.fmt.RI.i2);  goto ok;
14440    case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14441                                   ovl.fmt.RI.i2);  goto ok;
14442    case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14443                                   ovl.fmt.RI.i2);  goto ok;
14444    case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14445                                   ovl.fmt.RI.i2);  goto ok;
14446    case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14447                                   ovl.fmt.RI.i2);  goto ok;
14448    case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14449                                   ovl.fmt.RI.i2);  goto ok;
14450    case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14451                                   ovl.fmt.RI.i2);  goto ok;
14452    case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14453                                   ovl.fmt.RI.i2);  goto ok;
14454    case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14455                                   ovl.fmt.RI.i2);  goto ok;
14456    case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14457                                   ovl.fmt.RI.i2);  goto ok;
14458    case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14459                                   ovl.fmt.RI.i2);  goto ok;
14460    case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14461                                   ovl.fmt.RI.i2);  goto ok;
14462    case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14463                                   ovl.fmt.RI.i2);  goto ok;
14464    case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14465                                   ovl.fmt.RI.i2);  goto ok;
14466    case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14467                                   ovl.fmt.RI.i2);  goto ok;
14468    case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14469                                goto ok;
14470    case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14471                                   ovl.fmt.RI.i2);  goto ok;
14472    case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14473                                   ovl.fmt.RI.i2);  goto ok;
14474    case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14475                                   ovl.fmt.RI.i2);  goto ok;
14476    case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14477                                   goto ok;
14478    case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14479                                   ovl.fmt.RI.i2);  goto ok;
14480    case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14481                                   goto ok;
14482    case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14483                                   ovl.fmt.RI.i2);  goto ok;
14484    case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14485                                   goto ok;
14486    case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14487                                   ovl.fmt.RI.i2);  goto ok;
14488    case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14489                                   goto ok;
14490    case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14491                                   ovl.fmt.RI.i2);  goto ok;
14492    }
14493 
14494    switch ((ovl.value & 0xffff0000) >> 16) {
14495    case 0x8000: /* SSM */ goto unimplemented;
14496    case 0x8200: /* LPSW */ goto unimplemented;
14497    case 0x9300: /* TS */ goto unimplemented;
14498    case 0xb202: /* STIDP */ goto unimplemented;
14499    case 0xb204: /* SCK */ goto unimplemented;
14500    case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14501                 goto ok;
14502    case 0xb206: /* SCKC */ goto unimplemented;
14503    case 0xb207: /* STCKC */ goto unimplemented;
14504    case 0xb208: /* SPT */ goto unimplemented;
14505    case 0xb209: /* STPT */ goto unimplemented;
14506    case 0xb20a: /* SPKA */ goto unimplemented;
14507    case 0xb20b: /* IPK */ goto unimplemented;
14508    case 0xb20d: /* PTLB */ goto unimplemented;
14509    case 0xb210: /* SPX */ goto unimplemented;
14510    case 0xb211: /* STPX */ goto unimplemented;
14511    case 0xb212: /* STAP */ goto unimplemented;
14512    case 0xb214: /* SIE */ goto unimplemented;
14513    case 0xb218: /* PC */ goto unimplemented;
14514    case 0xb219: /* SAC */ goto unimplemented;
14515    case 0xb21a: /* CFC */ goto unimplemented;
14516    case 0xb221: /* IPTE */ goto unimplemented;
14517    case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1);  goto ok;
14518    case 0xb223: /* IVSK */ goto unimplemented;
14519    case 0xb224: /* IAC */ goto unimplemented;
14520    case 0xb225: /* SSAR */ goto unimplemented;
14521    case 0xb226: /* EPAR */ goto unimplemented;
14522    case 0xb227: /* ESAR */ goto unimplemented;
14523    case 0xb228: /* PT */ goto unimplemented;
14524    case 0xb229: /* ISKE */ goto unimplemented;
14525    case 0xb22a: /* RRBE */ goto unimplemented;
14526    case 0xb22b: /* SSKE */ goto unimplemented;
14527    case 0xb22c: /* TB */ goto unimplemented;
14528    case 0xb22d: /* DXR */ goto unimplemented;
14529    case 0xb22e: /* PGIN */ goto unimplemented;
14530    case 0xb22f: /* PGOUT */ goto unimplemented;
14531    case 0xb230: /* CSCH */ goto unimplemented;
14532    case 0xb231: /* HSCH */ goto unimplemented;
14533    case 0xb232: /* MSCH */ goto unimplemented;
14534    case 0xb233: /* SSCH */ goto unimplemented;
14535    case 0xb234: /* STSCH */ goto unimplemented;
14536    case 0xb235: /* TSCH */ goto unimplemented;
14537    case 0xb236: /* TPI */ goto unimplemented;
14538    case 0xb237: /* SAL */ goto unimplemented;
14539    case 0xb238: /* RSCH */ goto unimplemented;
14540    case 0xb239: /* STCRW */ goto unimplemented;
14541    case 0xb23a: /* STCPS */ goto unimplemented;
14542    case 0xb23b: /* RCHP */ goto unimplemented;
14543    case 0xb23c: /* SCHM */ goto unimplemented;
14544    case 0xb240: /* BAKR */ goto unimplemented;
14545    case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14546                                 ovl.fmt.RRE.r2);  goto ok;
14547    case 0xb244: /* SQDR */ goto unimplemented;
14548    case 0xb245: /* SQER */ goto unimplemented;
14549    case 0xb246: /* STURA */ goto unimplemented;
14550    case 0xb247: /* MSTA */ goto unimplemented;
14551    case 0xb248: /* PALB */ goto unimplemented;
14552    case 0xb249: /* EREG */ goto unimplemented;
14553    case 0xb24a: /* ESTA */ goto unimplemented;
14554    case 0xb24b: /* LURA */ goto unimplemented;
14555    case 0xb24c: /* TAR */ goto unimplemented;
14556    case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14557                                 ovl.fmt.RRE.r2);  goto ok;
14558    case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14559                                 goto ok;
14560    case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14561                                 goto ok;
14562    case 0xb250: /* CSP */ goto unimplemented;
14563    case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14564                                    ovl.fmt.RRE.r2);  goto ok;
14565    case 0xb254: /* MVPG */ goto unimplemented;
14566    case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14567                                    ovl.fmt.RRE.r2);  goto ok;
14568    case 0xb257: /* CUSE */ goto unimplemented;
14569    case 0xb258: /* BSG */ goto unimplemented;
14570    case 0xb25a: /* BSA */ goto unimplemented;
14571    case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14572                                    ovl.fmt.RRE.r2);  goto ok;
14573    case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14574                                    ovl.fmt.RRE.r2);  goto ok;
14575    case 0xb263: /* CMPSC */ goto unimplemented;
14576    case 0xb274: /* SIGA */ goto unimplemented;
14577    case 0xb276: /* XSCH */ goto unimplemented;
14578    case 0xb277: /* RP */ goto unimplemented;
14579    case 0xb278: s390_format_S_RD(s390_irgen_STCKE, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
14580    case 0xb279: /* SACF */ goto unimplemented;
14581    case 0xb27c: s390_format_S_RD(s390_irgen_STCKF, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
14582    case 0xb27d: /* STSI */ goto unimplemented;
14583    case 0xb280: /* LPP */ goto unimplemented;
14584    case 0xb284: /* LCCTL */ goto unimplemented;
14585    case 0xb285: /* LPCTL */ goto unimplemented;
14586    case 0xb286: /* QSI */ goto unimplemented;
14587    case 0xb287: /* LSCTL */ goto unimplemented;
14588    case 0xb28e: /* QCTRI */ goto unimplemented;
14589    case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14590                                  goto ok;
14591    case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14592                                  goto ok;
14593    case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14594                                  goto ok;
14595    case 0xb2a5: s390_format_RRE_FF(s390_irgen_TRE, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);  goto ok;
14596    case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14597                                        ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14598       goto ok;
14599    case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14600                                        ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14601       goto ok;
14602    case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14603                                  goto ok;
14604    case 0xb2b1: /* STFL */ goto unimplemented;
14605    case 0xb2b2: /* LPSWE */ goto unimplemented;
14606    case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14607       goto ok;
14608    case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14609       goto ok;
14610    case 0xb2bd: /* LFAS */ goto unimplemented;
14611    case 0xb2e0: /* SCCTR */ goto unimplemented;
14612    case 0xb2e1: /* SPCTR */ goto unimplemented;
14613    case 0xb2e4: /* ECCTR */ goto unimplemented;
14614    case 0xb2e5: /* EPCTR */ goto unimplemented;
14615    case 0xb2e8: /* PPA */ goto unimplemented;
14616    case 0xb2ec: /* ETND */ goto unimplemented;
14617    case 0xb2ed: /* ECPGA */ goto unimplemented;
14618    case 0xb2f8: /* TEND */ goto unimplemented;
14619    case 0xb2fa: /* NIAI */ goto unimplemented;
14620    case 0xb2fc: /* TABORT */ goto unimplemented;
14621    case 0xb2ff: /* TRAP4 */ goto unimplemented;
14622    case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14623                                    ovl.fmt.RRE.r2);  goto ok;
14624    case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14625                                    ovl.fmt.RRE.r2);  goto ok;
14626    case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14627                                    ovl.fmt.RRE.r2);  goto ok;
14628    case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14629                                    ovl.fmt.RRE.r2);  goto ok;
14630    case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14631                                    ovl.fmt.RRE.r2);  goto ok;
14632    case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14633                                    ovl.fmt.RRE.r2);  goto ok;
14634    case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14635                                    ovl.fmt.RRE.r2);  goto ok;
14636    case 0xb307: /* MXDBR */ goto unimplemented;
14637    case 0xb308: /* KEBR */ goto unimplemented;
14638    case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14639                                    ovl.fmt.RRE.r2);  goto ok;
14640    case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14641                                    ovl.fmt.RRE.r2);  goto ok;
14642    case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14643                                    ovl.fmt.RRE.r2);  goto ok;
14644    case 0xb30c: /* MDEBR */ goto unimplemented;
14645    case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14646                                    ovl.fmt.RRE.r2);  goto ok;
14647    case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14648                                      ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14649    case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14650                                      ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14651    case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14652                                    ovl.fmt.RRE.r2);  goto ok;
14653    case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14654                                    ovl.fmt.RRE.r2);  goto ok;
14655    case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14656                                    ovl.fmt.RRE.r2);  goto ok;
14657    case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14658                                    ovl.fmt.RRE.r2);  goto ok;
14659    case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14660                                    ovl.fmt.RRE.r2);  goto ok;
14661    case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14662                                    ovl.fmt.RRE.r2);  goto ok;
14663    case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14664                                    ovl.fmt.RRE.r2);  goto ok;
14665    case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14666                                    ovl.fmt.RRE.r2);  goto ok;
14667    case 0xb318: /* KDBR */ goto unimplemented;
14668    case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14669                                    ovl.fmt.RRE.r2);  goto ok;
14670    case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14671                                    ovl.fmt.RRE.r2);  goto ok;
14672    case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14673                                    ovl.fmt.RRE.r2);  goto ok;
14674    case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14675                                    ovl.fmt.RRE.r2);  goto ok;
14676    case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14677                                    ovl.fmt.RRE.r2);  goto ok;
14678    case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14679                                      ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14680    case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14681                                      ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14682    case 0xb324: s390_format_RRE_FF(s390_irgen_LDER, ovl.fmt.RRE.r1,
14683                                    ovl.fmt.RRE.r2); goto ok;
14684    case 0xb325: /* LXDR */ goto unimplemented;
14685    case 0xb326: /* LXER */ goto unimplemented;
14686    case 0xb32e: /* MAER */ goto unimplemented;
14687    case 0xb32f: /* MSER */ goto unimplemented;
14688    case 0xb336: /* SQXR */ goto unimplemented;
14689    case 0xb337: /* MEER */ goto unimplemented;
14690    case 0xb338: /* MAYLR */ goto unimplemented;
14691    case 0xb339: /* MYLR */ goto unimplemented;
14692    case 0xb33a: /* MAYR */ goto unimplemented;
14693    case 0xb33b: /* MYR */ goto unimplemented;
14694    case 0xb33c: /* MAYHR */ goto unimplemented;
14695    case 0xb33d: /* MYHR */ goto unimplemented;
14696    case 0xb33e: /* MADR */ goto unimplemented;
14697    case 0xb33f: /* MSDR */ goto unimplemented;
14698    case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14699                                    ovl.fmt.RRE.r2);  goto ok;
14700    case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14701                                    ovl.fmt.RRE.r2);  goto ok;
14702    case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14703                                    ovl.fmt.RRE.r2);  goto ok;
14704    case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14705                                    ovl.fmt.RRE.r2);  goto ok;
14706    case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14707                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14708                                      ovl.fmt.RRF2.r2);  goto ok;
14709    case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14710                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14711                                      ovl.fmt.RRF2.r2);  goto ok;
14712    case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14713                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14714                                      ovl.fmt.RRF2.r2);  goto ok;
14715    case 0xb347: s390_format_RRF_UUFF(s390_irgen_FIXBRA, ovl.fmt.RRF2.m3,
14716                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14717                                      ovl.fmt.RRF2.r2);  goto ok;
14718    case 0xb348: /* KXBR */ goto unimplemented;
14719    case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14720                                    ovl.fmt.RRE.r2);  goto ok;
14721    case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14722                                    ovl.fmt.RRE.r2);  goto ok;
14723    case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14724                                    ovl.fmt.RRE.r2);  goto ok;
14725    case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14726                                    ovl.fmt.RRE.r2);  goto ok;
14727    case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14728                                    ovl.fmt.RRE.r2);  goto ok;
14729    case 0xb350: /* TBEDR */ goto unimplemented;
14730    case 0xb351: /* TBDR */ goto unimplemented;
14731    case 0xb353: /* DIEBR */ goto unimplemented;
14732    case 0xb357: s390_format_RRF_UUFF(s390_irgen_FIEBRA, ovl.fmt.RRF2.m3,
14733                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14734                                      ovl.fmt.RRF2.r2);  goto ok;
14735    case 0xb358: /* THDER */ goto unimplemented;
14736    case 0xb359: /* THDR */ goto unimplemented;
14737    case 0xb35b: /* DIDBR */ goto unimplemented;
14738    case 0xb35f: s390_format_RRF_UUFF(s390_irgen_FIDBRA, ovl.fmt.RRF2.m3,
14739                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14740                                      ovl.fmt.RRF2.r2);  goto ok;
14741    case 0xb360: /* LPXR */ goto unimplemented;
14742    case 0xb361: /* LNXR */ goto unimplemented;
14743    case 0xb362: /* LTXR */ goto unimplemented;
14744    case 0xb363: /* LCXR */ goto unimplemented;
14745    case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14746                                    ovl.fmt.RRE.r2);  goto ok;
14747    case 0xb366: /* LEXR */ goto unimplemented;
14748    case 0xb367: /* FIXR */ goto unimplemented;
14749    case 0xb369: /* CXR */ goto unimplemented;
14750    case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14751                                    ovl.fmt.RRE.r2);  goto ok;
14752    case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14753                                    ovl.fmt.RRE.r2);  goto ok;
14754    case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14755                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14756                                       goto ok;
14757    case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14758                                    ovl.fmt.RRE.r2);  goto ok;
14759    case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1);  goto ok;
14760    case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1);  goto ok;
14761    case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1);  goto ok;
14762    case 0xb377: /* FIER */ goto unimplemented;
14763    case 0xb37f: /* FIDR */ goto unimplemented;
14764    case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1);  goto ok;
14765    case 0xb385: /* SFASR */ goto unimplemented;
14766    case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1);  goto ok;
14767    case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14768                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14769                                      ovl.fmt.RRF2.r2);  goto ok;
14770    case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14771                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14772                                      ovl.fmt.RRF2.r2);  goto ok;
14773    case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14774                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14775                                      ovl.fmt.RRF2.r2);  goto ok;
14776    case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14777                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14778                                      ovl.fmt.RRF2.r2);  goto ok;
14779    case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14780                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14781                                      ovl.fmt.RRF2.r2);  goto ok;
14782    case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14783                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14784                                      ovl.fmt.RRF2.r2);  goto ok;
14785    case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14786                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14787                                      ovl.fmt.RRF2.r2);  goto ok;
14788    case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14789                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14790                                      ovl.fmt.RRF2.r2);  goto ok;
14791    case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14792                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14793                                      ovl.fmt.RRF2.r2);  goto ok;
14794    case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14795                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14796                                      ovl.fmt.RRF2.r2);  goto ok;
14797    case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14798                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14799                                      ovl.fmt.RRF2.r2);  goto ok;
14800    case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14801                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14802                                      ovl.fmt.RRF2.r2);  goto ok;
14803    case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14804                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14805                                      ovl.fmt.RRF2.r2);  goto ok;
14806    case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14807                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14808                                      ovl.fmt.RRF2.r2);  goto ok;
14809    case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14810                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14811                                      ovl.fmt.RRF2.r2);  goto ok;
14812    case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14813                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14814                                      ovl.fmt.RRF2.r2);  goto ok;
14815    case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14816                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14817                                      ovl.fmt.RRF2.r2);  goto ok;
14818    case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14819                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14820                                      ovl.fmt.RRF2.r2);  goto ok;
14821    case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14822                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14823                                      ovl.fmt.RRF2.r2);  goto ok;
14824    case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14825                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14826                                      ovl.fmt.RRF2.r2);  goto ok;
14827    case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14828                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14829                                      ovl.fmt.RRF2.r2);  goto ok;
14830    case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14831                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14832                                      ovl.fmt.RRF2.r2);  goto ok;
14833    case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14834                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14835                                      ovl.fmt.RRF2.r2);  goto ok;
14836    case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14837                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14838                                      ovl.fmt.RRF2.r2);  goto ok;
14839    case 0xb3b4: /* CEFR */ goto unimplemented;
14840    case 0xb3b5: /* CDFR */ goto unimplemented;
14841    case 0xb3b6: /* CXFR */ goto unimplemented;
14842    case 0xb3b8: /* CFER */ goto unimplemented;
14843    case 0xb3b9: /* CFDR */ goto unimplemented;
14844    case 0xb3ba: /* CFXR */ goto unimplemented;
14845    case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14846                                    ovl.fmt.RRE.r2);  goto ok;
14847    case 0xb3c4: /* CEGR */ goto unimplemented;
14848    case 0xb3c5: /* CDGR */ goto unimplemented;
14849    case 0xb3c6: /* CXGR */ goto unimplemented;
14850    case 0xb3c8: /* CGER */ goto unimplemented;
14851    case 0xb3c9: /* CGDR */ goto unimplemented;
14852    case 0xb3ca: /* CGXR */ goto unimplemented;
14853    case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14854                                    ovl.fmt.RRE.r2);  goto ok;
14855    case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14856                                       ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14857                                       ovl.fmt.RRF4.r2); goto ok;
14858    case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14859                                       ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14860                                       ovl.fmt.RRF4.r2); goto ok;
14861    case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14862                                       ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14863                                       ovl.fmt.RRF4.r2); goto ok;
14864    case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14865                                       ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14866                                       ovl.fmt.RRF4.r2); goto ok;
14867    case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14868                                      ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14869    case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14870                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14871                                      ovl.fmt.RRF2.r2);  goto ok;
14872    case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14873                                    ovl.fmt.RRE.r2);  goto ok;
14874    case 0xb3d7: /* FIDTR */ goto unimplemented;
14875    case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14876                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14877                                      ovl.fmt.RRF4.r2); goto ok;
14878    case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14879                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14880                                      ovl.fmt.RRF4.r2); goto ok;
14881    case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14882                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14883                                      ovl.fmt.RRF4.r2); goto ok;
14884    case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14885                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14886                                      ovl.fmt.RRF4.r2); goto ok;
14887    case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14888                                      ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14889    case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14890                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14891                                      ovl.fmt.RRF2.r2);  goto ok;
14892    case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14893                                    ovl.fmt.RRE.r2);  goto ok;
14894    case 0xb3df: /* FIXTR */ goto unimplemented;
14895    case 0xb3e0: /* KDTR */ goto unimplemented;
14896    case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14897                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14898                                      ovl.fmt.RRF2.r2);  goto ok;
14899    case 0xb3e2: /* CUDTR */ goto unimplemented;
14900    case 0xb3e3: /* CSDTR */ goto unimplemented;
14901    case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14902                                    ovl.fmt.RRE.r2);  goto ok;
14903    case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14904                                    ovl.fmt.RRE.r2);  goto ok;
14905    case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14906                                    ovl.fmt.RRE.r2);  goto ok;
14907    case 0xb3e8: /* KXTR */ goto unimplemented;
14908    case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14909                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14910                                      ovl.fmt.RRF2.r2);  goto ok;
14911    case 0xb3ea: /* CUXTR */ goto unimplemented;
14912    case 0xb3eb: /* CSXTR */ goto unimplemented;
14913    case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14914                                    ovl.fmt.RRE.r2);  goto ok;
14915    case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14916                                    ovl.fmt.RRE.r2);  goto ok;
14917    case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14918                                    ovl.fmt.RRE.r2);  goto ok;
14919    case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14920                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14921                                      ovl.fmt.RRF2.r2);  goto ok;
14922    case 0xb3f2: /* CDUTR */ goto unimplemented;
14923    case 0xb3f3: /* CDSTR */ goto unimplemented;
14924    case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14925                                    ovl.fmt.RRE.r2);  goto ok;
14926    case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14927                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14928                                      ovl.fmt.RRF4.r2); goto ok;
14929    case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14930                                      ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14931    case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14932                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14933                                      ovl.fmt.RRF4.r2); goto ok;
14934    case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14935                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14936                                      ovl.fmt.RRF2.r2);  goto ok;
14937    case 0xb3fa: /* CXUTR */ goto unimplemented;
14938    case 0xb3fb: /* CXSTR */ goto unimplemented;
14939    case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14940                                    ovl.fmt.RRE.r2);  goto ok;
14941    case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14942                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14943                                      ovl.fmt.RRF4.r2); goto ok;
14944    case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14945                                      ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14946    case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14947                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14948                                      ovl.fmt.RRF4.r2); goto ok;
14949    case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14950                                    ovl.fmt.RRE.r2);  goto ok;
14951    case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14952                                    ovl.fmt.RRE.r2);  goto ok;
14953    case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14954                                    ovl.fmt.RRE.r2);  goto ok;
14955    case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14956                                    ovl.fmt.RRE.r2);  goto ok;
14957    case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14958                                    ovl.fmt.RRE.r2);  goto ok;
14959    case 0xb905: /* LURAG */ goto unimplemented;
14960    case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14961                                    ovl.fmt.RRE.r2);  goto ok;
14962    case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14963                                    ovl.fmt.RRE.r2);  goto ok;
14964    case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14965                                    ovl.fmt.RRE.r2);  goto ok;
14966    case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14967                                    ovl.fmt.RRE.r2);  goto ok;
14968    case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14969                                    ovl.fmt.RRE.r2);  goto ok;
14970    case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14971                                    ovl.fmt.RRE.r2);  goto ok;
14972    case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14973                                    ovl.fmt.RRE.r2);  goto ok;
14974    case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14975                                    ovl.fmt.RRE.r2);  goto ok;
14976    case 0xb90e: /* EREGG */ goto unimplemented;
14977    case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14978                                    ovl.fmt.RRE.r2);  goto ok;
14979    case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14980                                    ovl.fmt.RRE.r2);  goto ok;
14981    case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14982                                    ovl.fmt.RRE.r2);  goto ok;
14983    case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14984                                    ovl.fmt.RRE.r2);  goto ok;
14985    case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14986                                    ovl.fmt.RRE.r2);  goto ok;
14987    case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14988                                    ovl.fmt.RRE.r2);  goto ok;
14989    case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14990                                    ovl.fmt.RRE.r2);  goto ok;
14991    case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14992                                    ovl.fmt.RRE.r2);  goto ok;
14993    case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14994                                    ovl.fmt.RRE.r2);  goto ok;
14995    case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14996                                    ovl.fmt.RRE.r2);  goto ok;
14997    case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14998                                    ovl.fmt.RRE.r2);  goto ok;
14999    case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
15000                                    ovl.fmt.RRE.r2);  goto ok;
15001    case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
15002                                    ovl.fmt.RRE.r2);  goto ok;
15003    case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
15004                                    ovl.fmt.RRE.r2);  goto ok;
15005    case 0xb91e: /* KMAC */ goto unimplemented;
15006    case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
15007                                    ovl.fmt.RRE.r2);  goto ok;
15008    case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
15009                                    ovl.fmt.RRE.r2);  goto ok;
15010    case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
15011                                    ovl.fmt.RRE.r2);  goto ok;
15012    case 0xb925: /* STURG */ goto unimplemented;
15013    case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
15014                                    ovl.fmt.RRE.r2);  goto ok;
15015    case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
15016                                    ovl.fmt.RRE.r2);  goto ok;
15017    case 0xb928: /* PCKMO */ goto unimplemented;
15018    case 0xb92a: /* KMF */ goto unimplemented;
15019    case 0xb92b: /* KMO */ goto unimplemented;
15020    case 0xb92c: /* PCC */ goto unimplemented;
15021    case 0xb92d: /* KMCTR */ goto unimplemented;
15022    case 0xb92e: /* KM */ goto unimplemented;
15023    case 0xb92f: /* KMC */ goto unimplemented;
15024    case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
15025                                    ovl.fmt.RRE.r2);  goto ok;
15026    case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
15027                                    ovl.fmt.RRE.r2);  goto ok;
15028    case 0xb93e: /* KIMD */ goto unimplemented;
15029    case 0xb93f: /* KLMD */ goto unimplemented;
15030    case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
15031                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15032                                      ovl.fmt.RRF2.r2);  goto ok;
15033    case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
15034                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15035                                      ovl.fmt.RRF2.r2);  goto ok;
15036    case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
15037                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15038                                      ovl.fmt.RRF2.r2);  goto ok;
15039    case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
15040                                    ovl.fmt.RRE.r2);  goto ok;
15041    case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
15042                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15043                                      ovl.fmt.RRF2.r2);  goto ok;
15044    case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
15045                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15046                                      ovl.fmt.RRF2.r2);  goto ok;
15047    case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
15048                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15049                                      ovl.fmt.RRF2.r2);  goto ok;
15050    case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
15051                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15052                                      ovl.fmt.RRF2.r2);  goto ok;
15053    case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
15054                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15055                                      ovl.fmt.RRF2.r2);  goto ok;
15056    case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
15057                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15058                                      ovl.fmt.RRF2.r2);  goto ok;
15059    case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
15060                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15061                                      ovl.fmt.RRF2.r2);  goto ok;
15062    case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
15063                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15064                                      ovl.fmt.RRF2.r2);  goto ok;
15065    case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
15066                                      ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15067                                      ovl.fmt.RRF2.r2);  goto ok;
15068    case 0xb960: /* CGRT */ goto unimplemented;
15069    case 0xb961: /* CLGRT */ goto unimplemented;
15070    case 0xb972: /* CRT */ goto unimplemented;
15071    case 0xb973: /* CLRT */ goto unimplemented;
15072    case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
15073                                    ovl.fmt.RRE.r2);  goto ok;
15074    case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
15075                                    ovl.fmt.RRE.r2);  goto ok;
15076    case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
15077                                    ovl.fmt.RRE.r2);  goto ok;
15078    case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
15079                                    ovl.fmt.RRE.r2);  goto ok;
15080    case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
15081                                    ovl.fmt.RRE.r2);  goto ok;
15082    case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
15083                                    ovl.fmt.RRE.r2);  goto ok;
15084    case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
15085                                    ovl.fmt.RRE.r2);  goto ok;
15086    case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
15087                                    ovl.fmt.RRE.r2);  goto ok;
15088    case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
15089                                    ovl.fmt.RRE.r2);  goto ok;
15090    case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
15091                                    ovl.fmt.RRE.r2);  goto ok;
15092    case 0xb98a: /* CSPG */ goto unimplemented;
15093    case 0xb98d: /* EPSW */ goto unimplemented;
15094    case 0xb98e: /* IDTE */ goto unimplemented;
15095    case 0xb98f: /* CRDTE */ goto unimplemented;
15096    case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
15097                                    ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
15098    case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
15099                                    ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
15100    case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
15101                                    ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
15102    case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
15103                                    ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
15104    case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
15105                                    ovl.fmt.RRE.r2);  goto ok;
15106    case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
15107                                    ovl.fmt.RRE.r2);  goto ok;
15108    case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
15109                                    ovl.fmt.RRE.r2);  goto ok;
15110    case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
15111                                    ovl.fmt.RRE.r2);  goto ok;
15112    case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
15113                                    ovl.fmt.RRE.r2);  goto ok;
15114    case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
15115                                    ovl.fmt.RRE.r2);  goto ok;
15116    case 0xb99a: /* EPAIR */ goto unimplemented;
15117    case 0xb99b: /* ESAIR */ goto unimplemented;
15118    case 0xb99d: /* ESEA */ goto unimplemented;
15119    case 0xb99e: /* PTI */ goto unimplemented;
15120    case 0xb99f: /* SSAIR */ goto unimplemented;
15121    case 0xb9a2: /* PTF */ goto unimplemented;
15122    case 0xb9aa: /* LPTEA */ goto unimplemented;
15123    case 0xb9ae: /* RRBM */ goto unimplemented;
15124    case 0xb9af: /* PFMF */ goto unimplemented;
15125    case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
15126                                        ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
15127       goto ok;
15128    case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
15129                                        ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
15130       goto ok;
15131    case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
15132                                    ovl.fmt.RRE.r2);  goto ok;
15133    case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
15134                                    ovl.fmt.RRE.r2);  goto ok;
15135    case 0xb9bd: /* TRTRE */ goto unimplemented;
15136    case 0xb9be: /* SRSTU */ goto unimplemented;
15137    case 0xb9bf: /* TRTE */ goto unimplemented;
15138    case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
15139                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15140                                       goto ok;
15141    case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
15142                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15143                                       goto ok;
15144    case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
15145                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15146                                       goto ok;
15147    case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
15148                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15149                                       goto ok;
15150    case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
15151                                    ovl.fmt.RRE.r2);  goto ok;
15152    case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
15153                                    ovl.fmt.RRE.r2);  goto ok;
15154    case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
15155                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15156                                       goto ok;
15157    case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
15158                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15159                                       goto ok;
15160    case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
15161                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15162                                       goto ok;
15163    case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
15164                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15165                                       goto ok;
15166    case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
15167                                    ovl.fmt.RRE.r2);  goto ok;
15168    case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
15169                                    ovl.fmt.RRE.r2);  goto ok;
15170    case 0xb9e1: s390_format_RRE_RR(s390_irgen_POPCNT, ovl.fmt.RRE.r1,
15171                                    ovl.fmt.RRE.r2);  goto ok;
15172    case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
15173                                      ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
15174                                      S390_XMNM_LOCGR);  goto ok;
15175    case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
15176                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15177                                       goto ok;
15178    case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
15179                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15180                                       goto ok;
15181    case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
15182                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15183                                       goto ok;
15184    case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
15185                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15186                                       goto ok;
15187    case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
15188                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15189                                       goto ok;
15190    case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
15191                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15192                                       goto ok;
15193    case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
15194                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15195                                       goto ok;
15196    case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
15197                                      ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
15198                                      S390_XMNM_LOCR);  goto ok;
15199    case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
15200                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15201                                       goto ok;
15202    case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
15203                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15204                                       goto ok;
15205    case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
15206                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15207                                       goto ok;
15208    case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
15209                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15210                                       goto ok;
15211    case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
15212                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15213                                       goto ok;
15214    case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
15215                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15216                                       goto ok;
15217    case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
15218                                       ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15219                                       goto ok;
15220    }
15221 
15222    switch ((ovl.value & 0xff000000) >> 24) {
15223    case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15224                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15225    case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15226                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15227    case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15228                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15229    case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15230                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15231    case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15232                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15233    case 0x45: /* BAL */ goto unimplemented;
15234    case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15235                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15236    case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15237                              ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15238    case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15239                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15240    case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15241                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15242    case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15243                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15244    case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15245                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15246    case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15247                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15248    case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15249                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15250    case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15251                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15252    case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15253                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15254    case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15255                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15256    case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15257                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15258    case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15259                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15260    case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15261                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15262    case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15263                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15264    case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15265                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15266    case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15267                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15268    case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15269                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15270    case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15271                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15272    case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15273                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15274    case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15275                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15276    case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15277                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15278    case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15279                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15280    case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15281                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15282    case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15283                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15284    case 0x67: /* MXD */ goto unimplemented;
15285    case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15286                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15287    case 0x69: /* CD */ goto unimplemented;
15288    case 0x6a: /* AD */ goto unimplemented;
15289    case 0x6b: /* SD */ goto unimplemented;
15290    case 0x6c: /* MD */ goto unimplemented;
15291    case 0x6d: /* DD */ goto unimplemented;
15292    case 0x6e: /* AW */ goto unimplemented;
15293    case 0x6f: /* SW */ goto unimplemented;
15294    case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15295                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15296    case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15297                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15298    case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15299                                   ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15300    case 0x79: /* CE */ goto unimplemented;
15301    case 0x7a: /* AE */ goto unimplemented;
15302    case 0x7b: /* SE */ goto unimplemented;
15303    case 0x7c: /* MDE */ goto unimplemented;
15304    case 0x7d: /* DE */ goto unimplemented;
15305    case 0x7e: /* AU */ goto unimplemented;
15306    case 0x7f: /* SU */ goto unimplemented;
15307    case 0x83: /* DIAG */ goto unimplemented;
15308    case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
15309                                   ovl.fmt.RSI.r3, ovl.fmt.RSI.i2);  goto ok;
15310    case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
15311                                   ovl.fmt.RSI.r3, ovl.fmt.RSI.i2);  goto ok;
15312    case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15313                                   ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15314    case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15315                                   ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15316    case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15317                                   ovl.fmt.RS.d2);  goto ok;
15318    case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15319                                   ovl.fmt.RS.d2);  goto ok;
15320    case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15321                                   ovl.fmt.RS.d2);  goto ok;
15322    case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15323                                   ovl.fmt.RS.d2);  goto ok;
15324    case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15325                                   ovl.fmt.RS.d2);  goto ok;
15326    case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15327                                   ovl.fmt.RS.d2);  goto ok;
15328    case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15329                                   ovl.fmt.RS.d2);  goto ok;
15330    case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15331                                   ovl.fmt.RS.d2);  goto ok;
15332    case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15333                                   ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15334    case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15335                                  ovl.fmt.SI.d1);  goto ok;
15336    case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15337                                  ovl.fmt.SI.d1);  goto ok;
15338    case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15339                                  ovl.fmt.SI.d1);  goto ok;
15340    case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15341                                  ovl.fmt.SI.d1);  goto ok;
15342    case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15343                                  ovl.fmt.SI.d1);  goto ok;
15344    case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15345                                  ovl.fmt.SI.d1);  goto ok;
15346    case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15347                                   ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15348    case 0x99: /* TRACE */ goto unimplemented;
15349    case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15350                                   ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15351    case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15352                                   ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15353    case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
15354                                   ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15355                                   goto ok;
15356    case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
15357                                   ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15358                                   goto ok;
15359    case 0xac: /* STNSM */ goto unimplemented;
15360    case 0xad: /* STOSM */ goto unimplemented;
15361    case 0xae: /* SIGP */ goto unimplemented;
15362    case 0xaf: /* MC */ goto unimplemented;
15363    case 0xb1: /* LRA */ goto unimplemented;
15364    case 0xb6: /* STCTL */ goto unimplemented;
15365    case 0xb7: /* LCTL */ goto unimplemented;
15366    case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15367                                   ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15368    case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15369                                   ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15370    case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15371                                   ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15372    case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15373                                   ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15374    case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15375                                   ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15376    }
15377 
15378    return S390_DECODE_UNKNOWN_INSN;
15379 
15380 ok:
15381    return S390_DECODE_OK;
15382 
15383 unimplemented:
15384    return S390_DECODE_UNIMPLEMENTED_INSN;
15385 }
15386 
15387 static s390_decode_t
s390_decode_6byte_and_irgen(const UChar * bytes)15388 s390_decode_6byte_and_irgen(const UChar *bytes)
15389 {
15390    typedef union {
15391       struct {
15392          unsigned int op1 :  8;
15393          unsigned int r1  :  4;
15394          unsigned int r3  :  4;
15395          unsigned int i2  : 16;
15396          unsigned int     :  8;
15397          unsigned int op2 :  8;
15398       } RIE;
15399       struct {
15400          unsigned int op1 :  8;
15401          unsigned int r1  :  4;
15402          unsigned int r2  :  4;
15403          unsigned int i3  :  8;
15404          unsigned int i4  :  8;
15405          unsigned int i5  :  8;
15406          unsigned int op2 :  8;
15407       } RIE_RRUUU;
15408       struct {
15409          unsigned int op1 :  8;
15410          unsigned int r1  :  4;
15411          unsigned int     :  4;
15412          unsigned int i2  : 16;
15413          unsigned int m3  :  4;
15414          unsigned int     :  4;
15415          unsigned int op2 :  8;
15416       } RIEv1;
15417       struct {
15418          unsigned int op1 :  8;
15419          unsigned int r1  :  4;
15420          unsigned int r2  :  4;
15421          unsigned int i4  : 16;
15422          unsigned int m3  :  4;
15423          unsigned int     :  4;
15424          unsigned int op2 :  8;
15425       } RIE_RRPU;
15426       struct {
15427          unsigned int op1 :  8;
15428          unsigned int r1  :  4;
15429          unsigned int m3  :  4;
15430          unsigned int i4  : 16;
15431          unsigned int i2  :  8;
15432          unsigned int op2 :  8;
15433       } RIEv3;
15434       struct {
15435          unsigned int op1 :  8;
15436          unsigned int r1  :  4;
15437          unsigned int op2 :  4;
15438          unsigned int i2  : 32;
15439       } RIL;
15440       struct {
15441          unsigned int op1 :  8;
15442          unsigned int r1  :  4;
15443          unsigned int m3  :  4;
15444          unsigned int b4  :  4;
15445          unsigned int d4  : 12;
15446          unsigned int i2  :  8;
15447          unsigned int op2 :  8;
15448       } RIS;
15449       struct {
15450          unsigned int op1 :  8;
15451          unsigned int r1  :  4;
15452          unsigned int r2  :  4;
15453          unsigned int b4  :  4;
15454          unsigned int d4  : 12;
15455          unsigned int m3  :  4;
15456          unsigned int     :  4;
15457          unsigned int op2 :  8;
15458       } RRS;
15459       struct {
15460          unsigned int op1 :  8;
15461          unsigned int l1  :  4;
15462          unsigned int     :  4;
15463          unsigned int b1  :  4;
15464          unsigned int d1  : 12;
15465          unsigned int     :  8;
15466          unsigned int op2 :  8;
15467       } RSL;
15468       struct {
15469          unsigned int op1 :  8;
15470          unsigned int r1  :  4;
15471          unsigned int r3  :  4;
15472          unsigned int b2  :  4;
15473          unsigned int dl2 : 12;
15474          unsigned int dh2 :  8;
15475          unsigned int op2 :  8;
15476       } RSY;
15477       struct {
15478          unsigned int op1 :  8;
15479          unsigned int r1  :  4;
15480          unsigned int x2  :  4;
15481          unsigned int b2  :  4;
15482          unsigned int d2  : 12;
15483          unsigned int     :  8;
15484          unsigned int op2 :  8;
15485       } RXE;
15486       struct {
15487          unsigned int op1 :  8;
15488          unsigned int r3  :  4;
15489          unsigned int x2  :  4;
15490          unsigned int b2  :  4;
15491          unsigned int d2  : 12;
15492          unsigned int r1  :  4;
15493          unsigned int     :  4;
15494          unsigned int op2 :  8;
15495       } RXF;
15496       struct {
15497          unsigned int op1 :  8;
15498          unsigned int r1  :  4;
15499          unsigned int x2  :  4;
15500          unsigned int b2  :  4;
15501          unsigned int dl2 : 12;
15502          unsigned int dh2 :  8;
15503          unsigned int op2 :  8;
15504       } RXY;
15505       struct {
15506          unsigned int op1 :  8;
15507          unsigned int i2  :  8;
15508          unsigned int b1  :  4;
15509          unsigned int dl1 : 12;
15510          unsigned int dh1 :  8;
15511          unsigned int op2 :  8;
15512       } SIY;
15513       struct {
15514          unsigned int op :  8;
15515          unsigned int l  :  8;
15516          unsigned int b1 :  4;
15517          unsigned int d1 : 12;
15518          unsigned int b2 :  4;
15519          unsigned int d2 : 12;
15520       } SS;
15521       struct {
15522          unsigned int op :  8;
15523          unsigned int l1 :  4;
15524          unsigned int l2 :  4;
15525          unsigned int b1 :  4;
15526          unsigned int d1 : 12;
15527          unsigned int b2 :  4;
15528          unsigned int d2 : 12;
15529       } SS_LLRDRD;
15530       struct {
15531          unsigned int op :  8;
15532          unsigned int r1 :  4;
15533          unsigned int r3 :  4;
15534          unsigned int b2 :  4;
15535          unsigned int d2 : 12;
15536          unsigned int b4 :  4;
15537          unsigned int d4 : 12;
15538       } SS_RRRDRD2;
15539       struct {
15540          unsigned int op : 16;
15541          unsigned int b1 :  4;
15542          unsigned int d1 : 12;
15543          unsigned int b2 :  4;
15544          unsigned int d2 : 12;
15545       } SSE;
15546       struct {
15547          unsigned int op1 :  8;
15548          unsigned int r3  :  4;
15549          unsigned int op2 :  4;
15550          unsigned int b1  :  4;
15551          unsigned int d1  : 12;
15552          unsigned int b2  :  4;
15553          unsigned int d2  : 12;
15554       } SSF;
15555       struct {
15556          unsigned int op : 16;
15557          unsigned int b1 :  4;
15558          unsigned int d1 : 12;
15559          unsigned int i2 : 16;
15560       } SIL;
15561    } formats;
15562    union {
15563       formats fmt;
15564       ULong value;
15565    } ovl;
15566 
15567    vassert(sizeof(formats) == 6);
15568 
15569    ((UChar *)(&ovl.value))[0] = bytes[0];
15570    ((UChar *)(&ovl.value))[1] = bytes[1];
15571    ((UChar *)(&ovl.value))[2] = bytes[2];
15572    ((UChar *)(&ovl.value))[3] = bytes[3];
15573    ((UChar *)(&ovl.value))[4] = bytes[4];
15574    ((UChar *)(&ovl.value))[5] = bytes[5];
15575    ((UChar *)(&ovl.value))[6] = 0x0;
15576    ((UChar *)(&ovl.value))[7] = 0x0;
15577 
15578    switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15579    case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15580                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15581                                                 ovl.fmt.RXY.dl2,
15582                                                 ovl.fmt.RXY.dh2);  goto ok;
15583    case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15584    case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15585                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15586                                                 ovl.fmt.RXY.dl2,
15587                                                 ovl.fmt.RXY.dh2);  goto ok;
15588    case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15589                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15590                                                 ovl.fmt.RXY.dl2,
15591                                                 ovl.fmt.RXY.dh2);  goto ok;
15592    case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15593                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15594                                                 ovl.fmt.RXY.dl2,
15595                                                 ovl.fmt.RXY.dh2);  goto ok;
15596    case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15597                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15598                                                 ovl.fmt.RXY.dl2,
15599                                                 ovl.fmt.RXY.dh2);  goto ok;
15600    case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15601                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15602                                                 ovl.fmt.RXY.dl2,
15603                                                 ovl.fmt.RXY.dh2);  goto ok;
15604    case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15605                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15606                                                 ovl.fmt.RXY.dl2,
15607                                                 ovl.fmt.RXY.dh2);  goto ok;
15608    case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15609                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15610                                                 ovl.fmt.RXY.dl2,
15611                                                 ovl.fmt.RXY.dh2);  goto ok;
15612    case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15613                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15614                                                 ovl.fmt.RXY.dl2,
15615                                                 ovl.fmt.RXY.dh2);  goto ok;
15616    case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15617    case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
15618                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15619                                                 ovl.fmt.RXY.dl2,
15620                                                 ovl.fmt.RXY.dh2);  goto ok;
15621    case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
15622                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15623                                                 ovl.fmt.RXY.dl2,
15624                                                 ovl.fmt.RXY.dh2);  goto ok;
15625    case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15626    case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15627                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15628                                                 ovl.fmt.RXY.dl2,
15629                                                 ovl.fmt.RXY.dh2);  goto ok;
15630    case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15631                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15632                                                 ovl.fmt.RXY.dl2,
15633                                                 ovl.fmt.RXY.dh2);  goto ok;
15634    case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15635                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15636                                                 ovl.fmt.RXY.dl2,
15637                                                 ovl.fmt.RXY.dh2);  goto ok;
15638    case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15639                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15640                                                 ovl.fmt.RXY.dl2,
15641                                                 ovl.fmt.RXY.dh2);  goto ok;
15642    case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15643                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15644                                                 ovl.fmt.RXY.dl2,
15645                                                 ovl.fmt.RXY.dh2);  goto ok;
15646    case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15647                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15648                                                 ovl.fmt.RXY.dl2,
15649                                                 ovl.fmt.RXY.dh2);  goto ok;
15650    case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15651                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15652                                                 ovl.fmt.RXY.dl2,
15653                                                 ovl.fmt.RXY.dh2);  goto ok;
15654    case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15655                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15656                                                 ovl.fmt.RXY.dl2,
15657                                                 ovl.fmt.RXY.dh2);  goto ok;
15658    case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15659                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15660                                                 ovl.fmt.RXY.dl2,
15661                                                 ovl.fmt.RXY.dh2);  goto ok;
15662    case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15663                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15664                                                 ovl.fmt.RXY.dl2,
15665                                                 ovl.fmt.RXY.dh2);  goto ok;
15666    case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15667                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15668                                                 ovl.fmt.RXY.dl2,
15669                                                 ovl.fmt.RXY.dh2);  goto ok;
15670    case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15671                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15672                                                 ovl.fmt.RXY.dl2,
15673                                                 ovl.fmt.RXY.dh2);  goto ok;
15674    case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15675                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15676                                                 ovl.fmt.RXY.dl2,
15677                                                 ovl.fmt.RXY.dh2);  goto ok;
15678    case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15679                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15680                                                 ovl.fmt.RXY.dl2,
15681                                                 ovl.fmt.RXY.dh2);  goto ok;
15682    case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15683                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15684                                                 ovl.fmt.RXY.dl2,
15685                                                 ovl.fmt.RXY.dh2);  goto ok;
15686    case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
15687    case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15688                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15689                                                 ovl.fmt.RXY.dl2,
15690                                                 ovl.fmt.RXY.dh2);  goto ok;
15691    case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15692    case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15693                                                 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15694                                                 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15695                                                 ovl.fmt.RXY.dh2);  goto ok;
15696    case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15697                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15698                                                 ovl.fmt.RXY.dl2,
15699                                                 ovl.fmt.RXY.dh2);  goto ok;
15700    case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15701                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15702                                                 ovl.fmt.RXY.dl2,
15703                                                 ovl.fmt.RXY.dh2);  goto ok;
15704    case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15705                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15706                                                 ovl.fmt.RXY.dl2,
15707                                                 ovl.fmt.RXY.dh2);  goto ok;
15708    case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15709                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15710                                                 ovl.fmt.RXY.dl2,
15711                                                 ovl.fmt.RXY.dh2);  goto ok;
15712    case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15713                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15714                                                 ovl.fmt.RXY.dl2,
15715                                                 ovl.fmt.RXY.dh2);  goto ok;
15716    case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15717                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15718                                                 ovl.fmt.RXY.dl2,
15719                                                 ovl.fmt.RXY.dh2);  goto ok;
15720    case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15721                                                 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15722                                                 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15723                                                 ovl.fmt.RXY.dh2);  goto ok;
15724    case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15725                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15726                                                 ovl.fmt.RXY.dl2,
15727                                                 ovl.fmt.RXY.dh2);  goto ok;
15728    case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15729                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15730                                                 ovl.fmt.RXY.dl2,
15731                                                 ovl.fmt.RXY.dh2);  goto ok;
15732    case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15733                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15734                                                 ovl.fmt.RXY.dl2,
15735                                                 ovl.fmt.RXY.dh2);  goto ok;
15736    case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15737                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15738                                                 ovl.fmt.RXY.dl2,
15739                                                 ovl.fmt.RXY.dh2);  goto ok;
15740    case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15741                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15742                                                 ovl.fmt.RXY.dl2,
15743                                                 ovl.fmt.RXY.dh2);  goto ok;
15744    case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15745                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15746                                                 ovl.fmt.RXY.dl2,
15747                                                 ovl.fmt.RXY.dh2);  goto ok;
15748    case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15749                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15750                                                 ovl.fmt.RXY.dl2,
15751                                                 ovl.fmt.RXY.dh2);  goto ok;
15752    case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15753                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15754                                                 ovl.fmt.RXY.dl2,
15755                                                 ovl.fmt.RXY.dh2);  goto ok;
15756    case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15757                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15758                                                 ovl.fmt.RXY.dl2,
15759                                                 ovl.fmt.RXY.dh2);  goto ok;
15760    case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15761                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15762                                                 ovl.fmt.RXY.dl2,
15763                                                 ovl.fmt.RXY.dh2);  goto ok;
15764    case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15765                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15766                                                 ovl.fmt.RXY.dl2,
15767                                                 ovl.fmt.RXY.dh2);  goto ok;
15768    case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15769                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15770                                                 ovl.fmt.RXY.dl2,
15771                                                 ovl.fmt.RXY.dh2);  goto ok;
15772    case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15773                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15774                                                 ovl.fmt.RXY.dl2,
15775                                                 ovl.fmt.RXY.dh2);  goto ok;
15776    case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15777                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15778                                                 ovl.fmt.RXY.dl2,
15779                                                 ovl.fmt.RXY.dh2);  goto ok;
15780    case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15781                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15782                                                 ovl.fmt.RXY.dl2,
15783                                                 ovl.fmt.RXY.dh2);  goto ok;
15784    case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15785                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15786                                                 ovl.fmt.RXY.dl2,
15787                                                 ovl.fmt.RXY.dh2);  goto ok;
15788    case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15789                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15790                                                 ovl.fmt.RXY.dl2,
15791                                                 ovl.fmt.RXY.dh2);  goto ok;
15792    case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15793                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15794                                                 ovl.fmt.RXY.dl2,
15795                                                 ovl.fmt.RXY.dh2);  goto ok;
15796    case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15797                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15798                                                 ovl.fmt.RXY.dl2,
15799                                                 ovl.fmt.RXY.dh2);  goto ok;
15800    case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15801                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15802                                                 ovl.fmt.RXY.dl2,
15803                                                 ovl.fmt.RXY.dh2);  goto ok;
15804    case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15805                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15806                                                 ovl.fmt.RXY.dl2,
15807                                                 ovl.fmt.RXY.dh2);  goto ok;
15808    case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15809                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15810                                                 ovl.fmt.RXY.dl2,
15811                                                 ovl.fmt.RXY.dh2);  goto ok;
15812    case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15813                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15814                                                 ovl.fmt.RXY.dl2,
15815                                                 ovl.fmt.RXY.dh2);  goto ok;
15816    case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15817                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15818                                                 ovl.fmt.RXY.dl2,
15819                                                 ovl.fmt.RXY.dh2);  goto ok;
15820    case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15821                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15822                                                 ovl.fmt.RXY.dl2,
15823                                                 ovl.fmt.RXY.dh2);  goto ok;
15824    case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15825                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15826                                                 ovl.fmt.RXY.dl2,
15827                                                 ovl.fmt.RXY.dh2);  goto ok;
15828    case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15829                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15830                                                 ovl.fmt.RXY.dl2,
15831                                                 ovl.fmt.RXY.dh2);  goto ok;
15832    case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15833                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15834                                                 ovl.fmt.RXY.dl2,
15835                                                 ovl.fmt.RXY.dh2);  goto ok;
15836    case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15837                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15838                                                 ovl.fmt.RXY.dl2,
15839                                                 ovl.fmt.RXY.dh2);  goto ok;
15840    case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
15841    case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15842                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15843                                                 ovl.fmt.RXY.dl2,
15844                                                 ovl.fmt.RXY.dh2);  goto ok;
15845    case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15846                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15847                                                 ovl.fmt.RXY.dl2,
15848                                                 ovl.fmt.RXY.dh2);  goto ok;
15849    case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15850                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15851                                                 ovl.fmt.RXY.dl2,
15852                                                 ovl.fmt.RXY.dh2);  goto ok;
15853    case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15854                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15855                                                 ovl.fmt.RXY.dl2,
15856                                                 ovl.fmt.RXY.dh2);  goto ok;
15857    case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15858                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15859                                                 ovl.fmt.RXY.dl2,
15860                                                 ovl.fmt.RXY.dh2);  goto ok;
15861    case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15862                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15863                                                 ovl.fmt.RXY.dl2,
15864                                                 ovl.fmt.RXY.dh2);  goto ok;
15865    case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15866                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15867                                                 ovl.fmt.RXY.dl2,
15868                                                 ovl.fmt.RXY.dh2);  goto ok;
15869    case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15870                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15871                                                 ovl.fmt.RXY.dl2,
15872                                                 ovl.fmt.RXY.dh2);  goto ok;
15873    case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15874                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15875                                                 ovl.fmt.RXY.dl2,
15876                                                 ovl.fmt.RXY.dh2);  goto ok;
15877    case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15878                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15879                                                 ovl.fmt.RXY.dl2,
15880                                                 ovl.fmt.RXY.dh2);  goto ok;
15881    case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15882                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15883                                                 ovl.fmt.RXY.dl2,
15884                                                 ovl.fmt.RXY.dh2);  goto ok;
15885    case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15886                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15887                                                 ovl.fmt.RXY.dl2,
15888                                                 ovl.fmt.RXY.dh2);  goto ok;
15889    case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15890                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15891                                                 ovl.fmt.RXY.dl2,
15892                                                 ovl.fmt.RXY.dh2);  goto ok;
15893    case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15894                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15895                                                 ovl.fmt.RXY.dl2,
15896                                                 ovl.fmt.RXY.dh2);  goto ok;
15897    case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15898    case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15899    case 0xe3000000009fULL: /* LAT */ goto unimplemented;
15900    case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15901                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15902                                                 ovl.fmt.RXY.dl2,
15903                                                 ovl.fmt.RXY.dh2);  goto ok;
15904    case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15905                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15906                                                 ovl.fmt.RXY.dl2,
15907                                                 ovl.fmt.RXY.dh2);  goto ok;
15908    case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15909                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15910                                                 ovl.fmt.RXY.dl2,
15911                                                 ovl.fmt.RXY.dh2);  goto ok;
15912    case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15913                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15914                                                 ovl.fmt.RXY.dl2,
15915                                                 ovl.fmt.RXY.dh2);  goto ok;
15916    case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15917                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15918                                                 ovl.fmt.RXY.dl2,
15919                                                 ovl.fmt.RXY.dh2);  goto ok;
15920    case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15921                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15922                                                 ovl.fmt.RXY.dl2,
15923                                                 ovl.fmt.RXY.dh2);  goto ok;
15924    case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
15925    case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15926                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15927                                                 ovl.fmt.RXY.dl2,
15928                                                 ovl.fmt.RXY.dh2);  goto ok;
15929    case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15930                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15931                                                 ovl.fmt.RXY.dl2,
15932                                                 ovl.fmt.RXY.dh2);  goto ok;
15933    case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15934                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15935                                                 ovl.fmt.RXY.dl2,
15936                                                 ovl.fmt.RXY.dh2);  goto ok;
15937    case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15938                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15939                                                 ovl.fmt.RXY.dl2,
15940                                                 ovl.fmt.RXY.dh2);  goto ok;
15941    case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15942                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15943                                                 ovl.fmt.RSY.dl2,
15944                                                 ovl.fmt.RSY.dh2);  goto ok;
15945    case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15946                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15947                                                 ovl.fmt.RSY.dl2,
15948                                                 ovl.fmt.RSY.dh2);  goto ok;
15949    case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15950                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15951                                                 ovl.fmt.RSY.dl2,
15952                                                 ovl.fmt.RSY.dh2);  goto ok;
15953    case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15954                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15955                                                 ovl.fmt.RSY.dl2,
15956                                                 ovl.fmt.RSY.dh2);  goto ok;
15957    case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15958                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15959                                                 ovl.fmt.RSY.dl2,
15960                                                 ovl.fmt.RSY.dh2);  goto ok;
15961    case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15962    case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15963                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15964                                                 ovl.fmt.RSY.dl2,
15965                                                 ovl.fmt.RSY.dh2);  goto ok;
15966    case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15967                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15968                                                 ovl.fmt.RSY.dl2,
15969                                                 ovl.fmt.RSY.dh2);  goto ok;
15970    case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15971                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15972                                                 ovl.fmt.RSY.dl2,
15973                                                 ovl.fmt.RSY.dh2);  goto ok;
15974    case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15975                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15976                                                 ovl.fmt.RSY.dl2,
15977                                                 ovl.fmt.RSY.dh2);  goto ok;
15978    case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15979                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15980                                                 ovl.fmt.RSY.dl2,
15981                                                 ovl.fmt.RSY.dh2);  goto ok;
15982    case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
15983    case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15984                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15985                                                 ovl.fmt.RSY.dl2,
15986                                                 ovl.fmt.RSY.dh2);  goto ok;
15987    case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15988    case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15989                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15990                                                 ovl.fmt.RSY.dl2,
15991                                                 ovl.fmt.RSY.dh2);  goto ok;
15992    case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
15993    case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15994                                                 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15995                                                 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15996                                                 ovl.fmt.RSY.dh2);  goto ok;
15997    case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15998                                                 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15999                                                 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16000                                                 ovl.fmt.RSY.dh2);  goto ok;
16001    case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
16002    case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
16003                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16004                                                 ovl.fmt.RSY.dl2,
16005                                                 ovl.fmt.RSY.dh2);  goto ok;
16006    case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
16007                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16008                                                 ovl.fmt.RSY.dl2,
16009                                                 ovl.fmt.RSY.dh2);  goto ok;
16010    case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
16011                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16012                                                 ovl.fmt.RSY.dl2,
16013                                                 ovl.fmt.RSY.dh2);  goto ok;
16014    case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
16015                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16016                                                 ovl.fmt.RSY.dl2,
16017                                                 ovl.fmt.RSY.dh2);  goto ok;
16018    case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
16019                                                 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
16020                                                 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16021                                                 ovl.fmt.RSY.dh2);  goto ok;
16022    case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
16023                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16024                                                 ovl.fmt.RSY.dl2,
16025                                                 ovl.fmt.RSY.dh2);  goto ok;
16026    case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
16027                                                ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16028                                                ovl.fmt.SIY.dh1);  goto ok;
16029    case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
16030                                                ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16031                                                ovl.fmt.SIY.dh1);  goto ok;
16032    case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
16033                                                ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16034                                                ovl.fmt.SIY.dh1);  goto ok;
16035    case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
16036                                                ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16037                                                ovl.fmt.SIY.dh1);  goto ok;
16038    case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
16039                                                ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16040                                                ovl.fmt.SIY.dh1);  goto ok;
16041    case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
16042                                                ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16043                                                ovl.fmt.SIY.dh1);  goto ok;
16044    case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
16045                                                ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16046                                                ovl.fmt.SIY.dh1);  goto ok;
16047    case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
16048                                                ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16049                                                ovl.fmt.SIY.dh1);  goto ok;
16050    case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
16051                                                ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16052                                                ovl.fmt.SIY.dh1);  goto ok;
16053    case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
16054                                                ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16055                                                ovl.fmt.SIY.dh1);  goto ok;
16056    case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
16057                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16058                                                 ovl.fmt.RSY.dl2,
16059                                                 ovl.fmt.RSY.dh2);  goto ok;
16060    case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
16061                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16062                                                 ovl.fmt.RSY.dl2,
16063                                                 ovl.fmt.RSY.dh2);  goto ok;
16064    case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
16065    case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
16066    case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
16067                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16068                                                 ovl.fmt.RSY.dl2,
16069                                                 ovl.fmt.RSY.dh2);  goto ok;
16070    case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
16071                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16072                                                 ovl.fmt.RSY.dl2,
16073                                                 ovl.fmt.RSY.dh2);  goto ok;
16074    case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
16075                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16076                                                 ovl.fmt.RSY.dl2,
16077                                                 ovl.fmt.RSY.dh2);  goto ok;
16078    case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
16079                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16080                                                 ovl.fmt.RSY.dl2,
16081                                                 ovl.fmt.RSY.dh2);  goto ok;
16082    case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
16083                                                 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
16084                                                 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16085                                                 ovl.fmt.RSY.dh2);  goto ok;
16086    case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
16087    case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
16088                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16089                                                 ovl.fmt.RSY.dl2,
16090                                                 ovl.fmt.RSY.dh2);  goto ok;
16091    case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
16092                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16093                                                 ovl.fmt.RSY.dl2,
16094                                                 ovl.fmt.RSY.dh2);  goto ok;
16095    case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
16096                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16097                                                 ovl.fmt.RSY.dl2,
16098                                                 ovl.fmt.RSY.dh2);  goto ok;
16099    case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
16100                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16101                                                 ovl.fmt.RSY.dl2,
16102                                                 ovl.fmt.RSY.dh2);  goto ok;
16103    case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
16104                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16105                                                 ovl.fmt.RSY.dl2,
16106                                                 ovl.fmt.RSY.dh2,
16107                                                 S390_XMNM_LOCG);  goto ok;
16108    case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
16109                                                 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
16110                                                 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16111                                                 ovl.fmt.RSY.dh2,
16112                                                 S390_XMNM_STOCG);  goto ok;
16113    case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
16114                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16115                                                 ovl.fmt.RSY.dl2,
16116                                                 ovl.fmt.RSY.dh2);  goto ok;
16117    case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
16118                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16119                                                 ovl.fmt.RSY.dl2,
16120                                                 ovl.fmt.RSY.dh2);  goto ok;
16121    case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
16122                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16123                                                 ovl.fmt.RSY.dl2,
16124                                                 ovl.fmt.RSY.dh2);  goto ok;
16125    case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
16126                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16127                                                 ovl.fmt.RSY.dl2,
16128                                                 ovl.fmt.RSY.dh2);  goto ok;
16129    case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
16130                                                 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
16131                                                 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16132                                                 ovl.fmt.RSY.dh2);  goto ok;
16133    case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
16134                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16135                                                 ovl.fmt.RSY.dl2,
16136                                                 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
16137                                                 goto ok;
16138    case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
16139                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16140                                                 ovl.fmt.RSY.dl2,
16141                                                 ovl.fmt.RSY.dh2,
16142                                                 S390_XMNM_STOC);  goto ok;
16143    case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
16144                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16145                                                 ovl.fmt.RSY.dl2,
16146                                                 ovl.fmt.RSY.dh2);  goto ok;
16147    case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
16148                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16149                                                 ovl.fmt.RSY.dl2,
16150                                                 ovl.fmt.RSY.dh2);  goto ok;
16151    case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
16152                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16153                                                 ovl.fmt.RSY.dl2,
16154                                                 ovl.fmt.RSY.dh2);  goto ok;
16155    case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
16156                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16157                                                 ovl.fmt.RSY.dl2,
16158                                                 ovl.fmt.RSY.dh2);  goto ok;
16159    case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
16160                                                 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16161                                                 ovl.fmt.RSY.dl2,
16162                                                 ovl.fmt.RSY.dh2);  goto ok;
16163    case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
16164                                                ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
16165                                                goto ok;
16166    case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
16167                                                ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
16168                                                goto ok;
16169    case 0xec0000000051ULL: s390_format_RIE_RRUUU(s390_irgen_RISBLG,
16170                                                  ovl.fmt.RIE_RRUUU.r1,
16171                                                  ovl.fmt.RIE_RRUUU.r2,
16172                                                  ovl.fmt.RIE_RRUUU.i3,
16173                                                  ovl.fmt.RIE_RRUUU.i4,
16174                                                  ovl.fmt.RIE_RRUUU.i5);
16175                                                  goto ok;
16176    case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
16177                                                  ovl.fmt.RIE_RRUUU.r1,
16178                                                  ovl.fmt.RIE_RRUUU.r2,
16179                                                  ovl.fmt.RIE_RRUUU.i3,
16180                                                  ovl.fmt.RIE_RRUUU.i4,
16181                                                  ovl.fmt.RIE_RRUUU.i5);
16182                                                  goto ok;
16183    case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
16184                                                  ovl.fmt.RIE_RRUUU.r1,
16185                                                  ovl.fmt.RIE_RRUUU.r2,
16186                                                  ovl.fmt.RIE_RRUUU.i3,
16187                                                  ovl.fmt.RIE_RRUUU.i4,
16188                                                  ovl.fmt.RIE_RRUUU.i5);
16189                                                  goto ok;
16190    case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
16191                                                  ovl.fmt.RIE_RRUUU.r1,
16192                                                  ovl.fmt.RIE_RRUUU.r2,
16193                                                  ovl.fmt.RIE_RRUUU.i3,
16194                                                  ovl.fmt.RIE_RRUUU.i4,
16195                                                  ovl.fmt.RIE_RRUUU.i5);
16196                                                  goto ok;
16197    case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
16198                                                  ovl.fmt.RIE_RRUUU.r1,
16199                                                  ovl.fmt.RIE_RRUUU.r2,
16200                                                  ovl.fmt.RIE_RRUUU.i3,
16201                                                  ovl.fmt.RIE_RRUUU.i4,
16202                                                  ovl.fmt.RIE_RRUUU.i5);
16203                                                  goto ok;
16204    case 0xec0000000059ULL: s390_format_RIE_RRUUU(s390_irgen_RISBGN,
16205                                                  ovl.fmt.RIE_RRUUU.r1,
16206                                                  ovl.fmt.RIE_RRUUU.r2,
16207                                                  ovl.fmt.RIE_RRUUU.i3,
16208                                                  ovl.fmt.RIE_RRUUU.i4,
16209                                                  ovl.fmt.RIE_RRUUU.i5);
16210                                                  goto ok;
16211    case 0xec000000005dULL: s390_format_RIE_RRUUU(s390_irgen_RISBHG,
16212                                                  ovl.fmt.RIE_RRUUU.r1,
16213                                                  ovl.fmt.RIE_RRUUU.r2,
16214                                                  ovl.fmt.RIE_RRUUU.i3,
16215                                                  ovl.fmt.RIE_RRUUU.i4,
16216                                                  ovl.fmt.RIE_RRUUU.i5);
16217                                                  goto ok;
16218    case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
16219                                                 ovl.fmt.RIE_RRPU.r1,
16220                                                 ovl.fmt.RIE_RRPU.r2,
16221                                                 ovl.fmt.RIE_RRPU.i4,
16222                                                 ovl.fmt.RIE_RRPU.m3);  goto ok;
16223    case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
16224                                                 ovl.fmt.RIE_RRPU.r1,
16225                                                 ovl.fmt.RIE_RRPU.r2,
16226                                                 ovl.fmt.RIE_RRPU.i4,
16227                                                 ovl.fmt.RIE_RRPU.m3);  goto ok;
16228    case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
16229    case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
16230    case 0xec0000000072ULL: /* CIT */ goto unimplemented;
16231    case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
16232    case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
16233                                                 ovl.fmt.RIE_RRPU.r1,
16234                                                 ovl.fmt.RIE_RRPU.r2,
16235                                                 ovl.fmt.RIE_RRPU.i4,
16236                                                 ovl.fmt.RIE_RRPU.m3);  goto ok;
16237    case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
16238                                                 ovl.fmt.RIE_RRPU.r1,
16239                                                 ovl.fmt.RIE_RRPU.r2,
16240                                                 ovl.fmt.RIE_RRPU.i4,
16241                                                 ovl.fmt.RIE_RRPU.m3);  goto ok;
16242    case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
16243                                                 ovl.fmt.RIEv3.r1,
16244                                                 ovl.fmt.RIEv3.m3,
16245                                                 ovl.fmt.RIEv3.i4,
16246                                                 ovl.fmt.RIEv3.i2);  goto ok;
16247    case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
16248                                                 ovl.fmt.RIEv3.r1,
16249                                                 ovl.fmt.RIEv3.m3,
16250                                                 ovl.fmt.RIEv3.i4,
16251                                                 ovl.fmt.RIEv3.i2);  goto ok;
16252    case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
16253                                                 ovl.fmt.RIEv3.r1,
16254                                                 ovl.fmt.RIEv3.m3,
16255                                                 ovl.fmt.RIEv3.i4,
16256                                                 ovl.fmt.RIEv3.i2);  goto ok;
16257    case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
16258                                                 ovl.fmt.RIEv3.r1,
16259                                                 ovl.fmt.RIEv3.m3,
16260                                                 ovl.fmt.RIEv3.i4,
16261                                                 ovl.fmt.RIEv3.i2);  goto ok;
16262    case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
16263                                                 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
16264                                                 goto ok;
16265    case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
16266                                                 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16267                                                 ovl.fmt.RIE.i2);  goto ok;
16268    case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
16269                                                 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16270                                                 ovl.fmt.RIE.i2);  goto ok;
16271    case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
16272                                                 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16273                                                 ovl.fmt.RIE.i2);  goto ok;
16274    case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
16275                                            ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16276                                            ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16277                                            goto ok;
16278    case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
16279                                            ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16280                                            ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16281                                            goto ok;
16282    case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
16283                                            ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16284                                            ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16285                                            goto ok;
16286    case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
16287                                            ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16288                                            ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16289                                            goto ok;
16290    case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
16291                                                  ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16292                                                  ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16293                                                  ovl.fmt.RIS.i2);  goto ok;
16294    case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
16295                                                  ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16296                                                  ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16297                                                  ovl.fmt.RIS.i2);  goto ok;
16298    case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
16299                                                  ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
16300                                                  ovl.fmt.RIS.d4,
16301                                                  ovl.fmt.RIS.i2);  goto ok;
16302    case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
16303                                                  ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16304                                                  ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16305                                                  ovl.fmt.RIS.i2);  goto ok;
16306    case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
16307                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16308                                                 ovl.fmt.RXE.d2);  goto ok;
16309    case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
16310                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16311                                                 ovl.fmt.RXE.d2);  goto ok;
16312    case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
16313                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16314                                                 ovl.fmt.RXE.d2);  goto ok;
16315    case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
16316    case 0xed0000000008ULL: /* KEB */ goto unimplemented;
16317    case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
16318                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16319                                                 ovl.fmt.RXE.d2);  goto ok;
16320    case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
16321                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16322                                                 ovl.fmt.RXE.d2);  goto ok;
16323    case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
16324                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16325                                                 ovl.fmt.RXE.d2);  goto ok;
16326    case 0xed000000000cULL: /* MDEB */ goto unimplemented;
16327    case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
16328                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16329                                                 ovl.fmt.RXE.d2);  goto ok;
16330    case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
16331                                                  ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16332                                                  ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16333                                                  ovl.fmt.RXF.r1);  goto ok;
16334    case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
16335                                                  ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16336                                                  ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16337                                                  ovl.fmt.RXF.r1);  goto ok;
16338    case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
16339                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16340                                                 ovl.fmt.RXE.d2);  goto ok;
16341    case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
16342                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16343                                                 ovl.fmt.RXE.d2);  goto ok;
16344    case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
16345                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16346                                                 ovl.fmt.RXE.d2);  goto ok;
16347    case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
16348                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16349                                                 ovl.fmt.RXE.d2);  goto ok;
16350    case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
16351                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16352                                                 ovl.fmt.RXE.d2);  goto ok;
16353    case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
16354                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16355                                                 ovl.fmt.RXE.d2);  goto ok;
16356    case 0xed0000000018ULL: /* KDB */ goto unimplemented;
16357    case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
16358                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16359                                                 ovl.fmt.RXE.d2);  goto ok;
16360    case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
16361                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16362                                                 ovl.fmt.RXE.d2);  goto ok;
16363    case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
16364                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16365                                                 ovl.fmt.RXE.d2);  goto ok;
16366    case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
16367                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16368                                                 ovl.fmt.RXE.d2);  goto ok;
16369    case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
16370                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16371                                                 ovl.fmt.RXE.d2);  goto ok;
16372    case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
16373                                                  ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16374                                                  ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16375                                                  ovl.fmt.RXF.r1);  goto ok;
16376    case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
16377                                                  ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16378                                                  ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16379                                                  ovl.fmt.RXF.r1);  goto ok;
16380    case 0xed0000000024ULL: s390_format_RXE_FRRD(s390_irgen_LDE,
16381                                                 ovl.fmt.RXE.r1, ovl.fmt.RXE.x2,
16382                                                 ovl.fmt.RXE.b2,
16383                                                 ovl.fmt.RXE.d2); goto ok;
16384    case 0xed0000000025ULL: /* LXD */ goto unimplemented;
16385    case 0xed0000000026ULL: /* LXE */ goto unimplemented;
16386    case 0xed000000002eULL: /* MAE */ goto unimplemented;
16387    case 0xed000000002fULL: /* MSE */ goto unimplemented;
16388    case 0xed0000000034ULL: /* SQE */ goto unimplemented;
16389    case 0xed0000000035ULL: /* SQD */ goto unimplemented;
16390    case 0xed0000000037ULL: /* MEE */ goto unimplemented;
16391    case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
16392    case 0xed0000000039ULL: /* MYL */ goto unimplemented;
16393    case 0xed000000003aULL: /* MAY */ goto unimplemented;
16394    case 0xed000000003bULL: /* MY */ goto unimplemented;
16395    case 0xed000000003cULL: /* MAYH */ goto unimplemented;
16396    case 0xed000000003dULL: /* MYH */ goto unimplemented;
16397    case 0xed000000003eULL: /* MAD */ goto unimplemented;
16398    case 0xed000000003fULL: /* MSD */ goto unimplemented;
16399    case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
16400                                                  ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16401                                                  ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16402                                                  ovl.fmt.RXF.r1);  goto ok;
16403    case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
16404                                                  ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16405                                                  ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16406                                                  ovl.fmt.RXF.r1);  goto ok;
16407    case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
16408                                                  ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16409                                                  ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16410                                                  ovl.fmt.RXF.r1);  goto ok;
16411    case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
16412                                                  ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16413                                                  ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16414                                                  ovl.fmt.RXF.r1);  goto ok;
16415    case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
16416                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16417                                                 ovl.fmt.RXE.d2);  goto ok;
16418    case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
16419                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16420                                                 ovl.fmt.RXE.d2);  goto ok;
16421    case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
16422                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16423                                                 ovl.fmt.RXE.d2);  goto ok;
16424    case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
16425                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16426                                                 ovl.fmt.RXE.d2);  goto ok;
16427    case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
16428                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16429                                                 ovl.fmt.RXE.d2);  goto ok;
16430    case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
16431                                                 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16432                                                 ovl.fmt.RXE.d2);  goto ok;
16433    case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
16434                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16435                                                 ovl.fmt.RXY.dl2,
16436                                                 ovl.fmt.RXY.dh2);  goto ok;
16437    case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
16438                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16439                                                 ovl.fmt.RXY.dl2,
16440                                                 ovl.fmt.RXY.dh2);  goto ok;
16441    case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
16442                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16443                                                 ovl.fmt.RXY.dl2,
16444                                                 ovl.fmt.RXY.dh2);  goto ok;
16445    case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
16446                                                 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16447                                                 ovl.fmt.RXY.dl2,
16448                                                 ovl.fmt.RXY.dh2);  goto ok;
16449    case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
16450    case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
16451    case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
16452    case 0xed00000000abULL: /* CXZT */ goto unimplemented;
16453    }
16454 
16455    switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
16456    case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
16457                                       ovl.fmt.RIL.i2);  goto ok;
16458    case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
16459                                       ovl.fmt.RIL.i2);  goto ok;
16460    case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
16461                                    ovl.fmt.RIL.i2);  goto ok;
16462    case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16463                                       ovl.fmt.RIL.i2);  goto ok;
16464    case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16465                                       ovl.fmt.RIL.i2);  goto ok;
16466    case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16467                                       ovl.fmt.RIL.i2);  goto ok;
16468    case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16469                                       ovl.fmt.RIL.i2);  goto ok;
16470    case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16471                                       ovl.fmt.RIL.i2);  goto ok;
16472    case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16473                                       ovl.fmt.RIL.i2);  goto ok;
16474    case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16475                                       ovl.fmt.RIL.i2);  goto ok;
16476    case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16477                                       ovl.fmt.RIL.i2);  goto ok;
16478    case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16479                                       ovl.fmt.RIL.i2);  goto ok;
16480    case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16481                                       ovl.fmt.RIL.i2);  goto ok;
16482    case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16483                                       ovl.fmt.RIL.i2);  goto ok;
16484    case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16485                                       ovl.fmt.RIL.i2);  goto ok;
16486    case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16487                                       ovl.fmt.RIL.i2);  goto ok;
16488    case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16489                                       ovl.fmt.RIL.i2);  goto ok;
16490    case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16491                                       ovl.fmt.RIL.i2);  goto ok;
16492    case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16493                                       ovl.fmt.RIL.i2);  goto ok;
16494    case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16495                                       ovl.fmt.RIL.i2);  goto ok;
16496    case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16497                                       ovl.fmt.RIL.i2);  goto ok;
16498    case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16499                                       ovl.fmt.RIL.i2);  goto ok;
16500    case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16501                                       ovl.fmt.RIL.i2);  goto ok;
16502    case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16503                                       ovl.fmt.RIL.i2);  goto ok;
16504    case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16505                                       ovl.fmt.RIL.i2);  goto ok;
16506    case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16507                                       ovl.fmt.RIL.i2);  goto ok;
16508    case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16509                                       ovl.fmt.RIL.i2);  goto ok;
16510    case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16511                                       ovl.fmt.RIL.i2);  goto ok;
16512    case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16513                                       ovl.fmt.RIL.i2);  goto ok;
16514    case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16515                                       ovl.fmt.RIL.i2);  goto ok;
16516    case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16517                                       ovl.fmt.RIL.i2);  goto ok;
16518    case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16519                                       ovl.fmt.RIL.i2);  goto ok;
16520    case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16521                                       ovl.fmt.RIL.i2);  goto ok;
16522    case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16523                                       ovl.fmt.RIL.i2);  goto ok;
16524    case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16525                                       ovl.fmt.RIL.i2);  goto ok;
16526    case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16527                                       ovl.fmt.RIL.i2);  goto ok;
16528    case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16529                                       ovl.fmt.RIL.i2);  goto ok;
16530    case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16531                                       ovl.fmt.RIL.i2);  goto ok;
16532    case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16533                                       ovl.fmt.RIL.i2);  goto ok;
16534    case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16535                                       ovl.fmt.RIL.i2);  goto ok;
16536    case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16537                                       ovl.fmt.RIL.i2);  goto ok;
16538    case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16539                                       ovl.fmt.RIL.i2);  goto ok;
16540    case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16541                                       ovl.fmt.RIL.i2);  goto ok;
16542    case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16543                                       ovl.fmt.RIL.i2);  goto ok;
16544    case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16545                                       ovl.fmt.RIL.i2);  goto ok;
16546    case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16547                                       ovl.fmt.RIL.i2);  goto ok;
16548    case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16549                                       ovl.fmt.RIL.i2);  goto ok;
16550    case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16551                                       ovl.fmt.RIL.i2);  goto ok;
16552    case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16553                                       ovl.fmt.RIL.i2);  goto ok;
16554    case 0xc800ULL: /* MVCOS */ goto unimplemented;
16555    case 0xc801ULL: /* ECTG */ goto unimplemented;
16556    case 0xc802ULL: /* CSST */ goto unimplemented;
16557    case 0xc804ULL: /* LPD */ goto unimplemented;
16558    case 0xc805ULL: /* LPDG */ goto unimplemented;
16559    case 0xcc06ULL:  s390_format_RIL_RP(s390_irgen_BRCTH, ovl.fmt.RIL.r1,
16560                                        ovl.fmt.RIL.i2);  goto ok;
16561    case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16562                                       ovl.fmt.RIL.i2);  goto ok;
16563    case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16564                                       ovl.fmt.RIL.i2);  goto ok;
16565    case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16566                                       ovl.fmt.RIL.i2);  goto ok;
16567    case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16568                                       ovl.fmt.RIL.i2);  goto ok;
16569    case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16570                                       ovl.fmt.RIL.i2);  goto ok;
16571    }
16572 
16573    switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
16574    case 0xc5ULL: /* BPRP */ goto unimplemented;
16575    case 0xc7ULL: /* BPP */ goto unimplemented;
16576    case 0xd0ULL: /* TRTR */ goto unimplemented;
16577    case 0xd1ULL: /* MVN */ goto unimplemented;
16578    case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16579                                        ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16580                                        ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16581    case 0xd3ULL: /* MVZ */ goto unimplemented;
16582    case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16583                                        ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16584                                        ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16585    case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16586                                        ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16587                                        ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16588    case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16589                                        ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16590                                        ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16591    case 0xd7ULL:
16592       if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16593          s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16594       else
16595         s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16596                               ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16597                               ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16598       goto ok;
16599    case 0xd9ULL: /* MVCK */ goto unimplemented;
16600    case 0xdaULL: /* MVCP */ goto unimplemented;
16601    case 0xdbULL: /* MVCS */ goto unimplemented;
16602    case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16603                                        ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16604                                        ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16605    case 0xddULL: /* TRT */ goto unimplemented;
16606    case 0xdeULL: /* ED */ goto unimplemented;
16607    case 0xdfULL: /* EDMK */ goto unimplemented;
16608    case 0xe1ULL: /* PKU */ goto unimplemented;
16609    case 0xe2ULL: /* UNPKU */ goto unimplemented;
16610    case 0xe8ULL: s390_format_SS_L0RDRD(s390_irgen_MVCIN, ovl.fmt.SS.l,
16611                                        ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16612                                        ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16613    case 0xe9ULL: /* PKA */ goto unimplemented;
16614    case 0xeaULL: /* UNPKA */ goto unimplemented;
16615    case 0xeeULL: /* PLO */ goto unimplemented;
16616    case 0xefULL: /* LMD */ goto unimplemented;
16617    case 0xf0ULL: /* SRP */ goto unimplemented;
16618    case 0xf1ULL: /* MVO */ goto unimplemented;
16619    case 0xf2ULL: /* PACK */ goto unimplemented;
16620    case 0xf3ULL: /* UNPK */ goto unimplemented;
16621    case 0xf8ULL: /* ZAP */ goto unimplemented;
16622    case 0xf9ULL: /* CP */ goto unimplemented;
16623    case 0xfaULL: /* AP */ goto unimplemented;
16624    case 0xfbULL: /* SP */ goto unimplemented;
16625    case 0xfcULL: /* MP */ goto unimplemented;
16626    case 0xfdULL: /* DP */ goto unimplemented;
16627    }
16628 
16629    switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16630    case 0xe500ULL: /* LASP */ goto unimplemented;
16631    case 0xe501ULL: /* TPROT */ goto unimplemented;
16632    case 0xe502ULL: /* STRAG */ goto unimplemented;
16633    case 0xe50eULL: /* MVCSK */ goto unimplemented;
16634    case 0xe50fULL: /* MVCDK */ goto unimplemented;
16635    case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16636                                        ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16637                                        goto ok;
16638    case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16639                                        ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16640                                        goto ok;
16641    case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16642                                        ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16643                                        goto ok;
16644    case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16645                                        ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16646                                        goto ok;
16647    case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16648                                        ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16649                                        goto ok;
16650    case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16651                                        ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16652                                        goto ok;
16653    case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16654                                        ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16655                                        goto ok;
16656    case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16657                                        ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16658                                        goto ok;
16659    case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16660                                        ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16661                                        goto ok;
16662    case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16663    case 0xe561ULL: /* TBEGINC */ goto unimplemented;
16664    }
16665 
16666    return S390_DECODE_UNKNOWN_INSN;
16667 
16668 ok:
16669    return S390_DECODE_OK;
16670 
16671 unimplemented:
16672    return S390_DECODE_UNIMPLEMENTED_INSN;
16673 }
16674 
16675 /* Handle "special" instructions. */
16676 static s390_decode_t
s390_decode_special_and_irgen(const UChar * bytes)16677 s390_decode_special_and_irgen(const UChar *bytes)
16678 {
16679    s390_decode_t status = S390_DECODE_OK;
16680 
16681    /* Got a "Special" instruction preamble.  Which one is it? */
16682    if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16683       s390_irgen_client_request();
16684    } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16685       s390_irgen_guest_NRADDR();
16686    } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16687       s390_irgen_call_noredir();
16688    } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16689       vex_inject_ir(irsb, Iend_BE);
16690 
16691       /* Invalidate the current insn. The reason is that the IRop we're
16692          injecting here can change. In which case the translation has to
16693          be redone. For ease of handling, we simply invalidate all the
16694          time. */
16695       stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
16696                       mkU64(guest_IA_curr_instr)));
16697       stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN),
16698                       mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16699       vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16700               S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16701 
16702       put_IA(mkaddr_expr(guest_IA_next_instr));
16703       dis_res->whatNext    = Dis_StopHere;
16704       dis_res->jk_StopHere = Ijk_InvalICache;
16705    } else {
16706       /* We don't know what it is. */
16707       return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16708    }
16709 
16710    dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16711 
16712    return status;
16713 }
16714 
16715 
16716 /* Function returns # bytes that were decoded or 0 in case of failure */
16717 static UInt
s390_decode_and_irgen(const UChar * bytes,UInt insn_length,DisResult * dres)16718 s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres)
16719 {
16720    s390_decode_t status;
16721 
16722    dis_res = dres;
16723 
16724    /* Spot the 8-byte preamble:   18ff lr r15,r15
16725                                   1811 lr r1,r1
16726                                   1822 lr r2,r2
16727                                   1833 lr r3,r3 */
16728    if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16729        bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16730        bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16731 
16732       /* Handle special instruction that follows that preamble. */
16733       if (0) vex_printf("special function handling...\n");
16734 
16735       insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16736       guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16737 
16738       status =
16739          s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
16740    } else {
16741       /* Handle normal instructions. */
16742       switch (insn_length) {
16743       case 2:
16744          status = s390_decode_2byte_and_irgen(bytes);
16745          break;
16746 
16747       case 4:
16748          status = s390_decode_4byte_and_irgen(bytes);
16749          break;
16750 
16751       case 6:
16752          status = s390_decode_6byte_and_irgen(bytes);
16753          break;
16754 
16755       default:
16756         status = S390_DECODE_ERROR;
16757         break;
16758       }
16759    }
16760    /* If next instruction is execute, stop here */
16761    if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16762       put_IA(mkaddr_expr(guest_IA_next_instr));
16763       dis_res->whatNext = Dis_StopHere;
16764       dis_res->jk_StopHere = Ijk_Boring;
16765    }
16766 
16767    if (status == S390_DECODE_OK) return insn_length;  /* OK */
16768 
16769    /* Decoding failed somehow */
16770    if (sigill_diag) {
16771       vex_printf("vex s390->IR: ");
16772       switch (status) {
16773       case S390_DECODE_UNKNOWN_INSN:
16774          vex_printf("unknown insn: ");
16775          break;
16776 
16777       case S390_DECODE_UNIMPLEMENTED_INSN:
16778          vex_printf("unimplemented insn: ");
16779          break;
16780 
16781       case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16782          vex_printf("unimplemented special insn: ");
16783          break;
16784 
16785       case S390_DECODE_ERROR:
16786          vex_printf("decoding error: ");
16787          break;
16788 
16789       default:
16790          vpanic("s390_decode_and_irgen");
16791       }
16792 
16793       vex_printf("%02x%02x", bytes[0], bytes[1]);
16794       if (insn_length > 2) {
16795          vex_printf(" %02x%02x", bytes[2], bytes[3]);
16796       }
16797       if (insn_length > 4) {
16798          vex_printf(" %02x%02x", bytes[4], bytes[5]);
16799       }
16800       vex_printf("\n");
16801    }
16802 
16803    return 0;  /* Failed */
16804 }
16805 
16806 
16807 /* Disassemble a single instruction INSN into IR. */
16808 static DisResult
disInstr_S390_WRK(const UChar * insn)16809 disInstr_S390_WRK(const UChar *insn)
16810 {
16811    UChar byte;
16812    UInt  insn_length;
16813    DisResult dres;
16814 
16815    /* ---------------------------------------------------- */
16816    /* --- Compute instruction length                    -- */
16817    /* ---------------------------------------------------- */
16818 
16819    /* Get the first byte of the insn. */
16820    byte = insn[0];
16821 
16822    /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16823       00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16824    insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16825 
16826    guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16827 
16828    /* ---------------------------------------------------- */
16829    /* --- Initialise the DisResult data                 -- */
16830    /* ---------------------------------------------------- */
16831    dres.whatNext   = Dis_Continue;
16832    dres.len        = insn_length;
16833    dres.continueAt = 0;
16834    dres.jk_StopHere = Ijk_INVALID;
16835    dres.hint        = Dis_HintNone;
16836 
16837    /* fixs390: consider chasing of conditional jumps */
16838 
16839    /* Normal and special instruction handling starts here. */
16840    if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16841       /* All decode failures end up here. The decoder has already issued an
16842          error message.
16843          Tell the dispatcher that this insn cannot be decoded, and so has
16844          not been executed, and (is currently) the next to be executed.
16845          The insn address in the guest state needs to be set to
16846          guest_IA_curr_instr, otherwise the complaint will report an
16847          incorrect address. */
16848       put_IA(mkaddr_expr(guest_IA_curr_instr));
16849 
16850       dres.len         = 0;
16851       dres.whatNext    = Dis_StopHere;
16852       dres.jk_StopHere = Ijk_NoDecode;
16853       dres.continueAt  = 0;
16854    } else {
16855       /* Decode success */
16856       switch (dres.whatNext) {
16857       case Dis_Continue:
16858          put_IA(mkaddr_expr(guest_IA_next_instr));
16859          break;
16860       case Dis_ResteerU:
16861       case Dis_ResteerC:
16862          put_IA(mkaddr_expr(dres.continueAt));
16863          break;
16864       case Dis_StopHere:
16865          if (dres.jk_StopHere == Ijk_EmWarn ||
16866              dres.jk_StopHere == Ijk_EmFail) {
16867             /* We assume here, that emulation warnings are not given for
16868                insns that transfer control. There is no good way to
16869                do that. */
16870             put_IA(mkaddr_expr(guest_IA_next_instr));
16871          }
16872          break;
16873       default:
16874          vpanic("disInstr_S390_WRK");
16875       }
16876    }
16877 
16878    return dres;
16879 }
16880 
16881 
16882 /*------------------------------------------------------------*/
16883 /*--- Top-level fn                                         ---*/
16884 /*------------------------------------------------------------*/
16885 
16886 /* Disassemble a single instruction into IR.  The instruction
16887    is located in host memory at &guest_code[delta]. */
16888 
16889 DisResult
disInstr_S390(IRSB * irsb_IN,Bool (* resteerOkFn)(void *,Addr),Bool resteerCisOk,void * callback_opaque,const UChar * guest_code,Long delta,Addr guest_IP,VexArch guest_arch,const VexArchInfo * archinfo,const VexAbiInfo * abiinfo,VexEndness host_endness,Bool sigill_diag_IN)16890 disInstr_S390(IRSB        *irsb_IN,
16891               Bool       (*resteerOkFn)(void *, Addr),
16892               Bool         resteerCisOk,
16893               void        *callback_opaque,
16894               const UChar *guest_code,
16895               Long         delta,
16896               Addr         guest_IP,
16897               VexArch      guest_arch,
16898               const VexArchInfo *archinfo,
16899               const VexAbiInfo  *abiinfo,
16900               VexEndness   host_endness,
16901               Bool         sigill_diag_IN)
16902 {
16903    vassert(guest_arch == VexArchS390X);
16904 
16905    /* The instruction decoder requires a big-endian machine. */
16906    vassert(host_endness == VexEndnessBE);
16907 
16908    /* Set globals (see top of this file) */
16909    guest_IA_curr_instr = guest_IP;
16910    irsb = irsb_IN;
16911    resteer_fn = resteerOkFn;
16912    resteer_data = callback_opaque;
16913    sigill_diag = sigill_diag_IN;
16914 
16915    return disInstr_S390_WRK(guest_code + delta);
16916 }
16917 
16918 /*---------------------------------------------------------------*/
16919 /*--- end                                   guest_s390_toIR.c ---*/
16920 /*---------------------------------------------------------------*/
16921