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-2015
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/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(const UChar *, UInt, DisResult *);
52static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
53static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
54
55
56/*------------------------------------------------------------*/
57/*--- Globals                                              ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64   translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
73/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr);
75static void *resteer_data;
76
77/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
80/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef 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. */
98static __inline__ void
99stmt(IRStmt *st)
100{
101   addStmtToIRSB(irsb, st);
102}
103
104/* Allocate a new temporary of the given type. */
105static __inline__ IRTemp
106newTemp(IRType type)
107{
108   vassert(isPlausibleIRType(type));
109
110   return newIRTemp(irsb->tyenv, type);
111}
112
113/* Create an expression node for a temporary */
114static __inline__ IRExpr *
115mkexpr(IRTemp tmp)
116{
117   return IRExpr_RdTmp(tmp);
118}
119
120/* Generate an expression node for an address. */
121static __inline__ IRExpr *
122mkaddr_expr(Addr64 addr)
123{
124   return IRExpr_Const(IRConst_U64(addr));
125}
126
127/* Add a statement that assigns to a temporary */
128static __inline__ void
129assign(IRTemp dst, IRExpr *expr)
130{
131   stmt(IRStmt_WrTmp(dst, expr));
132}
133
134/* Write an address into the guest_IA */
135static __inline__ void
136put_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 */
142static __inline__ IRTemp
143mktemp(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 */
153static __inline__ IRExpr *
154unop(IROp kind, IRExpr *op)
155{
156   return IRExpr_Unop(kind, op);
157}
158
159/* Create a binary expression */
160static __inline__ IRExpr *
161binop(IROp kind, IRExpr *op1, IRExpr *op2)
162{
163   return IRExpr_Binop(kind, op1, op2);
164}
165
166/* Create a ternary expression */
167static __inline__ IRExpr *
168triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
169{
170   return IRExpr_Triop(kind, op1, op2, op3);
171}
172
173/* Create a quaternary expression */
174static __inline__  IRExpr *
175qop(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 */
181static __inline__ IRExpr *
182mkU8(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 */
190static __inline__ IRExpr *
191mkU16(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 */
199static __inline__ IRExpr *
200mkU32(UInt value)
201{
202   return IRExpr_Const(IRConst_U32(value));
203}
204
205/* Create an expression node for a 64-bit integer constant */
206static __inline__ IRExpr *
207mkU64(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. */
214static __inline__ IRExpr *
215mkF32i(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. */
222static __inline__ IRExpr *
223mkF64i(ULong value)
224{
225   return IRExpr_Const(IRConst_F64i(value));
226}
227
228/* Little helper function for my sanity. ITE = if-then-else */
229static IRExpr *
230mkite(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. */
238static __inline__ void
239store(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. */
246static __inline__ IRExpr *
247load(IRType type, IRExpr *addr)
248{
249   return IRExpr_Load(Iend_BE, type, addr);
250}
251
252/* Function call */
253static void
254call_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. */
263static void
264call_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 */
278static void
279return_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*/
296static void
297if_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. */
313static void
314if_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. */
329static void
330always_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. */
340static void
341always_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 */
356static void
357system_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. */
377static void
378iterate_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. */
388static __inline__ void
389iterate(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. */
396static void
397next_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 */
406static void
407restart_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 */
417static void
418yield_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
424static __inline__ IRExpr *get_fpr_dw0(UInt);
425static __inline__ void    put_fpr_dw0(UInt, IRExpr *);
426static __inline__ IRExpr *get_dpr_dw0(UInt);
427static __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 */
431static IRExpr *
432get_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. */
441static void
442put_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
454static IRExpr *
455get_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. */
464static void
465put_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. */
475static void
476emulation_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
485static void
486emulation_failure(VexEmNote fail_kind)
487{
488   emulation_failure_with_expr(mkU32(fail_kind));
489}
490
491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_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
502static void
503emulation_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
513static ULong
514s390_do_print(HChar *text, ULong value)
515{
516   vex_printf("%s %llu\n", text, value);
517   return 0;
518}
519
520static void
521s390_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. */
538static void
539s390_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. */
556static IRExpr *
557s390_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
582static void
583s390_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
596static void
597s390_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. */
621static void
622s390_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 */
638static void
639s390_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. */
662static void
663s390_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. */
686static void
687s390_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. */
702static void
703s390_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. */
720static void
721s390_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. */
736static void
737s390_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
752static void
753s390_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 */
761static IRExpr *
762s390_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 */
784static IRExpr *
785s390_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 */
820static IRExpr *
821s390_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. */
866static UInt
867ar_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. */
895static __inline__ UInt
896ar_w0_offset(UInt archreg)
897{
898   return ar_offset(archreg) + 0;
899}
900
901/* Write word #0 of a ar to the guest state. */
902static __inline__ void
903put_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. */
911static __inline__ IRExpr *
912get_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. */
923static UInt
924fpr_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. */
952static __inline__ UInt
953fpr_w0_offset(UInt archreg)
954{
955   return fpr_offset(archreg) + 0;
956}
957
958/* Write word #0 of a fpr to the guest state. */
959static __inline__ void
960put_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. */
968static __inline__ IRExpr *
969get_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. */
975static __inline__ UInt
976fpr_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. */
982static __inline__ void
983put_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. */
991static __inline__ IRExpr *
992get_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. */
998static __inline__ void
999put_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. */
1007static __inline__ IRExpr *
1008get_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. */
1014static __inline__ void
1015put_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. */
1023static __inline__ IRExpr *
1024get_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. */
1034static UInt
1035gpr_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. */
1063static __inline__ UInt
1064gpr_w0_offset(UInt archreg)
1065{
1066   return gpr_offset(archreg) + 0;
1067}
1068
1069/* Write word #0 of a gpr to the guest state. */
1070static __inline__ void
1071put_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. */
1079static __inline__ IRExpr *
1080get_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. */
1086static __inline__ UInt
1087gpr_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. */
1093static __inline__ void
1094put_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. */
1102static __inline__ IRExpr *
1103get_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. */
1109static __inline__ UInt
1110gpr_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. */
1116static __inline__ void
1117put_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. */
1125static __inline__ IRExpr *
1126get_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. */
1132static __inline__ UInt
1133gpr_b6_offset(UInt archreg)
1134{
1135   return gpr_offset(archreg) + 6;
1136}
1137
1138/* Write byte #6 of a gpr to the guest state. */
1139static __inline__ void
1140put_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. */
1148static __inline__ IRExpr *
1149get_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. */
1155static __inline__ UInt
1156gpr_b3_offset(UInt archreg)
1157{
1158   return gpr_offset(archreg) + 3;
1159}
1160
1161/* Write byte #3 of a gpr to the guest state. */
1162static __inline__ void
1163put_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. */
1171static __inline__ IRExpr *
1172get_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. */
1178static __inline__ UInt
1179gpr_b0_offset(UInt archreg)
1180{
1181   return gpr_offset(archreg) + 0;
1182}
1183
1184/* Write byte #0 of a gpr to the guest state. */
1185static __inline__ void
1186put_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. */
1194static __inline__ IRExpr *
1195get_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. */
1201static __inline__ UInt
1202gpr_w1_offset(UInt archreg)
1203{
1204   return gpr_offset(archreg) + 4;
1205}
1206
1207/* Write word #1 of a gpr to the guest state. */
1208static __inline__ void
1209put_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. */
1217static __inline__ IRExpr *
1218get_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. */
1224static __inline__ UInt
1225gpr_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. */
1231static __inline__ void
1232put_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. */
1240static __inline__ IRExpr *
1241get_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. */
1247static __inline__ UInt
1248gpr_b7_offset(UInt archreg)
1249{
1250   return gpr_offset(archreg) + 7;
1251}
1252
1253/* Write byte #7 of a gpr to the guest state. */
1254static __inline__ void
1255put_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. */
1263static __inline__ IRExpr *
1264get_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. */
1270static __inline__ UInt
1271gpr_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. */
1277static __inline__ void
1278put_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. */
1286static __inline__ IRExpr *
1287get_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. */
1293static __inline__ UInt
1294gpr_b4_offset(UInt archreg)
1295{
1296   return gpr_offset(archreg) + 4;
1297}
1298
1299/* Write byte #4 of a gpr to the guest state. */
1300static __inline__ void
1301put_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. */
1309static __inline__ IRExpr *
1310get_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. */
1316static __inline__ UInt
1317gpr_b1_offset(UInt archreg)
1318{
1319   return gpr_offset(archreg) + 1;
1320}
1321
1322/* Write byte #1 of a gpr to the guest state. */
1323static __inline__ void
1324put_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. */
1332static __inline__ IRExpr *
1333get_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. */
1339static __inline__ UInt
1340gpr_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. */
1346static __inline__ void
1347put_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. */
1355static __inline__ IRExpr *
1356get_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. */
1362static __inline__ UInt
1363gpr_b5_offset(UInt archreg)
1364{
1365   return gpr_offset(archreg) + 5;
1366}
1367
1368/* Write byte #5 of a gpr to the guest state. */
1369static __inline__ void
1370put_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. */
1378static __inline__ IRExpr *
1379get_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. */
1385static __inline__ UInt
1386gpr_b2_offset(UInt archreg)
1387{
1388   return gpr_offset(archreg) + 2;
1389}
1390
1391/* Write byte #2 of a gpr to the guest state. */
1392static __inline__ void
1393put_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. */
1401static __inline__ IRExpr *
1402get_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. */
1408static UInt
1409counter_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. */
1415static __inline__ UInt
1416counter_dw0_offset(void)
1417{
1418   return counter_offset() + 0;
1419}
1420
1421/* Write double word #0 of the counter to the guest state. */
1422static __inline__ void
1423put_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. */
1431static __inline__ IRExpr *
1432get_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. */
1438static __inline__ UInt
1439counter_w0_offset(void)
1440{
1441   return counter_offset() + 0;
1442}
1443
1444/* Return the guest state offset of word #1 of the counter register. */
1445static __inline__ UInt
1446counter_w1_offset(void)
1447{
1448   return counter_offset() + 4;
1449}
1450
1451/* Write word #0 of the counter to the guest state. */
1452static __inline__ void
1453put_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. */
1461static __inline__ IRExpr *
1462get_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. */
1468static __inline__ void
1469put_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. */
1477static __inline__ IRExpr *
1478get_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. */
1484static UInt
1485fpc_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. */
1491static __inline__ UInt
1492fpc_w0_offset(void)
1493{
1494   return fpc_offset() + 0;
1495}
1496
1497/* Write word #0 of the fpc to the guest state. */
1498static __inline__ void
1499put_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. */
1507static __inline__ IRExpr *
1508get_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*/
1530static IRExpr *
1531get_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). */
1564static IRTemp
1565encode_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*/
1602static IRExpr *
1603get_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. */
1624static IRTemp
1625encode_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*/
1687static IRExpr *
1688convert_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. */
1718static IRExpr *
1719convert_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/*------------------------------------------------------------*/
1730static void
1731s390_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
1740static void
1741s390_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
1749static void
1750s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
1751               UChar r1, UShort i2)
1752{
1753   irgen(r1, i2);
1754}
1755
1756static void
1757s390_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
1766static void
1767s390_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
1776static void
1777s390_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
1786static void
1787s390_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
1796static void
1797s390_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
1806static void
1807s390_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
1818static void
1819s390_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
1830static void
1831s390_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
1842static void
1843s390_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
1854static void
1855s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
1856                UChar r1, UInt i2)
1857{
1858   irgen(r1, i2);
1859}
1860
1861static void
1862s390_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
1871static void
1872s390_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
1881static void
1882s390_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
1891static void
1892s390_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
1901static void
1902s390_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
1919static void
1920s390_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
1937static void
1938s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
1939               UChar r1, UChar r2)
1940{
1941   irgen(r1, r2);
1942}
1943
1944static void
1945s390_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
1954static void
1955s390_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
1964static void
1965s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
1966                UChar r1, UChar r2)
1967{
1968   irgen(r1, r2);
1969}
1970
1971static void
1972s390_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
1981static void
1982s390_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
1991static void
1992s390_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
2001static void
2002s390_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
2011static void
2012s390_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
2021static void
2022s390_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
2031static void
2032s390_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
2041static void
2042s390_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
2051static void
2052s390_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
2061static void
2062s390_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
2072static void
2073s390_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
2082static void
2083s390_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
2093static void
2094s390_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
2105static void
2106s390_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
2115static void
2116s390_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
2125static void
2126s390_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
2135static void
2136s390_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
2145static void
2146s390_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
2155static void
2156s390_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
2165static void
2166s390_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
2183static void
2184s390_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
2199static void
2200s390_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
2215static void
2216s390_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
2231static void
2232s390_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
2247static void
2248s390_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
2257static void
2258s390_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
2275static void
2276s390_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
2293static void
2294s390_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
2311static void
2312s390_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
2333static void
2334s390_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
2347static void
2348s390_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
2364static void
2365s390_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
2381static void
2382s390_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
2398static void
2399s390_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
2415static void
2416s390_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
2434static void
2435s390_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
2453static void
2454s390_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
2472static void
2473s390_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
2488static void
2489s390_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
2504static void
2505s390_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
2522static void
2523s390_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
2540static void
2541s390_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
2559static void
2560s390_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
2575static void
2576s390_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
2597static const HChar *
2598s390_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
2613static const HChar *
2614s390_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
2629static const HChar *
2630s390_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
2645static const HChar *
2646s390_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
2661static const HChar *
2662s390_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
2677static const HChar *
2678s390_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
2693static const HChar *
2694s390_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
2709static const HChar *
2710s390_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
2725static const HChar *
2726s390_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
2741static const HChar *
2742s390_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
2758static const HChar *
2759s390_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
2775static const HChar *
2776s390_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
2792static const HChar *
2793s390_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
2809static const HChar *
2810s390_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
2826static const HChar *
2827s390_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
2843static const HChar *
2844s390_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
2859static const HChar *
2860s390_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
2875static const HChar *
2876s390_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
2892static const HChar *
2893s390_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
2909static const HChar *
2910s390_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
2925static const HChar *
2926s390_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
2941static const HChar *
2942s390_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
2958static const HChar *
2959s390_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
2974static const HChar *
2975s390_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
2990static const HChar *
2991s390_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
3006static const HChar *
3007s390_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
3022static const HChar *
3023s390_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
3038static const HChar *
3039s390_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
3054static const HChar *
3055s390_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
3070static const HChar *
3071s390_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
3086static const HChar *
3087s390_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
3102static const HChar *
3103s390_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
3119static const HChar *
3120s390_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
3136static const HChar *
3137s390_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
3152static const HChar *
3153s390_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
3168static const HChar *
3169s390_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
3187static const HChar *
3188s390_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
3207static const HChar *
3208s390_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
3226static const HChar *
3227s390_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
3246static const HChar *
3247s390_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
3263static const HChar *
3264s390_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
3280static const HChar *
3281s390_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
3297static const HChar *
3298s390_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
3314static const HChar *
3315s390_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
3331static const HChar *
3332s390_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
3346static const HChar *
3347s390_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
3362static const HChar *
3363s390_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
3378static const HChar *
3379s390_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
3394static const HChar *
3395s390_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
3410static const HChar *
3411s390_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
3426static const HChar *
3427s390_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
3442static const HChar *
3443s390_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
3458static const HChar *
3459s390_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
3474static const HChar *
3475s390_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
3490static const HChar *
3491s390_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
3506static const HChar *
3507s390_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
3522static const HChar *
3523s390_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
3538static const HChar *
3539s390_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
3554static const HChar *
3555s390_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
3570static const HChar *
3571s390_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
3586static const HChar *
3587s390_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
3607static const HChar *
3608s390_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
3619static const HChar *
3620s390_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
3644static const HChar *
3645s390_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
3665static const HChar *
3666s390_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
3677static const HChar *
3678s390_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
3689static const HChar *
3690s390_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
3699static const HChar *
3700s390_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
3709static const HChar *
3710s390_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
3722static const HChar *
3723s390_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
3735static const HChar *
3736s390_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
3748static const HChar *
3749s390_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
3761static const HChar *
3762s390_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
3770static const HChar *
3771s390_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
3779static const HChar *
3780s390_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
3802static const HChar *
3803s390_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
3823static const HChar *
3824s390_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
3833static const HChar *
3834s390_irgen_BRCTG(UChar r1, UShort i2)
3835{
3836   put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3837   if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3838                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3839
3840   return "brctg";
3841}
3842
3843static const HChar *
3844s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3845{
3846   IRTemp value = newTemp(Ity_I32);
3847
3848   assign(value, get_gpr_w1(r3 | 1));
3849   put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3850   if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3851                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3852
3853   return "brxh";
3854}
3855
3856static const HChar *
3857s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3858{
3859   IRTemp value = newTemp(Ity_I64);
3860
3861   assign(value, get_gpr_dw0(r3 | 1));
3862   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3863   if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3864                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3865
3866   return "brxhg";
3867}
3868
3869static const HChar *
3870s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3871{
3872   IRTemp value = newTemp(Ity_I32);
3873
3874   assign(value, get_gpr_w1(r3 | 1));
3875   put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3876   if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3877                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3878
3879   return "brxle";
3880}
3881
3882static const HChar *
3883s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3884{
3885   IRTemp value = newTemp(Ity_I64);
3886
3887   assign(value, get_gpr_dw0(r3 | 1));
3888   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3889   if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3890                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3891
3892   return "brxlg";
3893}
3894
3895static const HChar *
3896s390_irgen_CR(UChar r1, UChar r2)
3897{
3898   IRTemp op1 = newTemp(Ity_I32);
3899   IRTemp op2 = newTemp(Ity_I32);
3900
3901   assign(op1, get_gpr_w1(r1));
3902   assign(op2, get_gpr_w1(r2));
3903   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3904
3905   return "cr";
3906}
3907
3908static const HChar *
3909s390_irgen_CGR(UChar r1, UChar r2)
3910{
3911   IRTemp op1 = newTemp(Ity_I64);
3912   IRTemp op2 = newTemp(Ity_I64);
3913
3914   assign(op1, get_gpr_dw0(r1));
3915   assign(op2, get_gpr_dw0(r2));
3916   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3917
3918   return "cgr";
3919}
3920
3921static const HChar *
3922s390_irgen_CGFR(UChar r1, UChar r2)
3923{
3924   IRTemp op1 = newTemp(Ity_I64);
3925   IRTemp op2 = newTemp(Ity_I64);
3926
3927   assign(op1, get_gpr_dw0(r1));
3928   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3929   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3930
3931   return "cgfr";
3932}
3933
3934static const HChar *
3935s390_irgen_C(UChar r1, IRTemp op2addr)
3936{
3937   IRTemp op1 = newTemp(Ity_I32);
3938   IRTemp op2 = newTemp(Ity_I32);
3939
3940   assign(op1, get_gpr_w1(r1));
3941   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3942   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3943
3944   return "c";
3945}
3946
3947static const HChar *
3948s390_irgen_CY(UChar r1, IRTemp op2addr)
3949{
3950   IRTemp op1 = newTemp(Ity_I32);
3951   IRTemp op2 = newTemp(Ity_I32);
3952
3953   assign(op1, get_gpr_w1(r1));
3954   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3955   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3956
3957   return "cy";
3958}
3959
3960static const HChar *
3961s390_irgen_CG(UChar r1, IRTemp op2addr)
3962{
3963   IRTemp op1 = newTemp(Ity_I64);
3964   IRTemp op2 = newTemp(Ity_I64);
3965
3966   assign(op1, get_gpr_dw0(r1));
3967   assign(op2, load(Ity_I64, mkexpr(op2addr)));
3968   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3969
3970   return "cg";
3971}
3972
3973static const HChar *
3974s390_irgen_CGF(UChar r1, IRTemp op2addr)
3975{
3976   IRTemp op1 = newTemp(Ity_I64);
3977   IRTemp op2 = newTemp(Ity_I64);
3978
3979   assign(op1, get_gpr_dw0(r1));
3980   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3981   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3982
3983   return "cgf";
3984}
3985
3986static const HChar *
3987s390_irgen_CFI(UChar r1, UInt i2)
3988{
3989   IRTemp op1 = newTemp(Ity_I32);
3990   Int op2;
3991
3992   assign(op1, get_gpr_w1(r1));
3993   op2 = (Int)i2;
3994   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3995                       mkU32((UInt)op2)));
3996
3997   return "cfi";
3998}
3999
4000static const HChar *
4001s390_irgen_CGFI(UChar r1, UInt i2)
4002{
4003   IRTemp op1 = newTemp(Ity_I64);
4004   Long op2;
4005
4006   assign(op1, get_gpr_dw0(r1));
4007   op2 = (Long)(Int)i2;
4008   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4009                       mkU64((ULong)op2)));
4010
4011   return "cgfi";
4012}
4013
4014static const HChar *
4015s390_irgen_CRL(UChar r1, UInt i2)
4016{
4017   IRTemp op1 = newTemp(Ity_I32);
4018   IRTemp op2 = newTemp(Ity_I32);
4019
4020   assign(op1, get_gpr_w1(r1));
4021   assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4022          i2 << 1))));
4023   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4024
4025   return "crl";
4026}
4027
4028static const HChar *
4029s390_irgen_CGRL(UChar r1, UInt i2)
4030{
4031   IRTemp op1 = newTemp(Ity_I64);
4032   IRTemp op2 = newTemp(Ity_I64);
4033
4034   assign(op1, get_gpr_dw0(r1));
4035   assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4036          i2 << 1))));
4037   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4038
4039   return "cgrl";
4040}
4041
4042static const HChar *
4043s390_irgen_CGFRL(UChar r1, UInt i2)
4044{
4045   IRTemp op1 = newTemp(Ity_I64);
4046   IRTemp op2 = newTemp(Ity_I64);
4047
4048   assign(op1, get_gpr_dw0(r1));
4049   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4050          ((ULong)(Long)(Int)i2 << 1)))));
4051   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4052
4053   return "cgfrl";
4054}
4055
4056static const HChar *
4057s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4058{
4059   IRTemp op1 = newTemp(Ity_I32);
4060   IRTemp op2 = newTemp(Ity_I32);
4061   IRTemp cond = newTemp(Ity_I32);
4062
4063   if (m3 == 0) {
4064   } else {
4065      if (m3 == 14) {
4066         always_goto(mkexpr(op4addr));
4067      } else {
4068         assign(op1, get_gpr_w1(r1));
4069         assign(op2, get_gpr_w1(r2));
4070         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4071                                              op1, op2));
4072         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4073                                          mkU32(0)), mkexpr(op4addr));
4074      }
4075   }
4076
4077   return "crb";
4078}
4079
4080static const HChar *
4081s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4082{
4083   IRTemp op1 = newTemp(Ity_I64);
4084   IRTemp op2 = newTemp(Ity_I64);
4085   IRTemp cond = newTemp(Ity_I32);
4086
4087   if (m3 == 0) {
4088   } else {
4089      if (m3 == 14) {
4090         always_goto(mkexpr(op4addr));
4091      } else {
4092         assign(op1, get_gpr_dw0(r1));
4093         assign(op2, get_gpr_dw0(r2));
4094         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4095                                              op1, op2));
4096         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4097                                          mkU32(0)), mkexpr(op4addr));
4098      }
4099   }
4100
4101   return "cgrb";
4102}
4103
4104static const HChar *
4105s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4106{
4107   IRTemp op1 = newTemp(Ity_I32);
4108   IRTemp op2 = newTemp(Ity_I32);
4109   IRTemp cond = newTemp(Ity_I32);
4110
4111   if (m3 == 0) {
4112   } else {
4113      if (m3 == 14) {
4114         always_goto_and_chase(
4115                guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4116      } else {
4117         assign(op1, get_gpr_w1(r1));
4118         assign(op2, get_gpr_w1(r2));
4119         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4120                                              op1, op2));
4121         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4122                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4123
4124      }
4125   }
4126
4127   return "crj";
4128}
4129
4130static const HChar *
4131s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4132{
4133   IRTemp op1 = newTemp(Ity_I64);
4134   IRTemp op2 = newTemp(Ity_I64);
4135   IRTemp cond = newTemp(Ity_I32);
4136
4137   if (m3 == 0) {
4138   } else {
4139      if (m3 == 14) {
4140         always_goto_and_chase(
4141                guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4142      } else {
4143         assign(op1, get_gpr_dw0(r1));
4144         assign(op2, get_gpr_dw0(r2));
4145         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4146                                              op1, op2));
4147         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4148                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4149
4150      }
4151   }
4152
4153   return "cgrj";
4154}
4155
4156static const HChar *
4157s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4158{
4159   IRTemp op1 = newTemp(Ity_I32);
4160   Int op2;
4161   IRTemp cond = newTemp(Ity_I32);
4162
4163   if (m3 == 0) {
4164   } else {
4165      if (m3 == 14) {
4166         always_goto(mkexpr(op4addr));
4167      } else {
4168         assign(op1, get_gpr_w1(r1));
4169         op2 = (Int)(Char)i2;
4170         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4171                                              mktemp(Ity_I32, mkU32((UInt)op2))));
4172         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4173                                    mkexpr(op4addr));
4174      }
4175   }
4176
4177   return "cib";
4178}
4179
4180static const HChar *
4181s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4182{
4183   IRTemp op1 = newTemp(Ity_I64);
4184   Long op2;
4185   IRTemp cond = newTemp(Ity_I32);
4186
4187   if (m3 == 0) {
4188   } else {
4189      if (m3 == 14) {
4190         always_goto(mkexpr(op4addr));
4191      } else {
4192         assign(op1, get_gpr_dw0(r1));
4193         op2 = (Long)(Char)i2;
4194         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4195                                              mktemp(Ity_I64, mkU64((ULong)op2))));
4196         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4197                                    mkexpr(op4addr));
4198      }
4199   }
4200
4201   return "cgib";
4202}
4203
4204static const HChar *
4205s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4206{
4207   IRTemp op1 = newTemp(Ity_I32);
4208   Int op2;
4209   IRTemp cond = newTemp(Ity_I32);
4210
4211   if (m3 == 0) {
4212   } else {
4213      if (m3 == 14) {
4214         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4215      } else {
4216         assign(op1, get_gpr_w1(r1));
4217         op2 = (Int)(Char)i2;
4218         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4219                                              mktemp(Ity_I32, mkU32((UInt)op2))));
4220         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4221                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4222
4223      }
4224   }
4225
4226   return "cij";
4227}
4228
4229static const HChar *
4230s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4231{
4232   IRTemp op1 = newTemp(Ity_I64);
4233   Long op2;
4234   IRTemp cond = newTemp(Ity_I32);
4235
4236   if (m3 == 0) {
4237   } else {
4238      if (m3 == 14) {
4239         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4240      } else {
4241         assign(op1, get_gpr_dw0(r1));
4242         op2 = (Long)(Char)i2;
4243         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4244                                              mktemp(Ity_I64, mkU64((ULong)op2))));
4245         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4246                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4247
4248      }
4249   }
4250
4251   return "cgij";
4252}
4253
4254static const HChar *
4255s390_irgen_CH(UChar r1, IRTemp op2addr)
4256{
4257   IRTemp op1 = newTemp(Ity_I32);
4258   IRTemp op2 = newTemp(Ity_I32);
4259
4260   assign(op1, get_gpr_w1(r1));
4261   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4262   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4263
4264   return "ch";
4265}
4266
4267static const HChar *
4268s390_irgen_CHY(UChar r1, IRTemp op2addr)
4269{
4270   IRTemp op1 = newTemp(Ity_I32);
4271   IRTemp op2 = newTemp(Ity_I32);
4272
4273   assign(op1, get_gpr_w1(r1));
4274   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4275   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4276
4277   return "chy";
4278}
4279
4280static const HChar *
4281s390_irgen_CGH(UChar r1, IRTemp op2addr)
4282{
4283   IRTemp op1 = newTemp(Ity_I64);
4284   IRTemp op2 = newTemp(Ity_I64);
4285
4286   assign(op1, get_gpr_dw0(r1));
4287   assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4288   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4289
4290   return "cgh";
4291}
4292
4293static const HChar *
4294s390_irgen_CHI(UChar r1, UShort i2)
4295{
4296   IRTemp op1 = newTemp(Ity_I32);
4297   Int op2;
4298
4299   assign(op1, get_gpr_w1(r1));
4300   op2 = (Int)(Short)i2;
4301   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4302                       mkU32((UInt)op2)));
4303
4304   return "chi";
4305}
4306
4307static const HChar *
4308s390_irgen_CGHI(UChar r1, UShort i2)
4309{
4310   IRTemp op1 = newTemp(Ity_I64);
4311   Long op2;
4312
4313   assign(op1, get_gpr_dw0(r1));
4314   op2 = (Long)(Short)i2;
4315   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4316                       mkU64((ULong)op2)));
4317
4318   return "cghi";
4319}
4320
4321static const HChar *
4322s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4323{
4324   IRTemp op1 = newTemp(Ity_I16);
4325   Short op2;
4326
4327   assign(op1, load(Ity_I16, mkexpr(op1addr)));
4328   op2 = (Short)i2;
4329   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4330                       mkU16((UShort)op2)));
4331
4332   return "chhsi";
4333}
4334
4335static const HChar *
4336s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4337{
4338   IRTemp op1 = newTemp(Ity_I32);
4339   Int op2;
4340
4341   assign(op1, load(Ity_I32, mkexpr(op1addr)));
4342   op2 = (Int)(Short)i2;
4343   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4344                       mkU32((UInt)op2)));
4345
4346   return "chsi";
4347}
4348
4349static const HChar *
4350s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4351{
4352   IRTemp op1 = newTemp(Ity_I64);
4353   Long op2;
4354
4355   assign(op1, load(Ity_I64, mkexpr(op1addr)));
4356   op2 = (Long)(Short)i2;
4357   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4358                       mkU64((ULong)op2)));
4359
4360   return "cghsi";
4361}
4362
4363static const HChar *
4364s390_irgen_CHRL(UChar r1, UInt i2)
4365{
4366   IRTemp op1 = newTemp(Ity_I32);
4367   IRTemp op2 = newTemp(Ity_I32);
4368
4369   assign(op1, get_gpr_w1(r1));
4370   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4371          ((ULong)(Long)(Int)i2 << 1)))));
4372   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4373
4374   return "chrl";
4375}
4376
4377static const HChar *
4378s390_irgen_CGHRL(UChar r1, UInt i2)
4379{
4380   IRTemp op1 = newTemp(Ity_I64);
4381   IRTemp op2 = newTemp(Ity_I64);
4382
4383   assign(op1, get_gpr_dw0(r1));
4384   assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4385          ((ULong)(Long)(Int)i2 << 1)))));
4386   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4387
4388   return "cghrl";
4389}
4390
4391static const HChar *
4392s390_irgen_CHHR(UChar r1, UChar r2)
4393{
4394   IRTemp op1 = newTemp(Ity_I32);
4395   IRTemp op2 = newTemp(Ity_I32);
4396
4397   assign(op1, get_gpr_w0(r1));
4398   assign(op2, get_gpr_w0(r2));
4399   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4400
4401   return "chhr";
4402}
4403
4404static const HChar *
4405s390_irgen_CHLR(UChar r1, UChar r2)
4406{
4407   IRTemp op1 = newTemp(Ity_I32);
4408   IRTemp op2 = newTemp(Ity_I32);
4409
4410   assign(op1, get_gpr_w0(r1));
4411   assign(op2, get_gpr_w1(r2));
4412   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4413
4414   return "chlr";
4415}
4416
4417static const HChar *
4418s390_irgen_CHF(UChar r1, IRTemp op2addr)
4419{
4420   IRTemp op1 = newTemp(Ity_I32);
4421   IRTemp op2 = newTemp(Ity_I32);
4422
4423   assign(op1, get_gpr_w0(r1));
4424   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4425   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4426
4427   return "chf";
4428}
4429
4430static const HChar *
4431s390_irgen_CIH(UChar r1, UInt i2)
4432{
4433   IRTemp op1 = newTemp(Ity_I32);
4434   Int op2;
4435
4436   assign(op1, get_gpr_w0(r1));
4437   op2 = (Int)i2;
4438   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4439                       mkU32((UInt)op2)));
4440
4441   return "cih";
4442}
4443
4444static const HChar *
4445s390_irgen_CLR(UChar r1, UChar r2)
4446{
4447   IRTemp op1 = newTemp(Ity_I32);
4448   IRTemp op2 = newTemp(Ity_I32);
4449
4450   assign(op1, get_gpr_w1(r1));
4451   assign(op2, get_gpr_w1(r2));
4452   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4453
4454   return "clr";
4455}
4456
4457static const HChar *
4458s390_irgen_CLGR(UChar r1, UChar r2)
4459{
4460   IRTemp op1 = newTemp(Ity_I64);
4461   IRTemp op2 = newTemp(Ity_I64);
4462
4463   assign(op1, get_gpr_dw0(r1));
4464   assign(op2, get_gpr_dw0(r2));
4465   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4466
4467   return "clgr";
4468}
4469
4470static const HChar *
4471s390_irgen_CLGFR(UChar r1, UChar r2)
4472{
4473   IRTemp op1 = newTemp(Ity_I64);
4474   IRTemp op2 = newTemp(Ity_I64);
4475
4476   assign(op1, get_gpr_dw0(r1));
4477   assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4478   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4479
4480   return "clgfr";
4481}
4482
4483static const HChar *
4484s390_irgen_CL(UChar r1, IRTemp op2addr)
4485{
4486   IRTemp op1 = newTemp(Ity_I32);
4487   IRTemp op2 = newTemp(Ity_I32);
4488
4489   assign(op1, get_gpr_w1(r1));
4490   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4491   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4492
4493   return "cl";
4494}
4495
4496static const HChar *
4497s390_irgen_CLY(UChar r1, IRTemp op2addr)
4498{
4499   IRTemp op1 = newTemp(Ity_I32);
4500   IRTemp op2 = newTemp(Ity_I32);
4501
4502   assign(op1, get_gpr_w1(r1));
4503   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4504   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4505
4506   return "cly";
4507}
4508
4509static const HChar *
4510s390_irgen_CLG(UChar r1, IRTemp op2addr)
4511{
4512   IRTemp op1 = newTemp(Ity_I64);
4513   IRTemp op2 = newTemp(Ity_I64);
4514
4515   assign(op1, get_gpr_dw0(r1));
4516   assign(op2, load(Ity_I64, mkexpr(op2addr)));
4517   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4518
4519   return "clg";
4520}
4521
4522static const HChar *
4523s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4524{
4525   IRTemp op1 = newTemp(Ity_I64);
4526   IRTemp op2 = newTemp(Ity_I64);
4527
4528   assign(op1, get_gpr_dw0(r1));
4529   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4530   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4531
4532   return "clgf";
4533}
4534
4535static const HChar *
4536s390_irgen_CLFI(UChar r1, UInt i2)
4537{
4538   IRTemp op1 = newTemp(Ity_I32);
4539   UInt op2;
4540
4541   assign(op1, get_gpr_w1(r1));
4542   op2 = i2;
4543   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4544                       mkU32(op2)));
4545
4546   return "clfi";
4547}
4548
4549static const HChar *
4550s390_irgen_CLGFI(UChar r1, UInt i2)
4551{
4552   IRTemp op1 = newTemp(Ity_I64);
4553   ULong op2;
4554
4555   assign(op1, get_gpr_dw0(r1));
4556   op2 = (ULong)i2;
4557   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4558                       mkU64(op2)));
4559
4560   return "clgfi";
4561}
4562
4563static const HChar *
4564s390_irgen_CLI(UChar i2, IRTemp op1addr)
4565{
4566   IRTemp op1 = newTemp(Ity_I8);
4567   UChar op2;
4568
4569   assign(op1, load(Ity_I8, mkexpr(op1addr)));
4570   op2 = i2;
4571   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4572                       mkU8(op2)));
4573
4574   return "cli";
4575}
4576
4577static const HChar *
4578s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4579{
4580   IRTemp op1 = newTemp(Ity_I8);
4581   UChar op2;
4582
4583   assign(op1, load(Ity_I8, mkexpr(op1addr)));
4584   op2 = i2;
4585   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4586                       mkU8(op2)));
4587
4588   return "cliy";
4589}
4590
4591static const HChar *
4592s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4593{
4594   IRTemp op1 = newTemp(Ity_I32);
4595   UInt op2;
4596
4597   assign(op1, load(Ity_I32, mkexpr(op1addr)));
4598   op2 = (UInt)i2;
4599   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4600                       mkU32(op2)));
4601
4602   return "clfhsi";
4603}
4604
4605static const HChar *
4606s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4607{
4608   IRTemp op1 = newTemp(Ity_I64);
4609   ULong op2;
4610
4611   assign(op1, load(Ity_I64, mkexpr(op1addr)));
4612   op2 = (ULong)i2;
4613   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4614                       mkU64(op2)));
4615
4616   return "clghsi";
4617}
4618
4619static const HChar *
4620s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4621{
4622   IRTemp op1 = newTemp(Ity_I16);
4623   UShort op2;
4624
4625   assign(op1, load(Ity_I16, mkexpr(op1addr)));
4626   op2 = i2;
4627   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4628                       mkU16(op2)));
4629
4630   return "clhhsi";
4631}
4632
4633static const HChar *
4634s390_irgen_CLRL(UChar r1, UInt i2)
4635{
4636   IRTemp op1 = newTemp(Ity_I32);
4637   IRTemp op2 = newTemp(Ity_I32);
4638
4639   assign(op1, get_gpr_w1(r1));
4640   assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4641          i2 << 1))));
4642   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4643
4644   return "clrl";
4645}
4646
4647static const HChar *
4648s390_irgen_CLGRL(UChar r1, UInt i2)
4649{
4650   IRTemp op1 = newTemp(Ity_I64);
4651   IRTemp op2 = newTemp(Ity_I64);
4652
4653   assign(op1, get_gpr_dw0(r1));
4654   assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4655          i2 << 1))));
4656   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4657
4658   return "clgrl";
4659}
4660
4661static const HChar *
4662s390_irgen_CLGFRL(UChar r1, UInt i2)
4663{
4664   IRTemp op1 = newTemp(Ity_I64);
4665   IRTemp op2 = newTemp(Ity_I64);
4666
4667   assign(op1, get_gpr_dw0(r1));
4668   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4669          ((ULong)(Long)(Int)i2 << 1)))));
4670   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4671
4672   return "clgfrl";
4673}
4674
4675static const HChar *
4676s390_irgen_CLHRL(UChar r1, UInt i2)
4677{
4678   IRTemp op1 = newTemp(Ity_I32);
4679   IRTemp op2 = newTemp(Ity_I32);
4680
4681   assign(op1, get_gpr_w1(r1));
4682   assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4683          ((ULong)(Long)(Int)i2 << 1)))));
4684   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4685
4686   return "clhrl";
4687}
4688
4689static const HChar *
4690s390_irgen_CLGHRL(UChar r1, UInt i2)
4691{
4692   IRTemp op1 = newTemp(Ity_I64);
4693   IRTemp op2 = newTemp(Ity_I64);
4694
4695   assign(op1, get_gpr_dw0(r1));
4696   assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4697          ((ULong)(Long)(Int)i2 << 1)))));
4698   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4699
4700   return "clghrl";
4701}
4702
4703static const HChar *
4704s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4705{
4706   IRTemp op1 = newTemp(Ity_I32);
4707   IRTemp op2 = newTemp(Ity_I32);
4708   IRTemp cond = newTemp(Ity_I32);
4709
4710   if (m3 == 0) {
4711   } else {
4712      if (m3 == 14) {
4713         always_goto(mkexpr(op4addr));
4714      } else {
4715         assign(op1, get_gpr_w1(r1));
4716         assign(op2, get_gpr_w1(r2));
4717         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4718                                              op1, op2));
4719         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4720                                    mkexpr(op4addr));
4721      }
4722   }
4723
4724   return "clrb";
4725}
4726
4727static const HChar *
4728s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4729{
4730   IRTemp op1 = newTemp(Ity_I64);
4731   IRTemp op2 = newTemp(Ity_I64);
4732   IRTemp cond = newTemp(Ity_I32);
4733
4734   if (m3 == 0) {
4735   } else {
4736      if (m3 == 14) {
4737         always_goto(mkexpr(op4addr));
4738      } else {
4739         assign(op1, get_gpr_dw0(r1));
4740         assign(op2, get_gpr_dw0(r2));
4741         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4742                                              op1, op2));
4743         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4744                                    mkexpr(op4addr));
4745      }
4746   }
4747
4748   return "clgrb";
4749}
4750
4751static const HChar *
4752s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4753{
4754   IRTemp op1 = newTemp(Ity_I32);
4755   IRTemp op2 = newTemp(Ity_I32);
4756   IRTemp cond = newTemp(Ity_I32);
4757
4758   if (m3 == 0) {
4759   } else {
4760      if (m3 == 14) {
4761         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4762      } else {
4763         assign(op1, get_gpr_w1(r1));
4764         assign(op2, get_gpr_w1(r2));
4765         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4766                                              op1, op2));
4767         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4768                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4769
4770      }
4771   }
4772
4773   return "clrj";
4774}
4775
4776static const HChar *
4777s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4778{
4779   IRTemp op1 = newTemp(Ity_I64);
4780   IRTemp op2 = newTemp(Ity_I64);
4781   IRTemp cond = newTemp(Ity_I32);
4782
4783   if (m3 == 0) {
4784   } else {
4785      if (m3 == 14) {
4786         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4787      } else {
4788         assign(op1, get_gpr_dw0(r1));
4789         assign(op2, get_gpr_dw0(r2));
4790         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4791                                              op1, op2));
4792         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4793                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4794
4795      }
4796   }
4797
4798   return "clgrj";
4799}
4800
4801static const HChar *
4802s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4803{
4804   IRTemp op1 = newTemp(Ity_I32);
4805   UInt op2;
4806   IRTemp cond = newTemp(Ity_I32);
4807
4808   if (m3 == 0) {
4809   } else {
4810      if (m3 == 14) {
4811         always_goto(mkexpr(op4addr));
4812      } else {
4813         assign(op1, get_gpr_w1(r1));
4814         op2 = (UInt)i2;
4815         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4816                                              mktemp(Ity_I32, mkU32(op2))));
4817         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4818                                    mkexpr(op4addr));
4819      }
4820   }
4821
4822   return "clib";
4823}
4824
4825static const HChar *
4826s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4827{
4828   IRTemp op1 = newTemp(Ity_I64);
4829   ULong op2;
4830   IRTemp cond = newTemp(Ity_I32);
4831
4832   if (m3 == 0) {
4833   } else {
4834      if (m3 == 14) {
4835         always_goto(mkexpr(op4addr));
4836      } else {
4837         assign(op1, get_gpr_dw0(r1));
4838         op2 = (ULong)i2;
4839         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4840                                              mktemp(Ity_I64, mkU64(op2))));
4841         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4842                                    mkexpr(op4addr));
4843      }
4844   }
4845
4846   return "clgib";
4847}
4848
4849static const HChar *
4850s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4851{
4852   IRTemp op1 = newTemp(Ity_I32);
4853   UInt op2;
4854   IRTemp cond = newTemp(Ity_I32);
4855
4856   if (m3 == 0) {
4857   } else {
4858      if (m3 == 14) {
4859         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4860      } else {
4861         assign(op1, get_gpr_w1(r1));
4862         op2 = (UInt)i2;
4863         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4864                                              mktemp(Ity_I32, mkU32(op2))));
4865         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4866                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4867
4868      }
4869   }
4870
4871   return "clij";
4872}
4873
4874static const HChar *
4875s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4876{
4877   IRTemp op1 = newTemp(Ity_I64);
4878   ULong op2;
4879   IRTemp cond = newTemp(Ity_I32);
4880
4881   if (m3 == 0) {
4882   } else {
4883      if (m3 == 14) {
4884         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4885      } else {
4886         assign(op1, get_gpr_dw0(r1));
4887         op2 = (ULong)i2;
4888         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4889                                              mktemp(Ity_I64, mkU64(op2))));
4890         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4891                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4892
4893      }
4894   }
4895
4896   return "clgij";
4897}
4898
4899static const HChar *
4900s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4901{
4902   IRTemp op1 = newTemp(Ity_I32);
4903   IRTemp op2 = newTemp(Ity_I32);
4904   IRTemp b0 = newTemp(Ity_I32);
4905   IRTemp b1 = newTemp(Ity_I32);
4906   IRTemp b2 = newTemp(Ity_I32);
4907   IRTemp b3 = newTemp(Ity_I32);
4908   IRTemp c0 = newTemp(Ity_I32);
4909   IRTemp c1 = newTemp(Ity_I32);
4910   IRTemp c2 = newTemp(Ity_I32);
4911   IRTemp c3 = newTemp(Ity_I32);
4912   UChar n;
4913
4914   n = 0;
4915   if ((r3 & 8) != 0) {
4916      assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4917      assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4918      n = n + 1;
4919   } else {
4920      assign(b0, mkU32(0));
4921      assign(c0, mkU32(0));
4922   }
4923   if ((r3 & 4) != 0) {
4924      assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4925      assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4926             mkU64(n)))));
4927      n = n + 1;
4928   } else {
4929      assign(b1, mkU32(0));
4930      assign(c1, mkU32(0));
4931   }
4932   if ((r3 & 2) != 0) {
4933      assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4934      assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4935             mkU64(n)))));
4936      n = n + 1;
4937   } else {
4938      assign(b2, mkU32(0));
4939      assign(c2, mkU32(0));
4940   }
4941   if ((r3 & 1) != 0) {
4942      assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4943      assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4944             mkU64(n)))));
4945      n = n + 1;
4946   } else {
4947      assign(b3, mkU32(0));
4948      assign(c3, mkU32(0));
4949   }
4950   assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4951          mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4952          binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4953   assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4954          mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4955          binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4956   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4957
4958   return "clm";
4959}
4960
4961static const HChar *
4962s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4963{
4964   IRTemp op1 = newTemp(Ity_I32);
4965   IRTemp op2 = newTemp(Ity_I32);
4966   IRTemp b0 = newTemp(Ity_I32);
4967   IRTemp b1 = newTemp(Ity_I32);
4968   IRTemp b2 = newTemp(Ity_I32);
4969   IRTemp b3 = newTemp(Ity_I32);
4970   IRTemp c0 = newTemp(Ity_I32);
4971   IRTemp c1 = newTemp(Ity_I32);
4972   IRTemp c2 = newTemp(Ity_I32);
4973   IRTemp c3 = newTemp(Ity_I32);
4974   UChar n;
4975
4976   n = 0;
4977   if ((r3 & 8) != 0) {
4978      assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4979      assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4980      n = n + 1;
4981   } else {
4982      assign(b0, mkU32(0));
4983      assign(c0, mkU32(0));
4984   }
4985   if ((r3 & 4) != 0) {
4986      assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4987      assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4988             mkU64(n)))));
4989      n = n + 1;
4990   } else {
4991      assign(b1, mkU32(0));
4992      assign(c1, mkU32(0));
4993   }
4994   if ((r3 & 2) != 0) {
4995      assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4996      assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4997             mkU64(n)))));
4998      n = n + 1;
4999   } else {
5000      assign(b2, mkU32(0));
5001      assign(c2, mkU32(0));
5002   }
5003   if ((r3 & 1) != 0) {
5004      assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
5005      assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5006             mkU64(n)))));
5007      n = n + 1;
5008   } else {
5009      assign(b3, mkU32(0));
5010      assign(c3, mkU32(0));
5011   }
5012   assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5013          mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5014          binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5015   assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5016          mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5017          binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5018   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5019
5020   return "clmy";
5021}
5022
5023static const HChar *
5024s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5025{
5026   IRTemp op1 = newTemp(Ity_I32);
5027   IRTemp op2 = newTemp(Ity_I32);
5028   IRTemp b0 = newTemp(Ity_I32);
5029   IRTemp b1 = newTemp(Ity_I32);
5030   IRTemp b2 = newTemp(Ity_I32);
5031   IRTemp b3 = newTemp(Ity_I32);
5032   IRTemp c0 = newTemp(Ity_I32);
5033   IRTemp c1 = newTemp(Ity_I32);
5034   IRTemp c2 = newTemp(Ity_I32);
5035   IRTemp c3 = newTemp(Ity_I32);
5036   UChar n;
5037
5038   n = 0;
5039   if ((r3 & 8) != 0) {
5040      assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5041      assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5042      n = n + 1;
5043   } else {
5044      assign(b0, mkU32(0));
5045      assign(c0, mkU32(0));
5046   }
5047   if ((r3 & 4) != 0) {
5048      assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5049      assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5050             mkU64(n)))));
5051      n = n + 1;
5052   } else {
5053      assign(b1, mkU32(0));
5054      assign(c1, mkU32(0));
5055   }
5056   if ((r3 & 2) != 0) {
5057      assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5058      assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5059             mkU64(n)))));
5060      n = n + 1;
5061   } else {
5062      assign(b2, mkU32(0));
5063      assign(c2, mkU32(0));
5064   }
5065   if ((r3 & 1) != 0) {
5066      assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5067      assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5068             mkU64(n)))));
5069      n = n + 1;
5070   } else {
5071      assign(b3, mkU32(0));
5072      assign(c3, mkU32(0));
5073   }
5074   assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5075          mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5076          binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5077   assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5078          mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5079          binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5080   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5081
5082   return "clmh";
5083}
5084
5085static const HChar *
5086s390_irgen_CLHHR(UChar r1, UChar r2)
5087{
5088   IRTemp op1 = newTemp(Ity_I32);
5089   IRTemp op2 = newTemp(Ity_I32);
5090
5091   assign(op1, get_gpr_w0(r1));
5092   assign(op2, get_gpr_w0(r2));
5093   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5094
5095   return "clhhr";
5096}
5097
5098static const HChar *
5099s390_irgen_CLHLR(UChar r1, UChar r2)
5100{
5101   IRTemp op1 = newTemp(Ity_I32);
5102   IRTemp op2 = newTemp(Ity_I32);
5103
5104   assign(op1, get_gpr_w0(r1));
5105   assign(op2, get_gpr_w1(r2));
5106   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5107
5108   return "clhlr";
5109}
5110
5111static const HChar *
5112s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5113{
5114   IRTemp op1 = newTemp(Ity_I32);
5115   IRTemp op2 = newTemp(Ity_I32);
5116
5117   assign(op1, get_gpr_w0(r1));
5118   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5119   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5120
5121   return "clhf";
5122}
5123
5124static const HChar *
5125s390_irgen_CLIH(UChar r1, UInt i2)
5126{
5127   IRTemp op1 = newTemp(Ity_I32);
5128   UInt op2;
5129
5130   assign(op1, get_gpr_w0(r1));
5131   op2 = i2;
5132   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5133                       mkU32(op2)));
5134
5135   return "clih";
5136}
5137
5138static const HChar *
5139s390_irgen_CPYA(UChar r1, UChar r2)
5140{
5141   put_ar_w0(r1, get_ar_w0(r2));
5142   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5143      s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5144
5145   return "cpya";
5146}
5147
5148static const HChar *
5149s390_irgen_XR(UChar r1, UChar r2)
5150{
5151   IRTemp op1 = newTemp(Ity_I32);
5152   IRTemp op2 = newTemp(Ity_I32);
5153   IRTemp result = newTemp(Ity_I32);
5154
5155   if (r1 == r2) {
5156      assign(result, mkU32(0));
5157   } else {
5158      assign(op1, get_gpr_w1(r1));
5159      assign(op2, get_gpr_w1(r2));
5160      assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5161   }
5162   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5163   put_gpr_w1(r1, mkexpr(result));
5164
5165   return "xr";
5166}
5167
5168static const HChar *
5169s390_irgen_XGR(UChar r1, UChar r2)
5170{
5171   IRTemp op1 = newTemp(Ity_I64);
5172   IRTemp op2 = newTemp(Ity_I64);
5173   IRTemp result = newTemp(Ity_I64);
5174
5175   if (r1 == r2) {
5176      assign(result, mkU64(0));
5177   } else {
5178      assign(op1, get_gpr_dw0(r1));
5179      assign(op2, get_gpr_dw0(r2));
5180      assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5181   }
5182   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5183   put_gpr_dw0(r1, mkexpr(result));
5184
5185   return "xgr";
5186}
5187
5188static const HChar *
5189s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5190{
5191   IRTemp op2 = newTemp(Ity_I32);
5192   IRTemp op3 = newTemp(Ity_I32);
5193   IRTemp result = newTemp(Ity_I32);
5194
5195   assign(op2, get_gpr_w1(r2));
5196   assign(op3, get_gpr_w1(r3));
5197   assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5198   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5199   put_gpr_w1(r1, mkexpr(result));
5200
5201   return "xrk";
5202}
5203
5204static const HChar *
5205s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5206{
5207   IRTemp op2 = newTemp(Ity_I64);
5208   IRTemp op3 = newTemp(Ity_I64);
5209   IRTemp result = newTemp(Ity_I64);
5210
5211   assign(op2, get_gpr_dw0(r2));
5212   assign(op3, get_gpr_dw0(r3));
5213   assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5214   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5215   put_gpr_dw0(r1, mkexpr(result));
5216
5217   return "xgrk";
5218}
5219
5220static const HChar *
5221s390_irgen_X(UChar r1, IRTemp op2addr)
5222{
5223   IRTemp op1 = newTemp(Ity_I32);
5224   IRTemp op2 = newTemp(Ity_I32);
5225   IRTemp result = newTemp(Ity_I32);
5226
5227   assign(op1, get_gpr_w1(r1));
5228   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5229   assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5230   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5231   put_gpr_w1(r1, mkexpr(result));
5232
5233   return "x";
5234}
5235
5236static const HChar *
5237s390_irgen_XY(UChar r1, IRTemp op2addr)
5238{
5239   IRTemp op1 = newTemp(Ity_I32);
5240   IRTemp op2 = newTemp(Ity_I32);
5241   IRTemp result = newTemp(Ity_I32);
5242
5243   assign(op1, get_gpr_w1(r1));
5244   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5245   assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5246   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5247   put_gpr_w1(r1, mkexpr(result));
5248
5249   return "xy";
5250}
5251
5252static const HChar *
5253s390_irgen_XG(UChar r1, IRTemp op2addr)
5254{
5255   IRTemp op1 = newTemp(Ity_I64);
5256   IRTemp op2 = newTemp(Ity_I64);
5257   IRTemp result = newTemp(Ity_I64);
5258
5259   assign(op1, get_gpr_dw0(r1));
5260   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5261   assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5262   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5263   put_gpr_dw0(r1, mkexpr(result));
5264
5265   return "xg";
5266}
5267
5268static const HChar *
5269s390_irgen_XI(UChar i2, IRTemp op1addr)
5270{
5271   IRTemp op1 = newTemp(Ity_I8);
5272   UChar op2;
5273   IRTemp result = newTemp(Ity_I8);
5274
5275   assign(op1, load(Ity_I8, mkexpr(op1addr)));
5276   op2 = i2;
5277   assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5278   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5279   store(mkexpr(op1addr), mkexpr(result));
5280
5281   return "xi";
5282}
5283
5284static const HChar *
5285s390_irgen_XIY(UChar i2, IRTemp op1addr)
5286{
5287   IRTemp op1 = newTemp(Ity_I8);
5288   UChar op2;
5289   IRTemp result = newTemp(Ity_I8);
5290
5291   assign(op1, load(Ity_I8, mkexpr(op1addr)));
5292   op2 = i2;
5293   assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5294   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5295   store(mkexpr(op1addr), mkexpr(result));
5296
5297   return "xiy";
5298}
5299
5300static const HChar *
5301s390_irgen_XIHF(UChar r1, UInt i2)
5302{
5303   IRTemp op1 = newTemp(Ity_I32);
5304   UInt op2;
5305   IRTemp result = newTemp(Ity_I32);
5306
5307   assign(op1, get_gpr_w0(r1));
5308   op2 = i2;
5309   assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5310   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5311   put_gpr_w0(r1, mkexpr(result));
5312
5313   return "xihf";
5314}
5315
5316static const HChar *
5317s390_irgen_XILF(UChar r1, UInt i2)
5318{
5319   IRTemp op1 = newTemp(Ity_I32);
5320   UInt op2;
5321   IRTemp result = newTemp(Ity_I32);
5322
5323   assign(op1, get_gpr_w1(r1));
5324   op2 = i2;
5325   assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5326   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5327   put_gpr_w1(r1, mkexpr(result));
5328
5329   return "xilf";
5330}
5331
5332static const HChar *
5333s390_irgen_EAR(UChar r1, UChar r2)
5334{
5335   put_gpr_w1(r1, get_ar_w0(r2));
5336   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5337      s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5338
5339   return "ear";
5340}
5341
5342static const HChar *
5343s390_irgen_IC(UChar r1, IRTemp op2addr)
5344{
5345   put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5346
5347   return "ic";
5348}
5349
5350static const HChar *
5351s390_irgen_ICY(UChar r1, IRTemp op2addr)
5352{
5353   put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5354
5355   return "icy";
5356}
5357
5358static const HChar *
5359s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5360{
5361   UChar n;
5362   IRTemp result = newTemp(Ity_I32);
5363   UInt mask;
5364
5365   n = 0;
5366   mask = (UInt)r3;
5367   if ((mask & 8) != 0) {
5368      put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5369      n = n + 1;
5370   }
5371   if ((mask & 4) != 0) {
5372      put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5373
5374      n = n + 1;
5375   }
5376   if ((mask & 2) != 0) {
5377      put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5378
5379      n = n + 1;
5380   }
5381   if ((mask & 1) != 0) {
5382      put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5383
5384      n = n + 1;
5385   }
5386   assign(result, get_gpr_w1(r1));
5387   s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5388                       mkU32(mask)));
5389
5390   return "icm";
5391}
5392
5393static const HChar *
5394s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5395{
5396   UChar n;
5397   IRTemp result = newTemp(Ity_I32);
5398   UInt mask;
5399
5400   n = 0;
5401   mask = (UInt)r3;
5402   if ((mask & 8) != 0) {
5403      put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5404      n = n + 1;
5405   }
5406   if ((mask & 4) != 0) {
5407      put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5408
5409      n = n + 1;
5410   }
5411   if ((mask & 2) != 0) {
5412      put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5413
5414      n = n + 1;
5415   }
5416   if ((mask & 1) != 0) {
5417      put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5418
5419      n = n + 1;
5420   }
5421   assign(result, get_gpr_w1(r1));
5422   s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5423                       mkU32(mask)));
5424
5425   return "icmy";
5426}
5427
5428static const HChar *
5429s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5430{
5431   UChar n;
5432   IRTemp result = newTemp(Ity_I32);
5433   UInt mask;
5434
5435   n = 0;
5436   mask = (UInt)r3;
5437   if ((mask & 8) != 0) {
5438      put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5439      n = n + 1;
5440   }
5441   if ((mask & 4) != 0) {
5442      put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5443
5444      n = n + 1;
5445   }
5446   if ((mask & 2) != 0) {
5447      put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5448
5449      n = n + 1;
5450   }
5451   if ((mask & 1) != 0) {
5452      put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5453
5454      n = n + 1;
5455   }
5456   assign(result, get_gpr_w0(r1));
5457   s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5458                       mkU32(mask)));
5459
5460   return "icmh";
5461}
5462
5463static const HChar *
5464s390_irgen_IIHF(UChar r1, UInt i2)
5465{
5466   put_gpr_w0(r1, mkU32(i2));
5467
5468   return "iihf";
5469}
5470
5471static const HChar *
5472s390_irgen_IIHH(UChar r1, UShort i2)
5473{
5474   put_gpr_hw0(r1, mkU16(i2));
5475
5476   return "iihh";
5477}
5478
5479static const HChar *
5480s390_irgen_IIHL(UChar r1, UShort i2)
5481{
5482   put_gpr_hw1(r1, mkU16(i2));
5483
5484   return "iihl";
5485}
5486
5487static const HChar *
5488s390_irgen_IILF(UChar r1, UInt i2)
5489{
5490   put_gpr_w1(r1, mkU32(i2));
5491
5492   return "iilf";
5493}
5494
5495static const HChar *
5496s390_irgen_IILH(UChar r1, UShort i2)
5497{
5498   put_gpr_hw2(r1, mkU16(i2));
5499
5500   return "iilh";
5501}
5502
5503static const HChar *
5504s390_irgen_IILL(UChar r1, UShort i2)
5505{
5506   put_gpr_hw3(r1, mkU16(i2));
5507
5508   return "iill";
5509}
5510
5511static const HChar *
5512s390_irgen_LR(UChar r1, UChar r2)
5513{
5514   put_gpr_w1(r1, get_gpr_w1(r2));
5515
5516   return "lr";
5517}
5518
5519static const HChar *
5520s390_irgen_LGR(UChar r1, UChar r2)
5521{
5522   put_gpr_dw0(r1, get_gpr_dw0(r2));
5523
5524   return "lgr";
5525}
5526
5527static const HChar *
5528s390_irgen_LGFR(UChar r1, UChar r2)
5529{
5530   put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5531
5532   return "lgfr";
5533}
5534
5535static const HChar *
5536s390_irgen_L(UChar r1, IRTemp op2addr)
5537{
5538   put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5539
5540   return "l";
5541}
5542
5543static const HChar *
5544s390_irgen_LY(UChar r1, IRTemp op2addr)
5545{
5546   put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5547
5548   return "ly";
5549}
5550
5551static const HChar *
5552s390_irgen_LG(UChar r1, IRTemp op2addr)
5553{
5554   put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5555
5556   return "lg";
5557}
5558
5559static const HChar *
5560s390_irgen_LGF(UChar r1, IRTemp op2addr)
5561{
5562   put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5563
5564   return "lgf";
5565}
5566
5567static const HChar *
5568s390_irgen_LGFI(UChar r1, UInt i2)
5569{
5570   put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5571
5572   return "lgfi";
5573}
5574
5575static const HChar *
5576s390_irgen_LRL(UChar r1, UInt i2)
5577{
5578   put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5579              i2 << 1))));
5580
5581   return "lrl";
5582}
5583
5584static const HChar *
5585s390_irgen_LGRL(UChar r1, UInt i2)
5586{
5587   put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5588               i2 << 1))));
5589
5590   return "lgrl";
5591}
5592
5593static const HChar *
5594s390_irgen_LGFRL(UChar r1, UInt i2)
5595{
5596   put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5597               ((ULong)(Long)(Int)i2 << 1)))));
5598
5599   return "lgfrl";
5600}
5601
5602static const HChar *
5603s390_irgen_LA(UChar r1, IRTemp op2addr)
5604{
5605   put_gpr_dw0(r1, mkexpr(op2addr));
5606
5607   return "la";
5608}
5609
5610static const HChar *
5611s390_irgen_LAY(UChar r1, IRTemp op2addr)
5612{
5613   put_gpr_dw0(r1, mkexpr(op2addr));
5614
5615   return "lay";
5616}
5617
5618static const HChar *
5619s390_irgen_LAE(UChar r1, IRTemp op2addr)
5620{
5621   put_gpr_dw0(r1, mkexpr(op2addr));
5622
5623   return "lae";
5624}
5625
5626static const HChar *
5627s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5628{
5629   put_gpr_dw0(r1, mkexpr(op2addr));
5630
5631   return "laey";
5632}
5633
5634static const HChar *
5635s390_irgen_LARL(UChar r1, UInt i2)
5636{
5637   put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5638
5639   return "larl";
5640}
5641
5642/* The IR representation of LAA and friends is an approximation of what
5643   happens natively. Essentially a loop containing a compare-and-swap is
5644   constructed which will iterate until the CAS succeeds. As a consequence,
5645   instrumenters may see more memory accesses than happen natively. See also
5646   discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
5647static void
5648s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5649{
5650   IRCAS *cas;
5651   IRTemp old_mem = newTemp(Ity_I32);
5652   IRTemp op2 = newTemp(Ity_I32);
5653   IRTemp op3 = newTemp(Ity_I32);
5654   IRTemp result = newTemp(Ity_I32);
5655
5656   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5657   assign(op3, get_gpr_w1(r3));
5658   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5659
5660   /* Place the addition of second operand and third operand at the
5661      second-operand location everytime */
5662   cas = mkIRCAS(IRTemp_INVALID, old_mem,
5663                 Iend_BE, mkexpr(op2addr),
5664                 NULL, mkexpr(op2), /* expected value */
5665                 NULL, mkexpr(result)  /* new value */);
5666   stmt(IRStmt_CAS(cas));
5667
5668   /* Set CC according to 32-bit addition */
5669   if (is_signed) {
5670      s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5671   } else {
5672      s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5673   }
5674
5675   /* If old_mem contains the expected value, then the CAS succeeded.
5676      Otherwise, it did not */
5677   yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5678   put_gpr_w1(r1, mkexpr(old_mem));
5679}
5680
5681static void
5682s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5683{
5684   IRCAS *cas;
5685   IRTemp old_mem = newTemp(Ity_I64);
5686   IRTemp op2 = newTemp(Ity_I64);
5687   IRTemp op3 = newTemp(Ity_I64);
5688   IRTemp result = newTemp(Ity_I64);
5689
5690   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5691   assign(op3, get_gpr_dw0(r3));
5692   assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5693
5694   /* Place the addition of second operand and third operand at the
5695      second-operand location everytime */
5696   cas = mkIRCAS(IRTemp_INVALID, old_mem,
5697                 Iend_BE, mkexpr(op2addr),
5698                 NULL, mkexpr(op2), /* expected value */
5699                 NULL, mkexpr(result)  /* new value */);
5700   stmt(IRStmt_CAS(cas));
5701
5702   /* Set CC according to 64-bit addition */
5703   if (is_signed) {
5704      s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5705   } else {
5706      s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5707   }
5708
5709   /* If old_mem contains the expected value, then the CAS succeeded.
5710      Otherwise, it did not */
5711   yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5712   put_gpr_dw0(r1, mkexpr(old_mem));
5713}
5714
5715static void
5716s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5717{
5718   IRCAS *cas;
5719   IRTemp old_mem = newTemp(Ity_I32);
5720   IRTemp op2 = newTemp(Ity_I32);
5721   IRTemp op3 = newTemp(Ity_I32);
5722   IRTemp result = newTemp(Ity_I32);
5723
5724   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5725   assign(op3, get_gpr_w1(r3));
5726   assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5727
5728   /* Place the addition of second operand and third operand at the
5729      second-operand location everytime */
5730   cas = mkIRCAS(IRTemp_INVALID, old_mem,
5731                 Iend_BE, mkexpr(op2addr),
5732                 NULL, mkexpr(op2), /* expected value */
5733                 NULL, mkexpr(result)  /* new value */);
5734   stmt(IRStmt_CAS(cas));
5735
5736   /* Set CC according to bitwise operation */
5737   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5738
5739   /* If old_mem contains the expected value, then the CAS succeeded.
5740      Otherwise, it did not */
5741   yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5742   put_gpr_w1(r1, mkexpr(old_mem));
5743}
5744
5745static void
5746s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5747{
5748   IRCAS *cas;
5749   IRTemp old_mem = newTemp(Ity_I64);
5750   IRTemp op2 = newTemp(Ity_I64);
5751   IRTemp op3 = newTemp(Ity_I64);
5752   IRTemp result = newTemp(Ity_I64);
5753
5754   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5755   assign(op3, get_gpr_dw0(r3));
5756   assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5757
5758   /* Place the addition of second operand and third operand at the
5759      second-operand location everytime */
5760   cas = mkIRCAS(IRTemp_INVALID, old_mem,
5761                 Iend_BE, mkexpr(op2addr),
5762                 NULL, mkexpr(op2), /* expected value */
5763                 NULL, mkexpr(result)  /* new value */);
5764   stmt(IRStmt_CAS(cas));
5765
5766   /* Set CC according to bitwise operation */
5767   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5768
5769   /* If old_mem contains the expected value, then the CAS succeeded.
5770      Otherwise, it did not */
5771   yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5772   put_gpr_dw0(r1, mkexpr(old_mem));
5773}
5774
5775static const HChar *
5776s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5777{
5778   s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
5779
5780   return "laa";
5781}
5782
5783static const HChar *
5784s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5785{
5786   s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
5787
5788   return "laag";
5789}
5790
5791static const HChar *
5792s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5793{
5794   s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
5795
5796   return "laal";
5797}
5798
5799static const HChar *
5800s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5801{
5802   s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
5803
5804   return "laalg";
5805}
5806
5807static const HChar *
5808s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5809{
5810   s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
5811
5812   return "lan";
5813}
5814
5815static const HChar *
5816s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5817{
5818   s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
5819
5820   return "lang";
5821}
5822
5823static const HChar *
5824s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5825{
5826   s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
5827
5828   return "lax";
5829}
5830
5831static const HChar *
5832s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5833{
5834   s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
5835
5836   return "laxg";
5837}
5838
5839static const HChar *
5840s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5841{
5842   s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
5843
5844   return "lao";
5845}
5846
5847static const HChar *
5848s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5849{
5850   s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
5851
5852   return "laog";
5853}
5854
5855static const HChar *
5856s390_irgen_LTR(UChar r1, UChar r2)
5857{
5858   IRTemp op2 = newTemp(Ity_I32);
5859
5860   assign(op2, get_gpr_w1(r2));
5861   put_gpr_w1(r1, mkexpr(op2));
5862   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5863
5864   return "ltr";
5865}
5866
5867static const HChar *
5868s390_irgen_LTGR(UChar r1, UChar r2)
5869{
5870   IRTemp op2 = newTemp(Ity_I64);
5871
5872   assign(op2, get_gpr_dw0(r2));
5873   put_gpr_dw0(r1, mkexpr(op2));
5874   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5875
5876   return "ltgr";
5877}
5878
5879static const HChar *
5880s390_irgen_LTGFR(UChar r1, UChar r2)
5881{
5882   IRTemp op2 = newTemp(Ity_I64);
5883
5884   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5885   put_gpr_dw0(r1, mkexpr(op2));
5886   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5887
5888   return "ltgfr";
5889}
5890
5891static const HChar *
5892s390_irgen_LT(UChar r1, IRTemp op2addr)
5893{
5894   IRTemp op2 = newTemp(Ity_I32);
5895
5896   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5897   put_gpr_w1(r1, mkexpr(op2));
5898   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5899
5900   return "lt";
5901}
5902
5903static const HChar *
5904s390_irgen_LTG(UChar r1, IRTemp op2addr)
5905{
5906   IRTemp op2 = newTemp(Ity_I64);
5907
5908   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5909   put_gpr_dw0(r1, mkexpr(op2));
5910   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5911
5912   return "ltg";
5913}
5914
5915static const HChar *
5916s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5917{
5918   IRTemp op2 = newTemp(Ity_I64);
5919
5920   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5921   put_gpr_dw0(r1, mkexpr(op2));
5922   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5923
5924   return "ltgf";
5925}
5926
5927static const HChar *
5928s390_irgen_LBR(UChar r1, UChar r2)
5929{
5930   put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5931
5932   return "lbr";
5933}
5934
5935static const HChar *
5936s390_irgen_LGBR(UChar r1, UChar r2)
5937{
5938   put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5939
5940   return "lgbr";
5941}
5942
5943static const HChar *
5944s390_irgen_LB(UChar r1, IRTemp op2addr)
5945{
5946   put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5947
5948   return "lb";
5949}
5950
5951static const HChar *
5952s390_irgen_LGB(UChar r1, IRTemp op2addr)
5953{
5954   put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5955
5956   return "lgb";
5957}
5958
5959static const HChar *
5960s390_irgen_LBH(UChar r1, IRTemp op2addr)
5961{
5962   put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5963
5964   return "lbh";
5965}
5966
5967static const HChar *
5968s390_irgen_LCR(UChar r1, UChar r2)
5969{
5970   Int op1;
5971   IRTemp op2 = newTemp(Ity_I32);
5972   IRTemp result = newTemp(Ity_I32);
5973
5974   op1 = 0;
5975   assign(op2, get_gpr_w1(r2));
5976   assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5977   put_gpr_w1(r1, mkexpr(result));
5978   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5979                       op1)), op2);
5980
5981   return "lcr";
5982}
5983
5984static const HChar *
5985s390_irgen_LCGR(UChar r1, UChar r2)
5986{
5987   Long op1;
5988   IRTemp op2 = newTemp(Ity_I64);
5989   IRTemp result = newTemp(Ity_I64);
5990
5991   op1 = 0ULL;
5992   assign(op2, get_gpr_dw0(r2));
5993   assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5994   put_gpr_dw0(r1, mkexpr(result));
5995   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5996                       op1)), op2);
5997
5998   return "lcgr";
5999}
6000
6001static const HChar *
6002s390_irgen_LCGFR(UChar r1, UChar r2)
6003{
6004   Long op1;
6005   IRTemp op2 = newTemp(Ity_I64);
6006   IRTemp result = newTemp(Ity_I64);
6007
6008   op1 = 0ULL;
6009   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6010   assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6011   put_gpr_dw0(r1, mkexpr(result));
6012   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6013                       op1)), op2);
6014
6015   return "lcgfr";
6016}
6017
6018static const HChar *
6019s390_irgen_LHR(UChar r1, UChar r2)
6020{
6021   put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
6022
6023   return "lhr";
6024}
6025
6026static const HChar *
6027s390_irgen_LGHR(UChar r1, UChar r2)
6028{
6029   put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6030
6031   return "lghr";
6032}
6033
6034static const HChar *
6035s390_irgen_LH(UChar r1, IRTemp op2addr)
6036{
6037   put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6038
6039   return "lh";
6040}
6041
6042static const HChar *
6043s390_irgen_LHY(UChar r1, IRTemp op2addr)
6044{
6045   put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6046
6047   return "lhy";
6048}
6049
6050static const HChar *
6051s390_irgen_LGH(UChar r1, IRTemp op2addr)
6052{
6053   put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6054
6055   return "lgh";
6056}
6057
6058static const HChar *
6059s390_irgen_LHI(UChar r1, UShort i2)
6060{
6061   put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6062
6063   return "lhi";
6064}
6065
6066static const HChar *
6067s390_irgen_LGHI(UChar r1, UShort i2)
6068{
6069   put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6070
6071   return "lghi";
6072}
6073
6074static const HChar *
6075s390_irgen_LHRL(UChar r1, UInt i2)
6076{
6077   put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6078              ((ULong)(Long)(Int)i2 << 1)))));
6079
6080   return "lhrl";
6081}
6082
6083static const HChar *
6084s390_irgen_LGHRL(UChar r1, UInt i2)
6085{
6086   put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6087               ((ULong)(Long)(Int)i2 << 1)))));
6088
6089   return "lghrl";
6090}
6091
6092static const HChar *
6093s390_irgen_LHH(UChar r1, IRTemp op2addr)
6094{
6095   put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6096
6097   return "lhh";
6098}
6099
6100static const HChar *
6101s390_irgen_LFH(UChar r1, IRTemp op2addr)
6102{
6103   put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6104
6105   return "lfh";
6106}
6107
6108static const HChar *
6109s390_irgen_LLGFR(UChar r1, UChar r2)
6110{
6111   put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6112
6113   return "llgfr";
6114}
6115
6116static const HChar *
6117s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6118{
6119   put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6120
6121   return "llgf";
6122}
6123
6124static const HChar *
6125s390_irgen_LLGFRL(UChar r1, UInt i2)
6126{
6127   put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6128               ((ULong)(Long)(Int)i2 << 1)))));
6129
6130   return "llgfrl";
6131}
6132
6133static const HChar *
6134s390_irgen_LLCR(UChar r1, UChar r2)
6135{
6136   put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6137
6138   return "llcr";
6139}
6140
6141static const HChar *
6142s390_irgen_LLGCR(UChar r1, UChar r2)
6143{
6144   put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6145
6146   return "llgcr";
6147}
6148
6149static const HChar *
6150s390_irgen_LLC(UChar r1, IRTemp op2addr)
6151{
6152   put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6153
6154   return "llc";
6155}
6156
6157static const HChar *
6158s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6159{
6160   put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6161
6162   return "llgc";
6163}
6164
6165static const HChar *
6166s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6167{
6168   put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6169
6170   return "llch";
6171}
6172
6173static const HChar *
6174s390_irgen_LLHR(UChar r1, UChar r2)
6175{
6176   put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6177
6178   return "llhr";
6179}
6180
6181static const HChar *
6182s390_irgen_LLGHR(UChar r1, UChar r2)
6183{
6184   put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6185
6186   return "llghr";
6187}
6188
6189static const HChar *
6190s390_irgen_LLH(UChar r1, IRTemp op2addr)
6191{
6192   put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6193
6194   return "llh";
6195}
6196
6197static const HChar *
6198s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6199{
6200   put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6201
6202   return "llgh";
6203}
6204
6205static const HChar *
6206s390_irgen_LLHRL(UChar r1, UInt i2)
6207{
6208   put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6209              ((ULong)(Long)(Int)i2 << 1)))));
6210
6211   return "llhrl";
6212}
6213
6214static const HChar *
6215s390_irgen_LLGHRL(UChar r1, UInt i2)
6216{
6217   put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6218               ((ULong)(Long)(Int)i2 << 1)))));
6219
6220   return "llghrl";
6221}
6222
6223static const HChar *
6224s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6225{
6226   put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6227
6228   return "llhh";
6229}
6230
6231static const HChar *
6232s390_irgen_LLIHF(UChar r1, UInt i2)
6233{
6234   put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6235
6236   return "llihf";
6237}
6238
6239static const HChar *
6240s390_irgen_LLIHH(UChar r1, UShort i2)
6241{
6242   put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6243
6244   return "llihh";
6245}
6246
6247static const HChar *
6248s390_irgen_LLIHL(UChar r1, UShort i2)
6249{
6250   put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6251
6252   return "llihl";
6253}
6254
6255static const HChar *
6256s390_irgen_LLILF(UChar r1, UInt i2)
6257{
6258   put_gpr_dw0(r1, mkU64(i2));
6259
6260   return "llilf";
6261}
6262
6263static const HChar *
6264s390_irgen_LLILH(UChar r1, UShort i2)
6265{
6266   put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6267
6268   return "llilh";
6269}
6270
6271static const HChar *
6272s390_irgen_LLILL(UChar r1, UShort i2)
6273{
6274   put_gpr_dw0(r1, mkU64(i2));
6275
6276   return "llill";
6277}
6278
6279static const HChar *
6280s390_irgen_LLGTR(UChar r1, UChar r2)
6281{
6282   put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6283               mkU32(2147483647))));
6284
6285   return "llgtr";
6286}
6287
6288static const HChar *
6289s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6290{
6291   put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6292               mkexpr(op2addr)), mkU32(2147483647))));
6293
6294   return "llgt";
6295}
6296
6297static const HChar *
6298s390_irgen_LNR(UChar r1, UChar r2)
6299{
6300   IRTemp op2 = newTemp(Ity_I32);
6301   IRTemp result = newTemp(Ity_I32);
6302
6303   assign(op2, get_gpr_w1(r2));
6304   assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6305          binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6306   put_gpr_w1(r1, mkexpr(result));
6307   s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6308
6309   return "lnr";
6310}
6311
6312static const HChar *
6313s390_irgen_LNGR(UChar r1, UChar r2)
6314{
6315   IRTemp op2 = newTemp(Ity_I64);
6316   IRTemp result = newTemp(Ity_I64);
6317
6318   assign(op2, get_gpr_dw0(r2));
6319   assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6320          binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6321   put_gpr_dw0(r1, mkexpr(result));
6322   s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6323
6324   return "lngr";
6325}
6326
6327static const HChar *
6328s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6329{
6330   IRTemp op2 = newTemp(Ity_I64);
6331   IRTemp result = newTemp(Ity_I64);
6332
6333   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6334   assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6335          binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6336   put_gpr_dw0(r1, mkexpr(result));
6337   s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6338
6339   return "lngfr";
6340}
6341
6342static const HChar *
6343s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6344{
6345   next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
6346   put_gpr_w1(r1, get_gpr_w1(r2));
6347
6348   return "locr";
6349}
6350
6351static const HChar *
6352s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6353{
6354   next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
6355   put_gpr_dw0(r1, get_gpr_dw0(r2));
6356
6357   return "locgr";
6358}
6359
6360static const HChar *
6361s390_irgen_LOC(UChar r1, IRTemp op2addr)
6362{
6363   /* condition is checked in format handler */
6364   put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6365
6366   return "loc";
6367}
6368
6369static const HChar *
6370s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6371{
6372   /* condition is checked in format handler */
6373   put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6374
6375   return "locg";
6376}
6377
6378static const HChar *
6379s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6380{
6381   put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6382   put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6383               ));
6384
6385   return "lpq";
6386}
6387
6388static const HChar *
6389s390_irgen_LPR(UChar r1, UChar r2)
6390{
6391   IRTemp op2 = newTemp(Ity_I32);
6392   IRTemp result = newTemp(Ity_I32);
6393
6394   assign(op2, get_gpr_w1(r2));
6395   assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6396          binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6397   put_gpr_w1(r1, mkexpr(result));
6398   s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6399
6400   return "lpr";
6401}
6402
6403static const HChar *
6404s390_irgen_LPGR(UChar r1, UChar r2)
6405{
6406   IRTemp op2 = newTemp(Ity_I64);
6407   IRTemp result = newTemp(Ity_I64);
6408
6409   assign(op2, get_gpr_dw0(r2));
6410   assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6411          binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6412   put_gpr_dw0(r1, mkexpr(result));
6413   s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6414
6415   return "lpgr";
6416}
6417
6418static const HChar *
6419s390_irgen_LPGFR(UChar r1, UChar r2)
6420{
6421   IRTemp op2 = newTemp(Ity_I64);
6422   IRTemp result = newTemp(Ity_I64);
6423
6424   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6425   assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6426          binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6427   put_gpr_dw0(r1, mkexpr(result));
6428   s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6429
6430   return "lpgfr";
6431}
6432
6433static const HChar *
6434s390_irgen_LRVR(UChar r1, UChar r2)
6435{
6436   IRTemp b0 = newTemp(Ity_I8);
6437   IRTemp b1 = newTemp(Ity_I8);
6438   IRTemp b2 = newTemp(Ity_I8);
6439   IRTemp b3 = newTemp(Ity_I8);
6440
6441   assign(b3, get_gpr_b7(r2));
6442   assign(b2, get_gpr_b6(r2));
6443   assign(b1, get_gpr_b5(r2));
6444   assign(b0, get_gpr_b4(r2));
6445   put_gpr_b4(r1, mkexpr(b3));
6446   put_gpr_b5(r1, mkexpr(b2));
6447   put_gpr_b6(r1, mkexpr(b1));
6448   put_gpr_b7(r1, mkexpr(b0));
6449
6450   return "lrvr";
6451}
6452
6453static const HChar *
6454s390_irgen_LRVGR(UChar r1, UChar r2)
6455{
6456   IRTemp b0 = newTemp(Ity_I8);
6457   IRTemp b1 = newTemp(Ity_I8);
6458   IRTemp b2 = newTemp(Ity_I8);
6459   IRTemp b3 = newTemp(Ity_I8);
6460   IRTemp b4 = newTemp(Ity_I8);
6461   IRTemp b5 = newTemp(Ity_I8);
6462   IRTemp b6 = newTemp(Ity_I8);
6463   IRTemp b7 = newTemp(Ity_I8);
6464
6465   assign(b7, get_gpr_b7(r2));
6466   assign(b6, get_gpr_b6(r2));
6467   assign(b5, get_gpr_b5(r2));
6468   assign(b4, get_gpr_b4(r2));
6469   assign(b3, get_gpr_b3(r2));
6470   assign(b2, get_gpr_b2(r2));
6471   assign(b1, get_gpr_b1(r2));
6472   assign(b0, get_gpr_b0(r2));
6473   put_gpr_b0(r1, mkexpr(b7));
6474   put_gpr_b1(r1, mkexpr(b6));
6475   put_gpr_b2(r1, mkexpr(b5));
6476   put_gpr_b3(r1, mkexpr(b4));
6477   put_gpr_b4(r1, mkexpr(b3));
6478   put_gpr_b5(r1, mkexpr(b2));
6479   put_gpr_b6(r1, mkexpr(b1));
6480   put_gpr_b7(r1, mkexpr(b0));
6481
6482   return "lrvgr";
6483}
6484
6485static const HChar *
6486s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6487{
6488   IRTemp op2 = newTemp(Ity_I16);
6489
6490   assign(op2, load(Ity_I16, mkexpr(op2addr)));
6491   put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6492   put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6493
6494   return "lrvh";
6495}
6496
6497static const HChar *
6498s390_irgen_LRV(UChar r1, IRTemp op2addr)
6499{
6500   IRTemp op2 = newTemp(Ity_I32);
6501
6502   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6503   put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6504   put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6505              mkU8(8)), mkU32(255))));
6506   put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6507              mkU8(16)), mkU32(255))));
6508   put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6509              mkU8(24)), mkU32(255))));
6510
6511   return "lrv";
6512}
6513
6514static const HChar *
6515s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6516{
6517   IRTemp op2 = newTemp(Ity_I64);
6518
6519   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6520   put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6521   put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6522              mkU8(8)), mkU64(255))));
6523   put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6524              mkU8(16)), mkU64(255))));
6525   put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6526              mkU8(24)), mkU64(255))));
6527   put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6528              mkU8(32)), mkU64(255))));
6529   put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6530              mkU8(40)), mkU64(255))));
6531   put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6532              mkU8(48)), mkU64(255))));
6533   put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6534              mkU8(56)), mkU64(255))));
6535
6536   return "lrvg";
6537}
6538
6539static const HChar *
6540s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6541{
6542   store(mkexpr(op1addr), mkU16(i2));
6543
6544   return "mvhhi";
6545}
6546
6547static const HChar *
6548s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6549{
6550   store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6551
6552   return "mvhi";
6553}
6554
6555static const HChar *
6556s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6557{
6558   store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6559
6560   return "mvghi";
6561}
6562
6563static const HChar *
6564s390_irgen_MVI(UChar i2, IRTemp op1addr)
6565{
6566   store(mkexpr(op1addr), mkU8(i2));
6567
6568   return "mvi";
6569}
6570
6571static const HChar *
6572s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6573{
6574   store(mkexpr(op1addr), mkU8(i2));
6575
6576   return "mviy";
6577}
6578
6579static const HChar *
6580s390_irgen_MR(UChar r1, UChar r2)
6581{
6582   IRTemp op1 = newTemp(Ity_I32);
6583   IRTemp op2 = newTemp(Ity_I32);
6584   IRTemp result = newTemp(Ity_I64);
6585
6586   assign(op1, get_gpr_w1(r1 + 1));
6587   assign(op2, get_gpr_w1(r2));
6588   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6589   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6590   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6591
6592   return "mr";
6593}
6594
6595static const HChar *
6596s390_irgen_M(UChar r1, IRTemp op2addr)
6597{
6598   IRTemp op1 = newTemp(Ity_I32);
6599   IRTemp op2 = newTemp(Ity_I32);
6600   IRTemp result = newTemp(Ity_I64);
6601
6602   assign(op1, get_gpr_w1(r1 + 1));
6603   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6604   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6605   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6606   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6607
6608   return "m";
6609}
6610
6611static const HChar *
6612s390_irgen_MFY(UChar r1, IRTemp op2addr)
6613{
6614   IRTemp op1 = newTemp(Ity_I32);
6615   IRTemp op2 = newTemp(Ity_I32);
6616   IRTemp result = newTemp(Ity_I64);
6617
6618   assign(op1, get_gpr_w1(r1 + 1));
6619   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6620   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6621   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6622   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6623
6624   return "mfy";
6625}
6626
6627static const HChar *
6628s390_irgen_MH(UChar r1, IRTemp op2addr)
6629{
6630   IRTemp op1 = newTemp(Ity_I32);
6631   IRTemp op2 = newTemp(Ity_I16);
6632   IRTemp result = newTemp(Ity_I64);
6633
6634   assign(op1, get_gpr_w1(r1));
6635   assign(op2, load(Ity_I16, mkexpr(op2addr)));
6636   assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6637          ));
6638   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6639
6640   return "mh";
6641}
6642
6643static const HChar *
6644s390_irgen_MHY(UChar r1, IRTemp op2addr)
6645{
6646   IRTemp op1 = newTemp(Ity_I32);
6647   IRTemp op2 = newTemp(Ity_I16);
6648   IRTemp result = newTemp(Ity_I64);
6649
6650   assign(op1, get_gpr_w1(r1));
6651   assign(op2, load(Ity_I16, mkexpr(op2addr)));
6652   assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6653          ));
6654   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6655
6656   return "mhy";
6657}
6658
6659static const HChar *
6660s390_irgen_MHI(UChar r1, UShort i2)
6661{
6662   IRTemp op1 = newTemp(Ity_I32);
6663   Short op2;
6664   IRTemp result = newTemp(Ity_I64);
6665
6666   assign(op1, get_gpr_w1(r1));
6667   op2 = (Short)i2;
6668   assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6669          mkU16((UShort)op2))));
6670   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6671
6672   return "mhi";
6673}
6674
6675static const HChar *
6676s390_irgen_MGHI(UChar r1, UShort i2)
6677{
6678   IRTemp op1 = newTemp(Ity_I64);
6679   Short op2;
6680   IRTemp result = newTemp(Ity_I128);
6681
6682   assign(op1, get_gpr_dw0(r1));
6683   op2 = (Short)i2;
6684   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6685          mkU16((UShort)op2))));
6686   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6687
6688   return "mghi";
6689}
6690
6691static const HChar *
6692s390_irgen_MLR(UChar r1, UChar r2)
6693{
6694   IRTemp op1 = newTemp(Ity_I32);
6695   IRTemp op2 = newTemp(Ity_I32);
6696   IRTemp result = newTemp(Ity_I64);
6697
6698   assign(op1, get_gpr_w1(r1 + 1));
6699   assign(op2, get_gpr_w1(r2));
6700   assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6701   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6702   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6703
6704   return "mlr";
6705}
6706
6707static const HChar *
6708s390_irgen_MLGR(UChar r1, UChar r2)
6709{
6710   IRTemp op1 = newTemp(Ity_I64);
6711   IRTemp op2 = newTemp(Ity_I64);
6712   IRTemp result = newTemp(Ity_I128);
6713
6714   assign(op1, get_gpr_dw0(r1 + 1));
6715   assign(op2, get_gpr_dw0(r2));
6716   assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6717   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6718   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6719
6720   return "mlgr";
6721}
6722
6723static const HChar *
6724s390_irgen_ML(UChar r1, IRTemp op2addr)
6725{
6726   IRTemp op1 = newTemp(Ity_I32);
6727   IRTemp op2 = newTemp(Ity_I32);
6728   IRTemp result = newTemp(Ity_I64);
6729
6730   assign(op1, get_gpr_w1(r1 + 1));
6731   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6732   assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6733   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6734   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6735
6736   return "ml";
6737}
6738
6739static const HChar *
6740s390_irgen_MLG(UChar r1, IRTemp op2addr)
6741{
6742   IRTemp op1 = newTemp(Ity_I64);
6743   IRTemp op2 = newTemp(Ity_I64);
6744   IRTemp result = newTemp(Ity_I128);
6745
6746   assign(op1, get_gpr_dw0(r1 + 1));
6747   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6748   assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6749   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6750   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6751
6752   return "mlg";
6753}
6754
6755static const HChar *
6756s390_irgen_MSR(UChar r1, UChar r2)
6757{
6758   IRTemp op1 = newTemp(Ity_I32);
6759   IRTemp op2 = newTemp(Ity_I32);
6760   IRTemp result = newTemp(Ity_I64);
6761
6762   assign(op1, get_gpr_w1(r1));
6763   assign(op2, get_gpr_w1(r2));
6764   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6765   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6766
6767   return "msr";
6768}
6769
6770static const HChar *
6771s390_irgen_MSGR(UChar r1, UChar r2)
6772{
6773   IRTemp op1 = newTemp(Ity_I64);
6774   IRTemp op2 = newTemp(Ity_I64);
6775   IRTemp result = newTemp(Ity_I128);
6776
6777   assign(op1, get_gpr_dw0(r1));
6778   assign(op2, get_gpr_dw0(r2));
6779   assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6780   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6781
6782   return "msgr";
6783}
6784
6785static const HChar *
6786s390_irgen_MSGFR(UChar r1, UChar r2)
6787{
6788   IRTemp op1 = newTemp(Ity_I64);
6789   IRTemp op2 = newTemp(Ity_I32);
6790   IRTemp result = newTemp(Ity_I128);
6791
6792   assign(op1, get_gpr_dw0(r1));
6793   assign(op2, get_gpr_w1(r2));
6794   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6795          ));
6796   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6797
6798   return "msgfr";
6799}
6800
6801static const HChar *
6802s390_irgen_MS(UChar r1, IRTemp op2addr)
6803{
6804   IRTemp op1 = newTemp(Ity_I32);
6805   IRTemp op2 = newTemp(Ity_I32);
6806   IRTemp result = newTemp(Ity_I64);
6807
6808   assign(op1, get_gpr_w1(r1));
6809   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6810   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6811   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6812
6813   return "ms";
6814}
6815
6816static const HChar *
6817s390_irgen_MSY(UChar r1, IRTemp op2addr)
6818{
6819   IRTemp op1 = newTemp(Ity_I32);
6820   IRTemp op2 = newTemp(Ity_I32);
6821   IRTemp result = newTemp(Ity_I64);
6822
6823   assign(op1, get_gpr_w1(r1));
6824   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6825   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6826   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6827
6828   return "msy";
6829}
6830
6831static const HChar *
6832s390_irgen_MSG(UChar r1, IRTemp op2addr)
6833{
6834   IRTemp op1 = newTemp(Ity_I64);
6835   IRTemp op2 = newTemp(Ity_I64);
6836   IRTemp result = newTemp(Ity_I128);
6837
6838   assign(op1, get_gpr_dw0(r1));
6839   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6840   assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6841   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6842
6843   return "msg";
6844}
6845
6846static const HChar *
6847s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6848{
6849   IRTemp op1 = newTemp(Ity_I64);
6850   IRTemp op2 = newTemp(Ity_I32);
6851   IRTemp result = newTemp(Ity_I128);
6852
6853   assign(op1, get_gpr_dw0(r1));
6854   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6855   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6856          ));
6857   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6858
6859   return "msgf";
6860}
6861
6862static const HChar *
6863s390_irgen_MSFI(UChar r1, UInt i2)
6864{
6865   IRTemp op1 = newTemp(Ity_I32);
6866   Int op2;
6867   IRTemp result = newTemp(Ity_I64);
6868
6869   assign(op1, get_gpr_w1(r1));
6870   op2 = (Int)i2;
6871   assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6872   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6873
6874   return "msfi";
6875}
6876
6877static const HChar *
6878s390_irgen_MSGFI(UChar r1, UInt i2)
6879{
6880   IRTemp op1 = newTemp(Ity_I64);
6881   Int op2;
6882   IRTemp result = newTemp(Ity_I128);
6883
6884   assign(op1, get_gpr_dw0(r1));
6885   op2 = (Int)i2;
6886   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6887          op2))));
6888   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6889
6890   return "msgfi";
6891}
6892
6893static const HChar *
6894s390_irgen_OR(UChar r1, UChar r2)
6895{
6896   IRTemp op1 = newTemp(Ity_I32);
6897   IRTemp op2 = newTemp(Ity_I32);
6898   IRTemp result = newTemp(Ity_I32);
6899
6900   assign(op1, get_gpr_w1(r1));
6901   assign(op2, get_gpr_w1(r2));
6902   assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6903   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6904   put_gpr_w1(r1, mkexpr(result));
6905
6906   return "or";
6907}
6908
6909static const HChar *
6910s390_irgen_OGR(UChar r1, UChar r2)
6911{
6912   IRTemp op1 = newTemp(Ity_I64);
6913   IRTemp op2 = newTemp(Ity_I64);
6914   IRTemp result = newTemp(Ity_I64);
6915
6916   assign(op1, get_gpr_dw0(r1));
6917   assign(op2, get_gpr_dw0(r2));
6918   assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6919   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6920   put_gpr_dw0(r1, mkexpr(result));
6921
6922   return "ogr";
6923}
6924
6925static const HChar *
6926s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6927{
6928   IRTemp op2 = newTemp(Ity_I32);
6929   IRTemp op3 = newTemp(Ity_I32);
6930   IRTemp result = newTemp(Ity_I32);
6931
6932   assign(op2, get_gpr_w1(r2));
6933   assign(op3, get_gpr_w1(r3));
6934   assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6935   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6936   put_gpr_w1(r1, mkexpr(result));
6937
6938   return "ork";
6939}
6940
6941static const HChar *
6942s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6943{
6944   IRTemp op2 = newTemp(Ity_I64);
6945   IRTemp op3 = newTemp(Ity_I64);
6946   IRTemp result = newTemp(Ity_I64);
6947
6948   assign(op2, get_gpr_dw0(r2));
6949   assign(op3, get_gpr_dw0(r3));
6950   assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6951   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6952   put_gpr_dw0(r1, mkexpr(result));
6953
6954   return "ogrk";
6955}
6956
6957static const HChar *
6958s390_irgen_O(UChar r1, IRTemp op2addr)
6959{
6960   IRTemp op1 = newTemp(Ity_I32);
6961   IRTemp op2 = newTemp(Ity_I32);
6962   IRTemp result = newTemp(Ity_I32);
6963
6964   assign(op1, get_gpr_w1(r1));
6965   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6966   assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6967   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6968   put_gpr_w1(r1, mkexpr(result));
6969
6970   return "o";
6971}
6972
6973static const HChar *
6974s390_irgen_OY(UChar r1, IRTemp op2addr)
6975{
6976   IRTemp op1 = newTemp(Ity_I32);
6977   IRTemp op2 = newTemp(Ity_I32);
6978   IRTemp result = newTemp(Ity_I32);
6979
6980   assign(op1, get_gpr_w1(r1));
6981   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6982   assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6983   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6984   put_gpr_w1(r1, mkexpr(result));
6985
6986   return "oy";
6987}
6988
6989static const HChar *
6990s390_irgen_OG(UChar r1, IRTemp op2addr)
6991{
6992   IRTemp op1 = newTemp(Ity_I64);
6993   IRTemp op2 = newTemp(Ity_I64);
6994   IRTemp result = newTemp(Ity_I64);
6995
6996   assign(op1, get_gpr_dw0(r1));
6997   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6998   assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6999   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7000   put_gpr_dw0(r1, mkexpr(result));
7001
7002   return "og";
7003}
7004
7005static const HChar *
7006s390_irgen_OI(UChar i2, IRTemp op1addr)
7007{
7008   IRTemp op1 = newTemp(Ity_I8);
7009   UChar op2;
7010   IRTemp result = newTemp(Ity_I8);
7011
7012   assign(op1, load(Ity_I8, mkexpr(op1addr)));
7013   op2 = i2;
7014   assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7015   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7016   store(mkexpr(op1addr), mkexpr(result));
7017
7018   return "oi";
7019}
7020
7021static const HChar *
7022s390_irgen_OIY(UChar i2, IRTemp op1addr)
7023{
7024   IRTemp op1 = newTemp(Ity_I8);
7025   UChar op2;
7026   IRTemp result = newTemp(Ity_I8);
7027
7028   assign(op1, load(Ity_I8, mkexpr(op1addr)));
7029   op2 = i2;
7030   assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7031   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7032   store(mkexpr(op1addr), mkexpr(result));
7033
7034   return "oiy";
7035}
7036
7037static const HChar *
7038s390_irgen_OIHF(UChar r1, UInt i2)
7039{
7040   IRTemp op1 = newTemp(Ity_I32);
7041   UInt op2;
7042   IRTemp result = newTemp(Ity_I32);
7043
7044   assign(op1, get_gpr_w0(r1));
7045   op2 = i2;
7046   assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7047   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7048   put_gpr_w0(r1, mkexpr(result));
7049
7050   return "oihf";
7051}
7052
7053static const HChar *
7054s390_irgen_OIHH(UChar r1, UShort i2)
7055{
7056   IRTemp op1 = newTemp(Ity_I16);
7057   UShort op2;
7058   IRTemp result = newTemp(Ity_I16);
7059
7060   assign(op1, get_gpr_hw0(r1));
7061   op2 = i2;
7062   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7063   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7064   put_gpr_hw0(r1, mkexpr(result));
7065
7066   return "oihh";
7067}
7068
7069static const HChar *
7070s390_irgen_OIHL(UChar r1, UShort i2)
7071{
7072   IRTemp op1 = newTemp(Ity_I16);
7073   UShort op2;
7074   IRTemp result = newTemp(Ity_I16);
7075
7076   assign(op1, get_gpr_hw1(r1));
7077   op2 = i2;
7078   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7079   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7080   put_gpr_hw1(r1, mkexpr(result));
7081
7082   return "oihl";
7083}
7084
7085static const HChar *
7086s390_irgen_OILF(UChar r1, UInt i2)
7087{
7088   IRTemp op1 = newTemp(Ity_I32);
7089   UInt op2;
7090   IRTemp result = newTemp(Ity_I32);
7091
7092   assign(op1, get_gpr_w1(r1));
7093   op2 = i2;
7094   assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7095   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7096   put_gpr_w1(r1, mkexpr(result));
7097
7098   return "oilf";
7099}
7100
7101static const HChar *
7102s390_irgen_OILH(UChar r1, UShort i2)
7103{
7104   IRTemp op1 = newTemp(Ity_I16);
7105   UShort op2;
7106   IRTemp result = newTemp(Ity_I16);
7107
7108   assign(op1, get_gpr_hw2(r1));
7109   op2 = i2;
7110   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7111   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7112   put_gpr_hw2(r1, mkexpr(result));
7113
7114   return "oilh";
7115}
7116
7117static const HChar *
7118s390_irgen_OILL(UChar r1, UShort i2)
7119{
7120   IRTemp op1 = newTemp(Ity_I16);
7121   UShort op2;
7122   IRTemp result = newTemp(Ity_I16);
7123
7124   assign(op1, get_gpr_hw3(r1));
7125   op2 = i2;
7126   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7127   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7128   put_gpr_hw3(r1, mkexpr(result));
7129
7130   return "oill";
7131}
7132
7133static const HChar *
7134s390_irgen_PFD(void)
7135{
7136
7137   return "pfd";
7138}
7139
7140static const HChar *
7141s390_irgen_PFDRL(void)
7142{
7143
7144   return "pfdrl";
7145}
7146
7147static IRExpr *
7148get_rounding_mode_from_gr0(void)
7149{
7150   IRTemp rm_bits = newTemp(Ity_I32);
7151   IRExpr *s390rm;
7152   IRExpr *irrm;
7153
7154   /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7155      when PFPO insn is called. So, extract the bits at [60:63] */
7156   assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7157   s390rm = mkexpr(rm_bits);
7158   irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7159            mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7160            mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7161              mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7162              mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7163                mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7164                mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7165                  mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7166                  mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7167                    mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7168                    mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7169                      mkexpr(encode_dfp_rounding_mode(
7170                               S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7171                      mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7172                        mkexpr(encode_dfp_rounding_mode(
7173                                 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7174                        mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7175                          mkexpr(encode_dfp_rounding_mode(
7176                                   S390_DFP_ROUND_AWAY_0)),
7177                          mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7178                            mkexpr(encode_dfp_rounding_mode(
7179                                     S390_DFP_ROUND_PREPARE_SHORT_15)),
7180                                /* if rounding mode is 0 or invalid (2-7)
7181                                   set S390_DFP_ROUND_PER_FPC_0 */
7182                            mkexpr(encode_dfp_rounding_mode(
7183                                     S390_DFP_ROUND_PER_FPC_0)))))))))));
7184
7185   return irrm;
7186}
7187
7188static IRExpr *
7189s390_call_pfpo_helper(IRExpr *gr0)
7190{
7191   IRExpr **args, *call;
7192
7193   args = mkIRExprVec_1(gr0);
7194   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7195                        "s390_do_pfpo", &s390_do_pfpo, args);
7196   /* Nothing is excluded from definedness checking. */
7197   call->Iex.CCall.cee->mcx_mask = 0;
7198
7199   return call;
7200}
7201
7202static const HChar *
7203s390_irgen_PFPO(void)
7204{
7205   IRTemp gr0 = newTemp(Ity_I32);     /* word 1 [32:63] of GR 0 */
7206   IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7207   IRTemp fn = newTemp(Ity_I32);       /* [33:55] of GR 0 - function code */
7208   IRTemp ef = newTemp(Ity_I32);       /* Emulation Failure */
7209   IRTemp src1 = newTemp(Ity_F32);
7210   IRTemp dst1 = newTemp(Ity_D32);
7211   IRTemp src2 = newTemp(Ity_F32);
7212   IRTemp dst2 = newTemp(Ity_D64);
7213   IRTemp src3 = newTemp(Ity_F32);
7214   IRTemp dst3 = newTemp(Ity_D128);
7215   IRTemp src4 = newTemp(Ity_F64);
7216   IRTemp dst4 = newTemp(Ity_D32);
7217   IRTemp src5 = newTemp(Ity_F64);
7218   IRTemp dst5 = newTemp(Ity_D64);
7219   IRTemp src6 = newTemp(Ity_F64);
7220   IRTemp dst6 = newTemp(Ity_D128);
7221   IRTemp src7 = newTemp(Ity_F128);
7222   IRTemp dst7 = newTemp(Ity_D32);
7223   IRTemp src8 = newTemp(Ity_F128);
7224   IRTemp dst8 = newTemp(Ity_D64);
7225   IRTemp src9 = newTemp(Ity_F128);
7226   IRTemp dst9 = newTemp(Ity_D128);
7227   IRTemp src10 = newTemp(Ity_D32);
7228   IRTemp dst10 = newTemp(Ity_F32);
7229   IRTemp src11 = newTemp(Ity_D32);
7230   IRTemp dst11 = newTemp(Ity_F64);
7231   IRTemp src12 = newTemp(Ity_D32);
7232   IRTemp dst12 = newTemp(Ity_F128);
7233   IRTemp src13 = newTemp(Ity_D64);
7234   IRTemp dst13 = newTemp(Ity_F32);
7235   IRTemp src14 = newTemp(Ity_D64);
7236   IRTemp dst14 = newTemp(Ity_F64);
7237   IRTemp src15 = newTemp(Ity_D64);
7238   IRTemp dst15 = newTemp(Ity_F128);
7239   IRTemp src16 = newTemp(Ity_D128);
7240   IRTemp dst16 = newTemp(Ity_F32);
7241   IRTemp src17 = newTemp(Ity_D128);
7242   IRTemp dst17 = newTemp(Ity_F64);
7243   IRTemp src18 = newTemp(Ity_D128);
7244   IRTemp dst18 = newTemp(Ity_F128);
7245   IRExpr *irrm;
7246
7247   if (! s390_host_has_pfpo) {
7248      emulation_failure(EmFail_S390X_pfpo);
7249      goto done;
7250   }
7251
7252   assign(gr0, get_gpr_w1(0));
7253   /* get function code */
7254   assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7255                    mkU32(0x7fffff)));
7256   /* get validity test bit */
7257   assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7258                          mkU32(0x1)));
7259   irrm = get_rounding_mode_from_gr0();
7260
7261   /* test_bit is 1 */
7262   assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
7263   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7264
7265   /* Return code set in GR1 is usually 0. Non-zero value is set only
7266      when exceptions are raised. See Programming Notes point 5 in the
7267      instrcution description of pfpo in POP. Since valgrind does not
7268      model exception, it might be safe to just set 0 to GR 1. */
7269   put_gpr_w1(1, mkU32(0x0));
7270   next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7271
7272   /* Check validity of function code in GR 0 */
7273   assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
7274   emulation_failure_with_expr(mkexpr(ef));
7275
7276   stmt(
7277        IRStmt_Exit(
7278                    binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7279                    Ijk_EmFail,
7280                    IRConst_U64(guest_IA_next_instr),
7281                    S390X_GUEST_OFFSET(guest_IA)
7282                    )
7283        );
7284
7285   /* F32 -> D32 */
7286   /* get source from FPR 4,6 - already set in src1 */
7287   assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
7288   put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
7289   put_gpr_w1(1, mkU32(0x0));
7290   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
7291   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
7292
7293   /* F32 -> D64 */
7294   assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
7295   assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
7296   put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
7297   put_gpr_w1(1, mkU32(0x0));
7298   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
7299   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
7300
7301   /* F32 -> D128 */
7302   assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
7303   assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
7304   put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7305   put_gpr_w1(1, mkU32(0x0));
7306   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
7307   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
7308
7309   /* F64 -> D32 */
7310   assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7311   assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
7312   put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7313   put_gpr_w1(1, mkU32(0x0));
7314   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
7315   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
7316
7317   /* F64 -> D64 */
7318   assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7319   assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
7320   put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7321   put_gpr_w1(1, mkU32(0x0));
7322   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
7323   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7324
7325   /* F64 -> D128 */
7326   assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7327   assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
7328   put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7329   put_gpr_w1(1, mkU32(0x0));
7330   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
7331   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7332
7333   /* F128 -> D32 */
7334   assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
7335   assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
7336   put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
7337   put_gpr_w1(1, mkU32(0x0));
7338   s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
7339   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
7340
7341   /* F128 -> D64 */
7342   assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
7343   assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
7344   put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
7345   put_gpr_w1(1, mkU32(0x0));
7346   s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
7347   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
7348
7349   /* F128 -> D128 */
7350   assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
7351   assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
7352   put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
7353   put_gpr_w1(1, mkU32(0x0));
7354   s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
7355   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7356
7357   /* D32 -> F32 */
7358   assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
7359   assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
7360   put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
7361   put_gpr_w1(1, mkU32(0x0));
7362   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
7363   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
7364
7365   /* D32 -> F64 */
7366   assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
7367   assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
7368   put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
7369   put_gpr_w1(1, mkU32(0x0));
7370   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
7371   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
7372
7373   /* D32 -> F128 */
7374   assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
7375   assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
7376   put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
7377   put_gpr_w1(1, mkU32(0x0));
7378   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
7379   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
7380
7381   /* D64 -> F32 */
7382   assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7383   assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
7384   put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
7385   put_gpr_w1(1, mkU32(0x0));
7386   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
7387   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
7388
7389   /* D64 -> F64 */
7390   assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7391   assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
7392   put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
7393   put_gpr_w1(1, mkU32(0x0));
7394   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
7395   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7396
7397   /* D64 -> F128 */
7398   assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7399   assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
7400   put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
7401   put_gpr_w1(1, mkU32(0x0));
7402   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
7403   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
7404
7405   /* D128 -> F32 */
7406   assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
7407   assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
7408   put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
7409   put_gpr_w1(1, mkU32(0x0));
7410   s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
7411   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
7412
7413   /* D128 -> F64 */
7414   assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
7415   assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
7416   put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
7417   put_gpr_w1(1, mkU32(0x0));
7418   s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
7419   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7420
7421   /* D128 -> F128 */
7422   assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
7423   assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
7424   put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
7425   put_gpr_w1(1, mkU32(0x0));
7426   s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
7427   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7428
7429 done:
7430   return "pfpo";
7431}
7432
7433static const HChar *
7434s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7435{
7436   IRTemp amount = newTemp(Ity_I64);
7437   IRTemp op = newTemp(Ity_I32);
7438
7439   assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7440   assign(op, get_gpr_w1(r3));
7441   put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7442              mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7443              binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7444
7445   return "rll";
7446}
7447
7448static const HChar *
7449s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7450{
7451   IRTemp amount = newTemp(Ity_I64);
7452   IRTemp op = newTemp(Ity_I64);
7453
7454   assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7455   assign(op, get_gpr_dw0(r3));
7456   put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7457               mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7458               binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7459
7460   return "rllg";
7461}
7462
7463static const HChar *
7464s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7465{
7466   UChar from;
7467   UChar to;
7468   UChar rot;
7469   UChar t_bit;
7470   ULong mask;
7471   ULong maskc;
7472   IRTemp result = newTemp(Ity_I64);
7473   IRTemp op2 = newTemp(Ity_I64);
7474
7475   from = i3 & 63;
7476   to = i4 & 63;
7477   rot = i5 & 63;
7478   t_bit = i3 & 128;
7479   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7480          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7481          mkU8(64 - rot))));
7482   if (from <= to) {
7483      mask = ~0ULL;
7484      mask = (mask >> from) & (mask << (63 - to));
7485      maskc = ~mask;
7486   } else {
7487      maskc = ~0ULL;
7488      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7489      mask = ~maskc;
7490   }
7491   assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7492          ), mkU64(mask)));
7493   if (t_bit == 0) {
7494      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7495                  mkU64(maskc)), mkexpr(result)));
7496   }
7497   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7498
7499   return "rnsbg";
7500}
7501
7502static const HChar *
7503s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7504{
7505   UChar from;
7506   UChar to;
7507   UChar rot;
7508   UChar t_bit;
7509   ULong mask;
7510   ULong maskc;
7511   IRTemp result = newTemp(Ity_I64);
7512   IRTemp op2 = newTemp(Ity_I64);
7513
7514   from = i3 & 63;
7515   to = i4 & 63;
7516   rot = i5 & 63;
7517   t_bit = i3 & 128;
7518   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7519          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7520          mkU8(64 - rot))));
7521   if (from <= to) {
7522      mask = ~0ULL;
7523      mask = (mask >> from) & (mask << (63 - to));
7524      maskc = ~mask;
7525   } else {
7526      maskc = ~0ULL;
7527      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7528      mask = ~maskc;
7529   }
7530   assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7531          ), mkU64(mask)));
7532   if (t_bit == 0) {
7533      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7534                  mkU64(maskc)), mkexpr(result)));
7535   }
7536   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7537
7538   return "rxsbg";
7539}
7540
7541static const HChar *
7542s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7543{
7544   UChar from;
7545   UChar to;
7546   UChar rot;
7547   UChar t_bit;
7548   ULong mask;
7549   ULong maskc;
7550   IRTemp result = newTemp(Ity_I64);
7551   IRTemp op2 = newTemp(Ity_I64);
7552
7553   from = i3 & 63;
7554   to = i4 & 63;
7555   rot = i5 & 63;
7556   t_bit = i3 & 128;
7557   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7558          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7559          mkU8(64 - rot))));
7560   if (from <= to) {
7561      mask = ~0ULL;
7562      mask = (mask >> from) & (mask << (63 - to));
7563      maskc = ~mask;
7564   } else {
7565      maskc = ~0ULL;
7566      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7567      mask = ~maskc;
7568   }
7569   assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7570          ), mkU64(mask)));
7571   if (t_bit == 0) {
7572      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7573                  mkU64(maskc)), mkexpr(result)));
7574   }
7575   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7576
7577   return "rosbg";
7578}
7579
7580static const HChar *
7581s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7582{
7583   UChar from;
7584   UChar to;
7585   UChar rot;
7586   UChar z_bit;
7587   ULong mask;
7588   ULong maskc;
7589   IRTemp op2 = newTemp(Ity_I64);
7590   IRTemp result = newTemp(Ity_I64);
7591
7592   from = i3 & 63;
7593   to = i4 & 63;
7594   rot = i5 & 63;
7595   z_bit = i4 & 128;
7596   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7597          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7598          mkU8(64 - rot))));
7599   if (from <= to) {
7600      mask = ~0ULL;
7601      mask = (mask >> from) & (mask << (63 - to));
7602      maskc = ~mask;
7603   } else {
7604      maskc = ~0ULL;
7605      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7606      mask = ~maskc;
7607   }
7608   if (z_bit == 0) {
7609      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7610                  mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7611   } else {
7612      put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7613   }
7614   assign(result, get_gpr_dw0(r1));
7615   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7616
7617   return "risbg";
7618}
7619
7620static const HChar *
7621s390_irgen_SAR(UChar r1, UChar r2)
7622{
7623   put_ar_w0(r1, get_gpr_w1(r2));
7624   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
7625      s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7626
7627   return "sar";
7628}
7629
7630static const HChar *
7631s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7632{
7633   IRTemp p1 = newTemp(Ity_I64);
7634   IRTemp p2 = newTemp(Ity_I64);
7635   IRTemp op = newTemp(Ity_I64);
7636   IRTemp result = newTemp(Ity_I64);
7637   ULong sign_mask;
7638   IRTemp shift_amount = newTemp(Ity_I64);
7639
7640   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7641   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7642   assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7643          ));
7644   sign_mask = 1ULL << 63;
7645   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7646   assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
7647          unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7648          binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
7649   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7650   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7651   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7652
7653   return "slda";
7654}
7655
7656static const HChar *
7657s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7658{
7659   IRTemp p1 = newTemp(Ity_I64);
7660   IRTemp p2 = newTemp(Ity_I64);
7661   IRTemp result = newTemp(Ity_I64);
7662
7663   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7664   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7665   assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7666          mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7667          mkexpr(op2addr), mkU64(63)))));
7668   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7669   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7670
7671   return "sldl";
7672}
7673
7674static const HChar *
7675s390_irgen_SLA(UChar r1, IRTemp op2addr)
7676{
7677   IRTemp uop = newTemp(Ity_I32);
7678   IRTemp result = newTemp(Ity_I32);
7679   UInt sign_mask;
7680   IRTemp shift_amount = newTemp(Ity_I64);
7681   IRTemp op = newTemp(Ity_I32);
7682
7683   assign(op, get_gpr_w1(r1));
7684   assign(uop, get_gpr_w1(r1));
7685   sign_mask = 2147483648U;
7686   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7687   assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7688          unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7689          binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7690   put_gpr_w1(r1, mkexpr(result));
7691   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7692
7693   return "sla";
7694}
7695
7696static const HChar *
7697s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7698{
7699   IRTemp uop = newTemp(Ity_I32);
7700   IRTemp result = newTemp(Ity_I32);
7701   UInt sign_mask;
7702   IRTemp shift_amount = newTemp(Ity_I64);
7703   IRTemp op = newTemp(Ity_I32);
7704
7705   assign(op, get_gpr_w1(r3));
7706   assign(uop, get_gpr_w1(r3));
7707   sign_mask = 2147483648U;
7708   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7709   assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7710          unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7711          binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7712   put_gpr_w1(r1, mkexpr(result));
7713   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7714
7715   return "slak";
7716}
7717
7718static const HChar *
7719s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7720{
7721   IRTemp uop = newTemp(Ity_I64);
7722   IRTemp result = newTemp(Ity_I64);
7723   ULong sign_mask;
7724   IRTemp shift_amount = newTemp(Ity_I64);
7725   IRTemp op = newTemp(Ity_I64);
7726
7727   assign(op, get_gpr_dw0(r3));
7728   assign(uop, get_gpr_dw0(r3));
7729   sign_mask = 9223372036854775808ULL;
7730   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7731   assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7732          unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7733          binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7734   put_gpr_dw0(r1, mkexpr(result));
7735   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7736
7737   return "slag";
7738}
7739
7740static const HChar *
7741s390_irgen_SLL(UChar r1, IRTemp op2addr)
7742{
7743   put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7744              binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7745
7746   return "sll";
7747}
7748
7749static const HChar *
7750s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7751{
7752   put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7753              binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7754
7755   return "sllk";
7756}
7757
7758static const HChar *
7759s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7760{
7761   put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7762               binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7763
7764   return "sllg";
7765}
7766
7767static const HChar *
7768s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7769{
7770   IRTemp p1 = newTemp(Ity_I64);
7771   IRTemp p2 = newTemp(Ity_I64);
7772   IRTemp result = newTemp(Ity_I64);
7773
7774   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7775   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7776   assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7777          mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7778          mkexpr(op2addr), mkU64(63)))));
7779   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7780   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7781   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7782
7783   return "srda";
7784}
7785
7786static const HChar *
7787s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7788{
7789   IRTemp p1 = newTemp(Ity_I64);
7790   IRTemp p2 = newTemp(Ity_I64);
7791   IRTemp result = newTemp(Ity_I64);
7792
7793   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7794   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7795   assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7796          mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7797          mkexpr(op2addr), mkU64(63)))));
7798   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7799   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7800
7801   return "srdl";
7802}
7803
7804static const HChar *
7805s390_irgen_SRA(UChar r1, IRTemp op2addr)
7806{
7807   IRTemp result = newTemp(Ity_I32);
7808   IRTemp op = newTemp(Ity_I32);
7809
7810   assign(op, get_gpr_w1(r1));
7811   assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7812          mkexpr(op2addr), mkU64(63)))));
7813   put_gpr_w1(r1, mkexpr(result));
7814   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7815
7816   return "sra";
7817}
7818
7819static const HChar *
7820s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7821{
7822   IRTemp result = newTemp(Ity_I32);
7823   IRTemp op = newTemp(Ity_I32);
7824
7825   assign(op, get_gpr_w1(r3));
7826   assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7827          mkexpr(op2addr), mkU64(63)))));
7828   put_gpr_w1(r1, mkexpr(result));
7829   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7830
7831   return "srak";
7832}
7833
7834static const HChar *
7835s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7836{
7837   IRTemp result = newTemp(Ity_I64);
7838   IRTemp op = newTemp(Ity_I64);
7839
7840   assign(op, get_gpr_dw0(r3));
7841   assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7842          mkexpr(op2addr), mkU64(63)))));
7843   put_gpr_dw0(r1, mkexpr(result));
7844   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7845
7846   return "srag";
7847}
7848
7849static const HChar *
7850s390_irgen_SRL(UChar r1, IRTemp op2addr)
7851{
7852   IRTemp op = newTemp(Ity_I32);
7853
7854   assign(op, get_gpr_w1(r1));
7855   put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7856              mkexpr(op2addr), mkU64(63)))));
7857
7858   return "srl";
7859}
7860
7861static const HChar *
7862s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7863{
7864   IRTemp op = newTemp(Ity_I32);
7865
7866   assign(op, get_gpr_w1(r3));
7867   put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7868              mkexpr(op2addr), mkU64(63)))));
7869
7870   return "srlk";
7871}
7872
7873static const HChar *
7874s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7875{
7876   IRTemp op = newTemp(Ity_I64);
7877
7878   assign(op, get_gpr_dw0(r3));
7879   put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7880               mkexpr(op2addr), mkU64(63)))));
7881
7882   return "srlg";
7883}
7884
7885static const HChar *
7886s390_irgen_ST(UChar r1, IRTemp op2addr)
7887{
7888   store(mkexpr(op2addr), get_gpr_w1(r1));
7889
7890   return "st";
7891}
7892
7893static const HChar *
7894s390_irgen_STY(UChar r1, IRTemp op2addr)
7895{
7896   store(mkexpr(op2addr), get_gpr_w1(r1));
7897
7898   return "sty";
7899}
7900
7901static const HChar *
7902s390_irgen_STG(UChar r1, IRTemp op2addr)
7903{
7904   store(mkexpr(op2addr), get_gpr_dw0(r1));
7905
7906   return "stg";
7907}
7908
7909static const HChar *
7910s390_irgen_STRL(UChar r1, UInt i2)
7911{
7912   store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7913         get_gpr_w1(r1));
7914
7915   return "strl";
7916}
7917
7918static const HChar *
7919s390_irgen_STGRL(UChar r1, UInt i2)
7920{
7921   store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7922         get_gpr_dw0(r1));
7923
7924   return "stgrl";
7925}
7926
7927static const HChar *
7928s390_irgen_STC(UChar r1, IRTemp op2addr)
7929{
7930   store(mkexpr(op2addr), get_gpr_b7(r1));
7931
7932   return "stc";
7933}
7934
7935static const HChar *
7936s390_irgen_STCY(UChar r1, IRTemp op2addr)
7937{
7938   store(mkexpr(op2addr), get_gpr_b7(r1));
7939
7940   return "stcy";
7941}
7942
7943static const HChar *
7944s390_irgen_STCH(UChar r1, IRTemp op2addr)
7945{
7946   store(mkexpr(op2addr), get_gpr_b3(r1));
7947
7948   return "stch";
7949}
7950
7951static const HChar *
7952s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7953{
7954   UChar mask;
7955   UChar n;
7956
7957   mask = (UChar)r3;
7958   n = 0;
7959   if ((mask & 8) != 0) {
7960      store(mkexpr(op2addr), get_gpr_b4(r1));
7961      n = n + 1;
7962   }
7963   if ((mask & 4) != 0) {
7964      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7965      n = n + 1;
7966   }
7967   if ((mask & 2) != 0) {
7968      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7969      n = n + 1;
7970   }
7971   if ((mask & 1) != 0) {
7972      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7973   }
7974
7975   return "stcm";
7976}
7977
7978static const HChar *
7979s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7980{
7981   UChar mask;
7982   UChar n;
7983
7984   mask = (UChar)r3;
7985   n = 0;
7986   if ((mask & 8) != 0) {
7987      store(mkexpr(op2addr), get_gpr_b4(r1));
7988      n = n + 1;
7989   }
7990   if ((mask & 4) != 0) {
7991      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7992      n = n + 1;
7993   }
7994   if ((mask & 2) != 0) {
7995      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7996      n = n + 1;
7997   }
7998   if ((mask & 1) != 0) {
7999      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
8000   }
8001
8002   return "stcmy";
8003}
8004
8005static const HChar *
8006s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
8007{
8008   UChar mask;
8009   UChar n;
8010
8011   mask = (UChar)r3;
8012   n = 0;
8013   if ((mask & 8) != 0) {
8014      store(mkexpr(op2addr), get_gpr_b0(r1));
8015      n = n + 1;
8016   }
8017   if ((mask & 4) != 0) {
8018      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
8019      n = n + 1;
8020   }
8021   if ((mask & 2) != 0) {
8022      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
8023      n = n + 1;
8024   }
8025   if ((mask & 1) != 0) {
8026      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
8027   }
8028
8029   return "stcmh";
8030}
8031
8032static const HChar *
8033s390_irgen_STH(UChar r1, IRTemp op2addr)
8034{
8035   store(mkexpr(op2addr), get_gpr_hw3(r1));
8036
8037   return "sth";
8038}
8039
8040static const HChar *
8041s390_irgen_STHY(UChar r1, IRTemp op2addr)
8042{
8043   store(mkexpr(op2addr), get_gpr_hw3(r1));
8044
8045   return "sthy";
8046}
8047
8048static const HChar *
8049s390_irgen_STHRL(UChar r1, UInt i2)
8050{
8051   store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8052         get_gpr_hw3(r1));
8053
8054   return "sthrl";
8055}
8056
8057static const HChar *
8058s390_irgen_STHH(UChar r1, IRTemp op2addr)
8059{
8060   store(mkexpr(op2addr), get_gpr_hw1(r1));
8061
8062   return "sthh";
8063}
8064
8065static const HChar *
8066s390_irgen_STFH(UChar r1, IRTemp op2addr)
8067{
8068   store(mkexpr(op2addr), get_gpr_w0(r1));
8069
8070   return "stfh";
8071}
8072
8073static const HChar *
8074s390_irgen_STOC(UChar r1, IRTemp op2addr)
8075{
8076   /* condition is checked in format handler */
8077   store(mkexpr(op2addr), get_gpr_w1(r1));
8078
8079   return "stoc";
8080}
8081
8082static const HChar *
8083s390_irgen_STOCG(UChar r1, IRTemp op2addr)
8084{
8085   /* condition is checked in format handler */
8086   store(mkexpr(op2addr), get_gpr_dw0(r1));
8087
8088   return "stocg";
8089}
8090
8091static const HChar *
8092s390_irgen_STPQ(UChar r1, IRTemp op2addr)
8093{
8094   store(mkexpr(op2addr), get_gpr_dw0(r1));
8095   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
8096
8097   return "stpq";
8098}
8099
8100static const HChar *
8101s390_irgen_STRVH(UChar r1, IRTemp op2addr)
8102{
8103   store(mkexpr(op2addr), get_gpr_b7(r1));
8104   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8105
8106   return "strvh";
8107}
8108
8109static const HChar *
8110s390_irgen_STRV(UChar r1, IRTemp op2addr)
8111{
8112   store(mkexpr(op2addr), get_gpr_b7(r1));
8113   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8114   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8115   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8116
8117   return "strv";
8118}
8119
8120static const HChar *
8121s390_irgen_STRVG(UChar r1, IRTemp op2addr)
8122{
8123   store(mkexpr(op2addr), get_gpr_b7(r1));
8124   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8125   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8126   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8127   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
8128   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
8129   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
8130   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
8131
8132   return "strvg";
8133}
8134
8135static const HChar *
8136s390_irgen_SR(UChar r1, UChar r2)
8137{
8138   IRTemp op1 = newTemp(Ity_I32);
8139   IRTemp op2 = newTemp(Ity_I32);
8140   IRTemp result = newTemp(Ity_I32);
8141
8142   assign(op1, get_gpr_w1(r1));
8143   assign(op2, get_gpr_w1(r2));
8144   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8145   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8146   put_gpr_w1(r1, mkexpr(result));
8147
8148   return "sr";
8149}
8150
8151static const HChar *
8152s390_irgen_SGR(UChar r1, UChar r2)
8153{
8154   IRTemp op1 = newTemp(Ity_I64);
8155   IRTemp op2 = newTemp(Ity_I64);
8156   IRTemp result = newTemp(Ity_I64);
8157
8158   assign(op1, get_gpr_dw0(r1));
8159   assign(op2, get_gpr_dw0(r2));
8160   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8161   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8162   put_gpr_dw0(r1, mkexpr(result));
8163
8164   return "sgr";
8165}
8166
8167static const HChar *
8168s390_irgen_SGFR(UChar r1, UChar r2)
8169{
8170   IRTemp op1 = newTemp(Ity_I64);
8171   IRTemp op2 = newTemp(Ity_I64);
8172   IRTemp result = newTemp(Ity_I64);
8173
8174   assign(op1, get_gpr_dw0(r1));
8175   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8176   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8177   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8178   put_gpr_dw0(r1, mkexpr(result));
8179
8180   return "sgfr";
8181}
8182
8183static const HChar *
8184s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8185{
8186   IRTemp op2 = newTemp(Ity_I32);
8187   IRTemp op3 = newTemp(Ity_I32);
8188   IRTemp result = newTemp(Ity_I32);
8189
8190   assign(op2, get_gpr_w1(r2));
8191   assign(op3, get_gpr_w1(r3));
8192   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8193   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8194   put_gpr_w1(r1, mkexpr(result));
8195
8196   return "srk";
8197}
8198
8199static const HChar *
8200s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8201{
8202   IRTemp op2 = newTemp(Ity_I64);
8203   IRTemp op3 = newTemp(Ity_I64);
8204   IRTemp result = newTemp(Ity_I64);
8205
8206   assign(op2, get_gpr_dw0(r2));
8207   assign(op3, get_gpr_dw0(r3));
8208   assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8209   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8210   put_gpr_dw0(r1, mkexpr(result));
8211
8212   return "sgrk";
8213}
8214
8215static const HChar *
8216s390_irgen_S(UChar r1, IRTemp op2addr)
8217{
8218   IRTemp op1 = newTemp(Ity_I32);
8219   IRTemp op2 = newTemp(Ity_I32);
8220   IRTemp result = newTemp(Ity_I32);
8221
8222   assign(op1, get_gpr_w1(r1));
8223   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8224   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8225   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8226   put_gpr_w1(r1, mkexpr(result));
8227
8228   return "s";
8229}
8230
8231static const HChar *
8232s390_irgen_SY(UChar r1, IRTemp op2addr)
8233{
8234   IRTemp op1 = newTemp(Ity_I32);
8235   IRTemp op2 = newTemp(Ity_I32);
8236   IRTemp result = newTemp(Ity_I32);
8237
8238   assign(op1, get_gpr_w1(r1));
8239   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8240   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8241   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8242   put_gpr_w1(r1, mkexpr(result));
8243
8244   return "sy";
8245}
8246
8247static const HChar *
8248s390_irgen_SG(UChar r1, IRTemp op2addr)
8249{
8250   IRTemp op1 = newTemp(Ity_I64);
8251   IRTemp op2 = newTemp(Ity_I64);
8252   IRTemp result = newTemp(Ity_I64);
8253
8254   assign(op1, get_gpr_dw0(r1));
8255   assign(op2, load(Ity_I64, mkexpr(op2addr)));
8256   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8257   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8258   put_gpr_dw0(r1, mkexpr(result));
8259
8260   return "sg";
8261}
8262
8263static const HChar *
8264s390_irgen_SGF(UChar r1, IRTemp op2addr)
8265{
8266   IRTemp op1 = newTemp(Ity_I64);
8267   IRTemp op2 = newTemp(Ity_I64);
8268   IRTemp result = newTemp(Ity_I64);
8269
8270   assign(op1, get_gpr_dw0(r1));
8271   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8272   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8273   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8274   put_gpr_dw0(r1, mkexpr(result));
8275
8276   return "sgf";
8277}
8278
8279static const HChar *
8280s390_irgen_SH(UChar r1, IRTemp op2addr)
8281{
8282   IRTemp op1 = newTemp(Ity_I32);
8283   IRTemp op2 = newTemp(Ity_I32);
8284   IRTemp result = newTemp(Ity_I32);
8285
8286   assign(op1, get_gpr_w1(r1));
8287   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8288   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8289   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8290   put_gpr_w1(r1, mkexpr(result));
8291
8292   return "sh";
8293}
8294
8295static const HChar *
8296s390_irgen_SHY(UChar r1, IRTemp op2addr)
8297{
8298   IRTemp op1 = newTemp(Ity_I32);
8299   IRTemp op2 = newTemp(Ity_I32);
8300   IRTemp result = newTemp(Ity_I32);
8301
8302   assign(op1, get_gpr_w1(r1));
8303   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8304   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8305   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8306   put_gpr_w1(r1, mkexpr(result));
8307
8308   return "shy";
8309}
8310
8311static const HChar *
8312s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8313{
8314   IRTemp op2 = newTemp(Ity_I32);
8315   IRTemp op3 = newTemp(Ity_I32);
8316   IRTemp result = newTemp(Ity_I32);
8317
8318   assign(op2, get_gpr_w0(r1));
8319   assign(op3, get_gpr_w0(r2));
8320   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8321   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8322   put_gpr_w0(r1, mkexpr(result));
8323
8324   return "shhhr";
8325}
8326
8327static const HChar *
8328s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8329{
8330   IRTemp op2 = newTemp(Ity_I32);
8331   IRTemp op3 = newTemp(Ity_I32);
8332   IRTemp result = newTemp(Ity_I32);
8333
8334   assign(op2, get_gpr_w0(r1));
8335   assign(op3, get_gpr_w1(r2));
8336   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8337   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8338   put_gpr_w0(r1, mkexpr(result));
8339
8340   return "shhlr";
8341}
8342
8343static const HChar *
8344s390_irgen_SLR(UChar r1, UChar r2)
8345{
8346   IRTemp op1 = newTemp(Ity_I32);
8347   IRTemp op2 = newTemp(Ity_I32);
8348   IRTemp result = newTemp(Ity_I32);
8349
8350   assign(op1, get_gpr_w1(r1));
8351   assign(op2, get_gpr_w1(r2));
8352   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8353   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8354   put_gpr_w1(r1, mkexpr(result));
8355
8356   return "slr";
8357}
8358
8359static const HChar *
8360s390_irgen_SLGR(UChar r1, UChar r2)
8361{
8362   IRTemp op1 = newTemp(Ity_I64);
8363   IRTemp op2 = newTemp(Ity_I64);
8364   IRTemp result = newTemp(Ity_I64);
8365
8366   assign(op1, get_gpr_dw0(r1));
8367   assign(op2, get_gpr_dw0(r2));
8368   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8369   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8370   put_gpr_dw0(r1, mkexpr(result));
8371
8372   return "slgr";
8373}
8374
8375static const HChar *
8376s390_irgen_SLGFR(UChar r1, UChar r2)
8377{
8378   IRTemp op1 = newTemp(Ity_I64);
8379   IRTemp op2 = newTemp(Ity_I64);
8380   IRTemp result = newTemp(Ity_I64);
8381
8382   assign(op1, get_gpr_dw0(r1));
8383   assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8384   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8385   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8386   put_gpr_dw0(r1, mkexpr(result));
8387
8388   return "slgfr";
8389}
8390
8391static const HChar *
8392s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8393{
8394   IRTemp op2 = newTemp(Ity_I32);
8395   IRTemp op3 = newTemp(Ity_I32);
8396   IRTemp result = newTemp(Ity_I32);
8397
8398   assign(op2, get_gpr_w1(r2));
8399   assign(op3, get_gpr_w1(r3));
8400   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8401   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8402   put_gpr_w1(r1, mkexpr(result));
8403
8404   return "slrk";
8405}
8406
8407static const HChar *
8408s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8409{
8410   IRTemp op2 = newTemp(Ity_I64);
8411   IRTemp op3 = newTemp(Ity_I64);
8412   IRTemp result = newTemp(Ity_I64);
8413
8414   assign(op2, get_gpr_dw0(r2));
8415   assign(op3, get_gpr_dw0(r3));
8416   assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8417   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8418   put_gpr_dw0(r1, mkexpr(result));
8419
8420   return "slgrk";
8421}
8422
8423static const HChar *
8424s390_irgen_SL(UChar r1, IRTemp op2addr)
8425{
8426   IRTemp op1 = newTemp(Ity_I32);
8427   IRTemp op2 = newTemp(Ity_I32);
8428   IRTemp result = newTemp(Ity_I32);
8429
8430   assign(op1, get_gpr_w1(r1));
8431   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8432   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8433   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8434   put_gpr_w1(r1, mkexpr(result));
8435
8436   return "sl";
8437}
8438
8439static const HChar *
8440s390_irgen_SLY(UChar r1, IRTemp op2addr)
8441{
8442   IRTemp op1 = newTemp(Ity_I32);
8443   IRTemp op2 = newTemp(Ity_I32);
8444   IRTemp result = newTemp(Ity_I32);
8445
8446   assign(op1, get_gpr_w1(r1));
8447   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8448   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8449   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8450   put_gpr_w1(r1, mkexpr(result));
8451
8452   return "sly";
8453}
8454
8455static const HChar *
8456s390_irgen_SLG(UChar r1, IRTemp op2addr)
8457{
8458   IRTemp op1 = newTemp(Ity_I64);
8459   IRTemp op2 = newTemp(Ity_I64);
8460   IRTemp result = newTemp(Ity_I64);
8461
8462   assign(op1, get_gpr_dw0(r1));
8463   assign(op2, load(Ity_I64, mkexpr(op2addr)));
8464   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8465   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8466   put_gpr_dw0(r1, mkexpr(result));
8467
8468   return "slg";
8469}
8470
8471static const HChar *
8472s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8473{
8474   IRTemp op1 = newTemp(Ity_I64);
8475   IRTemp op2 = newTemp(Ity_I64);
8476   IRTemp result = newTemp(Ity_I64);
8477
8478   assign(op1, get_gpr_dw0(r1));
8479   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8480   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8481   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8482   put_gpr_dw0(r1, mkexpr(result));
8483
8484   return "slgf";
8485}
8486
8487static const HChar *
8488s390_irgen_SLFI(UChar r1, UInt i2)
8489{
8490   IRTemp op1 = newTemp(Ity_I32);
8491   UInt op2;
8492   IRTemp result = newTemp(Ity_I32);
8493
8494   assign(op1, get_gpr_w1(r1));
8495   op2 = i2;
8496   assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8497   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8498                       mkU32(op2)));
8499   put_gpr_w1(r1, mkexpr(result));
8500
8501   return "slfi";
8502}
8503
8504static const HChar *
8505s390_irgen_SLGFI(UChar r1, UInt i2)
8506{
8507   IRTemp op1 = newTemp(Ity_I64);
8508   ULong op2;
8509   IRTemp result = newTemp(Ity_I64);
8510
8511   assign(op1, get_gpr_dw0(r1));
8512   op2 = (ULong)i2;
8513   assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8514   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8515                       mkU64(op2)));
8516   put_gpr_dw0(r1, mkexpr(result));
8517
8518   return "slgfi";
8519}
8520
8521static const HChar *
8522s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8523{
8524   IRTemp op2 = newTemp(Ity_I32);
8525   IRTemp op3 = newTemp(Ity_I32);
8526   IRTemp result = newTemp(Ity_I32);
8527
8528   assign(op2, get_gpr_w0(r1));
8529   assign(op3, get_gpr_w0(r2));
8530   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8531   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8532   put_gpr_w0(r1, mkexpr(result));
8533
8534   return "slhhhr";
8535}
8536
8537static const HChar *
8538s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8539{
8540   IRTemp op2 = newTemp(Ity_I32);
8541   IRTemp op3 = newTemp(Ity_I32);
8542   IRTemp result = newTemp(Ity_I32);
8543
8544   assign(op2, get_gpr_w0(r1));
8545   assign(op3, get_gpr_w1(r2));
8546   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8547   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8548   put_gpr_w0(r1, mkexpr(result));
8549
8550   return "slhhlr";
8551}
8552
8553static const HChar *
8554s390_irgen_SLBR(UChar r1, UChar r2)
8555{
8556   IRTemp op1 = newTemp(Ity_I32);
8557   IRTemp op2 = newTemp(Ity_I32);
8558   IRTemp result = newTemp(Ity_I32);
8559   IRTemp borrow_in = newTemp(Ity_I32);
8560
8561   assign(op1, get_gpr_w1(r1));
8562   assign(op2, get_gpr_w1(r2));
8563   assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8564          s390_call_calculate_cc(), mkU8(1))));
8565   assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8566          mkexpr(borrow_in)));
8567   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8568   put_gpr_w1(r1, mkexpr(result));
8569
8570   return "slbr";
8571}
8572
8573static const HChar *
8574s390_irgen_SLBGR(UChar r1, UChar r2)
8575{
8576   IRTemp op1 = newTemp(Ity_I64);
8577   IRTemp op2 = newTemp(Ity_I64);
8578   IRTemp result = newTemp(Ity_I64);
8579   IRTemp borrow_in = newTemp(Ity_I64);
8580
8581   assign(op1, get_gpr_dw0(r1));
8582   assign(op2, get_gpr_dw0(r2));
8583   assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8584          binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8585   assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8586          mkexpr(borrow_in)));
8587   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8588   put_gpr_dw0(r1, mkexpr(result));
8589
8590   return "slbgr";
8591}
8592
8593static const HChar *
8594s390_irgen_SLB(UChar r1, IRTemp op2addr)
8595{
8596   IRTemp op1 = newTemp(Ity_I32);
8597   IRTemp op2 = newTemp(Ity_I32);
8598   IRTemp result = newTemp(Ity_I32);
8599   IRTemp borrow_in = newTemp(Ity_I32);
8600
8601   assign(op1, get_gpr_w1(r1));
8602   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8603   assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8604          s390_call_calculate_cc(), mkU8(1))));
8605   assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8606          mkexpr(borrow_in)));
8607   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8608   put_gpr_w1(r1, mkexpr(result));
8609
8610   return "slb";
8611}
8612
8613static const HChar *
8614s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8615{
8616   IRTemp op1 = newTemp(Ity_I64);
8617   IRTemp op2 = newTemp(Ity_I64);
8618   IRTemp result = newTemp(Ity_I64);
8619   IRTemp borrow_in = newTemp(Ity_I64);
8620
8621   assign(op1, get_gpr_dw0(r1));
8622   assign(op2, load(Ity_I64, mkexpr(op2addr)));
8623   assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8624          binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8625   assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8626          mkexpr(borrow_in)));
8627   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8628   put_gpr_dw0(r1, mkexpr(result));
8629
8630   return "slbg";
8631}
8632
8633static const HChar *
8634s390_irgen_SVC(UChar i)
8635{
8636   IRTemp sysno = newTemp(Ity_I64);
8637
8638   if (i != 0) {
8639      assign(sysno, mkU64(i));
8640   } else {
8641      assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8642   }
8643   system_call(mkexpr(sysno));
8644
8645   return "svc";
8646}
8647
8648static const HChar *
8649s390_irgen_TM(UChar i2, IRTemp op1addr)
8650{
8651   UChar mask;
8652   IRTemp value = newTemp(Ity_I8);
8653
8654   mask = i2;
8655   assign(value, load(Ity_I8, mkexpr(op1addr)));
8656   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8657                       mkU8(mask)));
8658
8659   return "tm";
8660}
8661
8662static const HChar *
8663s390_irgen_TMY(UChar i2, IRTemp op1addr)
8664{
8665   UChar mask;
8666   IRTemp value = newTemp(Ity_I8);
8667
8668   mask = i2;
8669   assign(value, load(Ity_I8, mkexpr(op1addr)));
8670   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8671                       mkU8(mask)));
8672
8673   return "tmy";
8674}
8675
8676static const HChar *
8677s390_irgen_TMHH(UChar r1, UShort i2)
8678{
8679   UShort mask;
8680   IRTemp value = newTemp(Ity_I16);
8681
8682   mask = i2;
8683   assign(value, get_gpr_hw0(r1));
8684   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8685                       mkU16(mask)));
8686
8687   return "tmhh";
8688}
8689
8690static const HChar *
8691s390_irgen_TMHL(UChar r1, UShort i2)
8692{
8693   UShort mask;
8694   IRTemp value = newTemp(Ity_I16);
8695
8696   mask = i2;
8697   assign(value, get_gpr_hw1(r1));
8698   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8699                       mkU16(mask)));
8700
8701   return "tmhl";
8702}
8703
8704static const HChar *
8705s390_irgen_TMLH(UChar r1, UShort i2)
8706{
8707   UShort mask;
8708   IRTemp value = newTemp(Ity_I16);
8709
8710   mask = i2;
8711   assign(value, get_gpr_hw2(r1));
8712   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8713                       mkU16(mask)));
8714
8715   return "tmlh";
8716}
8717
8718static const HChar *
8719s390_irgen_TMLL(UChar r1, UShort i2)
8720{
8721   UShort mask;
8722   IRTemp value = newTemp(Ity_I16);
8723
8724   mask = i2;
8725   assign(value, get_gpr_hw3(r1));
8726   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8727                       mkU16(mask)));
8728
8729   return "tmll";
8730}
8731
8732static const HChar *
8733s390_irgen_EFPC(UChar r1)
8734{
8735   put_gpr_w1(r1, get_fpc_w0());
8736
8737   return "efpc";
8738}
8739
8740static const HChar *
8741s390_irgen_LER(UChar r1, UChar r2)
8742{
8743   put_fpr_w0(r1, get_fpr_w0(r2));
8744
8745   return "ler";
8746}
8747
8748static const HChar *
8749s390_irgen_LDR(UChar r1, UChar r2)
8750{
8751   put_fpr_dw0(r1, get_fpr_dw0(r2));
8752
8753   return "ldr";
8754}
8755
8756static const HChar *
8757s390_irgen_LXR(UChar r1, UChar r2)
8758{
8759   put_fpr_dw0(r1, get_fpr_dw0(r2));
8760   put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8761
8762   return "lxr";
8763}
8764
8765static const HChar *
8766s390_irgen_LE(UChar r1, IRTemp op2addr)
8767{
8768   put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8769
8770   return "le";
8771}
8772
8773static const HChar *
8774s390_irgen_LD(UChar r1, IRTemp op2addr)
8775{
8776   put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8777
8778   return "ld";
8779}
8780
8781static const HChar *
8782s390_irgen_LEY(UChar r1, IRTemp op2addr)
8783{
8784   put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8785
8786   return "ley";
8787}
8788
8789static const HChar *
8790s390_irgen_LDY(UChar r1, IRTemp op2addr)
8791{
8792   put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8793
8794   return "ldy";
8795}
8796
8797static const HChar *
8798s390_irgen_LFPC(IRTemp op2addr)
8799{
8800   put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8801
8802   return "lfpc";
8803}
8804
8805static const HChar *
8806s390_irgen_LZER(UChar r1)
8807{
8808   put_fpr_w0(r1, mkF32i(0x0));
8809
8810   return "lzer";
8811}
8812
8813static const HChar *
8814s390_irgen_LZDR(UChar r1)
8815{
8816   put_fpr_dw0(r1, mkF64i(0x0));
8817
8818   return "lzdr";
8819}
8820
8821static const HChar *
8822s390_irgen_LZXR(UChar r1)
8823{
8824   put_fpr_dw0(r1, mkF64i(0x0));
8825   put_fpr_dw0(r1 + 2, mkF64i(0x0));
8826
8827   return "lzxr";
8828}
8829
8830static const HChar *
8831s390_irgen_SRNM(IRTemp op2addr)
8832{
8833   UInt input_mask, fpc_mask;
8834
8835   input_mask = 3;
8836   fpc_mask = s390_host_has_fpext ? 7 : 3;
8837
8838   put_fpc_w0(binop(Iop_Or32,
8839                    binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8840                    binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8841                          mkU32(input_mask))));
8842   return "srnm";
8843}
8844
8845static const HChar *
8846s390_irgen_SRNMB(IRTemp op2addr)
8847{
8848   UInt input_mask, fpc_mask;
8849
8850   input_mask = 7;
8851   fpc_mask = 7;
8852
8853   put_fpc_w0(binop(Iop_Or32,
8854                    binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8855                    binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8856                          mkU32(input_mask))));
8857   return "srnmb";
8858}
8859
8860static void
8861s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8862{
8863   if (b2 == 0) {  /* This is the typical case */
8864      if (d2 > 3) {
8865         if (s390_host_has_fpext && d2 == 7) {
8866            /* ok */
8867         } else {
8868            emulation_warning(EmWarn_S390X_invalid_rounding);
8869            d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
8870         }
8871      }
8872   }
8873
8874   s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8875}
8876
8877/* Wrapper to validate the parameter as in SRNMB is not required, as all
8878   the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8879static const HChar *
8880s390_irgen_SRNMT(IRTemp op2addr)
8881{
8882   UInt input_mask, fpc_mask;
8883
8884   input_mask = 7;
8885   fpc_mask = 0x70;
8886
8887   /* fpc[25:27] <- op2addr[61:63]
8888      fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8889   put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8890                    binop(Iop_Shl32, binop(Iop_And32,
8891                                           unop(Iop_64to32, mkexpr(op2addr)),
8892                                           mkU32(input_mask)), mkU8(4))));
8893   return "srnmt";
8894}
8895
8896
8897static const HChar *
8898s390_irgen_SFPC(UChar r1)
8899{
8900   put_fpc_w0(get_gpr_w1(r1));
8901
8902   return "sfpc";
8903}
8904
8905static const HChar *
8906s390_irgen_STE(UChar r1, IRTemp op2addr)
8907{
8908   store(mkexpr(op2addr), get_fpr_w0(r1));
8909
8910   return "ste";
8911}
8912
8913static const HChar *
8914s390_irgen_STD(UChar r1, IRTemp op2addr)
8915{
8916   store(mkexpr(op2addr), get_fpr_dw0(r1));
8917
8918   return "std";
8919}
8920
8921static const HChar *
8922s390_irgen_STEY(UChar r1, IRTemp op2addr)
8923{
8924   store(mkexpr(op2addr), get_fpr_w0(r1));
8925
8926   return "stey";
8927}
8928
8929static const HChar *
8930s390_irgen_STDY(UChar r1, IRTemp op2addr)
8931{
8932   store(mkexpr(op2addr), get_fpr_dw0(r1));
8933
8934   return "stdy";
8935}
8936
8937static const HChar *
8938s390_irgen_STFPC(IRTemp op2addr)
8939{
8940   store(mkexpr(op2addr), get_fpc_w0());
8941
8942   return "stfpc";
8943}
8944
8945static const HChar *
8946s390_irgen_AEBR(UChar r1, UChar r2)
8947{
8948   IRTemp op1 = newTemp(Ity_F32);
8949   IRTemp op2 = newTemp(Ity_F32);
8950   IRTemp result = newTemp(Ity_F32);
8951   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
8952
8953   assign(op1, get_fpr_w0(r1));
8954   assign(op2, get_fpr_w0(r2));
8955   assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
8956          mkexpr(op2)));
8957   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8958   put_fpr_w0(r1, mkexpr(result));
8959
8960   return "aebr";
8961}
8962
8963static const HChar *
8964s390_irgen_ADBR(UChar r1, UChar r2)
8965{
8966   IRTemp op1 = newTemp(Ity_F64);
8967   IRTemp op2 = newTemp(Ity_F64);
8968   IRTemp result = newTemp(Ity_F64);
8969   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
8970
8971   assign(op1, get_fpr_dw0(r1));
8972   assign(op2, get_fpr_dw0(r2));
8973   assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
8974          mkexpr(op2)));
8975   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8976   put_fpr_dw0(r1, mkexpr(result));
8977
8978   return "adbr";
8979}
8980
8981static const HChar *
8982s390_irgen_AEB(UChar r1, IRTemp op2addr)
8983{
8984   IRTemp op1 = newTemp(Ity_F32);
8985   IRTemp op2 = newTemp(Ity_F32);
8986   IRTemp result = newTemp(Ity_F32);
8987   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
8988
8989   assign(op1, get_fpr_w0(r1));
8990   assign(op2, load(Ity_F32, mkexpr(op2addr)));
8991   assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
8992          mkexpr(op2)));
8993   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8994   put_fpr_w0(r1, mkexpr(result));
8995
8996   return "aeb";
8997}
8998
8999static const HChar *
9000s390_irgen_ADB(UChar r1, IRTemp op2addr)
9001{
9002   IRTemp op1 = newTemp(Ity_F64);
9003   IRTemp op2 = newTemp(Ity_F64);
9004   IRTemp result = newTemp(Ity_F64);
9005   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9006
9007   assign(op1, get_fpr_dw0(r1));
9008   assign(op2, load(Ity_F64, mkexpr(op2addr)));
9009   assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
9010          mkexpr(op2)));
9011   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9012   put_fpr_dw0(r1, mkexpr(result));
9013
9014   return "adb";
9015}
9016
9017static const HChar *
9018s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
9019                 UChar r1, UChar r2)
9020{
9021   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9022      emulation_warning(EmWarn_S390X_fpext_rounding);
9023      m3 = S390_BFP_ROUND_PER_FPC;
9024   }
9025   IRTemp op2 = newTemp(Ity_I32);
9026
9027   assign(op2, get_gpr_w1(r2));
9028   put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9029                        mkexpr(op2)));
9030
9031   return "cefbr";
9032}
9033
9034static const HChar *
9035s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
9036                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9037{
9038   IRTemp op2 = newTemp(Ity_I32);
9039
9040   assign(op2, get_gpr_w1(r2));
9041   put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
9042
9043   return "cdfbr";
9044}
9045
9046static const HChar *
9047s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
9048                 UChar r1, UChar r2)
9049{
9050   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9051      emulation_warning(EmWarn_S390X_fpext_rounding);
9052      m3 = S390_BFP_ROUND_PER_FPC;
9053   }
9054   IRTemp op2 = newTemp(Ity_I64);
9055
9056   assign(op2, get_gpr_dw0(r2));
9057   put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9058                        mkexpr(op2)));
9059
9060   return "cegbr";
9061}
9062
9063static const HChar *
9064s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
9065                 UChar r1, UChar r2)
9066{
9067   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9068      emulation_warning(EmWarn_S390X_fpext_rounding);
9069      m3 = S390_BFP_ROUND_PER_FPC;
9070   }
9071   IRTemp op2 = newTemp(Ity_I64);
9072
9073   assign(op2, get_gpr_dw0(r2));
9074   put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
9075                         mkexpr(op2)));
9076
9077   return "cdgbr";
9078}
9079
9080static const HChar *
9081s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
9082                  UChar r1, UChar r2)
9083{
9084   if (! s390_host_has_fpext) {
9085      emulation_failure(EmFail_S390X_fpext);
9086   } else {
9087      IRTemp op2 = newTemp(Ity_I32);
9088
9089      assign(op2, get_gpr_w1(r2));
9090      put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9091                           mkexpr(op2)));
9092   }
9093   return "celfbr";
9094}
9095
9096static const HChar *
9097s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
9098                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9099{
9100   if (! s390_host_has_fpext) {
9101      emulation_failure(EmFail_S390X_fpext);
9102   } else {
9103      IRTemp op2 = newTemp(Ity_I32);
9104
9105      assign(op2, get_gpr_w1(r2));
9106      put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
9107   }
9108   return "cdlfbr";
9109}
9110
9111static const HChar *
9112s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
9113                  UChar r1, UChar r2)
9114{
9115   if (! s390_host_has_fpext) {
9116      emulation_failure(EmFail_S390X_fpext);
9117   } else {
9118      IRTemp op2 = newTemp(Ity_I64);
9119
9120      assign(op2, get_gpr_dw0(r2));
9121      put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9122                           mkexpr(op2)));
9123   }
9124   return "celgbr";
9125}
9126
9127static const HChar *
9128s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
9129                  UChar r1, UChar r2)
9130{
9131   if (! s390_host_has_fpext) {
9132      emulation_failure(EmFail_S390X_fpext);
9133   } else {
9134      IRTemp op2 = newTemp(Ity_I64);
9135
9136      assign(op2, get_gpr_dw0(r2));
9137      put_fpr_dw0(r1, binop(Iop_I64UtoF64,
9138                            mkexpr(encode_bfp_rounding_mode(m3)),
9139                            mkexpr(op2)));
9140   }
9141   return "cdlgbr";
9142}
9143
9144static const HChar *
9145s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9146                  UChar r1, UChar r2)
9147{
9148   if (! s390_host_has_fpext) {
9149      emulation_failure(EmFail_S390X_fpext);
9150   } else {
9151      IRTemp op = newTemp(Ity_F32);
9152      IRTemp result = newTemp(Ity_I32);
9153      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9154
9155      assign(op, get_fpr_w0(r2));
9156      assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
9157                           mkexpr(op)));
9158      put_gpr_w1(r1, mkexpr(result));
9159      s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
9160   }
9161   return "clfebr";
9162}
9163
9164static const HChar *
9165s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9166                  UChar r1, UChar r2)
9167{
9168   if (! s390_host_has_fpext) {
9169      emulation_failure(EmFail_S390X_fpext);
9170   } else {
9171      IRTemp op = newTemp(Ity_F64);
9172      IRTemp result = newTemp(Ity_I32);
9173      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9174
9175      assign(op, get_fpr_dw0(r2));
9176      assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
9177                           mkexpr(op)));
9178      put_gpr_w1(r1, mkexpr(result));
9179      s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
9180   }
9181   return "clfdbr";
9182}
9183
9184static const HChar *
9185s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9186                  UChar r1, UChar r2)
9187{
9188   if (! s390_host_has_fpext) {
9189      emulation_failure(EmFail_S390X_fpext);
9190   } else {
9191      IRTemp op = newTemp(Ity_F32);
9192      IRTemp result = newTemp(Ity_I64);
9193      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9194
9195      assign(op, get_fpr_w0(r2));
9196      assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
9197                           mkexpr(op)));
9198      put_gpr_dw0(r1, mkexpr(result));
9199      s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
9200   }
9201   return "clgebr";
9202}
9203
9204static const HChar *
9205s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9206                  UChar r1, UChar r2)
9207{
9208   if (! s390_host_has_fpext) {
9209      emulation_failure(EmFail_S390X_fpext);
9210   } else {
9211      IRTemp op = newTemp(Ity_F64);
9212      IRTemp result = newTemp(Ity_I64);
9213      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9214
9215      assign(op, get_fpr_dw0(r2));
9216      assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
9217                           mkexpr(op)));
9218      put_gpr_dw0(r1, mkexpr(result));
9219      s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
9220   }
9221   return "clgdbr";
9222}
9223
9224static const HChar *
9225s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9226                 UChar r1, UChar r2)
9227{
9228   IRTemp op = newTemp(Ity_F32);
9229   IRTemp result = newTemp(Ity_I32);
9230   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9231
9232   assign(op, get_fpr_w0(r2));
9233   assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
9234          mkexpr(op)));
9235   put_gpr_w1(r1, mkexpr(result));
9236   s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
9237
9238   return "cfebr";
9239}
9240
9241static const HChar *
9242s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9243                 UChar r1, UChar r2)
9244{
9245   IRTemp op = newTemp(Ity_F64);
9246   IRTemp result = newTemp(Ity_I32);
9247   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9248
9249   assign(op, get_fpr_dw0(r2));
9250   assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
9251          mkexpr(op)));
9252   put_gpr_w1(r1, mkexpr(result));
9253   s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
9254
9255   return "cfdbr";
9256}
9257
9258static const HChar *
9259s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9260                 UChar r1, UChar r2)
9261{
9262   IRTemp op = newTemp(Ity_F32);
9263   IRTemp result = newTemp(Ity_I64);
9264   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9265
9266   assign(op, get_fpr_w0(r2));
9267   assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
9268          mkexpr(op)));
9269   put_gpr_dw0(r1, mkexpr(result));
9270   s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
9271
9272   return "cgebr";
9273}
9274
9275static const HChar *
9276s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9277                 UChar r1, UChar r2)
9278{
9279   IRTemp op = newTemp(Ity_F64);
9280   IRTemp result = newTemp(Ity_I64);
9281   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9282
9283   assign(op, get_fpr_dw0(r2));
9284   assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
9285          mkexpr(op)));
9286   put_gpr_dw0(r1, mkexpr(result));
9287   s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
9288
9289   return "cgdbr";
9290}
9291
9292static const HChar *
9293s390_irgen_DEBR(UChar r1, UChar r2)
9294{
9295   IRTemp op1 = newTemp(Ity_F32);
9296   IRTemp op2 = newTemp(Ity_F32);
9297   IRTemp result = newTemp(Ity_F32);
9298   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9299
9300   assign(op1, get_fpr_w0(r1));
9301   assign(op2, get_fpr_w0(r2));
9302   assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
9303          mkexpr(op2)));
9304   put_fpr_w0(r1, mkexpr(result));
9305
9306   return "debr";
9307}
9308
9309static const HChar *
9310s390_irgen_DDBR(UChar r1, UChar r2)
9311{
9312   IRTemp op1 = newTemp(Ity_F64);
9313   IRTemp op2 = newTemp(Ity_F64);
9314   IRTemp result = newTemp(Ity_F64);
9315   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9316
9317   assign(op1, get_fpr_dw0(r1));
9318   assign(op2, get_fpr_dw0(r2));
9319   assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
9320          mkexpr(op2)));
9321   put_fpr_dw0(r1, mkexpr(result));
9322
9323   return "ddbr";
9324}
9325
9326static const HChar *
9327s390_irgen_DEB(UChar r1, IRTemp op2addr)
9328{
9329   IRTemp op1 = newTemp(Ity_F32);
9330   IRTemp op2 = newTemp(Ity_F32);
9331   IRTemp result = newTemp(Ity_F32);
9332   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9333
9334   assign(op1, get_fpr_w0(r1));
9335   assign(op2, load(Ity_F32, mkexpr(op2addr)));
9336   assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
9337          mkexpr(op2)));
9338   put_fpr_w0(r1, mkexpr(result));
9339
9340   return "deb";
9341}
9342
9343static const HChar *
9344s390_irgen_DDB(UChar r1, IRTemp op2addr)
9345{
9346   IRTemp op1 = newTemp(Ity_F64);
9347   IRTemp op2 = newTemp(Ity_F64);
9348   IRTemp result = newTemp(Ity_F64);
9349   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9350
9351   assign(op1, get_fpr_dw0(r1));
9352   assign(op2, load(Ity_F64, mkexpr(op2addr)));
9353   assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
9354          mkexpr(op2)));
9355   put_fpr_dw0(r1, mkexpr(result));
9356
9357   return "ddb";
9358}
9359
9360static const HChar *
9361s390_irgen_LTEBR(UChar r1, UChar r2)
9362{
9363   IRTemp result = newTemp(Ity_F32);
9364
9365   assign(result, get_fpr_w0(r2));
9366   put_fpr_w0(r1, mkexpr(result));
9367   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9368
9369   return "ltebr";
9370}
9371
9372static const HChar *
9373s390_irgen_LTDBR(UChar r1, UChar r2)
9374{
9375   IRTemp result = newTemp(Ity_F64);
9376
9377   assign(result, get_fpr_dw0(r2));
9378   put_fpr_dw0(r1, mkexpr(result));
9379   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9380
9381   return "ltdbr";
9382}
9383
9384static const HChar *
9385s390_irgen_LCEBR(UChar r1, UChar r2)
9386{
9387   IRTemp result = newTemp(Ity_F32);
9388
9389   assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9390   put_fpr_w0(r1, mkexpr(result));
9391   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9392
9393   return "lcebr";
9394}
9395
9396static const HChar *
9397s390_irgen_LCDBR(UChar r1, UChar r2)
9398{
9399   IRTemp result = newTemp(Ity_F64);
9400
9401   assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9402   put_fpr_dw0(r1, mkexpr(result));
9403   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9404
9405   return "lcdbr";
9406}
9407
9408static const HChar *
9409s390_irgen_LDEBR(UChar r1, UChar r2)
9410{
9411   IRTemp op = newTemp(Ity_F32);
9412
9413   assign(op, get_fpr_w0(r2));
9414   put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9415
9416   return "ldebr";
9417}
9418
9419static const HChar *
9420s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9421{
9422   IRTemp op = newTemp(Ity_F32);
9423
9424   assign(op, load(Ity_F32, mkexpr(op2addr)));
9425   put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9426
9427   return "ldeb";
9428}
9429
9430static const HChar *
9431s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9432                 UChar r1, UChar r2)
9433{
9434   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9435      emulation_warning(EmWarn_S390X_fpext_rounding);
9436      m3 = S390_BFP_ROUND_PER_FPC;
9437   }
9438   IRTemp op = newTemp(Ity_F64);
9439
9440   assign(op, get_fpr_dw0(r2));
9441   put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
9442                        mkexpr(op)));
9443
9444   return "ledbr";
9445}
9446
9447static const HChar *
9448s390_irgen_MEEBR(UChar r1, UChar r2)
9449{
9450   IRTemp op1 = newTemp(Ity_F32);
9451   IRTemp op2 = newTemp(Ity_F32);
9452   IRTemp result = newTemp(Ity_F32);
9453   IRRoundingMode rounding_mode =
9454      encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9455
9456   assign(op1, get_fpr_w0(r1));
9457   assign(op2, get_fpr_w0(r2));
9458   assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
9459          mkexpr(op2)));
9460   put_fpr_w0(r1, mkexpr(result));
9461
9462   return "meebr";
9463}
9464
9465static const HChar *
9466s390_irgen_MDBR(UChar r1, UChar r2)
9467{
9468   IRTemp op1 = newTemp(Ity_F64);
9469   IRTemp op2 = newTemp(Ity_F64);
9470   IRTemp result = newTemp(Ity_F64);
9471   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9472
9473   assign(op1, get_fpr_dw0(r1));
9474   assign(op2, get_fpr_dw0(r2));
9475   assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
9476          mkexpr(op2)));
9477   put_fpr_dw0(r1, mkexpr(result));
9478
9479   return "mdbr";
9480}
9481
9482static const HChar *
9483s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9484{
9485   IRTemp op1 = newTemp(Ity_F32);
9486   IRTemp op2 = newTemp(Ity_F32);
9487   IRTemp result = newTemp(Ity_F32);
9488   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9489
9490   assign(op1, get_fpr_w0(r1));
9491   assign(op2, load(Ity_F32, mkexpr(op2addr)));
9492   assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
9493          mkexpr(op2)));
9494   put_fpr_w0(r1, mkexpr(result));
9495
9496   return "meeb";
9497}
9498
9499static const HChar *
9500s390_irgen_MDB(UChar r1, IRTemp op2addr)
9501{
9502   IRTemp op1 = newTemp(Ity_F64);
9503   IRTemp op2 = newTemp(Ity_F64);
9504   IRTemp result = newTemp(Ity_F64);
9505   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9506
9507   assign(op1, get_fpr_dw0(r1));
9508   assign(op2, load(Ity_F64, mkexpr(op2addr)));
9509   assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
9510          mkexpr(op2)));
9511   put_fpr_dw0(r1, mkexpr(result));
9512
9513   return "mdb";
9514}
9515
9516static const HChar *
9517s390_irgen_SEBR(UChar r1, UChar r2)
9518{
9519   IRTemp op1 = newTemp(Ity_F32);
9520   IRTemp op2 = newTemp(Ity_F32);
9521   IRTemp result = newTemp(Ity_F32);
9522   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9523
9524   assign(op1, get_fpr_w0(r1));
9525   assign(op2, get_fpr_w0(r2));
9526   assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
9527          mkexpr(op2)));
9528   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9529   put_fpr_w0(r1, mkexpr(result));
9530
9531   return "sebr";
9532}
9533
9534static const HChar *
9535s390_irgen_SDBR(UChar r1, UChar r2)
9536{
9537   IRTemp op1 = newTemp(Ity_F64);
9538   IRTemp op2 = newTemp(Ity_F64);
9539   IRTemp result = newTemp(Ity_F64);
9540   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9541
9542   assign(op1, get_fpr_dw0(r1));
9543   assign(op2, get_fpr_dw0(r2));
9544   assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
9545          mkexpr(op2)));
9546   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9547   put_fpr_dw0(r1, mkexpr(result));
9548
9549   return "sdbr";
9550}
9551
9552static const HChar *
9553s390_irgen_SEB(UChar r1, IRTemp op2addr)
9554{
9555   IRTemp op1 = newTemp(Ity_F32);
9556   IRTemp op2 = newTemp(Ity_F32);
9557   IRTemp result = newTemp(Ity_F32);
9558   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9559
9560   assign(op1, get_fpr_w0(r1));
9561   assign(op2, load(Ity_F32, mkexpr(op2addr)));
9562   assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
9563          mkexpr(op2)));
9564   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9565   put_fpr_w0(r1, mkexpr(result));
9566
9567   return "seb";
9568}
9569
9570static const HChar *
9571s390_irgen_SDB(UChar r1, IRTemp op2addr)
9572{
9573   IRTemp op1 = newTemp(Ity_F64);
9574   IRTemp op2 = newTemp(Ity_F64);
9575   IRTemp result = newTemp(Ity_F64);
9576   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9577
9578   assign(op1, get_fpr_dw0(r1));
9579   assign(op2, load(Ity_F64, mkexpr(op2addr)));
9580   assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
9581          mkexpr(op2)));
9582   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9583   put_fpr_dw0(r1, mkexpr(result));
9584
9585   return "sdb";
9586}
9587
9588static const HChar *
9589s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9590{
9591   if (! s390_host_has_dfp) {
9592      emulation_failure(EmFail_S390X_DFP_insn);
9593   } else {
9594      IRTemp op1 = newTemp(Ity_D64);
9595      IRTemp op2 = newTemp(Ity_D64);
9596      IRTemp result = newTemp(Ity_D64);
9597      IRTemp rounding_mode;
9598
9599      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9600         emulation_warning(EmWarn_S390X_fpext_rounding);
9601         m4 = S390_DFP_ROUND_PER_FPC_0;
9602      }
9603
9604      rounding_mode = encode_dfp_rounding_mode(m4);
9605      assign(op1, get_dpr_dw0(r2));
9606      assign(op2, get_dpr_dw0(r3));
9607      assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9608                           mkexpr(op2)));
9609      s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9610      put_dpr_dw0(r1, mkexpr(result));
9611   }
9612   return (m4 == 0) ? "adtr" : "adtra";
9613}
9614
9615static const HChar *
9616s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9617{
9618   if (! s390_host_has_dfp) {
9619      emulation_failure(EmFail_S390X_DFP_insn);
9620   } else {
9621      IRTemp op1 = newTemp(Ity_D128);
9622      IRTemp op2 = newTemp(Ity_D128);
9623      IRTemp result = newTemp(Ity_D128);
9624      IRTemp rounding_mode;
9625
9626      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9627         emulation_warning(EmWarn_S390X_fpext_rounding);
9628         m4 = S390_DFP_ROUND_PER_FPC_0;
9629      }
9630
9631      rounding_mode = encode_dfp_rounding_mode(m4);
9632      assign(op1, get_dpr_pair(r2));
9633      assign(op2, get_dpr_pair(r3));
9634      assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9635                           mkexpr(op2)));
9636      put_dpr_pair(r1, mkexpr(result));
9637
9638      s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9639   }
9640   return (m4 == 0) ? "axtr" : "axtra";
9641}
9642
9643static const HChar *
9644s390_irgen_CDTR(UChar r1, UChar r2)
9645{
9646   IRTemp op1 = newTemp(Ity_D64);
9647   IRTemp op2 = newTemp(Ity_D64);
9648   IRTemp cc_vex  = newTemp(Ity_I32);
9649   IRTemp cc_s390 = newTemp(Ity_I32);
9650
9651   assign(op1, get_dpr_dw0(r1));
9652   assign(op2, get_dpr_dw0(r2));
9653   assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9654
9655   assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9656   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9657
9658   return "cdtr";
9659}
9660
9661static const HChar *
9662s390_irgen_CXTR(UChar r1, UChar r2)
9663{
9664   IRTemp op1 = newTemp(Ity_D128);
9665   IRTemp op2 = newTemp(Ity_D128);
9666   IRTemp cc_vex  = newTemp(Ity_I32);
9667   IRTemp cc_s390 = newTemp(Ity_I32);
9668
9669   assign(op1, get_dpr_pair(r1));
9670   assign(op2, get_dpr_pair(r2));
9671   assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9672
9673   assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9674   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9675
9676   return "cxtr";
9677}
9678
9679static const HChar *
9680s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9681                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9682{
9683   if (! s390_host_has_dfp) {
9684      emulation_failure(EmFail_S390X_DFP_insn);
9685   } else {
9686      if (! s390_host_has_fpext) {
9687         emulation_failure(EmFail_S390X_fpext);
9688      } else {
9689         IRTemp op2 = newTemp(Ity_I32);
9690
9691         assign(op2, get_gpr_w1(r2));
9692         put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9693      }
9694   }
9695   return "cdftr";
9696}
9697
9698static const HChar *
9699s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9700                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9701{
9702   if (! s390_host_has_dfp) {
9703      emulation_failure(EmFail_S390X_DFP_insn);
9704   } else {
9705      if (! s390_host_has_fpext) {
9706         emulation_failure(EmFail_S390X_fpext);
9707      } else {
9708         IRTemp op2 = newTemp(Ity_I32);
9709
9710         assign(op2, get_gpr_w1(r2));
9711         put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9712      }
9713   }
9714   return "cxftr";
9715}
9716
9717static const HChar *
9718s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9719                  UChar r1, UChar r2)
9720{
9721   if (! s390_host_has_dfp) {
9722      emulation_failure(EmFail_S390X_DFP_insn);
9723   } else {
9724      IRTemp op2 = newTemp(Ity_I64);
9725
9726      if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9727         emulation_warning(EmWarn_S390X_fpext_rounding);
9728         m3 = S390_DFP_ROUND_PER_FPC_0;
9729      }
9730
9731      assign(op2, get_gpr_dw0(r2));
9732      put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9733                            mkexpr(op2)));
9734   }
9735   return (m3 == 0) ? "cdgtr" : "cdgtra";
9736}
9737
9738static const HChar *
9739s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9740                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9741{
9742   if (! s390_host_has_dfp) {
9743      emulation_failure(EmFail_S390X_DFP_insn);
9744   } else {
9745      IRTemp op2 = newTemp(Ity_I64);
9746
9747      /* No emulation warning here about an non-zero m3 on hosts without
9748         floating point extension facility. No rounding is performed */
9749
9750      assign(op2, get_gpr_dw0(r2));
9751      put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9752   }
9753   return "cxgtr";
9754}
9755
9756static const HChar *
9757s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9758                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9759{
9760   if (! s390_host_has_dfp) {
9761      emulation_failure(EmFail_S390X_DFP_insn);
9762   } else {
9763      if (! s390_host_has_fpext) {
9764         emulation_failure(EmFail_S390X_fpext);
9765      } else {
9766         IRTemp op2 = newTemp(Ity_I32);
9767
9768         assign(op2, get_gpr_w1(r2));
9769         put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9770      }
9771   }
9772   return "cdlftr";
9773}
9774
9775static const HChar *
9776s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9777                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9778{
9779   if (! s390_host_has_dfp) {
9780      emulation_failure(EmFail_S390X_DFP_insn);
9781   } else {
9782      if (! s390_host_has_fpext) {
9783         emulation_failure(EmFail_S390X_fpext);
9784      } else {
9785         IRTemp op2 = newTemp(Ity_I32);
9786
9787         assign(op2, get_gpr_w1(r2));
9788         put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9789      }
9790   }
9791   return "cxlftr";
9792}
9793
9794static const HChar *
9795s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9796                  UChar r1, UChar r2)
9797{
9798   if (! s390_host_has_dfp) {
9799      emulation_failure(EmFail_S390X_DFP_insn);
9800   } else {
9801      if (! s390_host_has_fpext) {
9802         emulation_failure(EmFail_S390X_fpext);
9803      } else {
9804         IRTemp op2 = newTemp(Ity_I64);
9805
9806         assign(op2, get_gpr_dw0(r2));
9807         put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9808                               mkexpr(encode_dfp_rounding_mode(m3)),
9809                               mkexpr(op2)));
9810      }
9811   }
9812   return "cdlgtr";
9813}
9814
9815static const HChar *
9816s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9817                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9818{
9819   if (! s390_host_has_dfp) {
9820      emulation_failure(EmFail_S390X_DFP_insn);
9821   } else {
9822      if (! s390_host_has_fpext) {
9823         emulation_failure(EmFail_S390X_fpext);
9824      } else {
9825         IRTemp op2 = newTemp(Ity_I64);
9826
9827         assign(op2, get_gpr_dw0(r2));
9828         put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9829      }
9830   }
9831   return "cxlgtr";
9832}
9833
9834static const HChar *
9835s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9836                 UChar r1, UChar r2)
9837{
9838   if (! s390_host_has_dfp) {
9839      emulation_failure(EmFail_S390X_DFP_insn);
9840   } else {
9841      if (! s390_host_has_fpext) {
9842         emulation_failure(EmFail_S390X_fpext);
9843      } else {
9844         IRTemp op = newTemp(Ity_D64);
9845         IRTemp result = newTemp(Ity_I32);
9846         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9847
9848         assign(op, get_dpr_dw0(r2));
9849         assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9850                              mkexpr(op)));
9851         put_gpr_w1(r1, mkexpr(result));
9852         s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9853      }
9854   }
9855   return "cfdtr";
9856}
9857
9858static const HChar *
9859s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9860                 UChar r1, UChar r2)
9861{
9862   if (! s390_host_has_dfp) {
9863      emulation_failure(EmFail_S390X_DFP_insn);
9864   } else {
9865      if (! s390_host_has_fpext) {
9866         emulation_failure(EmFail_S390X_fpext);
9867      } else {
9868         IRTemp op = newTemp(Ity_D128);
9869         IRTemp result = newTemp(Ity_I32);
9870         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9871
9872         assign(op, get_dpr_pair(r2));
9873         assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9874                              mkexpr(op)));
9875         put_gpr_w1(r1, mkexpr(result));
9876         s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op,
9877                                 rounding_mode);
9878      }
9879   }
9880   return "cfxtr";
9881}
9882
9883static const HChar *
9884s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9885                 UChar r1, UChar r2)
9886{
9887   if (! s390_host_has_dfp) {
9888      emulation_failure(EmFail_S390X_DFP_insn);
9889   } else {
9890      IRTemp op = newTemp(Ity_D64);
9891      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9892
9893      /* If fpext is not installed and m3 is in 1:7,
9894         rounding mode performed is unpredictable */
9895      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9896         emulation_warning(EmWarn_S390X_fpext_rounding);
9897         m3 = S390_DFP_ROUND_PER_FPC_0;
9898      }
9899
9900      assign(op, get_dpr_dw0(r2));
9901      put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9902      s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9903   }
9904   return "cgdtr";
9905}
9906
9907static const HChar *
9908s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9909                 UChar r1, UChar r2)
9910{
9911   if (! s390_host_has_dfp) {
9912      emulation_failure(EmFail_S390X_DFP_insn);
9913   } else {
9914      IRTemp op = newTemp(Ity_D128);
9915      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9916
9917      /* If fpext is not installed and m3 is in 1:7,
9918         rounding mode performed is unpredictable */
9919      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9920         emulation_warning(EmWarn_S390X_fpext_rounding);
9921         m3 = S390_DFP_ROUND_PER_FPC_0;
9922      }
9923      assign(op, get_dpr_pair(r2));
9924      put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9925      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9926   }
9927   return "cgxtr";
9928}
9929
9930static const HChar *
9931s390_irgen_CEDTR(UChar r1, UChar r2)
9932{
9933   if (! s390_host_has_dfp) {
9934      emulation_failure(EmFail_S390X_DFP_insn);
9935   } else {
9936      IRTemp op1 = newTemp(Ity_D64);
9937      IRTemp op2 = newTemp(Ity_D64);
9938      IRTemp cc_vex  = newTemp(Ity_I32);
9939      IRTemp cc_s390 = newTemp(Ity_I32);
9940
9941      assign(op1, get_dpr_dw0(r1));
9942      assign(op2, get_dpr_dw0(r2));
9943      assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9944
9945      assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9946      s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9947   }
9948   return "cedtr";
9949}
9950
9951static const HChar *
9952s390_irgen_CEXTR(UChar r1, UChar r2)
9953{
9954   if (! s390_host_has_dfp) {
9955      emulation_failure(EmFail_S390X_DFP_insn);
9956   } else {
9957      IRTemp op1 = newTemp(Ity_D128);
9958      IRTemp op2 = newTemp(Ity_D128);
9959      IRTemp cc_vex  = newTemp(Ity_I32);
9960      IRTemp cc_s390 = newTemp(Ity_I32);
9961
9962      assign(op1, get_dpr_pair(r1));
9963      assign(op2, get_dpr_pair(r2));
9964      assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9965
9966      assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9967      s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9968   }
9969   return "cextr";
9970}
9971
9972static const HChar *
9973s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9974                  UChar r1, UChar r2)
9975{
9976   if (! s390_host_has_dfp) {
9977      emulation_failure(EmFail_S390X_DFP_insn);
9978   } else {
9979      if (! s390_host_has_fpext) {
9980         emulation_failure(EmFail_S390X_fpext);
9981      } else {
9982         IRTemp op = newTemp(Ity_D64);
9983         IRTemp result = newTemp(Ity_I32);
9984         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9985
9986         assign(op, get_dpr_dw0(r2));
9987         assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9988                              mkexpr(op)));
9989         put_gpr_w1(r1, mkexpr(result));
9990         s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9991      }
9992   }
9993   return "clfdtr";
9994}
9995
9996static const HChar *
9997s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9998                  UChar r1, UChar r2)
9999{
10000   if (! s390_host_has_dfp) {
10001      emulation_failure(EmFail_S390X_DFP_insn);
10002   } else {
10003      if (! s390_host_has_fpext) {
10004         emulation_failure(EmFail_S390X_fpext);
10005      } else {
10006         IRTemp op = newTemp(Ity_D128);
10007         IRTemp result = newTemp(Ity_I32);
10008         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10009
10010         assign(op, get_dpr_pair(r2));
10011         assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
10012                              mkexpr(op)));
10013         put_gpr_w1(r1, mkexpr(result));
10014         s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op,
10015                                 rounding_mode);
10016      }
10017   }
10018   return "clfxtr";
10019}
10020
10021static const HChar *
10022s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
10023                  UChar r1, UChar r2)
10024{
10025   if (! s390_host_has_dfp) {
10026      emulation_failure(EmFail_S390X_DFP_insn);
10027   } else {
10028      if (! s390_host_has_fpext) {
10029         emulation_failure(EmFail_S390X_fpext);
10030      } else {
10031         IRTemp op = newTemp(Ity_D64);
10032         IRTemp result = newTemp(Ity_I64);
10033         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10034
10035         assign(op, get_dpr_dw0(r2));
10036         assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
10037                              mkexpr(op)));
10038         put_gpr_dw0(r1, mkexpr(result));
10039         s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
10040      }
10041   }
10042   return "clgdtr";
10043}
10044
10045static const HChar *
10046s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
10047                  UChar r1, UChar r2)
10048{
10049   if (! s390_host_has_dfp) {
10050      emulation_failure(EmFail_S390X_DFP_insn);
10051   } else {
10052      if (! s390_host_has_fpext) {
10053         emulation_failure(EmFail_S390X_fpext);
10054      } else {
10055         IRTemp op = newTemp(Ity_D128);
10056         IRTemp result = newTemp(Ity_I64);
10057         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10058
10059         assign(op, get_dpr_pair(r2));
10060         assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
10061                              mkexpr(op)));
10062         put_gpr_dw0(r1, mkexpr(result));
10063         s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
10064                                 rounding_mode);
10065      }
10066   }
10067   return "clgxtr";
10068}
10069
10070static const HChar *
10071s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10072{
10073   if (! s390_host_has_dfp) {
10074      emulation_failure(EmFail_S390X_DFP_insn);
10075   } else {
10076      IRTemp op1 = newTemp(Ity_D64);
10077      IRTemp op2 = newTemp(Ity_D64);
10078      IRTemp result = newTemp(Ity_D64);
10079      IRTemp rounding_mode;
10080
10081      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10082         emulation_warning(EmWarn_S390X_fpext_rounding);
10083         m4 = S390_DFP_ROUND_PER_FPC_0;
10084      }
10085
10086      rounding_mode = encode_dfp_rounding_mode(m4);
10087      assign(op1, get_dpr_dw0(r2));
10088      assign(op2, get_dpr_dw0(r3));
10089      assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
10090                           mkexpr(op2)));
10091      put_dpr_dw0(r1, mkexpr(result));
10092   }
10093   return (m4 == 0) ? "ddtr" : "ddtra";
10094}
10095
10096static const HChar *
10097s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10098{
10099   if (! s390_host_has_dfp) {
10100      emulation_failure(EmFail_S390X_DFP_insn);
10101   } else {
10102      IRTemp op1 = newTemp(Ity_D128);
10103      IRTemp op2 = newTemp(Ity_D128);
10104      IRTemp result = newTemp(Ity_D128);
10105      IRTemp rounding_mode;
10106
10107      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10108         emulation_warning(EmWarn_S390X_fpext_rounding);
10109         m4 = S390_DFP_ROUND_PER_FPC_0;
10110      }
10111
10112      rounding_mode = encode_dfp_rounding_mode(m4);
10113      assign(op1, get_dpr_pair(r2));
10114      assign(op2, get_dpr_pair(r3));
10115      assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
10116                           mkexpr(op2)));
10117      put_dpr_pair(r1, mkexpr(result));
10118   }
10119   return (m4 == 0) ? "dxtr" : "dxtra";
10120}
10121
10122static const HChar *
10123s390_irgen_EEDTR(UChar r1, UChar r2)
10124{
10125   if (! s390_host_has_dfp) {
10126      emulation_failure(EmFail_S390X_DFP_insn);
10127   } else {
10128      put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
10129   }
10130   return "eedtr";
10131}
10132
10133static const HChar *
10134s390_irgen_EEXTR(UChar r1, UChar r2)
10135{
10136   if (! s390_host_has_dfp) {
10137      emulation_failure(EmFail_S390X_DFP_insn);
10138   } else {
10139      put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
10140   }
10141   return "eextr";
10142}
10143
10144static const HChar *
10145s390_irgen_ESDTR(UChar r1, UChar r2)
10146{
10147   if (! s390_host_has_dfp) {
10148      emulation_failure(EmFail_S390X_DFP_insn);
10149   } else {
10150      put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
10151   }
10152   return "esdtr";
10153}
10154
10155static const HChar *
10156s390_irgen_ESXTR(UChar r1, UChar r2)
10157{
10158   if (! s390_host_has_dfp) {
10159      emulation_failure(EmFail_S390X_DFP_insn);
10160   } else {
10161      put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
10162   }
10163   return "esxtr";
10164}
10165
10166static const HChar *
10167s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
10168{
10169   if (! s390_host_has_dfp) {
10170      emulation_failure(EmFail_S390X_DFP_insn);
10171   } else {
10172      IRTemp op1 = newTemp(Ity_I64);
10173      IRTemp op2 = newTemp(Ity_D64);
10174      IRTemp result = newTemp(Ity_D64);
10175
10176      assign(op1, get_gpr_dw0(r2));
10177      assign(op2, get_dpr_dw0(r3));
10178      assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
10179      put_dpr_dw0(r1, mkexpr(result));
10180   }
10181   return "iedtr";
10182}
10183
10184static const HChar *
10185s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
10186{
10187   if (! s390_host_has_dfp) {
10188      emulation_failure(EmFail_S390X_DFP_insn);
10189   } else {
10190      IRTemp op1 = newTemp(Ity_I64);
10191      IRTemp op2 = newTemp(Ity_D128);
10192      IRTemp result = newTemp(Ity_D128);
10193
10194      assign(op1, get_gpr_dw0(r2));
10195      assign(op2, get_dpr_pair(r3));
10196      assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10197      put_dpr_pair(r1, mkexpr(result));
10198   }
10199   return "iextr";
10200}
10201
10202static const HChar *
10203s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10204{
10205   if (! s390_host_has_dfp) {
10206      emulation_failure(EmFail_S390X_DFP_insn);
10207   } else {
10208      IRTemp op = newTemp(Ity_D32);
10209
10210      assign(op, get_dpr_w0(r2));
10211      put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10212   }
10213   return "ldetr";
10214}
10215
10216static const HChar *
10217s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10218{
10219   IRTemp op = newTemp(Ity_D64);
10220
10221   assign(op, get_dpr_dw0(r2));
10222   put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10223
10224   return "lxdtr";
10225}
10226
10227static const HChar *
10228s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10229                 UChar r1, UChar r2)
10230{
10231   if (! s390_host_has_dfp) {
10232      emulation_failure(EmFail_S390X_DFP_insn);
10233   } else {
10234      /* If fpext is not installed and m3 is in 1:7,
10235         rounding mode performed is unpredictable */
10236      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10237         emulation_warning(EmWarn_S390X_fpext_rounding);
10238         m3 = S390_DFP_ROUND_PER_FPC_0;
10239      }
10240      IRTemp result = newTemp(Ity_D64);
10241
10242      assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10243                           get_dpr_pair(r2)));
10244      put_dpr_dw0(r1, mkexpr(result));
10245   }
10246   return "ldxtr";
10247}
10248
10249static const HChar *
10250s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10251                 UChar r1, UChar r2)
10252{
10253   if (! s390_host_has_dfp) {
10254      emulation_failure(EmFail_S390X_DFP_insn);
10255   } else {
10256      /* If fpext is not installed and m3 is in 1:7,
10257         rounding mode performed is unpredictable */
10258      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10259         emulation_warning(EmWarn_S390X_fpext_rounding);
10260         m3 = S390_DFP_ROUND_PER_FPC_0;
10261      }
10262      IRTemp op = newTemp(Ity_D64);
10263
10264      assign(op, get_dpr_dw0(r2));
10265      put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10266                           mkexpr(op)));
10267   }
10268   return "ledtr";
10269}
10270
10271static const HChar *
10272s390_irgen_LTDTR(UChar r1, UChar r2)
10273{
10274   IRTemp result = newTemp(Ity_D64);
10275
10276   assign(result, get_dpr_dw0(r2));
10277   put_dpr_dw0(r1, mkexpr(result));
10278   s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10279
10280   return "ltdtr";
10281}
10282
10283static const HChar *
10284s390_irgen_LTXTR(UChar r1, UChar r2)
10285{
10286   IRTemp result = newTemp(Ity_D128);
10287
10288   assign(result, get_dpr_pair(r2));
10289   put_dpr_pair(r1, mkexpr(result));
10290   s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10291
10292   return "ltxtr";
10293}
10294
10295static const HChar *
10296s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10297{
10298   if (! s390_host_has_dfp) {
10299      emulation_failure(EmFail_S390X_DFP_insn);
10300   } else {
10301      IRTemp op1 = newTemp(Ity_D64);
10302      IRTemp op2 = newTemp(Ity_D64);
10303      IRTemp result = newTemp(Ity_D64);
10304      IRTemp rounding_mode;
10305
10306      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10307         emulation_warning(EmWarn_S390X_fpext_rounding);
10308         m4 = S390_DFP_ROUND_PER_FPC_0;
10309      }
10310
10311      rounding_mode = encode_dfp_rounding_mode(m4);
10312      assign(op1, get_dpr_dw0(r2));
10313      assign(op2, get_dpr_dw0(r3));
10314      assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10315                           mkexpr(op2)));
10316      put_dpr_dw0(r1, mkexpr(result));
10317   }
10318   return (m4 == 0) ? "mdtr" : "mdtra";
10319}
10320
10321static const HChar *
10322s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10323{
10324   if (! s390_host_has_dfp) {
10325      emulation_failure(EmFail_S390X_DFP_insn);
10326   } else {
10327      IRTemp op1 = newTemp(Ity_D128);
10328      IRTemp op2 = newTemp(Ity_D128);
10329      IRTemp result = newTemp(Ity_D128);
10330      IRTemp rounding_mode;
10331
10332      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10333         emulation_warning(EmWarn_S390X_fpext_rounding);
10334         m4 = S390_DFP_ROUND_PER_FPC_0;
10335      }
10336
10337      rounding_mode = encode_dfp_rounding_mode(m4);
10338      assign(op1, get_dpr_pair(r2));
10339      assign(op2, get_dpr_pair(r3));
10340      assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10341                           mkexpr(op2)));
10342      put_dpr_pair(r1, mkexpr(result));
10343   }
10344   return (m4 == 0) ? "mxtr" : "mxtra";
10345}
10346
10347static const HChar *
10348s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10349{
10350   if (! s390_host_has_dfp) {
10351      emulation_failure(EmFail_S390X_DFP_insn);
10352   } else {
10353      IRTemp op1 = newTemp(Ity_D64);
10354      IRTemp op2 = newTemp(Ity_D64);
10355      IRTemp result = newTemp(Ity_D64);
10356      IRTemp rounding_mode;
10357
10358      /* If fpext is not installed and m4 is in 1:7,
10359         rounding mode performed is unpredictable */
10360      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10361         emulation_warning(EmWarn_S390X_fpext_rounding);
10362         m4 = S390_DFP_ROUND_PER_FPC_0;
10363      }
10364
10365      rounding_mode = encode_dfp_rounding_mode(m4);
10366      assign(op1, get_dpr_dw0(r2));
10367      assign(op2, get_dpr_dw0(r3));
10368      assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10369                           mkexpr(op2)));
10370      put_dpr_dw0(r1, mkexpr(result));
10371   }
10372   return "qadtr";
10373}
10374
10375static const HChar *
10376s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10377{
10378   if (! s390_host_has_dfp) {
10379      emulation_failure(EmFail_S390X_DFP_insn);
10380   } else {
10381      IRTemp op1 = newTemp(Ity_D128);
10382      IRTemp op2 = newTemp(Ity_D128);
10383      IRTemp result = newTemp(Ity_D128);
10384      IRTemp rounding_mode;
10385
10386      /* If fpext is not installed and m4 is in 1:7,
10387         rounding mode performed is unpredictable */
10388      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10389         emulation_warning(EmWarn_S390X_fpext_rounding);
10390         m4 = S390_DFP_ROUND_PER_FPC_0;
10391      }
10392
10393      rounding_mode = encode_dfp_rounding_mode(m4);
10394      assign(op1, get_dpr_pair(r2));
10395      assign(op2, get_dpr_pair(r3));
10396      assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10397                           mkexpr(op2)));
10398      put_dpr_pair(r1, mkexpr(result));
10399   }
10400   return "qaxtr";
10401}
10402
10403static const HChar *
10404s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10405{
10406   if (! s390_host_has_dfp) {
10407      emulation_failure(EmFail_S390X_DFP_insn);
10408   } else {
10409      IRTemp op1 = newTemp(Ity_I8);
10410      IRTemp op2 = newTemp(Ity_D64);
10411      IRTemp result = newTemp(Ity_D64);
10412      IRTemp rounding_mode;
10413
10414      /* If fpext is not installed and m4 is in 1:7,
10415         rounding mode performed is unpredictable */
10416      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10417         emulation_warning(EmWarn_S390X_fpext_rounding);
10418         m4 = S390_DFP_ROUND_PER_FPC_0;
10419      }
10420
10421      rounding_mode = encode_dfp_rounding_mode(m4);
10422      assign(op1, get_gpr_b7(r2));
10423      assign(op2, get_dpr_dw0(r3));
10424      assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10425                           mkexpr(op1), mkexpr(op2)));
10426      put_dpr_dw0(r1, mkexpr(result));
10427   }
10428   return "rrdtr";
10429}
10430
10431static const HChar *
10432s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10433{
10434   if (! s390_host_has_dfp) {
10435      emulation_failure(EmFail_S390X_DFP_insn);
10436   } else {
10437      IRTemp op1 = newTemp(Ity_I8);
10438      IRTemp op2 = newTemp(Ity_D128);
10439      IRTemp result = newTemp(Ity_D128);
10440      IRTemp rounding_mode;
10441
10442      /* If fpext is not installed and m4 is in 1:7,
10443         rounding mode performed is unpredictable */
10444      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10445         emulation_warning(EmWarn_S390X_fpext_rounding);
10446         m4 = S390_DFP_ROUND_PER_FPC_0;
10447      }
10448
10449      rounding_mode = encode_dfp_rounding_mode(m4);
10450      assign(op1, get_gpr_b7(r2));
10451      assign(op2, get_dpr_pair(r3));
10452      assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10453                           mkexpr(op1), mkexpr(op2)));
10454      put_dpr_pair(r1, mkexpr(result));
10455   }
10456   return "rrxtr";
10457}
10458
10459static const HChar *
10460s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10461{
10462   if (! s390_host_has_dfp) {
10463      emulation_failure(EmFail_S390X_DFP_insn);
10464   } else {
10465      IRTemp op1 = newTemp(Ity_D64);
10466      IRTemp op2 = newTemp(Ity_D64);
10467      IRTemp result = newTemp(Ity_D64);
10468      IRTemp rounding_mode;
10469
10470      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10471         emulation_warning(EmWarn_S390X_fpext_rounding);
10472         m4 = S390_DFP_ROUND_PER_FPC_0;
10473      }
10474
10475      rounding_mode = encode_dfp_rounding_mode(m4);
10476      assign(op1, get_dpr_dw0(r2));
10477      assign(op2, get_dpr_dw0(r3));
10478      assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10479                           mkexpr(op2)));
10480      s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10481      put_dpr_dw0(r1, mkexpr(result));
10482   }
10483   return (m4 == 0) ? "sdtr" : "sdtra";
10484}
10485
10486static const HChar *
10487s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10488{
10489   if (! s390_host_has_dfp) {
10490      emulation_failure(EmFail_S390X_DFP_insn);
10491   } else {
10492      IRTemp op1 = newTemp(Ity_D128);
10493      IRTemp op2 = newTemp(Ity_D128);
10494      IRTemp result = newTemp(Ity_D128);
10495      IRTemp rounding_mode;
10496
10497      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10498         emulation_warning(EmWarn_S390X_fpext_rounding);
10499         m4 = S390_DFP_ROUND_PER_FPC_0;
10500      }
10501
10502      rounding_mode = encode_dfp_rounding_mode(m4);
10503      assign(op1, get_dpr_pair(r2));
10504      assign(op2, get_dpr_pair(r3));
10505      assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10506                           mkexpr(op2)));
10507      put_dpr_pair(r1, mkexpr(result));
10508
10509      s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10510   }
10511   return (m4 == 0) ? "sxtr" : "sxtra";
10512}
10513
10514static const HChar *
10515s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10516{
10517   if (! s390_host_has_dfp) {
10518      emulation_failure(EmFail_S390X_DFP_insn);
10519   } else {
10520      IRTemp op = newTemp(Ity_D64);
10521
10522      assign(op, get_dpr_dw0(r3));
10523      put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op),
10524                            unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10525                                                  mkU64(63)))));
10526   }
10527   return "sldt";
10528}
10529
10530static const HChar *
10531s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10532{
10533   if (! s390_host_has_dfp) {
10534      emulation_failure(EmFail_S390X_DFP_insn);
10535   } else {
10536      IRTemp op = newTemp(Ity_D128);
10537
10538      assign(op, get_dpr_pair(r3));
10539      put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op),
10540                             unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10541                                                   mkU64(63)))));
10542   }
10543   return "slxt";
10544}
10545
10546static const HChar *
10547s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10548{
10549   if (! s390_host_has_dfp) {
10550      emulation_failure(EmFail_S390X_DFP_insn);
10551   } else {
10552      IRTemp op = newTemp(Ity_D64);
10553
10554      assign(op, get_dpr_dw0(r3));
10555      put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op),
10556                            unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10557                                                  mkU64(63)))));
10558   }
10559   return "srdt";
10560}
10561
10562static const HChar *
10563s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10564{
10565   if (! s390_host_has_dfp) {
10566      emulation_failure(EmFail_S390X_DFP_insn);
10567   } else {
10568      IRTemp op = newTemp(Ity_D128);
10569
10570      assign(op, get_dpr_pair(r3));
10571      put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op),
10572                             unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10573                                                   mkU64(63)))));
10574   }
10575   return "srxt";
10576}
10577
10578static const HChar *
10579s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10580{
10581   if (! s390_host_has_dfp) {
10582      emulation_failure(EmFail_S390X_DFP_insn);
10583   } else {
10584      IRTemp value = newTemp(Ity_D32);
10585
10586      assign(value, get_dpr_w0(r1));
10587
10588      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10589   }
10590   return "tdcet";
10591}
10592
10593static const HChar *
10594s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10595{
10596   if (! s390_host_has_dfp) {
10597      emulation_failure(EmFail_S390X_DFP_insn);
10598   } else {
10599      IRTemp value = newTemp(Ity_D64);
10600
10601      assign(value, get_dpr_dw0(r1));
10602
10603      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10604   }
10605   return "tdcdt";
10606}
10607
10608static const HChar *
10609s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10610{
10611   if (! s390_host_has_dfp) {
10612      emulation_failure(EmFail_S390X_DFP_insn);
10613   } else {
10614      IRTemp value = newTemp(Ity_D128);
10615
10616      assign(value, get_dpr_pair(r1));
10617
10618      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10619   }
10620   return "tdcxt";
10621}
10622
10623static const HChar *
10624s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10625{
10626   if (! s390_host_has_dfp) {
10627      emulation_failure(EmFail_S390X_DFP_insn);
10628   } else {
10629      IRTemp value = newTemp(Ity_D32);
10630
10631      assign(value, get_dpr_w0(r1));
10632
10633      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10634   }
10635   return "tdget";
10636}
10637
10638static const HChar *
10639s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10640{
10641   if (! s390_host_has_dfp) {
10642      emulation_failure(EmFail_S390X_DFP_insn);
10643   } else {
10644      IRTemp value = newTemp(Ity_D64);
10645
10646      assign(value, get_dpr_dw0(r1));
10647
10648      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10649   }
10650   return "tdgdt";
10651}
10652
10653static const HChar *
10654s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10655{
10656   if (! s390_host_has_dfp) {
10657      emulation_failure(EmFail_S390X_DFP_insn);
10658   } else {
10659      IRTemp value = newTemp(Ity_D128);
10660
10661      assign(value, get_dpr_pair(r1));
10662
10663      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10664   }
10665   return "tdgxt";
10666}
10667
10668static const HChar *
10669s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10670{
10671   IRTemp len = newTemp(Ity_I64);
10672
10673   assign(len, mkU64(length));
10674   s390_irgen_CLC_EX(len, start1, start2);
10675
10676   return "clc";
10677}
10678
10679static const HChar *
10680s390_irgen_CLCL(UChar r1, UChar r2)
10681{
10682   IRTemp addr1 = newTemp(Ity_I64);
10683   IRTemp addr2 = newTemp(Ity_I64);
10684   IRTemp addr1_load = newTemp(Ity_I64);
10685   IRTemp addr2_load = newTemp(Ity_I64);
10686   IRTemp len1 = newTemp(Ity_I32);
10687   IRTemp len2 = newTemp(Ity_I32);
10688   IRTemp r1p1 = newTemp(Ity_I32);   /* contents of r1 + 1 */
10689   IRTemp r2p1 = newTemp(Ity_I32);   /* contents of r2 + 1 */
10690   IRTemp single1 = newTemp(Ity_I8);
10691   IRTemp single2 = newTemp(Ity_I8);
10692   IRTemp pad = newTemp(Ity_I8);
10693
10694   assign(addr1, get_gpr_dw0(r1));
10695   assign(r1p1, get_gpr_w1(r1 + 1));
10696   assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10697   assign(addr2, get_gpr_dw0(r2));
10698   assign(r2p1, get_gpr_w1(r2 + 1));
10699   assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10700   assign(pad, get_gpr_b4(r2 + 1));
10701
10702   /* len1 == 0 and len2 == 0? Exit */
10703   s390_cc_set(0);
10704   next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10705                                         mkexpr(len2)), mkU32(0)));
10706
10707   /* Because mkite evaluates both the then-clause and the else-clause
10708      we cannot load directly from addr1 here. If len1 is 0, then adddr1
10709      may be NULL and loading from there would segfault. So we provide a
10710      valid dummy address in that case. Loading from there does no harm and
10711      the value will be discarded at runtime. */
10712   assign(addr1_load,
10713          mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10714                mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10715   assign(single1,
10716          mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10717                mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10718
10719   assign(addr2_load,
10720          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10721                mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10722   assign(single2,
10723          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10724                mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10725
10726   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10727   /* Fields differ ? */
10728   next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
10729
10730   /* Update len1 and addr1, unless len1 == 0. */
10731   put_gpr_dw0(r1,
10732               mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10733                     mkexpr(addr1),
10734                     binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10735
10736   /* When updating len1 we must not modify bits (r1+1)[0:39] */
10737   put_gpr_w1(r1 + 1,
10738              mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10739                    binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10740                    binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10741
10742   /* Update len2 and addr2, unless len2 == 0. */
10743   put_gpr_dw0(r2,
10744               mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10745                     mkexpr(addr2),
10746                     binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10747
10748   /* When updating len2 we must not modify bits (r2+1)[0:39] */
10749   put_gpr_w1(r2 + 1,
10750              mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10751                    binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10752                    binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10753
10754   iterate();
10755
10756   return "clcl";
10757}
10758
10759static const HChar *
10760s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10761{
10762   IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10763
10764   addr1 = newTemp(Ity_I64);
10765   addr3 = newTemp(Ity_I64);
10766   addr1_load = newTemp(Ity_I64);
10767   addr3_load = newTemp(Ity_I64);
10768   len1 = newTemp(Ity_I64);
10769   len3 = newTemp(Ity_I64);
10770   single1 = newTemp(Ity_I8);
10771   single3 = newTemp(Ity_I8);
10772
10773   assign(addr1, get_gpr_dw0(r1));
10774   assign(len1, get_gpr_dw0(r1 + 1));
10775   assign(addr3, get_gpr_dw0(r3));
10776   assign(len3, get_gpr_dw0(r3 + 1));
10777
10778   /* len1 == 0 and len3 == 0? Exit */
10779   s390_cc_set(0);
10780   next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10781                                        mkexpr(len3)), mkU64(0)));
10782
10783   /* A mux requires both ways to be possible. This is a way to prevent clcle
10784      from reading from addr1 if it should read from the pad. Since the pad
10785      has no address, just read from the instruction, we discard that anyway */
10786   assign(addr1_load,
10787          mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10788                mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10789
10790   /* same for addr3 */
10791   assign(addr3_load,
10792          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10793                mkU64(guest_IA_curr_instr), mkexpr(addr3)));
10794
10795   assign(single1,
10796          mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10797                unop(Iop_64to8, mkexpr(pad2)),
10798                load(Ity_I8, mkexpr(addr1_load))));
10799
10800   assign(single3,
10801          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10802                unop(Iop_64to8, mkexpr(pad2)),
10803                load(Ity_I8, mkexpr(addr3_load))));
10804
10805   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10806   /* Both fields differ ? */
10807   next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
10808
10809   /* If a length in 0 we must not change this length and the address */
10810   put_gpr_dw0(r1,
10811               mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10812                     mkexpr(addr1),
10813                     binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10814
10815   put_gpr_dw0(r1 + 1,
10816               mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10817                     mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
10818
10819   put_gpr_dw0(r3,
10820               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10821                     mkexpr(addr3),
10822                     binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
10823
10824   put_gpr_dw0(r3 + 1,
10825               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10826                     mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
10827
10828   iterate();
10829
10830   return "clcle";
10831}
10832
10833
10834static void
10835s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10836{
10837   s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10838}
10839
10840
10841static void
10842s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10843{
10844   s390_irgen_xonc(Iop_And8, length, start1, start2);
10845}
10846
10847
10848static void
10849s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10850{
10851   s390_irgen_xonc(Iop_Or8, length, start1, start2);
10852}
10853
10854
10855static void
10856s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10857{
10858   IRTemp current1 = newTemp(Ity_I8);
10859   IRTemp current2 = newTemp(Ity_I8);
10860   IRTemp counter = newTemp(Ity_I64);
10861
10862   assign(counter, get_counter_dw0());
10863   put_counter_dw0(mkU64(0));
10864
10865   assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10866                                       mkexpr(counter))));
10867   assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10868                                       mkexpr(counter))));
10869   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10870                      False);
10871
10872   /* Both fields differ ? */
10873   next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
10874
10875   /* Check for end of field */
10876   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10877   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
10878   put_counter_dw0(mkU64(0));
10879}
10880
10881static void
10882s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10883{
10884   IRTemp counter = newTemp(Ity_I64);
10885
10886   assign(counter, get_counter_dw0());
10887
10888   store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10889         load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10890
10891   /* Check for end of field */
10892   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10893   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
10894   put_counter_dw0(mkU64(0));
10895}
10896
10897static void
10898s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10899{
10900   IRTemp op = newTemp(Ity_I8);
10901   IRTemp op1 = newTemp(Ity_I8);
10902   IRTemp result = newTemp(Ity_I64);
10903   IRTemp counter = newTemp(Ity_I64);
10904
10905   assign(counter, get_counter_dw0());
10906
10907   assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10908
10909   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10910
10911   assign(op1, load(Ity_I8, mkexpr(result)));
10912   store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10913
10914   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10915   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
10916   put_counter_dw0(mkU64(0));
10917}
10918
10919
10920static void
10921s390_irgen_EX_SS(UChar r, IRTemp addr2,
10922                 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
10923                 UInt lensize)
10924{
10925   struct SS {
10926      unsigned int op :  8;
10927      unsigned int l  :  8;
10928      unsigned int b1 :  4;
10929      unsigned int d1 : 12;
10930      unsigned int b2 :  4;
10931      unsigned int d2 : 12;
10932   };
10933   union {
10934      struct SS dec;
10935      unsigned long bytes;
10936   } ss;
10937   IRTemp cond;
10938   IRDirty *d;
10939   IRTemp torun;
10940
10941   IRTemp start1 = newTemp(Ity_I64);
10942   IRTemp start2 = newTemp(Ity_I64);
10943   IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10944   cond = newTemp(Ity_I1);
10945   torun = newTemp(Ity_I64);
10946
10947   assign(torun, load(Ity_I64, mkexpr(addr2)));
10948   /* Start with a check that the saved code is still correct */
10949   assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10950   /* If not, save the new value */
10951   d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10952                          mkIRExprVec_1(mkexpr(torun)));
10953   d->guard = mkexpr(cond);
10954   stmt(IRStmt_Dirty(d));
10955
10956   /* and restart */
10957   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
10958                   mkU64(guest_IA_curr_instr)));
10959   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
10960   restart_if(mkexpr(cond));
10961
10962   ss.bytes = last_execute_target;
10963   assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10964          ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10965   assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10966          ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10967   assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10968          r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10969   irgen(len, start1, start2);
10970
10971   last_execute_target = 0;
10972}
10973
10974static const HChar *
10975s390_irgen_EX(UChar r1, IRTemp addr2)
10976{
10977   switch(last_execute_target & 0xff00000000000000ULL) {
10978   case 0:
10979   {
10980      /* no code information yet */
10981      IRDirty *d;
10982
10983      /* so safe the code... */
10984      d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10985                             mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10986      stmt(IRStmt_Dirty(d));
10987      /* and restart */
10988      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
10989                      mkU64(guest_IA_curr_instr)));
10990      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
10991      restart_if(IRExpr_Const(IRConst_U1(True)));
10992
10993      /* we know that this will be invalidated */
10994      put_IA(mkaddr_expr(guest_IA_next_instr));
10995      dis_res->whatNext = Dis_StopHere;
10996      dis_res->jk_StopHere = Ijk_InvalICache;
10997      break;
10998   }
10999
11000   case 0xd200000000000000ULL:
11001      /* special case MVC */
11002      s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
11003      return "ex@mvc";
11004
11005   case 0xd500000000000000ULL:
11006      /* special case CLC */
11007      s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
11008      return "ex@clc";
11009
11010   case 0xd700000000000000ULL:
11011      /* special case XC */
11012      s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
11013      return "ex@xc";
11014
11015   case 0xd600000000000000ULL:
11016      /* special case OC */
11017      s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
11018      return "ex@oc";
11019
11020   case 0xd400000000000000ULL:
11021      /* special case NC */
11022      s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
11023      return "ex@nc";
11024
11025   case 0xdc00000000000000ULL:
11026      /* special case TR */
11027      s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
11028      return "ex@tr";
11029
11030   default:
11031   {
11032      /* everything else will get a self checking prefix that also checks the
11033         register content */
11034      IRDirty *d;
11035      UChar *bytes;
11036      IRTemp cond;
11037      IRTemp orperand;
11038      IRTemp torun;
11039
11040      cond = newTemp(Ity_I1);
11041      orperand = newTemp(Ity_I64);
11042      torun = newTemp(Ity_I64);
11043
11044      if (r1 == 0)
11045         assign(orperand, mkU64(0));
11046      else
11047         assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
11048      /* This code is going to be translated */
11049      assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
11050             binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
11051
11052      /* Start with a check that saved code is still correct */
11053      assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
11054             mkU64(last_execute_target)));
11055      /* If not, save the new value */
11056      d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
11057                             mkIRExprVec_1(mkexpr(torun)));
11058      d->guard = mkexpr(cond);
11059      stmt(IRStmt_Dirty(d));
11060
11061      /* and restart */
11062      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART), mkU64(guest_IA_curr_instr)));
11063      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
11064      restart_if(mkexpr(cond));
11065
11066      /* Now comes the actual translation */
11067      bytes = (UChar *) &last_execute_target;
11068      s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
11069                            dis_res);
11070      if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
11071         vex_printf("    which was executed by\n");
11072      /* dont make useless translations in the next execute */
11073      last_execute_target = 0;
11074   }
11075   }
11076   return "ex";
11077}
11078
11079static const HChar *
11080s390_irgen_EXRL(UChar r1, UInt offset)
11081{
11082   IRTemp addr = newTemp(Ity_I64);
11083   /* we might save one round trip because we know the target */
11084   if (!last_execute_target)
11085      last_execute_target = *(ULong *)(HWord)
11086                             (guest_IA_curr_instr + offset * 2UL);
11087   assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
11088   s390_irgen_EX(r1, addr);
11089   return "exrl";
11090}
11091
11092static const HChar *
11093s390_irgen_IPM(UChar r1)
11094{
11095   // As long as we dont support SPM, lets just assume 0 as program mask
11096   put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
11097                       binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
11098
11099   return "ipm";
11100}
11101
11102
11103static const HChar *
11104s390_irgen_SRST(UChar r1, UChar r2)
11105{
11106   IRTemp address = newTemp(Ity_I64);
11107   IRTemp next = newTemp(Ity_I64);
11108   IRTemp delim = newTemp(Ity_I8);
11109   IRTemp counter = newTemp(Ity_I64);
11110   IRTemp byte = newTemp(Ity_I8);
11111
11112   assign(address, get_gpr_dw0(r2));
11113   assign(next, get_gpr_dw0(r1));
11114
11115   assign(counter, get_counter_dw0());
11116   put_counter_dw0(mkU64(0));
11117
11118   // start = next?  CC=2 and out r1 and r2 unchanged
11119   s390_cc_set(2);
11120   put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
11121   next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
11122
11123   assign(byte, load(Ity_I8, mkexpr(address)));
11124   assign(delim, get_gpr_b7(0));
11125
11126   // byte = delim? CC=1, R1=address
11127   s390_cc_set(1);
11128   put_gpr_dw0(r1,  mkexpr(address));
11129   next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
11130
11131   // else: all equal, no end yet, loop
11132   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11133   put_gpr_dw0(r1, mkexpr(next));
11134   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
11135
11136   iterate();
11137
11138   return "srst";
11139}
11140
11141static const HChar *
11142s390_irgen_CLST(UChar r1, UChar r2)
11143{
11144   IRTemp address1 = newTemp(Ity_I64);
11145   IRTemp address2 = newTemp(Ity_I64);
11146   IRTemp end = newTemp(Ity_I8);
11147   IRTemp counter = newTemp(Ity_I64);
11148   IRTemp byte1 = newTemp(Ity_I8);
11149   IRTemp byte2 = newTemp(Ity_I8);
11150
11151   assign(address1, get_gpr_dw0(r1));
11152   assign(address2, get_gpr_dw0(r2));
11153   assign(end, get_gpr_b7(0));
11154   assign(counter, get_counter_dw0());
11155   put_counter_dw0(mkU64(0));
11156   assign(byte1, load(Ity_I8, mkexpr(address1)));
11157   assign(byte2, load(Ity_I8, mkexpr(address2)));
11158
11159   // end in both? all equal, reset r1 and r2 to start values
11160   s390_cc_set(0);
11161   put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
11162   put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
11163   next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
11164                      binop(Iop_Or8,
11165                            binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
11166                            binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
11167
11168   put_gpr_dw0(r1, mkexpr(address1));
11169   put_gpr_dw0(r2, mkexpr(address2));
11170
11171   // End found in string1
11172   s390_cc_set(1);
11173   next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
11174
11175   // End found in string2
11176   s390_cc_set(2);
11177   next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
11178
11179   // string1 < string2
11180   s390_cc_set(1);
11181   next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
11182                      unop(Iop_8Uto32, mkexpr(byte2))));
11183
11184   // string2 < string1
11185   s390_cc_set(2);
11186   next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
11187                      unop(Iop_8Uto32, mkexpr(byte1))));
11188
11189   // else: all equal, no end yet, loop
11190   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11191   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
11192   put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
11193
11194   iterate();
11195
11196   return "clst";
11197}
11198
11199static void
11200s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11201{
11202   UChar reg;
11203   IRTemp addr = newTemp(Ity_I64);
11204
11205   assign(addr, mkexpr(op2addr));
11206   reg = r1;
11207   do {
11208      IRTemp old = addr;
11209
11210      reg %= 16;
11211      put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
11212      addr = newTemp(Ity_I64);
11213      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11214      reg++;
11215   } while (reg != (r3 + 1));
11216}
11217
11218static const HChar *
11219s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
11220{
11221   s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11222
11223   return "lm";
11224}
11225
11226static const HChar *
11227s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11228{
11229   s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11230
11231   return "lmy";
11232}
11233
11234static const HChar *
11235s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11236{
11237   UChar reg;
11238   IRTemp addr = newTemp(Ity_I64);
11239
11240   assign(addr, mkexpr(op2addr));
11241   reg = r1;
11242   do {
11243      IRTemp old = addr;
11244
11245      reg %= 16;
11246      put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11247      addr = newTemp(Ity_I64);
11248      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11249      reg++;
11250   } while (reg != (r3 + 1));
11251
11252   return "lmh";
11253}
11254
11255static const HChar *
11256s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11257{
11258   UChar reg;
11259   IRTemp addr = newTemp(Ity_I64);
11260
11261   assign(addr, mkexpr(op2addr));
11262   reg = r1;
11263   do {
11264      IRTemp old = addr;
11265
11266      reg %= 16;
11267      put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11268      addr = newTemp(Ity_I64);
11269      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11270      reg++;
11271   } while (reg != (r3 + 1));
11272
11273   return "lmg";
11274}
11275
11276static void
11277s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11278{
11279   UChar reg;
11280   IRTemp addr = newTemp(Ity_I64);
11281
11282   assign(addr, mkexpr(op2addr));
11283   reg = r1;
11284   do {
11285      IRTemp old = addr;
11286
11287      reg %= 16;
11288      store(mkexpr(addr), get_gpr_w1(reg));
11289      addr = newTemp(Ity_I64);
11290      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11291      reg++;
11292   } while( reg != (r3 + 1));
11293}
11294
11295static const HChar *
11296s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11297{
11298   s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11299
11300   return "stm";
11301}
11302
11303static const HChar *
11304s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11305{
11306   s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11307
11308   return "stmy";
11309}
11310
11311static const HChar *
11312s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11313{
11314   UChar reg;
11315   IRTemp addr = newTemp(Ity_I64);
11316
11317   assign(addr, mkexpr(op2addr));
11318   reg = r1;
11319   do {
11320      IRTemp old = addr;
11321
11322      reg %= 16;
11323      store(mkexpr(addr), get_gpr_w0(reg));
11324      addr = newTemp(Ity_I64);
11325      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11326      reg++;
11327   } while( reg != (r3 + 1));
11328
11329   return "stmh";
11330}
11331
11332static const HChar *
11333s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11334{
11335   UChar reg;
11336   IRTemp addr = newTemp(Ity_I64);
11337
11338   assign(addr, mkexpr(op2addr));
11339   reg = r1;
11340   do {
11341      IRTemp old = addr;
11342
11343      reg %= 16;
11344      store(mkexpr(addr), get_gpr_dw0(reg));
11345      addr = newTemp(Ity_I64);
11346      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11347      reg++;
11348   } while( reg != (r3 + 1));
11349
11350   return "stmg";
11351}
11352
11353static void
11354s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
11355{
11356   IRTemp old1 = newTemp(Ity_I8);
11357   IRTemp old2 = newTemp(Ity_I8);
11358   IRTemp new1 = newTemp(Ity_I8);
11359   IRTemp counter = newTemp(Ity_I32);
11360   IRTemp addr1 = newTemp(Ity_I64);
11361
11362   assign(counter, get_counter_w0());
11363
11364   assign(addr1, binop(Iop_Add64, mkexpr(start1),
11365                       unop(Iop_32Uto64, mkexpr(counter))));
11366
11367   assign(old1, load(Ity_I8, mkexpr(addr1)));
11368   assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11369                                   unop(Iop_32Uto64,mkexpr(counter)))));
11370   assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11371
11372   /* Special case: xc is used to zero memory */
11373   if (op == Iop_Xor8) {
11374      store(mkexpr(addr1),
11375            mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11376                  mkU8(0), mkexpr(new1)));
11377   } else
11378      store(mkexpr(addr1), mkexpr(new1));
11379   put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11380                        get_counter_w1()));
11381
11382   /* Check for end of field */
11383   put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
11384   iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
11385   s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11386                      False);
11387   put_counter_dw0(mkU64(0));
11388}
11389
11390static const HChar *
11391s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11392{
11393   IRTemp len = newTemp(Ity_I32);
11394
11395   assign(len, mkU32(length));
11396   s390_irgen_xonc(Iop_Xor8, len, start1, start2);
11397
11398   return "xc";
11399}
11400
11401static void
11402s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11403{
11404   IRTemp counter = newTemp(Ity_I32);
11405   IRTemp start = newTemp(Ity_I64);
11406   IRTemp addr  = newTemp(Ity_I64);
11407
11408   assign(start,
11409          binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11410
11411   if (length < 8) {
11412      UInt i;
11413
11414      for (i = 0; i <= length; ++i) {
11415         store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11416      }
11417   } else {
11418     assign(counter, get_counter_w0());
11419
11420     assign(addr, binop(Iop_Add64, mkexpr(start),
11421                        unop(Iop_32Uto64, mkexpr(counter))));
11422
11423     store(mkexpr(addr), mkU8(0));
11424
11425     /* Check for end of field */
11426     put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
11427     iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
11428
11429     /* Reset counter */
11430     put_counter_dw0(mkU64(0));
11431   }
11432
11433   s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11434
11435   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
11436      s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11437}
11438
11439static const HChar *
11440s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11441{
11442   IRTemp len = newTemp(Ity_I32);
11443
11444   assign(len, mkU32(length));
11445   s390_irgen_xonc(Iop_And8, len, start1, start2);
11446
11447   return "nc";
11448}
11449
11450static const HChar *
11451s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11452{
11453   IRTemp len = newTemp(Ity_I32);
11454
11455   assign(len, mkU32(length));
11456   s390_irgen_xonc(Iop_Or8, len, start1, start2);
11457
11458   return "oc";
11459}
11460
11461
11462static const HChar *
11463s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11464{
11465   IRTemp len = newTemp(Ity_I64);
11466
11467   assign(len, mkU64(length));
11468   s390_irgen_MVC_EX(len, start1, start2);
11469
11470   return "mvc";
11471}
11472
11473static const HChar *
11474s390_irgen_MVCL(UChar r1, UChar r2)
11475{
11476   IRTemp addr1 = newTemp(Ity_I64);
11477   IRTemp addr2 = newTemp(Ity_I64);
11478   IRTemp addr2_load = newTemp(Ity_I64);
11479   IRTemp r1p1 = newTemp(Ity_I32);   /* contents of r1 + 1 */
11480   IRTemp r2p1 = newTemp(Ity_I32);   /* contents of r2 + 1 */
11481   IRTemp len1 = newTemp(Ity_I32);
11482   IRTemp len2 = newTemp(Ity_I32);
11483   IRTemp pad = newTemp(Ity_I8);
11484   IRTemp single = newTemp(Ity_I8);
11485
11486   assign(addr1, get_gpr_dw0(r1));
11487   assign(r1p1, get_gpr_w1(r1 + 1));
11488   assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11489   assign(addr2, get_gpr_dw0(r2));
11490   assign(r2p1, get_gpr_w1(r2 + 1));
11491   assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11492   assign(pad, get_gpr_b4(r2 + 1));
11493
11494   /* len1 == 0 ? */
11495   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
11496   next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
11497
11498   /* Check for destructive overlap:
11499      addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11500   s390_cc_set(3);
11501   IRTemp cond1 = newTemp(Ity_I32);
11502   assign(cond1, unop(Iop_1Uto32,
11503                      binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11504   IRTemp cond2 = newTemp(Ity_I32);
11505   assign(cond2, unop(Iop_1Uto32,
11506                      binop(Iop_CmpLT64U, mkexpr(addr1),
11507                            binop(Iop_Add64, mkexpr(addr2),
11508                                  unop(Iop_32Uto64, mkexpr(len1))))));
11509   IRTemp cond3 = newTemp(Ity_I32);
11510   assign(cond3, unop(Iop_1Uto32,
11511                      binop(Iop_CmpLT64U,
11512                            mkexpr(addr1),
11513                            binop(Iop_Add64, mkexpr(addr2),
11514                                  unop(Iop_32Uto64, mkexpr(len2))))));
11515
11516   next_insn_if(binop(Iop_CmpEQ32,
11517                      binop(Iop_And32,
11518                            binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11519                            mkexpr(cond3)),
11520                      mkU32(1)));
11521
11522   /* See s390_irgen_CLCL for explanation why we cannot load directly
11523      and need two steps. */
11524   assign(addr2_load,
11525          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11526                mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11527   assign(single,
11528          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11529                mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11530
11531   store(mkexpr(addr1), mkexpr(single));
11532
11533   /* Update addr1 and len1 */
11534   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11535   put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11536
11537   /* Update addr2 and len2 */
11538   put_gpr_dw0(r2,
11539               mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11540                     mkexpr(addr2),
11541                     binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11542
11543   /* When updating len2 we must not modify bits (r2+1)[0:39] */
11544   put_gpr_w1(r2 + 1,
11545              mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11546                    binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11547                    binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11548
11549   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
11550   iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
11551
11552   return "mvcl";
11553}
11554
11555
11556static const HChar *
11557s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11558{
11559   IRTemp addr1, addr3, addr3_load, len1, len3, single;
11560
11561   addr1 = newTemp(Ity_I64);
11562   addr3 = newTemp(Ity_I64);
11563   addr3_load = newTemp(Ity_I64);
11564   len1 = newTemp(Ity_I64);
11565   len3 = newTemp(Ity_I64);
11566   single = newTemp(Ity_I8);
11567
11568   assign(addr1, get_gpr_dw0(r1));
11569   assign(len1, get_gpr_dw0(r1 + 1));
11570   assign(addr3, get_gpr_dw0(r3));
11571   assign(len3, get_gpr_dw0(r3 + 1));
11572
11573   // len1 == 0 ?
11574   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
11575   next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
11576
11577   /* This is a hack to prevent mvcle from reading from addr3 if it
11578      should read from the pad. Since the pad has no address, just
11579      read from the instruction, we discard that anyway */
11580   assign(addr3_load,
11581          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11582                mkU64(guest_IA_curr_instr), mkexpr(addr3)));
11583
11584   assign(single,
11585          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11586                unop(Iop_64to8, mkexpr(pad2)),
11587                load(Ity_I8, mkexpr(addr3_load))));
11588   store(mkexpr(addr1), mkexpr(single));
11589
11590   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11591
11592   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11593
11594   put_gpr_dw0(r3,
11595               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11596                     mkexpr(addr3),
11597                     binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
11598
11599   put_gpr_dw0(r3 + 1,
11600               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11601                     mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
11602
11603   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
11604   iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
11605
11606   return "mvcle";
11607}
11608
11609static const HChar *
11610s390_irgen_MVST(UChar r1, UChar r2)
11611{
11612   IRTemp addr1 = newTemp(Ity_I64);
11613   IRTemp addr2 = newTemp(Ity_I64);
11614   IRTemp end = newTemp(Ity_I8);
11615   IRTemp byte = newTemp(Ity_I8);
11616   IRTemp counter = newTemp(Ity_I64);
11617
11618   assign(addr1, get_gpr_dw0(r1));
11619   assign(addr2, get_gpr_dw0(r2));
11620   assign(counter, get_counter_dw0());
11621   assign(end, get_gpr_b7(0));
11622   assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11623   store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11624
11625   // We use unlimited as cpu-determined number
11626   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11627   iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
11628
11629   // and always set cc=1 at the end + update r1
11630   s390_cc_set(1);
11631   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11632   put_counter_dw0(mkU64(0));
11633
11634   return "mvst";
11635}
11636
11637static void
11638s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11639{
11640   IRTemp op1 = newTemp(Ity_I64);
11641   IRTemp result = newTemp(Ity_I64);
11642
11643   assign(op1, binop(Iop_32HLto64,
11644                     get_gpr_w1(r1),         // high 32 bits
11645                     get_gpr_w1(r1 + 1)));   // low  32 bits
11646   assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11647   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));   // remainder
11648   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11649}
11650
11651static void
11652s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11653{
11654   IRTemp op1 = newTemp(Ity_I128);
11655   IRTemp result = newTemp(Ity_I128);
11656
11657   assign(op1, binop(Iop_64HLto128,
11658                     get_gpr_dw0(r1),         // high 64 bits
11659                     get_gpr_dw0(r1 + 1)));   // low  64 bits
11660   assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11661   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));   // remainder
11662   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11663}
11664
11665static void
11666s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11667{
11668   IRTemp op1 = newTemp(Ity_I64);
11669   IRTemp result = newTemp(Ity_I128);
11670
11671   assign(op1, get_gpr_dw0(r1 + 1));
11672   assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11673   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));   // remainder
11674   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11675}
11676
11677static const HChar *
11678s390_irgen_DR(UChar r1, UChar r2)
11679{
11680   IRTemp op2 = newTemp(Ity_I32);
11681
11682   assign(op2, get_gpr_w1(r2));
11683
11684   s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11685
11686   return "dr";
11687}
11688
11689static const HChar *
11690s390_irgen_D(UChar r1, IRTemp op2addr)
11691{
11692   IRTemp op2 = newTemp(Ity_I32);
11693
11694   assign(op2, load(Ity_I32, mkexpr(op2addr)));
11695
11696   s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11697
11698   return "d";
11699}
11700
11701static const HChar *
11702s390_irgen_DLR(UChar r1, UChar r2)
11703{
11704   IRTemp op2 = newTemp(Ity_I32);
11705
11706   assign(op2, get_gpr_w1(r2));
11707
11708   s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11709
11710   return "dlr";
11711}
11712
11713static const HChar *
11714s390_irgen_DL(UChar r1, IRTemp op2addr)
11715{
11716   IRTemp op2 = newTemp(Ity_I32);
11717
11718   assign(op2, load(Ity_I32, mkexpr(op2addr)));
11719
11720   s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11721
11722   return "dl";
11723}
11724
11725static const HChar *
11726s390_irgen_DLG(UChar r1, IRTemp op2addr)
11727{
11728   IRTemp op2 = newTemp(Ity_I64);
11729
11730   assign(op2, load(Ity_I64, mkexpr(op2addr)));
11731
11732   s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11733
11734   return "dlg";
11735}
11736
11737static const HChar *
11738s390_irgen_DLGR(UChar r1, UChar r2)
11739{
11740   IRTemp op2 = newTemp(Ity_I64);
11741
11742   assign(op2, get_gpr_dw0(r2));
11743
11744   s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11745
11746   return "dlgr";
11747}
11748
11749static const HChar *
11750s390_irgen_DSGR(UChar r1, UChar r2)
11751{
11752   IRTemp op2 = newTemp(Ity_I64);
11753
11754   assign(op2, get_gpr_dw0(r2));
11755
11756   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11757
11758   return "dsgr";
11759}
11760
11761static const HChar *
11762s390_irgen_DSG(UChar r1, IRTemp op2addr)
11763{
11764   IRTemp op2 = newTemp(Ity_I64);
11765
11766   assign(op2, load(Ity_I64, mkexpr(op2addr)));
11767
11768   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11769
11770   return "dsg";
11771}
11772
11773static const HChar *
11774s390_irgen_DSGFR(UChar r1, UChar r2)
11775{
11776   IRTemp op2 = newTemp(Ity_I64);
11777
11778   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11779
11780   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11781
11782   return "dsgfr";
11783}
11784
11785static const HChar *
11786s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11787{
11788   IRTemp op2 = newTemp(Ity_I64);
11789
11790   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11791
11792   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11793
11794   return "dsgf";
11795}
11796
11797static void
11798s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11799{
11800   UChar reg;
11801   IRTemp addr = newTemp(Ity_I64);
11802
11803   assign(addr, mkexpr(op2addr));
11804   reg = r1;
11805   do {
11806      IRTemp old = addr;
11807
11808      reg %= 16;
11809      put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11810      addr = newTemp(Ity_I64);
11811      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11812      reg++;
11813   } while (reg != (r3 + 1));
11814}
11815
11816static const HChar *
11817s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11818{
11819   s390_irgen_load_ar_multiple(r1, r3, op2addr);
11820
11821   return "lam";
11822}
11823
11824static const HChar *
11825s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11826{
11827   s390_irgen_load_ar_multiple(r1, r3, op2addr);
11828
11829   return "lamy";
11830}
11831
11832static void
11833s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11834{
11835   UChar reg;
11836   IRTemp addr = newTemp(Ity_I64);
11837
11838   assign(addr, mkexpr(op2addr));
11839   reg = r1;
11840   do {
11841      IRTemp old = addr;
11842
11843      reg %= 16;
11844      store(mkexpr(addr), get_ar_w0(reg));
11845      addr = newTemp(Ity_I64);
11846      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11847      reg++;
11848   } while (reg != (r3 + 1));
11849}
11850
11851static const HChar *
11852s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11853{
11854   s390_irgen_store_ar_multiple(r1, r3, op2addr);
11855
11856   return "stam";
11857}
11858
11859static const HChar *
11860s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11861{
11862   s390_irgen_store_ar_multiple(r1, r3, op2addr);
11863
11864   return "stamy";
11865}
11866
11867
11868/* Implementation for 32-bit compare-and-swap */
11869static void
11870s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11871{
11872   IRCAS *cas;
11873   IRTemp op1 = newTemp(Ity_I32);
11874   IRTemp old_mem = newTemp(Ity_I32);
11875   IRTemp op3 = newTemp(Ity_I32);
11876   IRTemp result = newTemp(Ity_I32);
11877   IRTemp nequal = newTemp(Ity_I1);
11878
11879   assign(op1, get_gpr_w1(r1));
11880   assign(op3, get_gpr_w1(r3));
11881
11882   /* The first and second operands are compared. If they are equal,
11883      the third operand is stored at the second- operand location. */
11884   cas = mkIRCAS(IRTemp_INVALID, old_mem,
11885                 Iend_BE, mkexpr(op2addr),
11886                 NULL, mkexpr(op1), /* expected value */
11887                 NULL, mkexpr(op3)  /* new value */);
11888   stmt(IRStmt_CAS(cas));
11889
11890   /* Set CC. Operands compared equal -> 0, else 1. */
11891   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11892   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11893
11894   /* If operands were equal (cc == 0) just store the old value op1 in r1.
11895      Otherwise, store the old_value from memory in r1 and yield. */
11896   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11897   put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
11898   yield_if(mkexpr(nequal));
11899}
11900
11901static const HChar *
11902s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11903{
11904   s390_irgen_cas_32(r1, r3, op2addr);
11905
11906   return "cs";
11907}
11908
11909static const HChar *
11910s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11911{
11912   s390_irgen_cas_32(r1, r3, op2addr);
11913
11914   return "csy";
11915}
11916
11917static const HChar *
11918s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11919{
11920   IRCAS *cas;
11921   IRTemp op1 = newTemp(Ity_I64);
11922   IRTemp old_mem = newTemp(Ity_I64);
11923   IRTemp op3 = newTemp(Ity_I64);
11924   IRTemp result = newTemp(Ity_I64);
11925   IRTemp nequal = newTemp(Ity_I1);
11926
11927   assign(op1, get_gpr_dw0(r1));
11928   assign(op3, get_gpr_dw0(r3));
11929
11930   /* The first and second operands are compared. If they are equal,
11931      the third operand is stored at the second- operand location. */
11932   cas = mkIRCAS(IRTemp_INVALID, old_mem,
11933                 Iend_BE, mkexpr(op2addr),
11934                 NULL, mkexpr(op1), /* expected value */
11935                 NULL, mkexpr(op3)  /* new value */);
11936   stmt(IRStmt_CAS(cas));
11937
11938   /* Set CC. Operands compared equal -> 0, else 1. */
11939   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11940   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11941
11942   /* If operands were equal (cc == 0) just store the old value op1 in r1.
11943      Otherwise, store the old_value from memory in r1 and yield. */
11944   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11945   put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
11946   yield_if(mkexpr(nequal));
11947
11948   return "csg";
11949}
11950
11951/* Implementation for 32-bit compare-double-and-swap */
11952static void
11953s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11954{
11955   IRCAS *cas;
11956   IRTemp op1_high = newTemp(Ity_I32);
11957   IRTemp op1_low  = newTemp(Ity_I32);
11958   IRTemp old_mem_high = newTemp(Ity_I32);
11959   IRTemp old_mem_low  = newTemp(Ity_I32);
11960   IRTemp op3_high = newTemp(Ity_I32);
11961   IRTemp op3_low  = newTemp(Ity_I32);
11962   IRTemp result = newTemp(Ity_I32);
11963   IRTemp nequal = newTemp(Ity_I1);
11964
11965   assign(op1_high, get_gpr_w1(r1));
11966   assign(op1_low,  get_gpr_w1(r1+1));
11967   assign(op3_high, get_gpr_w1(r3));
11968   assign(op3_low,  get_gpr_w1(r3+1));
11969
11970   /* The first and second operands are compared. If they are equal,
11971      the third operand is stored at the second-operand location. */
11972   cas = mkIRCAS(old_mem_high, old_mem_low,
11973                 Iend_BE, mkexpr(op2addr),
11974                 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11975                 mkexpr(op3_high), mkexpr(op3_low)  /* new value */);
11976   stmt(IRStmt_CAS(cas));
11977
11978   /* Set CC. Operands compared equal -> 0, else 1. */
11979   assign(result, unop(Iop_1Uto32,
11980          binop(Iop_CmpNE32,
11981                binop(Iop_Or32,
11982                      binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11983                      binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11984                mkU32(0))));
11985
11986   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11987
11988   /* If operands were equal (cc == 0) just store the old value op1 in r1.
11989      Otherwise, store the old_value from memory in r1 and yield. */
11990   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11991   put_gpr_w1(r1,   mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11992   put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low),  mkexpr(op1_low)));
11993   yield_if(mkexpr(nequal));
11994}
11995
11996static const HChar *
11997s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11998{
11999   s390_irgen_cdas_32(r1, r3, op2addr);
12000
12001   return "cds";
12002}
12003
12004static const HChar *
12005s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
12006{
12007   s390_irgen_cdas_32(r1, r3, op2addr);
12008
12009   return "cdsy";
12010}
12011
12012static const HChar *
12013s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
12014{
12015   IRCAS *cas;
12016   IRTemp op1_high = newTemp(Ity_I64);
12017   IRTemp op1_low  = newTemp(Ity_I64);
12018   IRTemp old_mem_high = newTemp(Ity_I64);
12019   IRTemp old_mem_low  = newTemp(Ity_I64);
12020   IRTemp op3_high = newTemp(Ity_I64);
12021   IRTemp op3_low  = newTemp(Ity_I64);
12022   IRTemp result = newTemp(Ity_I64);
12023   IRTemp nequal = newTemp(Ity_I1);
12024
12025   assign(op1_high, get_gpr_dw0(r1));
12026   assign(op1_low,  get_gpr_dw0(r1+1));
12027   assign(op3_high, get_gpr_dw0(r3));
12028   assign(op3_low,  get_gpr_dw0(r3+1));
12029
12030   /* The first and second operands are compared. If they are equal,
12031      the third operand is stored at the second-operand location. */
12032   cas = mkIRCAS(old_mem_high, old_mem_low,
12033                 Iend_BE, mkexpr(op2addr),
12034                 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
12035                 mkexpr(op3_high), mkexpr(op3_low)  /* new value */);
12036   stmt(IRStmt_CAS(cas));
12037
12038   /* Set CC. Operands compared equal -> 0, else 1. */
12039   assign(result, unop(Iop_1Uto64,
12040          binop(Iop_CmpNE64,
12041                binop(Iop_Or64,
12042                      binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
12043                      binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
12044                mkU64(0))));
12045
12046   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12047
12048   /* If operands were equal (cc == 0) just store the old value op1 in r1.
12049      Otherwise, store the old_value from memory in r1 and yield. */
12050   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12051   put_gpr_dw0(r1,   mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
12052   put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low),  mkexpr(op1_low)));
12053   yield_if(mkexpr(nequal));
12054
12055   return "cdsg";
12056}
12057
12058
12059/* Binary floating point */
12060
12061static const HChar *
12062s390_irgen_AXBR(UChar r1, UChar r2)
12063{
12064   IRTemp op1 = newTemp(Ity_F128);
12065   IRTemp op2 = newTemp(Ity_F128);
12066   IRTemp result = newTemp(Ity_F128);
12067   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12068
12069   assign(op1, get_fpr_pair(r1));
12070   assign(op2, get_fpr_pair(r2));
12071   assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
12072                        mkexpr(op2)));
12073   put_fpr_pair(r1, mkexpr(result));
12074
12075   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12076
12077   return "axbr";
12078}
12079
12080static const HChar *
12081s390_irgen_CEBR(UChar r1, UChar r2)
12082{
12083   IRTemp op1 = newTemp(Ity_F32);
12084   IRTemp op2 = newTemp(Ity_F32);
12085   IRTemp cc_vex  = newTemp(Ity_I32);
12086   IRTemp cc_s390 = newTemp(Ity_I32);
12087
12088   assign(op1, get_fpr_w0(r1));
12089   assign(op2, get_fpr_w0(r2));
12090   assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12091
12092   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12093   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12094
12095   return "cebr";
12096}
12097
12098static const HChar *
12099s390_irgen_CDBR(UChar r1, UChar r2)
12100{
12101   IRTemp op1 = newTemp(Ity_F64);
12102   IRTemp op2 = newTemp(Ity_F64);
12103   IRTemp cc_vex  = newTemp(Ity_I32);
12104   IRTemp cc_s390 = newTemp(Ity_I32);
12105
12106   assign(op1, get_fpr_dw0(r1));
12107   assign(op2, get_fpr_dw0(r2));
12108   assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12109
12110   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12111   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12112
12113   return "cdbr";
12114}
12115
12116static const HChar *
12117s390_irgen_CXBR(UChar r1, UChar r2)
12118{
12119   IRTemp op1 = newTemp(Ity_F128);
12120   IRTemp op2 = newTemp(Ity_F128);
12121   IRTemp cc_vex  = newTemp(Ity_I32);
12122   IRTemp cc_s390 = newTemp(Ity_I32);
12123
12124   assign(op1, get_fpr_pair(r1));
12125   assign(op2, get_fpr_pair(r2));
12126   assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
12127
12128   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12129   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12130
12131   return "cxbr";
12132}
12133
12134static const HChar *
12135s390_irgen_CEB(UChar r1, IRTemp op2addr)
12136{
12137   IRTemp op1 = newTemp(Ity_F32);
12138   IRTemp op2 = newTemp(Ity_F32);
12139   IRTemp cc_vex  = newTemp(Ity_I32);
12140   IRTemp cc_s390 = newTemp(Ity_I32);
12141
12142   assign(op1, get_fpr_w0(r1));
12143   assign(op2, load(Ity_F32, mkexpr(op2addr)));
12144   assign(cc_vex,  binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12145
12146   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12147   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12148
12149   return "ceb";
12150}
12151
12152static const HChar *
12153s390_irgen_CDB(UChar r1, IRTemp op2addr)
12154{
12155   IRTemp op1 = newTemp(Ity_F64);
12156   IRTemp op2 = newTemp(Ity_F64);
12157   IRTemp cc_vex  = newTemp(Ity_I32);
12158   IRTemp cc_s390 = newTemp(Ity_I32);
12159
12160   assign(op1, get_fpr_dw0(r1));
12161   assign(op2, load(Ity_F64, mkexpr(op2addr)));
12162   assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12163
12164   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12165   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12166
12167   return "cdb";
12168}
12169
12170static const HChar *
12171s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
12172                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12173{
12174   IRTemp op2 = newTemp(Ity_I32);
12175
12176   assign(op2, get_gpr_w1(r2));
12177   put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
12178
12179   return "cxfbr";
12180}
12181
12182static const HChar *
12183s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
12184                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12185{
12186   if (! s390_host_has_fpext) {
12187      emulation_failure(EmFail_S390X_fpext);
12188   } else {
12189      IRTemp op2 = newTemp(Ity_I32);
12190
12191      assign(op2, get_gpr_w1(r2));
12192      put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
12193   }
12194   return "cxlfbr";
12195}
12196
12197
12198static const HChar *
12199s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
12200                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12201{
12202   IRTemp op2 = newTemp(Ity_I64);
12203
12204   assign(op2, get_gpr_dw0(r2));
12205   put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
12206
12207   return "cxgbr";
12208}
12209
12210static const HChar *
12211s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
12212                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12213{
12214   if (! s390_host_has_fpext) {
12215      emulation_failure(EmFail_S390X_fpext);
12216   } else {
12217      IRTemp op2 = newTemp(Ity_I64);
12218
12219      assign(op2, get_gpr_dw0(r2));
12220      put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
12221   }
12222   return "cxlgbr";
12223}
12224
12225static const HChar *
12226s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
12227                 UChar r1, UChar r2)
12228{
12229   IRTemp op = newTemp(Ity_F128);
12230   IRTemp result = newTemp(Ity_I32);
12231   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12232
12233   assign(op, get_fpr_pair(r2));
12234   assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
12235                        mkexpr(op)));
12236   put_gpr_w1(r1, mkexpr(result));
12237   s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
12238
12239   return "cfxbr";
12240}
12241
12242static const HChar *
12243s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12244                  UChar r1, UChar r2)
12245{
12246   if (! s390_host_has_fpext) {
12247      emulation_failure(EmFail_S390X_fpext);
12248   } else {
12249      IRTemp op = newTemp(Ity_F128);
12250      IRTemp result = newTemp(Ity_I32);
12251      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12252
12253      assign(op, get_fpr_pair(r2));
12254      assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
12255                           mkexpr(op)));
12256      put_gpr_w1(r1, mkexpr(result));
12257      s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
12258   }
12259   return "clfxbr";
12260}
12261
12262
12263static const HChar *
12264s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12265                 UChar r1, UChar r2)
12266{
12267   IRTemp op = newTemp(Ity_F128);
12268   IRTemp result = newTemp(Ity_I64);
12269   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12270
12271   assign(op, get_fpr_pair(r2));
12272   assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
12273                        mkexpr(op)));
12274   put_gpr_dw0(r1, mkexpr(result));
12275   s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
12276
12277   return "cgxbr";
12278}
12279
12280static const HChar *
12281s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12282                  UChar r1, UChar r2)
12283{
12284   if (! s390_host_has_fpext) {
12285      emulation_failure(EmFail_S390X_fpext);
12286   } else {
12287      IRTemp op = newTemp(Ity_F128);
12288      IRTemp result = newTemp(Ity_I64);
12289      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12290
12291      assign(op, get_fpr_pair(r2));
12292      assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
12293                           mkexpr(op)));
12294      put_gpr_dw0(r1, mkexpr(result));
12295      s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12296                              rounding_mode);
12297   }
12298   return "clgxbr";
12299}
12300
12301static const HChar *
12302s390_irgen_DXBR(UChar r1, UChar r2)
12303{
12304   IRTemp op1 = newTemp(Ity_F128);
12305   IRTemp op2 = newTemp(Ity_F128);
12306   IRTemp result = newTemp(Ity_F128);
12307   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12308
12309   assign(op1, get_fpr_pair(r1));
12310   assign(op2, get_fpr_pair(r2));
12311   assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
12312                        mkexpr(op2)));
12313   put_fpr_pair(r1, mkexpr(result));
12314
12315   return "dxbr";
12316}
12317
12318static const HChar *
12319s390_irgen_LTXBR(UChar r1, UChar r2)
12320{
12321   IRTemp result = newTemp(Ity_F128);
12322
12323   assign(result, get_fpr_pair(r2));
12324   put_fpr_pair(r1, mkexpr(result));
12325   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12326
12327   return "ltxbr";
12328}
12329
12330static const HChar *
12331s390_irgen_LCXBR(UChar r1, UChar r2)
12332{
12333   IRTemp result = newTemp(Ity_F128);
12334
12335   assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
12336   put_fpr_pair(r1, mkexpr(result));
12337   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12338
12339   return "lcxbr";
12340}
12341
12342static const HChar *
12343s390_irgen_LXDBR(UChar r1, UChar r2)
12344{
12345   IRTemp op = newTemp(Ity_F64);
12346
12347   assign(op, get_fpr_dw0(r2));
12348   put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12349
12350   return "lxdbr";
12351}
12352
12353static const HChar *
12354s390_irgen_LXEBR(UChar r1, UChar r2)
12355{
12356   IRTemp op = newTemp(Ity_F32);
12357
12358   assign(op, get_fpr_w0(r2));
12359   put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12360
12361   return "lxebr";
12362}
12363
12364static const HChar *
12365s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12366{
12367   IRTemp op = newTemp(Ity_F64);
12368
12369   assign(op, load(Ity_F64, mkexpr(op2addr)));
12370   put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12371
12372   return "lxdb";
12373}
12374
12375static const HChar *
12376s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12377{
12378   IRTemp op = newTemp(Ity_F32);
12379
12380   assign(op, load(Ity_F32, mkexpr(op2addr)));
12381   put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12382
12383   return "lxeb";
12384}
12385
12386static const HChar *
12387s390_irgen_FIEBRA(UChar m3, UChar m4 __attribute__((unused)),
12388                  UChar r1, UChar r2)
12389{
12390   IRTemp result = newTemp(Ity_F32);
12391
12392   assign(result, binop(Iop_RoundF32toInt, mkexpr(encode_bfp_rounding_mode(m3)),
12393                        get_fpr_w0(r2)));
12394   put_fpr_w0(r1, mkexpr(result));
12395
12396   return "fiebra";
12397}
12398
12399static const HChar *
12400s390_irgen_FIDBRA(UChar m3, UChar m4 __attribute__((unused)),
12401                  UChar r1, UChar r2)
12402{
12403   IRTemp result = newTemp(Ity_F64);
12404
12405   assign(result, binop(Iop_RoundF64toInt, mkexpr(encode_bfp_rounding_mode(m3)),
12406                        get_fpr_dw0(r2)));
12407   put_fpr_dw0(r1, mkexpr(result));
12408
12409   return "fidbra";
12410}
12411
12412static const HChar *
12413s390_irgen_FIXBRA(UChar m3, UChar m4 __attribute__((unused)),
12414                  UChar r1, UChar r2)
12415{
12416   IRTemp result = newTemp(Ity_F128);
12417
12418   assign(result, binop(Iop_RoundF128toInt, mkexpr(encode_bfp_rounding_mode(m3)),
12419                        get_fpr_pair(r2)));
12420   put_fpr_pair(r1, mkexpr(result));
12421
12422   return "fixbra";
12423}
12424
12425static const HChar *
12426s390_irgen_LNEBR(UChar r1, UChar r2)
12427{
12428   IRTemp result = newTemp(Ity_F32);
12429
12430   assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12431   put_fpr_w0(r1, mkexpr(result));
12432   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12433
12434   return "lnebr";
12435}
12436
12437static const HChar *
12438s390_irgen_LNDBR(UChar r1, UChar r2)
12439{
12440   IRTemp result = newTemp(Ity_F64);
12441
12442   assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12443   put_fpr_dw0(r1, mkexpr(result));
12444   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12445
12446   return "lndbr";
12447}
12448
12449static const HChar *
12450s390_irgen_LNXBR(UChar r1, UChar r2)
12451{
12452   IRTemp result = newTemp(Ity_F128);
12453
12454   assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12455   put_fpr_pair(r1, mkexpr(result));
12456   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12457
12458   return "lnxbr";
12459}
12460
12461static const HChar *
12462s390_irgen_LPEBR(UChar r1, UChar r2)
12463{
12464   IRTemp result = newTemp(Ity_F32);
12465
12466   assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12467   put_fpr_w0(r1, mkexpr(result));
12468   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12469
12470   return "lpebr";
12471}
12472
12473static const HChar *
12474s390_irgen_LPDBR(UChar r1, UChar r2)
12475{
12476   IRTemp result = newTemp(Ity_F64);
12477
12478   assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12479   put_fpr_dw0(r1, mkexpr(result));
12480   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12481
12482   return "lpdbr";
12483}
12484
12485static const HChar *
12486s390_irgen_LPXBR(UChar r1, UChar r2)
12487{
12488   IRTemp result = newTemp(Ity_F128);
12489
12490   assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12491   put_fpr_pair(r1, mkexpr(result));
12492   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12493
12494   return "lpxbr";
12495}
12496
12497static const HChar *
12498s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12499                 UChar r1, UChar r2)
12500{
12501   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
12502      emulation_warning(EmWarn_S390X_fpext_rounding);
12503      m3 = S390_BFP_ROUND_PER_FPC;
12504   }
12505   IRTemp result = newTemp(Ity_F64);
12506
12507   assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
12508                        get_fpr_pair(r2)));
12509   put_fpr_dw0(r1, mkexpr(result));
12510
12511   return "ldxbr";
12512}
12513
12514static const HChar *
12515s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12516                 UChar r1, UChar r2)
12517{
12518   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
12519      emulation_warning(EmWarn_S390X_fpext_rounding);
12520      m3 = S390_BFP_ROUND_PER_FPC;
12521   }
12522   IRTemp result = newTemp(Ity_F32);
12523
12524   assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
12525                        get_fpr_pair(r2)));
12526   put_fpr_w0(r1, mkexpr(result));
12527
12528   return "lexbr";
12529}
12530
12531static const HChar *
12532s390_irgen_MXBR(UChar r1, UChar r2)
12533{
12534   IRTemp op1 = newTemp(Ity_F128);
12535   IRTemp op2 = newTemp(Ity_F128);
12536   IRTemp result = newTemp(Ity_F128);
12537   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12538
12539   assign(op1, get_fpr_pair(r1));
12540   assign(op2, get_fpr_pair(r2));
12541   assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
12542                        mkexpr(op2)));
12543   put_fpr_pair(r1, mkexpr(result));
12544
12545   return "mxbr";
12546}
12547
12548static const HChar *
12549s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12550{
12551   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12552
12553   put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
12554                      get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
12555
12556   return "maebr";
12557}
12558
12559static const HChar *
12560s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12561{
12562   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12563
12564   put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
12565                       get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
12566
12567   return "madbr";
12568}
12569
12570static const HChar *
12571s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12572{
12573   IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
12574   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12575
12576   put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
12577                      get_fpr_w0(r3), op2, get_fpr_w0(r1)));
12578
12579   return "maeb";
12580}
12581
12582static const HChar *
12583s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12584{
12585   IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
12586   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12587
12588   put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
12589                       get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
12590
12591   return "madb";
12592}
12593
12594static const HChar *
12595s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12596{
12597   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12598
12599   put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
12600                      get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
12601
12602   return "msebr";
12603}
12604
12605static const HChar *
12606s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12607{
12608   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12609
12610   put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
12611                       get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
12612
12613   return "msdbr";
12614}
12615
12616static const HChar *
12617s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12618{
12619   IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
12620   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12621
12622   put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
12623                      get_fpr_w0(r3), op2, get_fpr_w0(r1)));
12624
12625   return "mseb";
12626}
12627
12628static const HChar *
12629s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12630{
12631   IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
12632   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12633
12634   put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
12635                       get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
12636
12637   return "msdb";
12638}
12639
12640static const HChar *
12641s390_irgen_SQEBR(UChar r1, UChar r2)
12642{
12643   IRTemp result = newTemp(Ity_F32);
12644   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12645
12646   assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
12647   put_fpr_w0(r1, mkexpr(result));
12648
12649   return "sqebr";
12650}
12651
12652static const HChar *
12653s390_irgen_SQDBR(UChar r1, UChar r2)
12654{
12655   IRTemp result = newTemp(Ity_F64);
12656   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12657
12658   assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
12659   put_fpr_dw0(r1, mkexpr(result));
12660
12661   return "sqdbr";
12662}
12663
12664static const HChar *
12665s390_irgen_SQXBR(UChar r1, UChar r2)
12666{
12667   IRTemp result = newTemp(Ity_F128);
12668   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12669
12670   assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12671                        get_fpr_pair(r2)));
12672   put_fpr_pair(r1, mkexpr(result));
12673
12674   return "sqxbr";
12675}
12676
12677static const HChar *
12678s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12679{
12680   IRTemp op = newTemp(Ity_F32);
12681   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12682
12683   assign(op, load(Ity_F32, mkexpr(op2addr)));
12684   put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
12685
12686   return "sqeb";
12687}
12688
12689static const HChar *
12690s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12691{
12692   IRTemp op = newTemp(Ity_F64);
12693   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12694
12695   assign(op, load(Ity_F64, mkexpr(op2addr)));
12696   put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
12697
12698   return "sqdb";
12699}
12700
12701static const HChar *
12702s390_irgen_SXBR(UChar r1, UChar r2)
12703{
12704   IRTemp op1 = newTemp(Ity_F128);
12705   IRTemp op2 = newTemp(Ity_F128);
12706   IRTemp result = newTemp(Ity_F128);
12707   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12708
12709   assign(op1, get_fpr_pair(r1));
12710   assign(op2, get_fpr_pair(r2));
12711   assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
12712                        mkexpr(op2)));
12713   put_fpr_pair(r1, mkexpr(result));
12714   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12715
12716   return "sxbr";
12717}
12718
12719static const HChar *
12720s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12721{
12722   IRTemp value = newTemp(Ity_F32);
12723
12724   assign(value, get_fpr_w0(r1));
12725
12726   s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12727
12728   return "tceb";
12729}
12730
12731static const HChar *
12732s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12733{
12734   IRTemp value = newTemp(Ity_F64);
12735
12736   assign(value, get_fpr_dw0(r1));
12737
12738   s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12739
12740   return "tcdb";
12741}
12742
12743static const HChar *
12744s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12745{
12746   IRTemp value = newTemp(Ity_F128);
12747
12748   assign(value, get_fpr_pair(r1));
12749
12750   s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12751
12752   return "tcxb";
12753}
12754
12755static const HChar *
12756s390_irgen_LCDFR(UChar r1, UChar r2)
12757{
12758   IRTemp result = newTemp(Ity_F64);
12759
12760   assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12761   put_fpr_dw0(r1, mkexpr(result));
12762
12763   return "lcdfr";
12764}
12765
12766static const HChar *
12767s390_irgen_LNDFR(UChar r1, UChar r2)
12768{
12769   IRTemp result = newTemp(Ity_F64);
12770
12771   assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12772   put_fpr_dw0(r1, mkexpr(result));
12773
12774   return "lndfr";
12775}
12776
12777static const HChar *
12778s390_irgen_LPDFR(UChar r1, UChar r2)
12779{
12780   IRTemp result = newTemp(Ity_F64);
12781
12782   assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12783   put_fpr_dw0(r1, mkexpr(result));
12784
12785   return "lpdfr";
12786}
12787
12788static const HChar *
12789s390_irgen_LDGR(UChar r1, UChar r2)
12790{
12791   put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12792
12793   return "ldgr";
12794}
12795
12796static const HChar *
12797s390_irgen_LGDR(UChar r1, UChar r2)
12798{
12799   put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12800
12801   return "lgdr";
12802}
12803
12804
12805static const HChar *
12806s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12807{
12808   IRTemp sign  = newTemp(Ity_I64);
12809   IRTemp value = newTemp(Ity_I64);
12810
12811   assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12812                      mkU64(1ULL << 63)));
12813   assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12814                       mkU64((1ULL << 63) - 1)));
12815   put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12816                                                    mkexpr(sign))));
12817
12818   return "cpsdr";
12819}
12820
12821
12822static IRExpr *
12823s390_call_cvb(IRExpr *in)
12824{
12825   IRExpr **args, *call;
12826
12827   args = mkIRExprVec_1(in);
12828   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12829                        "s390_do_cvb", &s390_do_cvb, args);
12830
12831   /* Nothing is excluded from definedness checking. */
12832   call->Iex.CCall.cee->mcx_mask = 0;
12833
12834   return call;
12835}
12836
12837static const HChar *
12838s390_irgen_CVB(UChar r1, IRTemp op2addr)
12839{
12840   put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12841
12842   return "cvb";
12843}
12844
12845static const HChar *
12846s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12847{
12848   put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12849
12850   return "cvby";
12851}
12852
12853
12854static IRExpr *
12855s390_call_cvd(IRExpr *in)
12856{
12857   IRExpr **args, *call;
12858
12859   args = mkIRExprVec_1(in);
12860   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12861                        "s390_do_cvd", &s390_do_cvd, args);
12862
12863   /* Nothing is excluded from definedness checking. */
12864   call->Iex.CCall.cee->mcx_mask = 0;
12865
12866   return call;
12867}
12868
12869static const HChar *
12870s390_irgen_CVD(UChar r1, IRTemp op2addr)
12871{
12872   store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
12873
12874   return "cvd";
12875}
12876
12877static const HChar *
12878s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12879{
12880   store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12881
12882   return "cvdy";
12883}
12884
12885static const HChar *
12886s390_irgen_FLOGR(UChar r1, UChar r2)
12887{
12888   IRTemp input    = newTemp(Ity_I64);
12889   IRTemp not_zero = newTemp(Ity_I64);
12890   IRTemp tmpnum   = newTemp(Ity_I64);
12891   IRTemp num      = newTemp(Ity_I64);
12892   IRTemp shift_amount = newTemp(Ity_I8);
12893
12894   /* We use the "count leading zeroes" operator because the number of
12895      leading zeroes is identical with the bit position of the first '1' bit.
12896      However, that operator does not work when the input value is zero.
12897      Therefore, we set the LSB of the input value to 1 and use Clz64 on
12898      the modified value. If input == 0, then the result is 64. Otherwise,
12899      the result of Clz64 is what we want. */
12900
12901   assign(input, get_gpr_dw0(r2));
12902   assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12903   assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12904
12905   /* num = (input == 0) ? 64 : tmpnum */
12906   assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12907                     /* == 0 */ mkU64(64),
12908                     /* != 0 */ mkexpr(tmpnum)));
12909
12910   put_gpr_dw0(r1, mkexpr(num));
12911
12912   /* Set the leftmost '1' bit of the input value to zero. The general scheme
12913      is to first shift the input value by NUM + 1 bits to the left which
12914      causes the leftmost '1' bit to disappear. Then we shift logically to
12915      the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12916      Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12917      the width of the value-to-be-shifted, we need to special case
12918      NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12919      For both such INPUT values the result will be 0. */
12920
12921   assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12922                          mkU64(1))));
12923
12924   put_gpr_dw0(r1 + 1,
12925               mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12926                     /* == 0 || == 1*/ mkU64(0),
12927                     /* otherwise */
12928                     binop(Iop_Shr64,
12929                           binop(Iop_Shl64, mkexpr(input),
12930                                 mkexpr(shift_amount)),
12931                           mkexpr(shift_amount))));
12932
12933   /* Compare the original value as an unsigned integer with 0. */
12934   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12935                      mktemp(Ity_I64, mkU64(0)), False);
12936
12937   return "flogr";
12938}
12939
12940static const HChar *
12941s390_irgen_STCK(IRTemp op2addr)
12942{
12943   IRDirty *d;
12944   IRTemp cc = newTemp(Ity_I64);
12945
12946   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12947                         &s390x_dirtyhelper_STCK,
12948                         mkIRExprVec_1(mkexpr(op2addr)));
12949   d->mFx   = Ifx_Write;
12950   d->mAddr = mkexpr(op2addr);
12951   d->mSize = 8;
12952   stmt(IRStmt_Dirty(d));
12953   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12954                      mkexpr(cc), mkU64(0), mkU64(0));
12955   return "stck";
12956}
12957
12958static const HChar *
12959s390_irgen_STCKF(IRTemp op2addr)
12960{
12961   if (! s390_host_has_stckf) {
12962      emulation_failure(EmFail_S390X_stckf);
12963   } else {
12964      IRTemp cc = newTemp(Ity_I64);
12965
12966      IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12967                                     &s390x_dirtyhelper_STCKF,
12968                                     mkIRExprVec_1(mkexpr(op2addr)));
12969      d->mFx   = Ifx_Write;
12970      d->mAddr = mkexpr(op2addr);
12971      d->mSize = 8;
12972      stmt(IRStmt_Dirty(d));
12973      s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12974                         mkexpr(cc), mkU64(0), mkU64(0));
12975   }
12976   return "stckf";
12977}
12978
12979static const HChar *
12980s390_irgen_STCKE(IRTemp op2addr)
12981{
12982   IRDirty *d;
12983   IRTemp cc = newTemp(Ity_I64);
12984
12985   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12986                         &s390x_dirtyhelper_STCKE,
12987                         mkIRExprVec_1(mkexpr(op2addr)));
12988   d->mFx   = Ifx_Write;
12989   d->mAddr = mkexpr(op2addr);
12990   d->mSize = 16;
12991   stmt(IRStmt_Dirty(d));
12992   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12993                      mkexpr(cc), mkU64(0), mkU64(0));
12994   return "stcke";
12995}
12996
12997static const HChar *
12998s390_irgen_STFLE(IRTemp op2addr)
12999{
13000   if (! s390_host_has_stfle) {
13001      emulation_failure(EmFail_S390X_stfle);
13002      return "stfle";
13003   }
13004
13005   IRDirty *d;
13006   IRTemp cc = newTemp(Ity_I64);
13007
13008   /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper */
13009   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
13010                         &s390x_dirtyhelper_STFLE,
13011                         mkIRExprVec_2(IRExpr_BBPTR(), mkexpr(op2addr)));
13012
13013   d->nFxState = 1;
13014   vex_bzero(&d->fxState, sizeof(d->fxState));
13015
13016   d->fxState[0].fx     = Ifx_Modify;  /* read then write */
13017   d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
13018   d->fxState[0].size   = sizeof(ULong);
13019
13020   d->mAddr = mkexpr(op2addr);
13021   /* Pretend all double words are written */
13022   d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
13023   d->mFx   = Ifx_Write;
13024
13025   stmt(IRStmt_Dirty(d));
13026
13027   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
13028
13029   return "stfle";
13030}
13031
13032static const HChar *
13033s390_irgen_CKSM(UChar r1,UChar r2)
13034{
13035   IRTemp addr = newTemp(Ity_I64);
13036   IRTemp op = newTemp(Ity_I32);
13037   IRTemp len = newTemp(Ity_I64);
13038   IRTemp oldval = newTemp(Ity_I32);
13039   IRTemp mask = newTemp(Ity_I32);
13040   IRTemp newop = newTemp(Ity_I32);
13041   IRTemp result = newTemp(Ity_I32);
13042   IRTemp result1 = newTemp(Ity_I32);
13043   IRTemp inc = newTemp(Ity_I64);
13044
13045   assign(oldval, get_gpr_w1(r1));
13046   assign(addr, get_gpr_dw0(r2));
13047   assign(len, get_gpr_dw0(r2+1));
13048
13049   /* Condition code is always zero. */
13050   s390_cc_set(0);
13051
13052   /* If length is zero, there is no need to calculate the checksum */
13053   next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
13054
13055   /* Assiging the increment variable to adjust address and length
13056      later on. */
13057   assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
13058                           mkexpr(len), mkU64(4)));
13059
13060   /* If length < 4 the final 4-byte 2nd operand value is computed by
13061      appending the remaining bytes to the right with 0. This is done
13062      by AND'ing the 4 bytes loaded from memory with an appropriate
13063      mask. If length >= 4, that mask is simply 0xffffffff. */
13064
13065   assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
13066                      /* Mask computation when len < 4:
13067                         0xffffffff << (32 - (len % 4)*8) */
13068                      binop(Iop_Shl32, mkU32(0xffffffff),
13069                            unop(Iop_32to8,
13070                                 binop(Iop_Sub32, mkU32(32),
13071                                       binop(Iop_Shl32,
13072                                             unop(Iop_64to32,
13073                                                  binop(Iop_And64,
13074                                                        mkexpr(len), mkU64(3))),
13075                                             mkU8(3))))),
13076                      mkU32(0xffffffff)));
13077
13078   assign(op, load(Ity_I32, mkexpr(addr)));
13079   assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
13080   assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
13081
13082   /* Checking for carry */
13083   assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
13084                         binop(Iop_Add32, mkexpr(result), mkU32(1)),
13085                         mkexpr(result)));
13086
13087   put_gpr_w1(r1, mkexpr(result1));
13088   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
13089   put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
13090
13091   iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
13092
13093   return "cksm";
13094}
13095
13096static const HChar *
13097s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
13098{
13099   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13100   src_addr = newTemp(Ity_I64);
13101   des_addr = newTemp(Ity_I64);
13102   tab_addr = newTemp(Ity_I64);
13103   test_byte = newTemp(Ity_I8);
13104   src_len = newTemp(Ity_I64);
13105
13106   assign(src_addr, get_gpr_dw0(r2));
13107   assign(des_addr, get_gpr_dw0(r1));
13108   assign(tab_addr, get_gpr_dw0(1));
13109   assign(src_len, get_gpr_dw0(r1+1));
13110   assign(test_byte, get_gpr_b7(0));
13111
13112   IRTemp op = newTemp(Ity_I8);
13113   IRTemp op1 = newTemp(Ity_I8);
13114   IRTemp result = newTemp(Ity_I64);
13115
13116   /* End of source string? We're done; proceed to next insn */
13117   s390_cc_set(0);
13118   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13119
13120   /* Load character from source string, index translation table and
13121      store translated character in op1. */
13122   assign(op, load(Ity_I8, mkexpr(src_addr)));
13123
13124   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13125                        mkexpr(tab_addr)));
13126   assign(op1, load(Ity_I8, mkexpr(result)));
13127
13128   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13129      s390_cc_set(1);
13130      next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
13131   }
13132   store(get_gpr_dw0(r1), mkexpr(op1));
13133
13134   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13135   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13136   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13137
13138   iterate();
13139
13140   return "troo";
13141}
13142
13143static const HChar *
13144s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
13145{
13146   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13147   src_addr = newTemp(Ity_I64);
13148   des_addr = newTemp(Ity_I64);
13149   tab_addr = newTemp(Ity_I64);
13150   test_byte = newTemp(Ity_I8);
13151   src_len = newTemp(Ity_I64);
13152
13153   assign(src_addr, get_gpr_dw0(r2));
13154   assign(des_addr, get_gpr_dw0(r1));
13155   assign(tab_addr, get_gpr_dw0(1));
13156   assign(src_len, get_gpr_dw0(r1+1));
13157   assign(test_byte, get_gpr_b7(0));
13158
13159   IRTemp op = newTemp(Ity_I16);
13160   IRTemp op1 = newTemp(Ity_I8);
13161   IRTemp result = newTemp(Ity_I64);
13162
13163   /* End of source string? We're done; proceed to next insn */
13164   s390_cc_set(0);
13165   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13166
13167   /* Load character from source string, index translation table and
13168      store translated character in op1. */
13169   assign(op, load(Ity_I16, mkexpr(src_addr)));
13170
13171   assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13172                        mkexpr(tab_addr)));
13173
13174   assign(op1, load(Ity_I8, mkexpr(result)));
13175
13176   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13177      s390_cc_set(1);
13178      next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
13179   }
13180   store(get_gpr_dw0(r1), mkexpr(op1));
13181
13182   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13183   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13184   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13185
13186   iterate();
13187
13188   return "trto";
13189}
13190
13191static const HChar *
13192s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
13193{
13194   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13195   src_addr = newTemp(Ity_I64);
13196   des_addr = newTemp(Ity_I64);
13197   tab_addr = newTemp(Ity_I64);
13198   test_byte = newTemp(Ity_I16);
13199   src_len = newTemp(Ity_I64);
13200
13201   assign(src_addr, get_gpr_dw0(r2));
13202   assign(des_addr, get_gpr_dw0(r1));
13203   assign(tab_addr, get_gpr_dw0(1));
13204   assign(src_len, get_gpr_dw0(r1+1));
13205   assign(test_byte, get_gpr_hw3(0));
13206
13207   IRTemp op = newTemp(Ity_I8);
13208   IRTemp op1 = newTemp(Ity_I16);
13209   IRTemp result = newTemp(Ity_I64);
13210
13211   /* End of source string? We're done; proceed to next insn */
13212   s390_cc_set(0);
13213   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13214
13215   /* Load character from source string, index translation table and
13216      store translated character in op1. */
13217   assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
13218
13219   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13220                        mkexpr(tab_addr)));
13221   assign(op1, load(Ity_I16, mkexpr(result)));
13222
13223   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13224      s390_cc_set(1);
13225      next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
13226   }
13227   store(get_gpr_dw0(r1), mkexpr(op1));
13228
13229   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13230   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13231   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13232
13233   iterate();
13234
13235   return "trot";
13236}
13237
13238static const HChar *
13239s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
13240{
13241   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13242   src_addr = newTemp(Ity_I64);
13243   des_addr = newTemp(Ity_I64);
13244   tab_addr = newTemp(Ity_I64);
13245   test_byte = newTemp(Ity_I16);
13246   src_len = newTemp(Ity_I64);
13247
13248   assign(src_addr, get_gpr_dw0(r2));
13249   assign(des_addr, get_gpr_dw0(r1));
13250   assign(tab_addr, get_gpr_dw0(1));
13251   assign(src_len, get_gpr_dw0(r1+1));
13252   assign(test_byte, get_gpr_hw3(0));
13253
13254   IRTemp op = newTemp(Ity_I16);
13255   IRTemp op1 = newTemp(Ity_I16);
13256   IRTemp result = newTemp(Ity_I64);
13257
13258   /* End of source string? We're done; proceed to next insn */
13259   s390_cc_set(0);
13260   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13261
13262   /* Load character from source string, index translation table and
13263      store translated character in op1. */
13264   assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
13265
13266   assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13267                        mkexpr(tab_addr)));
13268   assign(op1, load(Ity_I16, mkexpr(result)));
13269
13270   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13271      s390_cc_set(1);
13272      next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
13273   }
13274
13275   store(get_gpr_dw0(r1), mkexpr(op1));
13276
13277   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13278   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13279   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13280
13281   iterate();
13282
13283   return "trtt";
13284}
13285
13286static const HChar *
13287s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13288{
13289   IRTemp len = newTemp(Ity_I64);
13290
13291   assign(len, mkU64(length));
13292   s390_irgen_TR_EX(len, start1, start2);
13293
13294   return "tr";
13295}
13296
13297static const HChar *
13298s390_irgen_TRE(UChar r1,UChar r2)
13299{
13300   IRTemp src_addr, tab_addr, src_len, test_byte;
13301   src_addr = newTemp(Ity_I64);
13302   tab_addr = newTemp(Ity_I64);
13303   src_len = newTemp(Ity_I64);
13304   test_byte = newTemp(Ity_I8);
13305
13306   assign(src_addr, get_gpr_dw0(r1));
13307   assign(src_len, get_gpr_dw0(r1+1));
13308   assign(tab_addr, get_gpr_dw0(r2));
13309   assign(test_byte, get_gpr_b7(0));
13310
13311   IRTemp op = newTemp(Ity_I8);
13312   IRTemp op1 = newTemp(Ity_I8);
13313   IRTemp result = newTemp(Ity_I64);
13314
13315   /* End of source string? We're done; proceed to next insn */
13316   s390_cc_set(0);
13317   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13318
13319   /* Load character from source string and compare with test byte */
13320   assign(op, load(Ity_I8, mkexpr(src_addr)));
13321
13322   s390_cc_set(1);
13323   next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
13324
13325   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13326			mkexpr(tab_addr)));
13327
13328   assign(op1, load(Ity_I8, mkexpr(result)));
13329
13330   store(get_gpr_dw0(r1), mkexpr(op1));
13331   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13332   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13333
13334   iterate();
13335
13336   return "tre";
13337}
13338
13339static IRExpr *
13340s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13341{
13342   IRExpr **args, *call;
13343   args = mkIRExprVec_2(srcval, low_surrogate);
13344   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13345                       "s390_do_cu21", &s390_do_cu21, args);
13346
13347   /* Nothing is excluded from definedness checking. */
13348   call->Iex.CCall.cee->mcx_mask = 0;
13349
13350   return call;
13351}
13352
13353static const HChar *
13354s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13355{
13356   IRTemp addr1 = newTemp(Ity_I64);
13357   IRTemp addr2 = newTemp(Ity_I64);
13358   IRTemp len1 = newTemp(Ity_I64);
13359   IRTemp len2 = newTemp(Ity_I64);
13360
13361   assign(addr1, get_gpr_dw0(r1));
13362   assign(addr2, get_gpr_dw0(r2));
13363   assign(len1, get_gpr_dw0(r1 + 1));
13364   assign(len2, get_gpr_dw0(r2 + 1));
13365
13366   /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13367      there are less than 2 bytes left, then the 2nd operand is exhausted
13368      and we're done here. cc = 0 */
13369   s390_cc_set(0);
13370   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
13371
13372   /* There are at least two bytes there. Read them. */
13373   IRTemp srcval = newTemp(Ity_I32);
13374   assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13375
13376   /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13377      inside the interval [0xd800 - 0xdbff] */
13378   IRTemp  is_high_surrogate = newTemp(Ity_I32);
13379   IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13380                         mkU32(1), mkU32(0));
13381   IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13382                         mkU32(1), mkU32(0));
13383   assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13384
13385   /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13386      then the 2nd operand is exhausted and we're done here. cc = 0 */
13387   IRExpr *not_enough_bytes =
13388      mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13389
13390   next_insn_if(binop(Iop_CmpEQ32,
13391                      binop(Iop_And32, mkexpr(is_high_surrogate),
13392                            not_enough_bytes), mkU32(1)));
13393
13394   /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13395      surrogate, read the next two bytes (low surrogate). */
13396   IRTemp  low_surrogate = newTemp(Ity_I32);
13397   IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13398
13399   assign(low_surrogate,
13400          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13401                unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13402                mkU32(0)));  // any value is fine; it will not be used
13403
13404   /* Call the helper */
13405   IRTemp retval = newTemp(Ity_I64);
13406   assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13407                                 unop(Iop_32Uto64, mkexpr(low_surrogate))));
13408
13409   /* Before we can test whether the 1st operand is exhausted we need to
13410      test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13411   if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13412      IRExpr *invalid_low_surrogate =
13413         binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13414
13415      s390_cc_set(2);
13416      next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
13417   }
13418
13419   /* Now test whether the 1st operand is exhausted */
13420   IRTemp num_bytes = newTemp(Ity_I64);
13421   assign(num_bytes, binop(Iop_And64,
13422                           binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13423                           mkU64(0xff)));
13424   s390_cc_set(1);
13425   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13426
13427   /* Extract the bytes to be stored at addr1 */
13428   IRTemp data = newTemp(Ity_I64);
13429   assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13430
13431   /* To store the bytes construct 4 dirty helper calls. The helper calls
13432      are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13433      one of them will be called at runtime. */
13434   UInt i;
13435   for (i = 1; i <= 4; ++i) {
13436      IRDirty *d;
13437
13438      d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13439                            &s390x_dirtyhelper_CUxy,
13440                            mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13441                                          mkexpr(num_bytes)));
13442      d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13443      d->mFx   = Ifx_Write;
13444      d->mAddr = mkexpr(addr1);
13445      d->mSize = i;
13446      stmt(IRStmt_Dirty(d));
13447   }
13448
13449   /* Update source address and length */
13450   IRTemp num_src_bytes = newTemp(Ity_I64);
13451   assign(num_src_bytes,
13452          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13453                mkU64(4), mkU64(2)));
13454   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13455   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
13456
13457   /* Update destination address and length */
13458   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13459   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13460
13461   iterate();
13462
13463   return "cu21";
13464}
13465
13466static IRExpr *
13467s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13468{
13469   IRExpr **args, *call;
13470   args = mkIRExprVec_2(srcval, low_surrogate);
13471   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13472                       "s390_do_cu24", &s390_do_cu24, args);
13473
13474   /* Nothing is excluded from definedness checking. */
13475   call->Iex.CCall.cee->mcx_mask = 0;
13476
13477   return call;
13478}
13479
13480static const HChar *
13481s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13482{
13483   IRTemp addr1 = newTemp(Ity_I64);
13484   IRTemp addr2 = newTemp(Ity_I64);
13485   IRTemp len1 = newTemp(Ity_I64);
13486   IRTemp len2 = newTemp(Ity_I64);
13487
13488   assign(addr1, get_gpr_dw0(r1));
13489   assign(addr2, get_gpr_dw0(r2));
13490   assign(len1, get_gpr_dw0(r1 + 1));
13491   assign(len2, get_gpr_dw0(r2 + 1));
13492
13493   /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13494      there are less than 2 bytes left, then the 2nd operand is exhausted
13495      and we're done here. cc = 0 */
13496   s390_cc_set(0);
13497   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
13498
13499   /* There are at least two bytes there. Read them. */
13500   IRTemp srcval = newTemp(Ity_I32);
13501   assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13502
13503   /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13504      inside the interval [0xd800 - 0xdbff] */
13505   IRTemp  is_high_surrogate = newTemp(Ity_I32);
13506   IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13507                         mkU32(1), mkU32(0));
13508   IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13509                         mkU32(1), mkU32(0));
13510   assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13511
13512   /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13513      then the 2nd operand is exhausted and we're done here. cc = 0 */
13514   IRExpr *not_enough_bytes =
13515      mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13516
13517   next_insn_if(binop(Iop_CmpEQ32,
13518                      binop(Iop_And32, mkexpr(is_high_surrogate),
13519                            not_enough_bytes),
13520                      mkU32(1)));
13521
13522   /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13523      surrogate, read the next two bytes (low surrogate). */
13524   IRTemp  low_surrogate = newTemp(Ity_I32);
13525   IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13526
13527   assign(low_surrogate,
13528          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13529                unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13530                mkU32(0)));  // any value is fine; it will not be used
13531
13532   /* Call the helper */
13533   IRTemp retval = newTemp(Ity_I64);
13534   assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13535                                 unop(Iop_32Uto64, mkexpr(low_surrogate))));
13536
13537   /* Before we can test whether the 1st operand is exhausted we need to
13538      test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13539   if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13540      IRExpr *invalid_low_surrogate =
13541         binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13542
13543      s390_cc_set(2);
13544      next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
13545   }
13546
13547   /* Now test whether the 1st operand is exhausted */
13548   s390_cc_set(1);
13549   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
13550
13551   /* Extract the bytes to be stored at addr1 */
13552   IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13553
13554   store(mkexpr(addr1), data);
13555
13556   /* Update source address and length */
13557   IRTemp num_src_bytes = newTemp(Ity_I64);
13558   assign(num_src_bytes,
13559          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13560                mkU64(4), mkU64(2)));
13561   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13562   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
13563
13564   /* Update destination address and length */
13565   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13566   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkU64(4)));
13567
13568   iterate();
13569
13570   return "cu24";
13571}
13572
13573static IRExpr *
13574s390_call_cu42(IRExpr *srcval)
13575{
13576   IRExpr **args, *call;
13577   args = mkIRExprVec_1(srcval);
13578   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13579                       "s390_do_cu42", &s390_do_cu42, args);
13580
13581   /* Nothing is excluded from definedness checking. */
13582   call->Iex.CCall.cee->mcx_mask = 0;
13583
13584   return call;
13585}
13586
13587static const HChar *
13588s390_irgen_CU42(UChar r1, UChar r2)
13589{
13590   IRTemp addr1 = newTemp(Ity_I64);
13591   IRTemp addr2 = newTemp(Ity_I64);
13592   IRTemp len1 = newTemp(Ity_I64);
13593   IRTemp len2 = newTemp(Ity_I64);
13594
13595   assign(addr1, get_gpr_dw0(r1));
13596   assign(addr2, get_gpr_dw0(r2));
13597   assign(len1, get_gpr_dw0(r1 + 1));
13598   assign(len2, get_gpr_dw0(r2 + 1));
13599
13600   /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13601      there are less than 4 bytes left, then the 2nd operand is exhausted
13602      and we're done here. cc = 0 */
13603   s390_cc_set(0);
13604   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13605
13606   /* Read the 2nd operand. */
13607   IRTemp srcval = newTemp(Ity_I32);
13608   assign(srcval, load(Ity_I32, mkexpr(addr2)));
13609
13610   /* Call the helper */
13611   IRTemp retval = newTemp(Ity_I64);
13612   assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
13613
13614   /* If the UTF-32 character was invalid, set cc=2 and we're done.
13615      cc=2 outranks cc=1 (1st operand exhausted) */
13616   IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13617
13618   s390_cc_set(2);
13619   next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13620
13621   /* Now test whether the 1st operand is exhausted */
13622   IRTemp num_bytes = newTemp(Ity_I64);
13623   assign(num_bytes, binop(Iop_And64,
13624                           binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13625                           mkU64(0xff)));
13626   s390_cc_set(1);
13627   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13628
13629   /* Extract the bytes to be stored at addr1 */
13630   IRTemp data = newTemp(Ity_I64);
13631   assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13632
13633   /* To store the bytes construct 2 dirty helper calls. The helper calls
13634      are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13635      that only one of them will be called at runtime. */
13636
13637   Int i;
13638   for (i = 2; i <= 4; ++i) {
13639      IRDirty *d;
13640
13641      if (i == 3) continue;  // skip this one
13642
13643      d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13644                            &s390x_dirtyhelper_CUxy,
13645                            mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13646                                          mkexpr(num_bytes)));
13647      d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13648      d->mFx   = Ifx_Write;
13649      d->mAddr = mkexpr(addr1);
13650      d->mSize = i;
13651      stmt(IRStmt_Dirty(d));
13652   }
13653
13654   /* Update source address and length */
13655   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13656   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkU64(4)));
13657
13658   /* Update destination address and length */
13659   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13660   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13661
13662   iterate();
13663
13664   return "cu42";
13665}
13666
13667static IRExpr *
13668s390_call_cu41(IRExpr *srcval)
13669{
13670   IRExpr **args, *call;
13671   args = mkIRExprVec_1(srcval);
13672   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13673                       "s390_do_cu41", &s390_do_cu41, args);
13674
13675   /* Nothing is excluded from definedness checking. */
13676   call->Iex.CCall.cee->mcx_mask = 0;
13677
13678   return call;
13679}
13680
13681static const HChar *
13682s390_irgen_CU41(UChar r1, UChar r2)
13683{
13684   IRTemp addr1 = newTemp(Ity_I64);
13685   IRTemp addr2 = newTemp(Ity_I64);
13686   IRTemp len1 = newTemp(Ity_I64);
13687   IRTemp len2 = newTemp(Ity_I64);
13688
13689   assign(addr1, get_gpr_dw0(r1));
13690   assign(addr2, get_gpr_dw0(r2));
13691   assign(len1, get_gpr_dw0(r1 + 1));
13692   assign(len2, get_gpr_dw0(r2 + 1));
13693
13694   /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13695      there are less than 4 bytes left, then the 2nd operand is exhausted
13696      and we're done here. cc = 0 */
13697   s390_cc_set(0);
13698   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13699
13700   /* Read the 2nd operand. */
13701   IRTemp srcval = newTemp(Ity_I32);
13702   assign(srcval, load(Ity_I32, mkexpr(addr2)));
13703
13704   /* Call the helper */
13705   IRTemp retval = newTemp(Ity_I64);
13706   assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
13707
13708   /* If the UTF-32 character was invalid, set cc=2 and we're done.
13709      cc=2 outranks cc=1 (1st operand exhausted) */
13710   IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13711
13712   s390_cc_set(2);
13713   next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13714
13715   /* Now test whether the 1st operand is exhausted */
13716   IRTemp num_bytes = newTemp(Ity_I64);
13717   assign(num_bytes, binop(Iop_And64,
13718                           binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13719                           mkU64(0xff)));
13720   s390_cc_set(1);
13721   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13722
13723   /* Extract the bytes to be stored at addr1 */
13724   IRTemp data = newTemp(Ity_I64);
13725   assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13726
13727   /* To store the bytes construct 4 dirty helper calls. The helper calls
13728      are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13729      one of them will be called at runtime. */
13730   UInt i;
13731   for (i = 1; i <= 4; ++i) {
13732      IRDirty *d;
13733
13734      d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13735                            &s390x_dirtyhelper_CUxy,
13736                            mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13737                                          mkexpr(num_bytes)));
13738      d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13739      d->mFx   = Ifx_Write;
13740      d->mAddr = mkexpr(addr1);
13741      d->mSize = i;
13742      stmt(IRStmt_Dirty(d));
13743   }
13744
13745   /* Update source address and length */
13746   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13747   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkU64(4)));
13748
13749   /* Update destination address and length */
13750   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13751   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13752
13753   iterate();
13754
13755   return "cu41";
13756}
13757
13758static IRExpr *
13759s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
13760{
13761   IRExpr **args, *call;
13762   args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
13763   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13764                        &s390_do_cu12_cu14_helper1, args);
13765
13766   /* Nothing is excluded from definedness checking. */
13767   call->Iex.CCall.cee->mcx_mask = 0;
13768
13769   return call;
13770}
13771
13772static IRExpr *
13773s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13774                       IRExpr *byte4, IRExpr *stuff)
13775{
13776   IRExpr **args, *call;
13777   args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13778   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13779                        "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13780
13781   /* Nothing is excluded from definedness checking. */
13782   call->Iex.CCall.cee->mcx_mask = 0;
13783
13784   return call;
13785}
13786
13787static IRExpr *
13788s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13789                       IRExpr *byte4, IRExpr *stuff)
13790{
13791   IRExpr **args, *call;
13792   args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13793   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13794                        "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13795
13796   /* Nothing is excluded from definedness checking. */
13797   call->Iex.CCall.cee->mcx_mask = 0;
13798
13799   return call;
13800}
13801
13802static void
13803s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
13804{
13805   IRTemp addr1 = newTemp(Ity_I64);
13806   IRTemp addr2 = newTemp(Ity_I64);
13807   IRTemp len1 = newTemp(Ity_I64);
13808   IRTemp len2 = newTemp(Ity_I64);
13809
13810   assign(addr1, get_gpr_dw0(r1));
13811   assign(addr2, get_gpr_dw0(r2));
13812   assign(len1, get_gpr_dw0(r1 + 1));
13813   assign(len2, get_gpr_dw0(r2 + 1));
13814
13815   UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13816
13817   /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13818      there is less than 1 byte left, then the 2nd operand is exhausted
13819      and we're done here. cc = 0 */
13820   s390_cc_set(0);
13821   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13822
13823   /* There is at least one byte there. Read it. */
13824   IRTemp byte1 = newTemp(Ity_I64);
13825   assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
13826
13827   /* Call the helper to get number of bytes and invalid byte indicator */
13828   IRTemp retval1 = newTemp(Ity_I64);
13829   assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
13830                                               mkU64(extended_checking)));
13831
13832   /* Check for invalid 1st byte */
13833   IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13834   s390_cc_set(2);
13835   next_insn_if(is_invalid);
13836
13837   /* How many bytes do we have to read? */
13838   IRTemp num_src_bytes = newTemp(Ity_I64);
13839   assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13840
13841   /* Now test whether the 2nd operand is exhausted */
13842   s390_cc_set(0);
13843   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13844
13845   /* Read the remaining bytes */
13846   IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13847
13848   cond  = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13849   addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
13850   byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
13851   cond  = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13852   addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13853   byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
13854   cond  = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13855   addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
13856   byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
13857
13858   /* Call the helper to get the converted value and invalid byte indicator.
13859      We can pass at most 5 arguments; therefore some encoding is needed
13860      here */
13861   IRExpr *stuff = binop(Iop_Or64,
13862                         binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13863                         mkU64(extended_checking));
13864   IRTemp retval2 = newTemp(Ity_I64);
13865
13866   if (is_cu12) {
13867      assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13868                                             byte4, stuff));
13869   } else {
13870      assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13871                                             byte4, stuff));
13872   }
13873
13874   /* Check for invalid character */
13875   s390_cc_set(2);
13876   is_invalid = unop(Iop_64to1, mkexpr(retval2));
13877   next_insn_if(is_invalid);
13878
13879   /* Now test whether the 1st operand is exhausted */
13880   IRTemp num_bytes = newTemp(Ity_I64);
13881   assign(num_bytes, binop(Iop_And64,
13882                           binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13883                           mkU64(0xff)));
13884   s390_cc_set(1);
13885   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13886
13887   /* Extract the bytes to be stored at addr1 */
13888   IRTemp data = newTemp(Ity_I64);
13889   assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13890
13891   if (is_cu12) {
13892      /* To store the bytes construct 2 dirty helper calls. The helper calls
13893         are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13894         that only one of them will be called at runtime. */
13895
13896      Int i;
13897      for (i = 2; i <= 4; ++i) {
13898         IRDirty *d;
13899
13900         if (i == 3) continue;  // skip this one
13901
13902         d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13903                               &s390x_dirtyhelper_CUxy,
13904                               mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13905                                             mkexpr(num_bytes)));
13906         d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13907         d->mFx   = Ifx_Write;
13908         d->mAddr = mkexpr(addr1);
13909         d->mSize = i;
13910         stmt(IRStmt_Dirty(d));
13911      }
13912   } else {
13913      // cu14
13914      store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
13915   }
13916
13917   /* Update source address and length */
13918   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13919   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
13920
13921   /* Update destination address and length */
13922   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13923   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13924
13925   iterate();
13926}
13927
13928static const HChar *
13929s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13930{
13931   s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
13932
13933   return "cu12";
13934}
13935
13936static const HChar *
13937s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13938{
13939   s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13940
13941   return "cu14";
13942}
13943
13944static IRExpr *
13945s390_call_ecag(IRExpr *op2addr)
13946{
13947   IRExpr **args, *call;
13948
13949   args = mkIRExprVec_1(op2addr);
13950   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13951                        "s390_do_ecag", &s390_do_ecag, args);
13952
13953   /* Nothing is excluded from definedness checking. */
13954   call->Iex.CCall.cee->mcx_mask = 0;
13955
13956   return call;
13957}
13958
13959static const HChar *
13960s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
13961{
13962   if (! s390_host_has_gie) {
13963      emulation_failure(EmFail_S390X_ecag);
13964   } else {
13965      put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13966   }
13967
13968   return "ecag";
13969}
13970
13971
13972/* New insns are added here.
13973   If an insn is contingent on a facility being installed also
13974   check whether the list of supported facilities in function
13975   s390x_dirtyhelper_STFLE needs updating */
13976
13977/*------------------------------------------------------------*/
13978/*--- Build IR for special instructions                    ---*/
13979/*------------------------------------------------------------*/
13980
13981static void
13982s390_irgen_client_request(void)
13983{
13984   if (0)
13985      vex_printf("%%R3 = client_request ( %%R2 )\n");
13986
13987   Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13988                                     + S390_SPECIAL_OP_SIZE;
13989
13990   dis_res->jk_StopHere = Ijk_ClientReq;
13991   dis_res->whatNext = Dis_StopHere;
13992
13993   put_IA(mkaddr_expr(next));
13994}
13995
13996static void
13997s390_irgen_guest_NRADDR(void)
13998{
13999   if (0)
14000      vex_printf("%%R3 = guest_NRADDR\n");
14001
14002   put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
14003}
14004
14005static void
14006s390_irgen_call_noredir(void)
14007{
14008   Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
14009                                     + S390_SPECIAL_OP_SIZE;
14010
14011   /* Continue after special op */
14012   put_gpr_dw0(14, mkaddr_expr(next));
14013
14014   /* The address is in REG1, all parameters are in the right (guest) places */
14015   put_IA(get_gpr_dw0(1));
14016
14017   dis_res->whatNext = Dis_StopHere;
14018   dis_res->jk_StopHere = Ijk_NoRedir;
14019}
14020
14021/* Force proper alignment for the structures below. */
14022#pragma pack(1)
14023
14024
14025static s390_decode_t
14026s390_decode_2byte_and_irgen(const UChar *bytes)
14027{
14028   typedef union {
14029      struct {
14030         unsigned int op : 16;
14031      } E;
14032      struct {
14033         unsigned int op :  8;
14034         unsigned int i  :  8;
14035      } I;
14036      struct {
14037         unsigned int op :  8;
14038         unsigned int r1 :  4;
14039         unsigned int r2 :  4;
14040      } RR;
14041   } formats;
14042   union {
14043      formats fmt;
14044      UShort value;
14045   } ovl;
14046
14047   vassert(sizeof(formats) == 2);
14048
14049   ((UChar *)(&ovl.value))[0] = bytes[0];
14050   ((UChar *)(&ovl.value))[1] = bytes[1];
14051
14052   switch (ovl.value & 0xffff) {
14053   case 0x0101: /* PR */ goto unimplemented;
14054   case 0x0102: /* UPT */ goto unimplemented;
14055   case 0x0104: /* PTFF */ goto unimplemented;
14056   case 0x0107: /* SCKPF */ goto unimplemented;
14057   case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
14058   case 0x010b: /* TAM */ goto unimplemented;
14059   case 0x010c: /* SAM24 */ goto unimplemented;
14060   case 0x010d: /* SAM31 */ goto unimplemented;
14061   case 0x010e: /* SAM64 */ goto unimplemented;
14062   case 0x01ff: /* TRAP2 */ goto unimplemented;
14063   }
14064
14065   switch ((ovl.value & 0xff00) >> 8) {
14066   case 0x04: /* SPM */ goto unimplemented;
14067   case 0x05: /* BALR */ goto unimplemented;
14068   case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14069                                goto ok;
14070   case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14071                             goto ok;
14072   case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i);  goto ok;
14073   case 0x0b: /* BSM */ goto unimplemented;
14074   case 0x0c: /* BASSM */ goto unimplemented;
14075   case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14076                                goto ok;
14077   case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14078                             goto ok;
14079   case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14080                             goto ok;
14081   case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14082                                goto ok;
14083   case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14084                                goto ok;
14085   case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14086                                goto ok;
14087   case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14088                                goto ok;
14089   case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14090                                goto ok;
14091   case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14092                                goto ok;
14093   case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14094                                goto ok;
14095   case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14096                                goto ok;
14097   case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14098                                goto ok;
14099   case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14100                                goto ok;
14101   case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14102                                goto ok;
14103   case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14104                                goto ok;
14105   case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14106                                goto ok;
14107   case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14108                                goto ok;
14109   case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14110                                goto ok;
14111   case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14112                                goto ok;
14113   case 0x20: /* LPDR */ goto unimplemented;
14114   case 0x21: /* LNDR */ goto unimplemented;
14115   case 0x22: /* LTDR */ goto unimplemented;
14116   case 0x23: /* LCDR */ goto unimplemented;
14117   case 0x24: /* HDR */ goto unimplemented;
14118   case 0x25: /* LDXR */ goto unimplemented;
14119   case 0x26: /* MXR */ goto unimplemented;
14120   case 0x27: /* MXDR */ goto unimplemented;
14121   case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14122                                goto ok;
14123   case 0x29: /* CDR */ goto unimplemented;
14124   case 0x2a: /* ADR */ goto unimplemented;
14125   case 0x2b: /* SDR */ goto unimplemented;
14126   case 0x2c: /* MDR */ goto unimplemented;
14127   case 0x2d: /* DDR */ goto unimplemented;
14128   case 0x2e: /* AWR */ goto unimplemented;
14129   case 0x2f: /* SWR */ goto unimplemented;
14130   case 0x30: /* LPER */ goto unimplemented;
14131   case 0x31: /* LNER */ goto unimplemented;
14132   case 0x32: /* LTER */ goto unimplemented;
14133   case 0x33: /* LCER */ goto unimplemented;
14134   case 0x34: /* HER */ goto unimplemented;
14135   case 0x35: /* LEDR */ goto unimplemented;
14136   case 0x36: /* AXR */ goto unimplemented;
14137   case 0x37: /* SXR */ goto unimplemented;
14138   case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14139                                goto ok;
14140   case 0x39: /* CER */ goto unimplemented;
14141   case 0x3a: /* AER */ goto unimplemented;
14142   case 0x3b: /* SER */ goto unimplemented;
14143   case 0x3c: /* MDER */ goto unimplemented;
14144   case 0x3d: /* DER */ goto unimplemented;
14145   case 0x3e: /* AUR */ goto unimplemented;
14146   case 0x3f: /* SUR */ goto unimplemented;
14147   }
14148
14149   return S390_DECODE_UNKNOWN_INSN;
14150
14151ok:
14152   return S390_DECODE_OK;
14153
14154unimplemented:
14155   return S390_DECODE_UNIMPLEMENTED_INSN;
14156}
14157
14158static s390_decode_t
14159s390_decode_4byte_and_irgen(const UChar *bytes)
14160{
14161   typedef union {
14162      struct {
14163         unsigned int op1 :  8;
14164         unsigned int r1  :  4;
14165         unsigned int op2 :  4;
14166         unsigned int i2  : 16;
14167      } RI;
14168      struct {
14169         unsigned int op : 16;
14170         unsigned int    :  8;
14171         unsigned int r1 :  4;
14172         unsigned int r2 :  4;
14173      } RRE;
14174      struct {
14175         unsigned int op : 16;
14176         unsigned int r1 :  4;
14177         unsigned int    :  4;
14178         unsigned int r3 :  4;
14179         unsigned int r2 :  4;
14180      } RRF;
14181      struct {
14182         unsigned int op : 16;
14183         unsigned int m3 :  4;
14184         unsigned int m4 :  4;
14185         unsigned int r1 :  4;
14186         unsigned int r2 :  4;
14187      } RRF2;
14188      struct {
14189         unsigned int op : 16;
14190         unsigned int r3 :  4;
14191         unsigned int    :  4;
14192         unsigned int r1 :  4;
14193         unsigned int r2 :  4;
14194      } RRF3;
14195      struct {
14196         unsigned int op : 16;
14197         unsigned int r3 :  4;
14198         unsigned int    :  4;
14199         unsigned int r1 :  4;
14200         unsigned int r2 :  4;
14201      } RRR;
14202      struct {
14203         unsigned int op : 16;
14204         unsigned int r3 :  4;
14205         unsigned int m4 :  4;
14206         unsigned int r1 :  4;
14207         unsigned int r2 :  4;
14208      } RRF4;
14209      struct {
14210         unsigned int op : 16;
14211         unsigned int    :  4;
14212         unsigned int m4 :  4;
14213         unsigned int r1 :  4;
14214         unsigned int r2 :  4;
14215      } RRF5;
14216      struct {
14217         unsigned int op :  8;
14218         unsigned int r1 :  4;
14219         unsigned int r3 :  4;
14220         unsigned int b2 :  4;
14221         unsigned int d2 : 12;
14222      } RS;
14223      struct {
14224         unsigned int op :  8;
14225         unsigned int r1 :  4;
14226         unsigned int r3 :  4;
14227         unsigned int i2 : 16;
14228      } RSI;
14229      struct {
14230         unsigned int op :  8;
14231         unsigned int r1 :  4;
14232         unsigned int x2 :  4;
14233         unsigned int b2 :  4;
14234         unsigned int d2 : 12;
14235      } RX;
14236      struct {
14237         unsigned int op : 16;
14238         unsigned int b2 :  4;
14239         unsigned int d2 : 12;
14240      } S;
14241      struct {
14242         unsigned int op :  8;
14243         unsigned int i2 :  8;
14244         unsigned int b1 :  4;
14245         unsigned int d1 : 12;
14246      } SI;
14247   } formats;
14248   union {
14249      formats fmt;
14250      UInt value;
14251   } ovl;
14252
14253   vassert(sizeof(formats) == 4);
14254
14255   ((UChar *)(&ovl.value))[0] = bytes[0];
14256   ((UChar *)(&ovl.value))[1] = bytes[1];
14257   ((UChar *)(&ovl.value))[2] = bytes[2];
14258   ((UChar *)(&ovl.value))[3] = bytes[3];
14259
14260   switch ((ovl.value & 0xff0f0000) >> 16) {
14261   case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
14262                                  ovl.fmt.RI.i2);  goto ok;
14263   case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
14264                                  ovl.fmt.RI.i2);  goto ok;
14265   case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14266                                  ovl.fmt.RI.i2);  goto ok;
14267   case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14268                                  ovl.fmt.RI.i2);  goto ok;
14269   case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14270                                  ovl.fmt.RI.i2);  goto ok;
14271   case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14272                                  ovl.fmt.RI.i2);  goto ok;
14273   case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14274                                  ovl.fmt.RI.i2);  goto ok;
14275   case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14276                                  ovl.fmt.RI.i2);  goto ok;
14277   case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14278                                  ovl.fmt.RI.i2);  goto ok;
14279   case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14280                                  ovl.fmt.RI.i2);  goto ok;
14281   case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14282                                  ovl.fmt.RI.i2);  goto ok;
14283   case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14284                                  ovl.fmt.RI.i2);  goto ok;
14285   case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14286                                  ovl.fmt.RI.i2);  goto ok;
14287   case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14288                                  ovl.fmt.RI.i2);  goto ok;
14289   case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14290                                  ovl.fmt.RI.i2);  goto ok;
14291   case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14292                                  ovl.fmt.RI.i2);  goto ok;
14293   case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14294                                  ovl.fmt.RI.i2);  goto ok;
14295   case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14296                                  ovl.fmt.RI.i2);  goto ok;
14297   case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14298                                  ovl.fmt.RI.i2);  goto ok;
14299   case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14300                                  ovl.fmt.RI.i2);  goto ok;
14301   case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14302                               goto ok;
14303   case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14304                                  ovl.fmt.RI.i2);  goto ok;
14305   case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14306                                  ovl.fmt.RI.i2);  goto ok;
14307   case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14308                                  ovl.fmt.RI.i2);  goto ok;
14309   case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14310                                  goto ok;
14311   case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14312                                  ovl.fmt.RI.i2);  goto ok;
14313   case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14314                                  goto ok;
14315   case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14316                                  ovl.fmt.RI.i2);  goto ok;
14317   case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14318                                  goto ok;
14319   case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14320                                  ovl.fmt.RI.i2);  goto ok;
14321   case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14322                                  goto ok;
14323   case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14324                                  ovl.fmt.RI.i2);  goto ok;
14325   }
14326
14327   switch ((ovl.value & 0xffff0000) >> 16) {
14328   case 0x8000: /* SSM */ goto unimplemented;
14329   case 0x8200: /* LPSW */ goto unimplemented;
14330   case 0x9300: /* TS */ goto unimplemented;
14331   case 0xb202: /* STIDP */ goto unimplemented;
14332   case 0xb204: /* SCK */ goto unimplemented;
14333   case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14334                goto ok;
14335   case 0xb206: /* SCKC */ goto unimplemented;
14336   case 0xb207: /* STCKC */ goto unimplemented;
14337   case 0xb208: /* SPT */ goto unimplemented;
14338   case 0xb209: /* STPT */ goto unimplemented;
14339   case 0xb20a: /* SPKA */ goto unimplemented;
14340   case 0xb20b: /* IPK */ goto unimplemented;
14341   case 0xb20d: /* PTLB */ goto unimplemented;
14342   case 0xb210: /* SPX */ goto unimplemented;
14343   case 0xb211: /* STPX */ goto unimplemented;
14344   case 0xb212: /* STAP */ goto unimplemented;
14345   case 0xb214: /* SIE */ goto unimplemented;
14346   case 0xb218: /* PC */ goto unimplemented;
14347   case 0xb219: /* SAC */ goto unimplemented;
14348   case 0xb21a: /* CFC */ goto unimplemented;
14349   case 0xb221: /* IPTE */ goto unimplemented;
14350   case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1);  goto ok;
14351   case 0xb223: /* IVSK */ goto unimplemented;
14352   case 0xb224: /* IAC */ goto unimplemented;
14353   case 0xb225: /* SSAR */ goto unimplemented;
14354   case 0xb226: /* EPAR */ goto unimplemented;
14355   case 0xb227: /* ESAR */ goto unimplemented;
14356   case 0xb228: /* PT */ goto unimplemented;
14357   case 0xb229: /* ISKE */ goto unimplemented;
14358   case 0xb22a: /* RRBE */ goto unimplemented;
14359   case 0xb22b: /* SSKE */ goto unimplemented;
14360   case 0xb22c: /* TB */ goto unimplemented;
14361   case 0xb22d: /* DXR */ goto unimplemented;
14362   case 0xb22e: /* PGIN */ goto unimplemented;
14363   case 0xb22f: /* PGOUT */ goto unimplemented;
14364   case 0xb230: /* CSCH */ goto unimplemented;
14365   case 0xb231: /* HSCH */ goto unimplemented;
14366   case 0xb232: /* MSCH */ goto unimplemented;
14367   case 0xb233: /* SSCH */ goto unimplemented;
14368   case 0xb234: /* STSCH */ goto unimplemented;
14369   case 0xb235: /* TSCH */ goto unimplemented;
14370   case 0xb236: /* TPI */ goto unimplemented;
14371   case 0xb237: /* SAL */ goto unimplemented;
14372   case 0xb238: /* RSCH */ goto unimplemented;
14373   case 0xb239: /* STCRW */ goto unimplemented;
14374   case 0xb23a: /* STCPS */ goto unimplemented;
14375   case 0xb23b: /* RCHP */ goto unimplemented;
14376   case 0xb23c: /* SCHM */ goto unimplemented;
14377   case 0xb240: /* BAKR */ goto unimplemented;
14378   case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14379                                ovl.fmt.RRE.r2);  goto ok;
14380   case 0xb244: /* SQDR */ goto unimplemented;
14381   case 0xb245: /* SQER */ goto unimplemented;
14382   case 0xb246: /* STURA */ goto unimplemented;
14383   case 0xb247: /* MSTA */ goto unimplemented;
14384   case 0xb248: /* PALB */ goto unimplemented;
14385   case 0xb249: /* EREG */ goto unimplemented;
14386   case 0xb24a: /* ESTA */ goto unimplemented;
14387   case 0xb24b: /* LURA */ goto unimplemented;
14388   case 0xb24c: /* TAR */ goto unimplemented;
14389   case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14390                                ovl.fmt.RRE.r2);  goto ok;
14391   case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14392                                goto ok;
14393   case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14394                                goto ok;
14395   case 0xb250: /* CSP */ goto unimplemented;
14396   case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14397                                   ovl.fmt.RRE.r2);  goto ok;
14398   case 0xb254: /* MVPG */ goto unimplemented;
14399   case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14400                                   ovl.fmt.RRE.r2);  goto ok;
14401   case 0xb257: /* CUSE */ goto unimplemented;
14402   case 0xb258: /* BSG */ goto unimplemented;
14403   case 0xb25a: /* BSA */ goto unimplemented;
14404   case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14405                                   ovl.fmt.RRE.r2);  goto ok;
14406   case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14407                                   ovl.fmt.RRE.r2);  goto ok;
14408   case 0xb263: /* CMPSC */ goto unimplemented;
14409   case 0xb274: /* SIGA */ goto unimplemented;
14410   case 0xb276: /* XSCH */ goto unimplemented;
14411   case 0xb277: /* RP */ goto unimplemented;
14412   case 0xb278: s390_format_S_RD(s390_irgen_STCKE, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
14413   case 0xb279: /* SACF */ goto unimplemented;
14414   case 0xb27c: s390_format_S_RD(s390_irgen_STCKF, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
14415   case 0xb27d: /* STSI */ goto unimplemented;
14416   case 0xb280: /* LPP */ goto unimplemented;
14417   case 0xb284: /* LCCTL */ goto unimplemented;
14418   case 0xb285: /* LPCTL */ goto unimplemented;
14419   case 0xb286: /* QSI */ goto unimplemented;
14420   case 0xb287: /* LSCTL */ goto unimplemented;
14421   case 0xb28e: /* QCTRI */ goto unimplemented;
14422   case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14423                                 goto ok;
14424   case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14425                                 goto ok;
14426   case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14427                                 goto ok;
14428   case 0xb2a5: s390_format_RRE_FF(s390_irgen_TRE, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);  goto ok;
14429   case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14430                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14431      goto ok;
14432   case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14433                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14434      goto ok;
14435   case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14436                                 goto ok;
14437   case 0xb2b1: /* STFL */ goto unimplemented;
14438   case 0xb2b2: /* LPSWE */ goto unimplemented;
14439   case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14440      goto ok;
14441   case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14442      goto ok;
14443   case 0xb2bd: /* LFAS */ goto unimplemented;
14444   case 0xb2e0: /* SCCTR */ goto unimplemented;
14445   case 0xb2e1: /* SPCTR */ goto unimplemented;
14446   case 0xb2e4: /* ECCTR */ goto unimplemented;
14447   case 0xb2e5: /* EPCTR */ goto unimplemented;
14448   case 0xb2e8: /* PPA */ goto unimplemented;
14449   case 0xb2ec: /* ETND */ goto unimplemented;
14450   case 0xb2ed: /* ECPGA */ goto unimplemented;
14451   case 0xb2f8: /* TEND */ goto unimplemented;
14452   case 0xb2fa: /* NIAI */ goto unimplemented;
14453   case 0xb2fc: /* TABORT */ goto unimplemented;
14454   case 0xb2ff: /* TRAP4 */ goto unimplemented;
14455   case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14456                                   ovl.fmt.RRE.r2);  goto ok;
14457   case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14458                                   ovl.fmt.RRE.r2);  goto ok;
14459   case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14460                                   ovl.fmt.RRE.r2);  goto ok;
14461   case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14462                                   ovl.fmt.RRE.r2);  goto ok;
14463   case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14464                                   ovl.fmt.RRE.r2);  goto ok;
14465   case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14466                                   ovl.fmt.RRE.r2);  goto ok;
14467   case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14468                                   ovl.fmt.RRE.r2);  goto ok;
14469   case 0xb307: /* MXDBR */ goto unimplemented;
14470   case 0xb308: /* KEBR */ goto unimplemented;
14471   case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14472                                   ovl.fmt.RRE.r2);  goto ok;
14473   case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14474                                   ovl.fmt.RRE.r2);  goto ok;
14475   case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14476                                   ovl.fmt.RRE.r2);  goto ok;
14477   case 0xb30c: /* MDEBR */ goto unimplemented;
14478   case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14479                                   ovl.fmt.RRE.r2);  goto ok;
14480   case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14481                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14482   case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14483                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14484   case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14485                                   ovl.fmt.RRE.r2);  goto ok;
14486   case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14487                                   ovl.fmt.RRE.r2);  goto ok;
14488   case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14489                                   ovl.fmt.RRE.r2);  goto ok;
14490   case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14491                                   ovl.fmt.RRE.r2);  goto ok;
14492   case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14493                                   ovl.fmt.RRE.r2);  goto ok;
14494   case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14495                                   ovl.fmt.RRE.r2);  goto ok;
14496   case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14497                                   ovl.fmt.RRE.r2);  goto ok;
14498   case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14499                                   ovl.fmt.RRE.r2);  goto ok;
14500   case 0xb318: /* KDBR */ goto unimplemented;
14501   case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14502                                   ovl.fmt.RRE.r2);  goto ok;
14503   case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14504                                   ovl.fmt.RRE.r2);  goto ok;
14505   case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14506                                   ovl.fmt.RRE.r2);  goto ok;
14507   case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14508                                   ovl.fmt.RRE.r2);  goto ok;
14509   case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14510                                   ovl.fmt.RRE.r2);  goto ok;
14511   case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14512                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14513   case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14514                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14515   case 0xb324: /* LDER */ goto unimplemented;
14516   case 0xb325: /* LXDR */ goto unimplemented;
14517   case 0xb326: /* LXER */ goto unimplemented;
14518   case 0xb32e: /* MAER */ goto unimplemented;
14519   case 0xb32f: /* MSER */ goto unimplemented;
14520   case 0xb336: /* SQXR */ goto unimplemented;
14521   case 0xb337: /* MEER */ goto unimplemented;
14522   case 0xb338: /* MAYLR */ goto unimplemented;
14523   case 0xb339: /* MYLR */ goto unimplemented;
14524   case 0xb33a: /* MAYR */ goto unimplemented;
14525   case 0xb33b: /* MYR */ goto unimplemented;
14526   case 0xb33c: /* MAYHR */ goto unimplemented;
14527   case 0xb33d: /* MYHR */ goto unimplemented;
14528   case 0xb33e: /* MADR */ goto unimplemented;
14529   case 0xb33f: /* MSDR */ goto unimplemented;
14530   case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14531                                   ovl.fmt.RRE.r2);  goto ok;
14532   case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14533                                   ovl.fmt.RRE.r2);  goto ok;
14534   case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14535                                   ovl.fmt.RRE.r2);  goto ok;
14536   case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14537                                   ovl.fmt.RRE.r2);  goto ok;
14538   case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14539                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14540                                     ovl.fmt.RRF2.r2);  goto ok;
14541   case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14542                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14543                                     ovl.fmt.RRF2.r2);  goto ok;
14544   case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14545                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14546                                     ovl.fmt.RRF2.r2);  goto ok;
14547   case 0xb347: s390_format_RRF_UUFF(s390_irgen_FIXBRA, ovl.fmt.RRF2.m3,
14548                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14549                                     ovl.fmt.RRF2.r2);  goto ok;
14550   case 0xb348: /* KXBR */ goto unimplemented;
14551   case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14552                                   ovl.fmt.RRE.r2);  goto ok;
14553   case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14554                                   ovl.fmt.RRE.r2);  goto ok;
14555   case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14556                                   ovl.fmt.RRE.r2);  goto ok;
14557   case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14558                                   ovl.fmt.RRE.r2);  goto ok;
14559   case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14560                                   ovl.fmt.RRE.r2);  goto ok;
14561   case 0xb350: /* TBEDR */ goto unimplemented;
14562   case 0xb351: /* TBDR */ goto unimplemented;
14563   case 0xb353: /* DIEBR */ goto unimplemented;
14564   case 0xb357: s390_format_RRF_UUFF(s390_irgen_FIEBRA, ovl.fmt.RRF2.m3,
14565                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14566                                     ovl.fmt.RRF2.r2);  goto ok;
14567   case 0xb358: /* THDER */ goto unimplemented;
14568   case 0xb359: /* THDR */ goto unimplemented;
14569   case 0xb35b: /* DIDBR */ goto unimplemented;
14570   case 0xb35f: s390_format_RRF_UUFF(s390_irgen_FIDBRA, ovl.fmt.RRF2.m3,
14571                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14572                                     ovl.fmt.RRF2.r2);  goto ok;
14573   case 0xb360: /* LPXR */ goto unimplemented;
14574   case 0xb361: /* LNXR */ goto unimplemented;
14575   case 0xb362: /* LTXR */ goto unimplemented;
14576   case 0xb363: /* LCXR */ goto unimplemented;
14577   case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14578                                   ovl.fmt.RRE.r2);  goto ok;
14579   case 0xb366: /* LEXR */ goto unimplemented;
14580   case 0xb367: /* FIXR */ goto unimplemented;
14581   case 0xb369: /* CXR */ goto unimplemented;
14582   case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14583                                   ovl.fmt.RRE.r2);  goto ok;
14584   case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14585                                   ovl.fmt.RRE.r2);  goto ok;
14586   case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14587                                      ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14588                                      goto ok;
14589   case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14590                                   ovl.fmt.RRE.r2);  goto ok;
14591   case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1);  goto ok;
14592   case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1);  goto ok;
14593   case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1);  goto ok;
14594   case 0xb377: /* FIER */ goto unimplemented;
14595   case 0xb37f: /* FIDR */ goto unimplemented;
14596   case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1);  goto ok;
14597   case 0xb385: /* SFASR */ goto unimplemented;
14598   case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1);  goto ok;
14599   case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14600                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14601                                     ovl.fmt.RRF2.r2);  goto ok;
14602   case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14603                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14604                                     ovl.fmt.RRF2.r2);  goto ok;
14605   case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14606                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14607                                     ovl.fmt.RRF2.r2);  goto ok;
14608   case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14609                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14610                                     ovl.fmt.RRF2.r2);  goto ok;
14611   case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14612                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14613                                     ovl.fmt.RRF2.r2);  goto ok;
14614   case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14615                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14616                                     ovl.fmt.RRF2.r2);  goto ok;
14617   case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14618                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14619                                     ovl.fmt.RRF2.r2);  goto ok;
14620   case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14621                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14622                                     ovl.fmt.RRF2.r2);  goto ok;
14623   case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14624                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14625                                     ovl.fmt.RRF2.r2);  goto ok;
14626   case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14627                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14628                                     ovl.fmt.RRF2.r2);  goto ok;
14629   case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14630                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14631                                     ovl.fmt.RRF2.r2);  goto ok;
14632   case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14633                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14634                                     ovl.fmt.RRF2.r2);  goto ok;
14635   case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14636                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14637                                     ovl.fmt.RRF2.r2);  goto ok;
14638   case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14639                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14640                                     ovl.fmt.RRF2.r2);  goto ok;
14641   case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14642                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14643                                     ovl.fmt.RRF2.r2);  goto ok;
14644   case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14645                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14646                                     ovl.fmt.RRF2.r2);  goto ok;
14647   case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14648                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14649                                     ovl.fmt.RRF2.r2);  goto ok;
14650   case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14651                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14652                                     ovl.fmt.RRF2.r2);  goto ok;
14653   case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14654                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14655                                     ovl.fmt.RRF2.r2);  goto ok;
14656   case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14657                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14658                                     ovl.fmt.RRF2.r2);  goto ok;
14659   case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14660                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14661                                     ovl.fmt.RRF2.r2);  goto ok;
14662   case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14663                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14664                                     ovl.fmt.RRF2.r2);  goto ok;
14665   case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14666                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14667                                     ovl.fmt.RRF2.r2);  goto ok;
14668   case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14669                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14670                                     ovl.fmt.RRF2.r2);  goto ok;
14671   case 0xb3b4: /* CEFR */ goto unimplemented;
14672   case 0xb3b5: /* CDFR */ goto unimplemented;
14673   case 0xb3b6: /* CXFR */ goto unimplemented;
14674   case 0xb3b8: /* CFER */ goto unimplemented;
14675   case 0xb3b9: /* CFDR */ goto unimplemented;
14676   case 0xb3ba: /* CFXR */ goto unimplemented;
14677   case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14678                                   ovl.fmt.RRE.r2);  goto ok;
14679   case 0xb3c4: /* CEGR */ goto unimplemented;
14680   case 0xb3c5: /* CDGR */ goto unimplemented;
14681   case 0xb3c6: /* CXGR */ goto unimplemented;
14682   case 0xb3c8: /* CGER */ goto unimplemented;
14683   case 0xb3c9: /* CGDR */ goto unimplemented;
14684   case 0xb3ca: /* CGXR */ goto unimplemented;
14685   case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14686                                   ovl.fmt.RRE.r2);  goto ok;
14687   case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14688                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14689                                      ovl.fmt.RRF4.r2); goto ok;
14690   case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14691                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14692                                      ovl.fmt.RRF4.r2); goto ok;
14693   case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14694                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14695                                      ovl.fmt.RRF4.r2); goto ok;
14696   case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14697                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14698                                      ovl.fmt.RRF4.r2); goto ok;
14699   case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14700                                     ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14701   case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14702                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14703                                     ovl.fmt.RRF2.r2);  goto ok;
14704   case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14705                                   ovl.fmt.RRE.r2);  goto ok;
14706   case 0xb3d7: /* FIDTR */ goto unimplemented;
14707   case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14708                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14709                                     ovl.fmt.RRF4.r2); goto ok;
14710   case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14711                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14712                                     ovl.fmt.RRF4.r2); goto ok;
14713   case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14714                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14715                                     ovl.fmt.RRF4.r2); goto ok;
14716   case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14717                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14718                                     ovl.fmt.RRF4.r2); goto ok;
14719   case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14720                                     ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14721   case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14722                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14723                                     ovl.fmt.RRF2.r2);  goto ok;
14724   case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14725                                   ovl.fmt.RRE.r2);  goto ok;
14726   case 0xb3df: /* FIXTR */ goto unimplemented;
14727   case 0xb3e0: /* KDTR */ goto unimplemented;
14728   case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14729                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14730                                     ovl.fmt.RRF2.r2);  goto ok;
14731   case 0xb3e2: /* CUDTR */ goto unimplemented;
14732   case 0xb3e3: /* CSDTR */ goto unimplemented;
14733   case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14734                                   ovl.fmt.RRE.r2);  goto ok;
14735   case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14736                                   ovl.fmt.RRE.r2);  goto ok;
14737   case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14738                                   ovl.fmt.RRE.r2);  goto ok;
14739   case 0xb3e8: /* KXTR */ goto unimplemented;
14740   case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14741                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14742                                     ovl.fmt.RRF2.r2);  goto ok;
14743   case 0xb3ea: /* CUXTR */ goto unimplemented;
14744   case 0xb3eb: /* CSXTR */ goto unimplemented;
14745   case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14746                                   ovl.fmt.RRE.r2);  goto ok;
14747   case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14748                                   ovl.fmt.RRE.r2);  goto ok;
14749   case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14750                                   ovl.fmt.RRE.r2);  goto ok;
14751   case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14752                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14753                                     ovl.fmt.RRF2.r2);  goto ok;
14754   case 0xb3f2: /* CDUTR */ goto unimplemented;
14755   case 0xb3f3: /* CDSTR */ goto unimplemented;
14756   case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14757                                   ovl.fmt.RRE.r2);  goto ok;
14758   case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14759                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14760                                     ovl.fmt.RRF4.r2); goto ok;
14761   case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14762                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14763   case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14764                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14765                                     ovl.fmt.RRF4.r2); goto ok;
14766   case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14767                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14768                                     ovl.fmt.RRF2.r2);  goto ok;
14769   case 0xb3fa: /* CXUTR */ goto unimplemented;
14770   case 0xb3fb: /* CXSTR */ goto unimplemented;
14771   case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14772                                   ovl.fmt.RRE.r2);  goto ok;
14773   case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14774                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14775                                     ovl.fmt.RRF4.r2); goto ok;
14776   case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14777                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14778   case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14779                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14780                                     ovl.fmt.RRF4.r2); goto ok;
14781   case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14782                                   ovl.fmt.RRE.r2);  goto ok;
14783   case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14784                                   ovl.fmt.RRE.r2);  goto ok;
14785   case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14786                                   ovl.fmt.RRE.r2);  goto ok;
14787   case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14788                                   ovl.fmt.RRE.r2);  goto ok;
14789   case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14790                                   ovl.fmt.RRE.r2);  goto ok;
14791   case 0xb905: /* LURAG */ goto unimplemented;
14792   case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14793                                   ovl.fmt.RRE.r2);  goto ok;
14794   case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14795                                   ovl.fmt.RRE.r2);  goto ok;
14796   case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14797                                   ovl.fmt.RRE.r2);  goto ok;
14798   case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14799                                   ovl.fmt.RRE.r2);  goto ok;
14800   case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14801                                   ovl.fmt.RRE.r2);  goto ok;
14802   case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14803                                   ovl.fmt.RRE.r2);  goto ok;
14804   case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14805                                   ovl.fmt.RRE.r2);  goto ok;
14806   case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14807                                   ovl.fmt.RRE.r2);  goto ok;
14808   case 0xb90e: /* EREGG */ goto unimplemented;
14809   case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14810                                   ovl.fmt.RRE.r2);  goto ok;
14811   case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14812                                   ovl.fmt.RRE.r2);  goto ok;
14813   case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14814                                   ovl.fmt.RRE.r2);  goto ok;
14815   case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14816                                   ovl.fmt.RRE.r2);  goto ok;
14817   case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14818                                   ovl.fmt.RRE.r2);  goto ok;
14819   case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14820                                   ovl.fmt.RRE.r2);  goto ok;
14821   case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14822                                   ovl.fmt.RRE.r2);  goto ok;
14823   case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14824                                   ovl.fmt.RRE.r2);  goto ok;
14825   case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14826                                   ovl.fmt.RRE.r2);  goto ok;
14827   case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14828                                   ovl.fmt.RRE.r2);  goto ok;
14829   case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14830                                   ovl.fmt.RRE.r2);  goto ok;
14831   case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14832                                   ovl.fmt.RRE.r2);  goto ok;
14833   case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14834                                   ovl.fmt.RRE.r2);  goto ok;
14835   case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14836                                   ovl.fmt.RRE.r2);  goto ok;
14837   case 0xb91e: /* KMAC */ goto unimplemented;
14838   case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14839                                   ovl.fmt.RRE.r2);  goto ok;
14840   case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14841                                   ovl.fmt.RRE.r2);  goto ok;
14842   case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14843                                   ovl.fmt.RRE.r2);  goto ok;
14844   case 0xb925: /* STURG */ goto unimplemented;
14845   case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14846                                   ovl.fmt.RRE.r2);  goto ok;
14847   case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14848                                   ovl.fmt.RRE.r2);  goto ok;
14849   case 0xb928: /* PCKMO */ goto unimplemented;
14850   case 0xb92a: /* KMF */ goto unimplemented;
14851   case 0xb92b: /* KMO */ goto unimplemented;
14852   case 0xb92c: /* PCC */ goto unimplemented;
14853   case 0xb92d: /* KMCTR */ goto unimplemented;
14854   case 0xb92e: /* KM */ goto unimplemented;
14855   case 0xb92f: /* KMC */ goto unimplemented;
14856   case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14857                                   ovl.fmt.RRE.r2);  goto ok;
14858   case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14859                                   ovl.fmt.RRE.r2);  goto ok;
14860   case 0xb93e: /* KIMD */ goto unimplemented;
14861   case 0xb93f: /* KLMD */ goto unimplemented;
14862   case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14863                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14864                                     ovl.fmt.RRF2.r2);  goto ok;
14865   case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14866                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14867                                     ovl.fmt.RRF2.r2);  goto ok;
14868   case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14869                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14870                                     ovl.fmt.RRF2.r2);  goto ok;
14871   case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14872                                   ovl.fmt.RRE.r2);  goto ok;
14873   case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14874                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14875                                     ovl.fmt.RRF2.r2);  goto ok;
14876   case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14877                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14878                                     ovl.fmt.RRF2.r2);  goto ok;
14879   case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14880                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14881                                     ovl.fmt.RRF2.r2);  goto ok;
14882   case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14883                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14884                                     ovl.fmt.RRF2.r2);  goto ok;
14885   case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14886                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14887                                     ovl.fmt.RRF2.r2);  goto ok;
14888   case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14889                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14890                                     ovl.fmt.RRF2.r2);  goto ok;
14891   case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14892                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14893                                     ovl.fmt.RRF2.r2);  goto ok;
14894   case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14895                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14896                                     ovl.fmt.RRF2.r2);  goto ok;
14897   case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14898                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14899                                     ovl.fmt.RRF2.r2);  goto ok;
14900   case 0xb960: /* CGRT */ goto unimplemented;
14901   case 0xb961: /* CLGRT */ goto unimplemented;
14902   case 0xb972: /* CRT */ goto unimplemented;
14903   case 0xb973: /* CLRT */ goto unimplemented;
14904   case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14905                                   ovl.fmt.RRE.r2);  goto ok;
14906   case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14907                                   ovl.fmt.RRE.r2);  goto ok;
14908   case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14909                                   ovl.fmt.RRE.r2);  goto ok;
14910   case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14911                                   ovl.fmt.RRE.r2);  goto ok;
14912   case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14913                                   ovl.fmt.RRE.r2);  goto ok;
14914   case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14915                                   ovl.fmt.RRE.r2);  goto ok;
14916   case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14917                                   ovl.fmt.RRE.r2);  goto ok;
14918   case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14919                                   ovl.fmt.RRE.r2);  goto ok;
14920   case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14921                                   ovl.fmt.RRE.r2);  goto ok;
14922   case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14923                                   ovl.fmt.RRE.r2);  goto ok;
14924   case 0xb98a: /* CSPG */ goto unimplemented;
14925   case 0xb98d: /* EPSW */ goto unimplemented;
14926   case 0xb98e: /* IDTE */ goto unimplemented;
14927   case 0xb98f: /* CRDTE */ goto unimplemented;
14928   case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14929                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
14930   case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14931                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
14932   case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14933                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
14934   case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14935                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
14936   case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14937                                   ovl.fmt.RRE.r2);  goto ok;
14938   case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14939                                   ovl.fmt.RRE.r2);  goto ok;
14940   case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14941                                   ovl.fmt.RRE.r2);  goto ok;
14942   case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14943                                   ovl.fmt.RRE.r2);  goto ok;
14944   case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14945                                   ovl.fmt.RRE.r2);  goto ok;
14946   case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14947                                   ovl.fmt.RRE.r2);  goto ok;
14948   case 0xb99a: /* EPAIR */ goto unimplemented;
14949   case 0xb99b: /* ESAIR */ goto unimplemented;
14950   case 0xb99d: /* ESEA */ goto unimplemented;
14951   case 0xb99e: /* PTI */ goto unimplemented;
14952   case 0xb99f: /* SSAIR */ goto unimplemented;
14953   case 0xb9a2: /* PTF */ goto unimplemented;
14954   case 0xb9aa: /* LPTEA */ goto unimplemented;
14955   case 0xb9ae: /* RRBM */ goto unimplemented;
14956   case 0xb9af: /* PFMF */ goto unimplemented;
14957   case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14958                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14959      goto ok;
14960   case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14961                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14962      goto ok;
14963   case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14964                                   ovl.fmt.RRE.r2);  goto ok;
14965   case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14966                                   ovl.fmt.RRE.r2);  goto ok;
14967   case 0xb9bd: /* TRTRE */ goto unimplemented;
14968   case 0xb9be: /* SRSTU */ goto unimplemented;
14969   case 0xb9bf: /* TRTE */ goto unimplemented;
14970   case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14971                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14972                                      goto ok;
14973   case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14974                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14975                                      goto ok;
14976   case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14977                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14978                                      goto ok;
14979   case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14980                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14981                                      goto ok;
14982   case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14983                                   ovl.fmt.RRE.r2);  goto ok;
14984   case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14985                                   ovl.fmt.RRE.r2);  goto ok;
14986   case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14987                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14988                                      goto ok;
14989   case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14990                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14991                                      goto ok;
14992   case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14993                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14994                                      goto ok;
14995   case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14996                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14997                                      goto ok;
14998   case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14999                                   ovl.fmt.RRE.r2);  goto ok;
15000   case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
15001                                   ovl.fmt.RRE.r2);  goto ok;
15002   case 0xb9e1: /* POPCNT */ goto unimplemented;
15003   case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
15004                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
15005                                     S390_XMNM_LOCGR);  goto ok;
15006   case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
15007                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15008                                      goto ok;
15009   case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
15010                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15011                                      goto ok;
15012   case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
15013                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15014                                      goto ok;
15015   case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
15016                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15017                                      goto ok;
15018   case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
15019                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15020                                      goto ok;
15021   case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
15022                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15023                                      goto ok;
15024   case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
15025                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15026                                      goto ok;
15027   case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
15028                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
15029                                     S390_XMNM_LOCR);  goto ok;
15030   case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
15031                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15032                                      goto ok;
15033   case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
15034                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15035                                      goto ok;
15036   case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
15037                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15038                                      goto ok;
15039   case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
15040                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15041                                      goto ok;
15042   case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
15043                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15044                                      goto ok;
15045   case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
15046                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15047                                      goto ok;
15048   case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
15049                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15050                                      goto ok;
15051   }
15052
15053   switch ((ovl.value & 0xff000000) >> 24) {
15054   case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15055                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15056   case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15057                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15058   case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15059                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15060   case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15061                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15062   case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15063                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15064   case 0x45: /* BAL */ goto unimplemented;
15065   case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15066                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15067   case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15068                             ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15069   case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15070                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15071   case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15072                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15073   case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15074                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15075   case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15076                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15077   case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15078                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15079   case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15080                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15081   case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15082                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15083   case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15084                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15085   case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15086                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15087   case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15088                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15089   case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15090                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15091   case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15092                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15093   case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15094                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15095   case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15096                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15097   case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15098                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15099   case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15100                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15101   case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15102                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15103   case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15104                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15105   case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15106                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15107   case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15108                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15109   case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15110                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15111   case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15112                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15113   case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15114                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15115   case 0x67: /* MXD */ goto unimplemented;
15116   case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15117                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15118   case 0x69: /* CD */ goto unimplemented;
15119   case 0x6a: /* AD */ goto unimplemented;
15120   case 0x6b: /* SD */ goto unimplemented;
15121   case 0x6c: /* MD */ goto unimplemented;
15122   case 0x6d: /* DD */ goto unimplemented;
15123   case 0x6e: /* AW */ goto unimplemented;
15124   case 0x6f: /* SW */ goto unimplemented;
15125   case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15126                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15127   case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15128                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15129   case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15130                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15131   case 0x79: /* CE */ goto unimplemented;
15132   case 0x7a: /* AE */ goto unimplemented;
15133   case 0x7b: /* SE */ goto unimplemented;
15134   case 0x7c: /* MDE */ goto unimplemented;
15135   case 0x7d: /* DE */ goto unimplemented;
15136   case 0x7e: /* AU */ goto unimplemented;
15137   case 0x7f: /* SU */ goto unimplemented;
15138   case 0x83: /* DIAG */ goto unimplemented;
15139   case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
15140                                  ovl.fmt.RSI.r3, ovl.fmt.RSI.i2);  goto ok;
15141   case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
15142                                  ovl.fmt.RSI.r3, ovl.fmt.RSI.i2);  goto ok;
15143   case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15144                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15145   case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15146                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15147   case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15148                                  ovl.fmt.RS.d2);  goto ok;
15149   case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15150                                  ovl.fmt.RS.d2);  goto ok;
15151   case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15152                                  ovl.fmt.RS.d2);  goto ok;
15153   case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15154                                  ovl.fmt.RS.d2);  goto ok;
15155   case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15156                                  ovl.fmt.RS.d2);  goto ok;
15157   case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15158                                  ovl.fmt.RS.d2);  goto ok;
15159   case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15160                                  ovl.fmt.RS.d2);  goto ok;
15161   case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15162                                  ovl.fmt.RS.d2);  goto ok;
15163   case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15164                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15165   case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15166                                 ovl.fmt.SI.d1);  goto ok;
15167   case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15168                                 ovl.fmt.SI.d1);  goto ok;
15169   case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15170                                 ovl.fmt.SI.d1);  goto ok;
15171   case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15172                                 ovl.fmt.SI.d1);  goto ok;
15173   case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15174                                 ovl.fmt.SI.d1);  goto ok;
15175   case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15176                                 ovl.fmt.SI.d1);  goto ok;
15177   case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15178                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15179   case 0x99: /* TRACE */ goto unimplemented;
15180   case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15181                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15182   case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15183                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15184   case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
15185                                  ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15186                                  goto ok;
15187   case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
15188                                  ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15189                                  goto ok;
15190   case 0xac: /* STNSM */ goto unimplemented;
15191   case 0xad: /* STOSM */ goto unimplemented;
15192   case 0xae: /* SIGP */ goto unimplemented;
15193   case 0xaf: /* MC */ goto unimplemented;
15194   case 0xb1: /* LRA */ goto unimplemented;
15195   case 0xb6: /* STCTL */ goto unimplemented;
15196   case 0xb7: /* LCTL */ goto unimplemented;
15197   case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15198                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15199   case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15200                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15201   case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15202                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15203   case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15204                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15205   case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15206                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15207   }
15208
15209   return S390_DECODE_UNKNOWN_INSN;
15210
15211ok:
15212   return S390_DECODE_OK;
15213
15214unimplemented:
15215   return S390_DECODE_UNIMPLEMENTED_INSN;
15216}
15217
15218static s390_decode_t
15219s390_decode_6byte_and_irgen(const UChar *bytes)
15220{
15221   typedef union {
15222      struct {
15223         unsigned int op1 :  8;
15224         unsigned int r1  :  4;
15225         unsigned int r3  :  4;
15226         unsigned int i2  : 16;
15227         unsigned int     :  8;
15228         unsigned int op2 :  8;
15229      } RIE;
15230      struct {
15231         unsigned int op1 :  8;
15232         unsigned int r1  :  4;
15233         unsigned int r2  :  4;
15234         unsigned int i3  :  8;
15235         unsigned int i4  :  8;
15236         unsigned int i5  :  8;
15237         unsigned int op2 :  8;
15238      } RIE_RRUUU;
15239      struct {
15240         unsigned int op1 :  8;
15241         unsigned int r1  :  4;
15242         unsigned int     :  4;
15243         unsigned int i2  : 16;
15244         unsigned int m3  :  4;
15245         unsigned int     :  4;
15246         unsigned int op2 :  8;
15247      } RIEv1;
15248      struct {
15249         unsigned int op1 :  8;
15250         unsigned int r1  :  4;
15251         unsigned int r2  :  4;
15252         unsigned int i4  : 16;
15253         unsigned int m3  :  4;
15254         unsigned int     :  4;
15255         unsigned int op2 :  8;
15256      } RIE_RRPU;
15257      struct {
15258         unsigned int op1 :  8;
15259         unsigned int r1  :  4;
15260         unsigned int m3  :  4;
15261         unsigned int i4  : 16;
15262         unsigned int i2  :  8;
15263         unsigned int op2 :  8;
15264      } RIEv3;
15265      struct {
15266         unsigned int op1 :  8;
15267         unsigned int r1  :  4;
15268         unsigned int op2 :  4;
15269         unsigned int i2  : 32;
15270      } RIL;
15271      struct {
15272         unsigned int op1 :  8;
15273         unsigned int r1  :  4;
15274         unsigned int m3  :  4;
15275         unsigned int b4  :  4;
15276         unsigned int d4  : 12;
15277         unsigned int i2  :  8;
15278         unsigned int op2 :  8;
15279      } RIS;
15280      struct {
15281         unsigned int op1 :  8;
15282         unsigned int r1  :  4;
15283         unsigned int r2  :  4;
15284         unsigned int b4  :  4;
15285         unsigned int d4  : 12;
15286         unsigned int m3  :  4;
15287         unsigned int     :  4;
15288         unsigned int op2 :  8;
15289      } RRS;
15290      struct {
15291         unsigned int op1 :  8;
15292         unsigned int l1  :  4;
15293         unsigned int     :  4;
15294         unsigned int b1  :  4;
15295         unsigned int d1  : 12;
15296         unsigned int     :  8;
15297         unsigned int op2 :  8;
15298      } RSL;
15299      struct {
15300         unsigned int op1 :  8;
15301         unsigned int r1  :  4;
15302         unsigned int r3  :  4;
15303         unsigned int b2  :  4;
15304         unsigned int dl2 : 12;
15305         unsigned int dh2 :  8;
15306         unsigned int op2 :  8;
15307      } RSY;
15308      struct {
15309         unsigned int op1 :  8;
15310         unsigned int r1  :  4;
15311         unsigned int x2  :  4;
15312         unsigned int b2  :  4;
15313         unsigned int d2  : 12;
15314         unsigned int     :  8;
15315         unsigned int op2 :  8;
15316      } RXE;
15317      struct {
15318         unsigned int op1 :  8;
15319         unsigned int r3  :  4;
15320         unsigned int x2  :  4;
15321         unsigned int b2  :  4;
15322         unsigned int d2  : 12;
15323         unsigned int r1  :  4;
15324         unsigned int     :  4;
15325         unsigned int op2 :  8;
15326      } RXF;
15327      struct {
15328         unsigned int op1 :  8;
15329         unsigned int r1  :  4;
15330         unsigned int x2  :  4;
15331         unsigned int b2  :  4;
15332         unsigned int dl2 : 12;
15333         unsigned int dh2 :  8;
15334         unsigned int op2 :  8;
15335      } RXY;
15336      struct {
15337         unsigned int op1 :  8;
15338         unsigned int i2  :  8;
15339         unsigned int b1  :  4;
15340         unsigned int dl1 : 12;
15341         unsigned int dh1 :  8;
15342         unsigned int op2 :  8;
15343      } SIY;
15344      struct {
15345         unsigned int op :  8;
15346         unsigned int l  :  8;
15347         unsigned int b1 :  4;
15348         unsigned int d1 : 12;
15349         unsigned int b2 :  4;
15350         unsigned int d2 : 12;
15351      } SS;
15352      struct {
15353         unsigned int op :  8;
15354         unsigned int l1 :  4;
15355         unsigned int l2 :  4;
15356         unsigned int b1 :  4;
15357         unsigned int d1 : 12;
15358         unsigned int b2 :  4;
15359         unsigned int d2 : 12;
15360      } SS_LLRDRD;
15361      struct {
15362         unsigned int op :  8;
15363         unsigned int r1 :  4;
15364         unsigned int r3 :  4;
15365         unsigned int b2 :  4;
15366         unsigned int d2 : 12;
15367         unsigned int b4 :  4;
15368         unsigned int d4 : 12;
15369      } SS_RRRDRD2;
15370      struct {
15371         unsigned int op : 16;
15372         unsigned int b1 :  4;
15373         unsigned int d1 : 12;
15374         unsigned int b2 :  4;
15375         unsigned int d2 : 12;
15376      } SSE;
15377      struct {
15378         unsigned int op1 :  8;
15379         unsigned int r3  :  4;
15380         unsigned int op2 :  4;
15381         unsigned int b1  :  4;
15382         unsigned int d1  : 12;
15383         unsigned int b2  :  4;
15384         unsigned int d2  : 12;
15385      } SSF;
15386      struct {
15387         unsigned int op : 16;
15388         unsigned int b1 :  4;
15389         unsigned int d1 : 12;
15390         unsigned int i2 : 16;
15391      } SIL;
15392   } formats;
15393   union {
15394      formats fmt;
15395      ULong value;
15396   } ovl;
15397
15398   vassert(sizeof(formats) == 6);
15399
15400   ((UChar *)(&ovl.value))[0] = bytes[0];
15401   ((UChar *)(&ovl.value))[1] = bytes[1];
15402   ((UChar *)(&ovl.value))[2] = bytes[2];
15403   ((UChar *)(&ovl.value))[3] = bytes[3];
15404   ((UChar *)(&ovl.value))[4] = bytes[4];
15405   ((UChar *)(&ovl.value))[5] = bytes[5];
15406   ((UChar *)(&ovl.value))[6] = 0x0;
15407   ((UChar *)(&ovl.value))[7] = 0x0;
15408
15409   switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15410   case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15411                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15412                                                ovl.fmt.RXY.dl2,
15413                                                ovl.fmt.RXY.dh2);  goto ok;
15414   case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15415   case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15416                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15417                                                ovl.fmt.RXY.dl2,
15418                                                ovl.fmt.RXY.dh2);  goto ok;
15419   case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15420                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15421                                                ovl.fmt.RXY.dl2,
15422                                                ovl.fmt.RXY.dh2);  goto ok;
15423   case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15424                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15425                                                ovl.fmt.RXY.dl2,
15426                                                ovl.fmt.RXY.dh2);  goto ok;
15427   case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15428                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15429                                                ovl.fmt.RXY.dl2,
15430                                                ovl.fmt.RXY.dh2);  goto ok;
15431   case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15432                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15433                                                ovl.fmt.RXY.dl2,
15434                                                ovl.fmt.RXY.dh2);  goto ok;
15435   case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15436                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15437                                                ovl.fmt.RXY.dl2,
15438                                                ovl.fmt.RXY.dh2);  goto ok;
15439   case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15440                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15441                                                ovl.fmt.RXY.dl2,
15442                                                ovl.fmt.RXY.dh2);  goto ok;
15443   case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15444                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15445                                                ovl.fmt.RXY.dl2,
15446                                                ovl.fmt.RXY.dh2);  goto ok;
15447   case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15448   case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
15449                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15450                                                ovl.fmt.RXY.dl2,
15451                                                ovl.fmt.RXY.dh2);  goto ok;
15452   case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
15453                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15454                                                ovl.fmt.RXY.dl2,
15455                                                ovl.fmt.RXY.dh2);  goto ok;
15456   case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15457   case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15458                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15459                                                ovl.fmt.RXY.dl2,
15460                                                ovl.fmt.RXY.dh2);  goto ok;
15461   case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15462                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15463                                                ovl.fmt.RXY.dl2,
15464                                                ovl.fmt.RXY.dh2);  goto ok;
15465   case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15466                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15467                                                ovl.fmt.RXY.dl2,
15468                                                ovl.fmt.RXY.dh2);  goto ok;
15469   case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15470                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15471                                                ovl.fmt.RXY.dl2,
15472                                                ovl.fmt.RXY.dh2);  goto ok;
15473   case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15474                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15475                                                ovl.fmt.RXY.dl2,
15476                                                ovl.fmt.RXY.dh2);  goto ok;
15477   case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15478                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15479                                                ovl.fmt.RXY.dl2,
15480                                                ovl.fmt.RXY.dh2);  goto ok;
15481   case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15482                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15483                                                ovl.fmt.RXY.dl2,
15484                                                ovl.fmt.RXY.dh2);  goto ok;
15485   case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15486                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15487                                                ovl.fmt.RXY.dl2,
15488                                                ovl.fmt.RXY.dh2);  goto ok;
15489   case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15490                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15491                                                ovl.fmt.RXY.dl2,
15492                                                ovl.fmt.RXY.dh2);  goto ok;
15493   case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15494                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15495                                                ovl.fmt.RXY.dl2,
15496                                                ovl.fmt.RXY.dh2);  goto ok;
15497   case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15498                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15499                                                ovl.fmt.RXY.dl2,
15500                                                ovl.fmt.RXY.dh2);  goto ok;
15501   case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15502                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15503                                                ovl.fmt.RXY.dl2,
15504                                                ovl.fmt.RXY.dh2);  goto ok;
15505   case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15506                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15507                                                ovl.fmt.RXY.dl2,
15508                                                ovl.fmt.RXY.dh2);  goto ok;
15509   case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15510                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15511                                                ovl.fmt.RXY.dl2,
15512                                                ovl.fmt.RXY.dh2);  goto ok;
15513   case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15514                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15515                                                ovl.fmt.RXY.dl2,
15516                                                ovl.fmt.RXY.dh2);  goto ok;
15517   case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
15518   case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15519                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15520                                                ovl.fmt.RXY.dl2,
15521                                                ovl.fmt.RXY.dh2);  goto ok;
15522   case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15523   case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15524                                                ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15525                                                ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15526                                                ovl.fmt.RXY.dh2);  goto ok;
15527   case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15528                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15529                                                ovl.fmt.RXY.dl2,
15530                                                ovl.fmt.RXY.dh2);  goto ok;
15531   case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15532                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15533                                                ovl.fmt.RXY.dl2,
15534                                                ovl.fmt.RXY.dh2);  goto ok;
15535   case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15536                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15537                                                ovl.fmt.RXY.dl2,
15538                                                ovl.fmt.RXY.dh2);  goto ok;
15539   case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15540                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15541                                                ovl.fmt.RXY.dl2,
15542                                                ovl.fmt.RXY.dh2);  goto ok;
15543   case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15544                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15545                                                ovl.fmt.RXY.dl2,
15546                                                ovl.fmt.RXY.dh2);  goto ok;
15547   case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15548                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15549                                                ovl.fmt.RXY.dl2,
15550                                                ovl.fmt.RXY.dh2);  goto ok;
15551   case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15552                                                ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15553                                                ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15554                                                ovl.fmt.RXY.dh2);  goto ok;
15555   case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15556                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15557                                                ovl.fmt.RXY.dl2,
15558                                                ovl.fmt.RXY.dh2);  goto ok;
15559   case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15560                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15561                                                ovl.fmt.RXY.dl2,
15562                                                ovl.fmt.RXY.dh2);  goto ok;
15563   case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15564                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15565                                                ovl.fmt.RXY.dl2,
15566                                                ovl.fmt.RXY.dh2);  goto ok;
15567   case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15568                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15569                                                ovl.fmt.RXY.dl2,
15570                                                ovl.fmt.RXY.dh2);  goto ok;
15571   case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15572                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15573                                                ovl.fmt.RXY.dl2,
15574                                                ovl.fmt.RXY.dh2);  goto ok;
15575   case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15576                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15577                                                ovl.fmt.RXY.dl2,
15578                                                ovl.fmt.RXY.dh2);  goto ok;
15579   case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, 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 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15584                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15585                                                ovl.fmt.RXY.dl2,
15586                                                ovl.fmt.RXY.dh2);  goto ok;
15587   case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15588                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15589                                                ovl.fmt.RXY.dl2,
15590                                                ovl.fmt.RXY.dh2);  goto ok;
15591   case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15592                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15593                                                ovl.fmt.RXY.dl2,
15594                                                ovl.fmt.RXY.dh2);  goto ok;
15595   case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15596                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15597                                                ovl.fmt.RXY.dl2,
15598                                                ovl.fmt.RXY.dh2);  goto ok;
15599   case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15600                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15601                                                ovl.fmt.RXY.dl2,
15602                                                ovl.fmt.RXY.dh2);  goto ok;
15603   case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15604                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15605                                                ovl.fmt.RXY.dl2,
15606                                                ovl.fmt.RXY.dh2);  goto ok;
15607   case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15608                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15609                                                ovl.fmt.RXY.dl2,
15610                                                ovl.fmt.RXY.dh2);  goto ok;
15611   case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15612                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15613                                                ovl.fmt.RXY.dl2,
15614                                                ovl.fmt.RXY.dh2);  goto ok;
15615   case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15616                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15617                                                ovl.fmt.RXY.dl2,
15618                                                ovl.fmt.RXY.dh2);  goto ok;
15619   case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15620                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15621                                                ovl.fmt.RXY.dl2,
15622                                                ovl.fmt.RXY.dh2);  goto ok;
15623   case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15624                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15625                                                ovl.fmt.RXY.dl2,
15626                                                ovl.fmt.RXY.dh2);  goto ok;
15627   case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15628                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15629                                                ovl.fmt.RXY.dl2,
15630                                                ovl.fmt.RXY.dh2);  goto ok;
15631   case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15632                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15633                                                ovl.fmt.RXY.dl2,
15634                                                ovl.fmt.RXY.dh2);  goto ok;
15635   case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15636                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15637                                                ovl.fmt.RXY.dl2,
15638                                                ovl.fmt.RXY.dh2);  goto ok;
15639   case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15640                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15641                                                ovl.fmt.RXY.dl2,
15642                                                ovl.fmt.RXY.dh2);  goto ok;
15643   case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15644                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15645                                                ovl.fmt.RXY.dl2,
15646                                                ovl.fmt.RXY.dh2);  goto ok;
15647   case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15648                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15649                                                ovl.fmt.RXY.dl2,
15650                                                ovl.fmt.RXY.dh2);  goto ok;
15651   case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15652                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15653                                                ovl.fmt.RXY.dl2,
15654                                                ovl.fmt.RXY.dh2);  goto ok;
15655   case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15656                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15657                                                ovl.fmt.RXY.dl2,
15658                                                ovl.fmt.RXY.dh2);  goto ok;
15659   case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15660                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15661                                                ovl.fmt.RXY.dl2,
15662                                                ovl.fmt.RXY.dh2);  goto ok;
15663   case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15664                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15665                                                ovl.fmt.RXY.dl2,
15666                                                ovl.fmt.RXY.dh2);  goto ok;
15667   case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15668                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15669                                                ovl.fmt.RXY.dl2,
15670                                                ovl.fmt.RXY.dh2);  goto ok;
15671   case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
15672   case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15673                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15674                                                ovl.fmt.RXY.dl2,
15675                                                ovl.fmt.RXY.dh2);  goto ok;
15676   case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15677                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15678                                                ovl.fmt.RXY.dl2,
15679                                                ovl.fmt.RXY.dh2);  goto ok;
15680   case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15681                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15682                                                ovl.fmt.RXY.dl2,
15683                                                ovl.fmt.RXY.dh2);  goto ok;
15684   case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15685                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15686                                                ovl.fmt.RXY.dl2,
15687                                                ovl.fmt.RXY.dh2);  goto ok;
15688   case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15689                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15690                                                ovl.fmt.RXY.dl2,
15691                                                ovl.fmt.RXY.dh2);  goto ok;
15692   case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15693                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15694                                                ovl.fmt.RXY.dl2,
15695                                                ovl.fmt.RXY.dh2);  goto ok;
15696   case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, 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 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, 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 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, 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 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, 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 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, 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 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, 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 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15721                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15722                                                ovl.fmt.RXY.dl2,
15723                                                ovl.fmt.RXY.dh2);  goto ok;
15724   case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, 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 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15729   case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15730   case 0xe3000000009fULL: /* LAT */ goto unimplemented;
15731   case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15732                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15733                                                ovl.fmt.RXY.dl2,
15734                                                ovl.fmt.RXY.dh2);  goto ok;
15735   case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15736                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15737                                                ovl.fmt.RXY.dl2,
15738                                                ovl.fmt.RXY.dh2);  goto ok;
15739   case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15740                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15741                                                ovl.fmt.RXY.dl2,
15742                                                ovl.fmt.RXY.dh2);  goto ok;
15743   case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15744                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15745                                                ovl.fmt.RXY.dl2,
15746                                                ovl.fmt.RXY.dh2);  goto ok;
15747   case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15748                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15749                                                ovl.fmt.RXY.dl2,
15750                                                ovl.fmt.RXY.dh2);  goto ok;
15751   case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15752                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15753                                                ovl.fmt.RXY.dl2,
15754                                                ovl.fmt.RXY.dh2);  goto ok;
15755   case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
15756   case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, 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 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, 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 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, 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 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, 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 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15773                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15774                                                ovl.fmt.RSY.dl2,
15775                                                ovl.fmt.RSY.dh2);  goto ok;
15776   case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15777                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15778                                                ovl.fmt.RSY.dl2,
15779                                                ovl.fmt.RSY.dh2);  goto ok;
15780   case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15781                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15782                                                ovl.fmt.RSY.dl2,
15783                                                ovl.fmt.RSY.dh2);  goto ok;
15784   case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15785                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15786                                                ovl.fmt.RSY.dl2,
15787                                                ovl.fmt.RSY.dh2);  goto ok;
15788   case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15789                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15790                                                ovl.fmt.RSY.dl2,
15791                                                ovl.fmt.RSY.dh2);  goto ok;
15792   case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15793   case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15794                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15795                                                ovl.fmt.RSY.dl2,
15796                                                ovl.fmt.RSY.dh2);  goto ok;
15797   case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15798                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15799                                                ovl.fmt.RSY.dl2,
15800                                                ovl.fmt.RSY.dh2);  goto ok;
15801   case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15802                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15803                                                ovl.fmt.RSY.dl2,
15804                                                ovl.fmt.RSY.dh2);  goto ok;
15805   case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15806                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15807                                                ovl.fmt.RSY.dl2,
15808                                                ovl.fmt.RSY.dh2);  goto ok;
15809   case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15810                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15811                                                ovl.fmt.RSY.dl2,
15812                                                ovl.fmt.RSY.dh2);  goto ok;
15813   case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
15814   case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15815                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15816                                                ovl.fmt.RSY.dl2,
15817                                                ovl.fmt.RSY.dh2);  goto ok;
15818   case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15819   case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15820                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15821                                                ovl.fmt.RSY.dl2,
15822                                                ovl.fmt.RSY.dh2);  goto ok;
15823   case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
15824   case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15825                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15826                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15827                                                ovl.fmt.RSY.dh2);  goto ok;
15828   case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15829                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15830                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15831                                                ovl.fmt.RSY.dh2);  goto ok;
15832   case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15833   case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15834                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15835                                                ovl.fmt.RSY.dl2,
15836                                                ovl.fmt.RSY.dh2);  goto ok;
15837   case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15838                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15839                                                ovl.fmt.RSY.dl2,
15840                                                ovl.fmt.RSY.dh2);  goto ok;
15841   case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15842                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15843                                                ovl.fmt.RSY.dl2,
15844                                                ovl.fmt.RSY.dh2);  goto ok;
15845   case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15846                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15847                                                ovl.fmt.RSY.dl2,
15848                                                ovl.fmt.RSY.dh2);  goto ok;
15849   case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15850                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15851                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15852                                                ovl.fmt.RSY.dh2);  goto ok;
15853   case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15854                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15855                                                ovl.fmt.RSY.dl2,
15856                                                ovl.fmt.RSY.dh2);  goto ok;
15857   case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15858                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15859                                               ovl.fmt.SIY.dh1);  goto ok;
15860   case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15861                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15862                                               ovl.fmt.SIY.dh1);  goto ok;
15863   case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15864                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15865                                               ovl.fmt.SIY.dh1);  goto ok;
15866   case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15867                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15868                                               ovl.fmt.SIY.dh1);  goto ok;
15869   case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15870                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15871                                               ovl.fmt.SIY.dh1);  goto ok;
15872   case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15873                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15874                                               ovl.fmt.SIY.dh1);  goto ok;
15875   case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15876                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15877                                               ovl.fmt.SIY.dh1);  goto ok;
15878   case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15879                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15880                                               ovl.fmt.SIY.dh1);  goto ok;
15881   case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15882                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15883                                               ovl.fmt.SIY.dh1);  goto ok;
15884   case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15885                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15886                                               ovl.fmt.SIY.dh1);  goto ok;
15887   case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15888                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15889                                                ovl.fmt.RSY.dl2,
15890                                                ovl.fmt.RSY.dh2);  goto ok;
15891   case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15892                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15893                                                ovl.fmt.RSY.dl2,
15894                                                ovl.fmt.RSY.dh2);  goto ok;
15895   case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15896   case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15897   case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15898                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15899                                                ovl.fmt.RSY.dl2,
15900                                                ovl.fmt.RSY.dh2);  goto ok;
15901   case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15902                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15903                                                ovl.fmt.RSY.dl2,
15904                                                ovl.fmt.RSY.dh2);  goto ok;
15905   case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15906                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15907                                                ovl.fmt.RSY.dl2,
15908                                                ovl.fmt.RSY.dh2);  goto ok;
15909   case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15910                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15911                                                ovl.fmt.RSY.dl2,
15912                                                ovl.fmt.RSY.dh2);  goto ok;
15913   case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15914                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15915                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15916                                                ovl.fmt.RSY.dh2);  goto ok;
15917   case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15918   case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15919                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15920                                                ovl.fmt.RSY.dl2,
15921                                                ovl.fmt.RSY.dh2);  goto ok;
15922   case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15923                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15924                                                ovl.fmt.RSY.dl2,
15925                                                ovl.fmt.RSY.dh2);  goto ok;
15926   case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15927                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15928                                                ovl.fmt.RSY.dl2,
15929                                                ovl.fmt.RSY.dh2);  goto ok;
15930   case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15931                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15932                                                ovl.fmt.RSY.dl2,
15933                                                ovl.fmt.RSY.dh2);  goto ok;
15934   case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15935                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15936                                                ovl.fmt.RSY.dl2,
15937                                                ovl.fmt.RSY.dh2,
15938                                                S390_XMNM_LOCG);  goto ok;
15939   case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15940                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15941                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15942                                                ovl.fmt.RSY.dh2,
15943                                                S390_XMNM_STOCG);  goto ok;
15944   case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15945                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15946                                                ovl.fmt.RSY.dl2,
15947                                                ovl.fmt.RSY.dh2);  goto ok;
15948   case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15949                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15950                                                ovl.fmt.RSY.dl2,
15951                                                ovl.fmt.RSY.dh2);  goto ok;
15952   case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15953                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15954                                                ovl.fmt.RSY.dl2,
15955                                                ovl.fmt.RSY.dh2);  goto ok;
15956   case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15957                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15958                                                ovl.fmt.RSY.dl2,
15959                                                ovl.fmt.RSY.dh2);  goto ok;
15960   case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15961                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15962                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15963                                                ovl.fmt.RSY.dh2);  goto ok;
15964   case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15965                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15966                                                ovl.fmt.RSY.dl2,
15967                                                ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15968                                                goto ok;
15969   case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15970                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15971                                                ovl.fmt.RSY.dl2,
15972                                                ovl.fmt.RSY.dh2,
15973                                                S390_XMNM_STOC);  goto ok;
15974   case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, 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 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, 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 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15983                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15984                                                ovl.fmt.RSY.dl2,
15985                                                ovl.fmt.RSY.dh2);  goto ok;
15986   case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15987                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15988                                                ovl.fmt.RSY.dl2,
15989                                                ovl.fmt.RSY.dh2);  goto ok;
15990   case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15991                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15992                                                ovl.fmt.RSY.dl2,
15993                                                ovl.fmt.RSY.dh2);  goto ok;
15994   case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15995                                               ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15996                                               goto ok;
15997   case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15998                                               ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15999                                               goto ok;
16000   case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
16001   case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
16002                                                 ovl.fmt.RIE_RRUUU.r1,
16003                                                 ovl.fmt.RIE_RRUUU.r2,
16004                                                 ovl.fmt.RIE_RRUUU.i3,
16005                                                 ovl.fmt.RIE_RRUUU.i4,
16006                                                 ovl.fmt.RIE_RRUUU.i5);
16007                                                 goto ok;
16008   case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
16009                                                 ovl.fmt.RIE_RRUUU.r1,
16010                                                 ovl.fmt.RIE_RRUUU.r2,
16011                                                 ovl.fmt.RIE_RRUUU.i3,
16012                                                 ovl.fmt.RIE_RRUUU.i4,
16013                                                 ovl.fmt.RIE_RRUUU.i5);
16014                                                 goto ok;
16015   case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
16016                                                 ovl.fmt.RIE_RRUUU.r1,
16017                                                 ovl.fmt.RIE_RRUUU.r2,
16018                                                 ovl.fmt.RIE_RRUUU.i3,
16019                                                 ovl.fmt.RIE_RRUUU.i4,
16020                                                 ovl.fmt.RIE_RRUUU.i5);
16021                                                 goto ok;
16022   case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
16023                                                 ovl.fmt.RIE_RRUUU.r1,
16024                                                 ovl.fmt.RIE_RRUUU.r2,
16025                                                 ovl.fmt.RIE_RRUUU.i3,
16026                                                 ovl.fmt.RIE_RRUUU.i4,
16027                                                 ovl.fmt.RIE_RRUUU.i5);
16028                                                 goto ok;
16029   case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
16030   case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
16031   case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
16032                                                ovl.fmt.RIE_RRPU.r1,
16033                                                ovl.fmt.RIE_RRPU.r2,
16034                                                ovl.fmt.RIE_RRPU.i4,
16035                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
16036   case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
16037                                                ovl.fmt.RIE_RRPU.r1,
16038                                                ovl.fmt.RIE_RRPU.r2,
16039                                                ovl.fmt.RIE_RRPU.i4,
16040                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
16041   case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
16042   case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
16043   case 0xec0000000072ULL: /* CIT */ goto unimplemented;
16044   case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
16045   case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
16046                                                ovl.fmt.RIE_RRPU.r1,
16047                                                ovl.fmt.RIE_RRPU.r2,
16048                                                ovl.fmt.RIE_RRPU.i4,
16049                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
16050   case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
16051                                                ovl.fmt.RIE_RRPU.r1,
16052                                                ovl.fmt.RIE_RRPU.r2,
16053                                                ovl.fmt.RIE_RRPU.i4,
16054                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
16055   case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
16056                                                ovl.fmt.RIEv3.r1,
16057                                                ovl.fmt.RIEv3.m3,
16058                                                ovl.fmt.RIEv3.i4,
16059                                                ovl.fmt.RIEv3.i2);  goto ok;
16060   case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
16061                                                ovl.fmt.RIEv3.r1,
16062                                                ovl.fmt.RIEv3.m3,
16063                                                ovl.fmt.RIEv3.i4,
16064                                                ovl.fmt.RIEv3.i2);  goto ok;
16065   case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
16066                                                ovl.fmt.RIEv3.r1,
16067                                                ovl.fmt.RIEv3.m3,
16068                                                ovl.fmt.RIEv3.i4,
16069                                                ovl.fmt.RIEv3.i2);  goto ok;
16070   case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
16071                                                ovl.fmt.RIEv3.r1,
16072                                                ovl.fmt.RIEv3.m3,
16073                                                ovl.fmt.RIEv3.i4,
16074                                                ovl.fmt.RIEv3.i2);  goto ok;
16075   case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
16076                                                ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
16077                                                goto ok;
16078   case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
16079                                                ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16080                                                ovl.fmt.RIE.i2);  goto ok;
16081   case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
16082                                                ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16083                                                ovl.fmt.RIE.i2);  goto ok;
16084   case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
16085                                                ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16086                                                ovl.fmt.RIE.i2);  goto ok;
16087   case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
16088                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16089                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16090                                           goto ok;
16091   case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
16092                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16093                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16094                                           goto ok;
16095   case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
16096                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16097                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16098                                           goto ok;
16099   case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
16100                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16101                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16102                                           goto ok;
16103   case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
16104                                                 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16105                                                 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16106                                                 ovl.fmt.RIS.i2);  goto ok;
16107   case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
16108                                                 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16109                                                 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16110                                                 ovl.fmt.RIS.i2);  goto ok;
16111   case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
16112                                                 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
16113                                                 ovl.fmt.RIS.d4,
16114                                                 ovl.fmt.RIS.i2);  goto ok;
16115   case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
16116                                                 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16117                                                 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16118                                                 ovl.fmt.RIS.i2);  goto ok;
16119   case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
16120                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16121                                                ovl.fmt.RXE.d2);  goto ok;
16122   case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
16123                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16124                                                ovl.fmt.RXE.d2);  goto ok;
16125   case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
16126                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16127                                                ovl.fmt.RXE.d2);  goto ok;
16128   case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
16129   case 0xed0000000008ULL: /* KEB */ goto unimplemented;
16130   case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
16131                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16132                                                ovl.fmt.RXE.d2);  goto ok;
16133   case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
16134                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16135                                                ovl.fmt.RXE.d2);  goto ok;
16136   case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
16137                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16138                                                ovl.fmt.RXE.d2);  goto ok;
16139   case 0xed000000000cULL: /* MDEB */ goto unimplemented;
16140   case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
16141                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16142                                                ovl.fmt.RXE.d2);  goto ok;
16143   case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
16144                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16145                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16146                                                 ovl.fmt.RXF.r1);  goto ok;
16147   case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
16148                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16149                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16150                                                 ovl.fmt.RXF.r1);  goto ok;
16151   case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
16152                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16153                                                ovl.fmt.RXE.d2);  goto ok;
16154   case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
16155                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16156                                                ovl.fmt.RXE.d2);  goto ok;
16157   case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
16158                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16159                                                ovl.fmt.RXE.d2);  goto ok;
16160   case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
16161                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16162                                                ovl.fmt.RXE.d2);  goto ok;
16163   case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
16164                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16165                                                ovl.fmt.RXE.d2);  goto ok;
16166   case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
16167                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16168                                                ovl.fmt.RXE.d2);  goto ok;
16169   case 0xed0000000018ULL: /* KDB */ goto unimplemented;
16170   case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
16171                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16172                                                ovl.fmt.RXE.d2);  goto ok;
16173   case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
16174                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16175                                                ovl.fmt.RXE.d2);  goto ok;
16176   case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
16177                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16178                                                ovl.fmt.RXE.d2);  goto ok;
16179   case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
16180                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16181                                                ovl.fmt.RXE.d2);  goto ok;
16182   case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
16183                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16184                                                ovl.fmt.RXE.d2);  goto ok;
16185   case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
16186                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16187                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16188                                                 ovl.fmt.RXF.r1);  goto ok;
16189   case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
16190                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16191                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16192                                                 ovl.fmt.RXF.r1);  goto ok;
16193   case 0xed0000000024ULL: /* LDE */ goto unimplemented;
16194   case 0xed0000000025ULL: /* LXD */ goto unimplemented;
16195   case 0xed0000000026ULL: /* LXE */ goto unimplemented;
16196   case 0xed000000002eULL: /* MAE */ goto unimplemented;
16197   case 0xed000000002fULL: /* MSE */ goto unimplemented;
16198   case 0xed0000000034ULL: /* SQE */ goto unimplemented;
16199   case 0xed0000000035ULL: /* SQD */ goto unimplemented;
16200   case 0xed0000000037ULL: /* MEE */ goto unimplemented;
16201   case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
16202   case 0xed0000000039ULL: /* MYL */ goto unimplemented;
16203   case 0xed000000003aULL: /* MAY */ goto unimplemented;
16204   case 0xed000000003bULL: /* MY */ goto unimplemented;
16205   case 0xed000000003cULL: /* MAYH */ goto unimplemented;
16206   case 0xed000000003dULL: /* MYH */ goto unimplemented;
16207   case 0xed000000003eULL: /* MAD */ goto unimplemented;
16208   case 0xed000000003fULL: /* MSD */ goto unimplemented;
16209   case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
16210                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16211                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16212                                                 ovl.fmt.RXF.r1);  goto ok;
16213   case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
16214                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16215                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16216                                                 ovl.fmt.RXF.r1);  goto ok;
16217   case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
16218                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16219                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16220                                                 ovl.fmt.RXF.r1);  goto ok;
16221   case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
16222                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16223                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16224                                                 ovl.fmt.RXF.r1);  goto ok;
16225   case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
16226                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16227                                                ovl.fmt.RXE.d2);  goto ok;
16228   case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
16229                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16230                                                ovl.fmt.RXE.d2);  goto ok;
16231   case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
16232                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16233                                                ovl.fmt.RXE.d2);  goto ok;
16234   case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
16235                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16236                                                ovl.fmt.RXE.d2);  goto ok;
16237   case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
16238                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16239                                                ovl.fmt.RXE.d2);  goto ok;
16240   case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
16241                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16242                                                ovl.fmt.RXE.d2);  goto ok;
16243   case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
16244                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16245                                                ovl.fmt.RXY.dl2,
16246                                                ovl.fmt.RXY.dh2);  goto ok;
16247   case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
16248                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16249                                                ovl.fmt.RXY.dl2,
16250                                                ovl.fmt.RXY.dh2);  goto ok;
16251   case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
16252                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16253                                                ovl.fmt.RXY.dl2,
16254                                                ovl.fmt.RXY.dh2);  goto ok;
16255   case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
16256                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16257                                                ovl.fmt.RXY.dl2,
16258                                                ovl.fmt.RXY.dh2);  goto ok;
16259   case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
16260   case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
16261   case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
16262   case 0xed00000000abULL: /* CXZT */ goto unimplemented;
16263   }
16264
16265   switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
16266   case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
16267                                      ovl.fmt.RIL.i2);  goto ok;
16268   case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
16269                                      ovl.fmt.RIL.i2);  goto ok;
16270   case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
16271                                   ovl.fmt.RIL.i2);  goto ok;
16272   case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16273                                      ovl.fmt.RIL.i2);  goto ok;
16274   case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16275                                      ovl.fmt.RIL.i2);  goto ok;
16276   case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16277                                      ovl.fmt.RIL.i2);  goto ok;
16278   case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16279                                      ovl.fmt.RIL.i2);  goto ok;
16280   case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16281                                      ovl.fmt.RIL.i2);  goto ok;
16282   case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16283                                      ovl.fmt.RIL.i2);  goto ok;
16284   case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16285                                      ovl.fmt.RIL.i2);  goto ok;
16286   case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16287                                      ovl.fmt.RIL.i2);  goto ok;
16288   case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16289                                      ovl.fmt.RIL.i2);  goto ok;
16290   case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16291                                      ovl.fmt.RIL.i2);  goto ok;
16292   case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16293                                      ovl.fmt.RIL.i2);  goto ok;
16294   case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16295                                      ovl.fmt.RIL.i2);  goto ok;
16296   case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16297                                      ovl.fmt.RIL.i2);  goto ok;
16298   case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16299                                      ovl.fmt.RIL.i2);  goto ok;
16300   case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16301                                      ovl.fmt.RIL.i2);  goto ok;
16302   case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16303                                      ovl.fmt.RIL.i2);  goto ok;
16304   case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16305                                      ovl.fmt.RIL.i2);  goto ok;
16306   case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16307                                      ovl.fmt.RIL.i2);  goto ok;
16308   case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16309                                      ovl.fmt.RIL.i2);  goto ok;
16310   case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16311                                      ovl.fmt.RIL.i2);  goto ok;
16312   case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16313                                      ovl.fmt.RIL.i2);  goto ok;
16314   case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16315                                      ovl.fmt.RIL.i2);  goto ok;
16316   case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16317                                      ovl.fmt.RIL.i2);  goto ok;
16318   case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16319                                      ovl.fmt.RIL.i2);  goto ok;
16320   case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16321                                      ovl.fmt.RIL.i2);  goto ok;
16322   case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16323                                      ovl.fmt.RIL.i2);  goto ok;
16324   case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16325                                      ovl.fmt.RIL.i2);  goto ok;
16326   case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16327                                      ovl.fmt.RIL.i2);  goto ok;
16328   case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16329                                      ovl.fmt.RIL.i2);  goto ok;
16330   case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16331                                      ovl.fmt.RIL.i2);  goto ok;
16332   case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16333                                      ovl.fmt.RIL.i2);  goto ok;
16334   case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16335                                      ovl.fmt.RIL.i2);  goto ok;
16336   case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16337                                      ovl.fmt.RIL.i2);  goto ok;
16338   case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16339                                      ovl.fmt.RIL.i2);  goto ok;
16340   case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16341                                      ovl.fmt.RIL.i2);  goto ok;
16342   case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16343                                      ovl.fmt.RIL.i2);  goto ok;
16344   case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16345                                      ovl.fmt.RIL.i2);  goto ok;
16346   case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16347                                      ovl.fmt.RIL.i2);  goto ok;
16348   case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16349                                      ovl.fmt.RIL.i2);  goto ok;
16350   case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16351                                      ovl.fmt.RIL.i2);  goto ok;
16352   case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16353                                      ovl.fmt.RIL.i2);  goto ok;
16354   case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16355                                      ovl.fmt.RIL.i2);  goto ok;
16356   case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16357                                      ovl.fmt.RIL.i2);  goto ok;
16358   case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16359                                      ovl.fmt.RIL.i2);  goto ok;
16360   case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16361                                      ovl.fmt.RIL.i2);  goto ok;
16362   case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16363                                      ovl.fmt.RIL.i2);  goto ok;
16364   case 0xc800ULL: /* MVCOS */ goto unimplemented;
16365   case 0xc801ULL: /* ECTG */ goto unimplemented;
16366   case 0xc802ULL: /* CSST */ goto unimplemented;
16367   case 0xc804ULL: /* LPD */ goto unimplemented;
16368   case 0xc805ULL: /* LPDG */ goto unimplemented;
16369   case 0xcc06ULL: /* BRCTH */ goto unimplemented;
16370   case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16371                                      ovl.fmt.RIL.i2);  goto ok;
16372   case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16373                                      ovl.fmt.RIL.i2);  goto ok;
16374   case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16375                                      ovl.fmt.RIL.i2);  goto ok;
16376   case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16377                                      ovl.fmt.RIL.i2);  goto ok;
16378   case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16379                                      ovl.fmt.RIL.i2);  goto ok;
16380   }
16381
16382   switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
16383   case 0xc5ULL: /* BPRP */ goto unimplemented;
16384   case 0xc7ULL: /* BPP */ goto unimplemented;
16385   case 0xd0ULL: /* TRTR */ goto unimplemented;
16386   case 0xd1ULL: /* MVN */ goto unimplemented;
16387   case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16388                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16389                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16390   case 0xd3ULL: /* MVZ */ goto unimplemented;
16391   case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16392                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16393                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16394   case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16395                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16396                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16397   case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16398                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16399                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16400   case 0xd7ULL:
16401      if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16402         s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16403      else
16404        s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16405                              ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16406                              ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16407      goto ok;
16408   case 0xd9ULL: /* MVCK */ goto unimplemented;
16409   case 0xdaULL: /* MVCP */ goto unimplemented;
16410   case 0xdbULL: /* MVCS */ goto unimplemented;
16411   case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16412                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16413                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16414   case 0xddULL: /* TRT */ goto unimplemented;
16415   case 0xdeULL: /* ED */ goto unimplemented;
16416   case 0xdfULL: /* EDMK */ goto unimplemented;
16417   case 0xe1ULL: /* PKU */ goto unimplemented;
16418   case 0xe2ULL: /* UNPKU */ goto unimplemented;
16419   case 0xe8ULL: /* MVCIN */ goto unimplemented;
16420   case 0xe9ULL: /* PKA */ goto unimplemented;
16421   case 0xeaULL: /* UNPKA */ goto unimplemented;
16422   case 0xeeULL: /* PLO */ goto unimplemented;
16423   case 0xefULL: /* LMD */ goto unimplemented;
16424   case 0xf0ULL: /* SRP */ goto unimplemented;
16425   case 0xf1ULL: /* MVO */ goto unimplemented;
16426   case 0xf2ULL: /* PACK */ goto unimplemented;
16427   case 0xf3ULL: /* UNPK */ goto unimplemented;
16428   case 0xf8ULL: /* ZAP */ goto unimplemented;
16429   case 0xf9ULL: /* CP */ goto unimplemented;
16430   case 0xfaULL: /* AP */ goto unimplemented;
16431   case 0xfbULL: /* SP */ goto unimplemented;
16432   case 0xfcULL: /* MP */ goto unimplemented;
16433   case 0xfdULL: /* DP */ goto unimplemented;
16434   }
16435
16436   switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16437   case 0xe500ULL: /* LASP */ goto unimplemented;
16438   case 0xe501ULL: /* TPROT */ goto unimplemented;
16439   case 0xe502ULL: /* STRAG */ goto unimplemented;
16440   case 0xe50eULL: /* MVCSK */ goto unimplemented;
16441   case 0xe50fULL: /* MVCDK */ goto unimplemented;
16442   case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16443                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16444                                       goto ok;
16445   case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16446                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16447                                       goto ok;
16448   case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16449                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16450                                       goto ok;
16451   case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16452                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16453                                       goto ok;
16454   case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16455                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16456                                       goto ok;
16457   case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16458                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16459                                       goto ok;
16460   case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16461                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16462                                       goto ok;
16463   case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16464                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16465                                       goto ok;
16466   case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16467                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16468                                       goto ok;
16469   case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16470   case 0xe561ULL: /* TBEGINC */ goto unimplemented;
16471   }
16472
16473   return S390_DECODE_UNKNOWN_INSN;
16474
16475ok:
16476   return S390_DECODE_OK;
16477
16478unimplemented:
16479   return S390_DECODE_UNIMPLEMENTED_INSN;
16480}
16481
16482/* Handle "special" instructions. */
16483static s390_decode_t
16484s390_decode_special_and_irgen(const UChar *bytes)
16485{
16486   s390_decode_t status = S390_DECODE_OK;
16487
16488   /* Got a "Special" instruction preamble.  Which one is it? */
16489   if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16490      s390_irgen_client_request();
16491   } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16492      s390_irgen_guest_NRADDR();
16493   } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16494      s390_irgen_call_noredir();
16495   } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16496      vex_inject_ir(irsb, Iend_BE);
16497
16498      /* Invalidate the current insn. The reason is that the IRop we're
16499         injecting here can change. In which case the translation has to
16500         be redone. For ease of handling, we simply invalidate all the
16501         time. */
16502      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
16503                      mkU64(guest_IA_curr_instr)));
16504      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN),
16505                      mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16506      vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16507              S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16508
16509      put_IA(mkaddr_expr(guest_IA_next_instr));
16510      dis_res->whatNext    = Dis_StopHere;
16511      dis_res->jk_StopHere = Ijk_InvalICache;
16512   } else {
16513      /* We don't know what it is. */
16514      return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16515   }
16516
16517   dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16518
16519   return status;
16520}
16521
16522
16523/* Function returns # bytes that were decoded or 0 in case of failure */
16524static UInt
16525s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres)
16526{
16527   s390_decode_t status;
16528
16529   dis_res = dres;
16530
16531   /* Spot the 8-byte preamble:   18ff lr r15,r15
16532                                  1811 lr r1,r1
16533                                  1822 lr r2,r2
16534                                  1833 lr r3,r3 */
16535   if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16536       bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16537       bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16538
16539      /* Handle special instruction that follows that preamble. */
16540      if (0) vex_printf("special function handling...\n");
16541
16542      insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16543      guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16544
16545      status =
16546         s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
16547   } else {
16548      /* Handle normal instructions. */
16549      switch (insn_length) {
16550      case 2:
16551         status = s390_decode_2byte_and_irgen(bytes);
16552         break;
16553
16554      case 4:
16555         status = s390_decode_4byte_and_irgen(bytes);
16556         break;
16557
16558      case 6:
16559         status = s390_decode_6byte_and_irgen(bytes);
16560         break;
16561
16562      default:
16563        status = S390_DECODE_ERROR;
16564        break;
16565      }
16566   }
16567   /* If next instruction is execute, stop here */
16568   if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16569      put_IA(mkaddr_expr(guest_IA_next_instr));
16570      dis_res->whatNext = Dis_StopHere;
16571      dis_res->jk_StopHere = Ijk_Boring;
16572   }
16573
16574   if (status == S390_DECODE_OK) return insn_length;  /* OK */
16575
16576   /* Decoding failed somehow */
16577   if (sigill_diag) {
16578      vex_printf("vex s390->IR: ");
16579      switch (status) {
16580      case S390_DECODE_UNKNOWN_INSN:
16581         vex_printf("unknown insn: ");
16582         break;
16583
16584      case S390_DECODE_UNIMPLEMENTED_INSN:
16585         vex_printf("unimplemented insn: ");
16586         break;
16587
16588      case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16589         vex_printf("unimplemented special insn: ");
16590         break;
16591
16592      case S390_DECODE_ERROR:
16593         vex_printf("decoding error: ");
16594         break;
16595
16596      default:
16597         vpanic("s390_decode_and_irgen");
16598      }
16599
16600      vex_printf("%02x%02x", bytes[0], bytes[1]);
16601      if (insn_length > 2) {
16602         vex_printf(" %02x%02x", bytes[2], bytes[3]);
16603      }
16604      if (insn_length > 4) {
16605         vex_printf(" %02x%02x", bytes[4], bytes[5]);
16606      }
16607      vex_printf("\n");
16608   }
16609
16610   return 0;  /* Failed */
16611}
16612
16613
16614/* Disassemble a single instruction INSN into IR. */
16615static DisResult
16616disInstr_S390_WRK(const UChar *insn)
16617{
16618   UChar byte;
16619   UInt  insn_length;
16620   DisResult dres;
16621
16622   /* ---------------------------------------------------- */
16623   /* --- Compute instruction length                    -- */
16624   /* ---------------------------------------------------- */
16625
16626   /* Get the first byte of the insn. */
16627   byte = insn[0];
16628
16629   /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16630      00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16631   insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16632
16633   guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16634
16635   /* ---------------------------------------------------- */
16636   /* --- Initialise the DisResult data                 -- */
16637   /* ---------------------------------------------------- */
16638   dres.whatNext   = Dis_Continue;
16639   dres.len        = insn_length;
16640   dres.continueAt = 0;
16641   dres.jk_StopHere = Ijk_INVALID;
16642
16643   /* fixs390: consider chasing of conditional jumps */
16644
16645   /* Normal and special instruction handling starts here. */
16646   if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16647      /* All decode failures end up here. The decoder has already issued an
16648         error message.
16649         Tell the dispatcher that this insn cannot be decoded, and so has
16650         not been executed, and (is currently) the next to be executed.
16651         The insn address in the guest state needs to be set to
16652         guest_IA_curr_instr, otherwise the complaint will report an
16653         incorrect address. */
16654      put_IA(mkaddr_expr(guest_IA_curr_instr));
16655
16656      dres.len         = 0;
16657      dres.whatNext    = Dis_StopHere;
16658      dres.jk_StopHere = Ijk_NoDecode;
16659      dres.continueAt  = 0;
16660   } else {
16661      /* Decode success */
16662      switch (dres.whatNext) {
16663      case Dis_Continue:
16664         put_IA(mkaddr_expr(guest_IA_next_instr));
16665         break;
16666      case Dis_ResteerU:
16667      case Dis_ResteerC:
16668         put_IA(mkaddr_expr(dres.continueAt));
16669         break;
16670      case Dis_StopHere:
16671         if (dres.jk_StopHere == Ijk_EmWarn ||
16672             dres.jk_StopHere == Ijk_EmFail) {
16673            /* We assume here, that emulation warnings are not given for
16674               insns that transfer control. There is no good way to
16675               do that. */
16676            put_IA(mkaddr_expr(guest_IA_next_instr));
16677         }
16678         break;
16679      default:
16680         vpanic("disInstr_S390_WRK");
16681      }
16682   }
16683
16684   return dres;
16685}
16686
16687
16688/*------------------------------------------------------------*/
16689/*--- Top-level fn                                         ---*/
16690/*------------------------------------------------------------*/
16691
16692/* Disassemble a single instruction into IR.  The instruction
16693   is located in host memory at &guest_code[delta]. */
16694
16695DisResult
16696disInstr_S390(IRSB        *irsb_IN,
16697              Bool       (*resteerOkFn)(void *, Addr),
16698              Bool         resteerCisOk,
16699              void        *callback_opaque,
16700              const UChar *guest_code,
16701              Long         delta,
16702              Addr         guest_IP,
16703              VexArch      guest_arch,
16704              const VexArchInfo *archinfo,
16705              const VexAbiInfo  *abiinfo,
16706              VexEndness   host_endness,
16707              Bool         sigill_diag_IN)
16708{
16709   vassert(guest_arch == VexArchS390X);
16710
16711   /* The instruction decoder requires a big-endian machine. */
16712   vassert(host_endness == VexEndnessBE);
16713
16714   /* Set globals (see top of this file) */
16715   guest_IA_curr_instr = guest_IP;
16716   irsb = irsb_IN;
16717   resteer_fn = resteerOkFn;
16718   resteer_data = callback_opaque;
16719   sigill_diag = sigill_diag_IN;
16720
16721   return disInstr_S390_WRK(guest_code + delta);
16722}
16723
16724/*---------------------------------------------------------------*/
16725/*--- end                                   guest_s390_toIR.c ---*/
16726/*---------------------------------------------------------------*/
16727