1/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin                                 guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8   This file is part of Valgrind, a dynamic binary instrumentation
9   framework.
10
11   Copyright IBM Corp. 2010-2017
12
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License as
15   published by the Free Software Foundation; either version 2 of the
16   License, or (at your option) any later version.
17
18   This program is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21   General Public License for more details.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26   02110-1301, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
37#include "libvex_emnote.h"
38#include "libvex_s390x_common.h"
39#include "main_util.h"               /* vassert */
40#include "main_globals.h"            /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h"  /* DisResult */
42#include "guest_s390_defs.h"         /* prototypes for this file's functions */
43#include "s390_disasm.h"
44#include "s390_defs.h"               /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h"          /* s390_host_has_xyzzy */
46
47
48/*------------------------------------------------------------*/
49/*--- Forward declarations                                 ---*/
50/*------------------------------------------------------------*/
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_BRCTH(UChar r1, UInt i2)
3835{
3836   put_gpr_w0(r1, binop(Iop_Sub32, get_gpr_w0(r1), mkU32(1)));
3837   if_condition_goto(binop(Iop_CmpNE32, get_gpr_w0(r1), mkU32(0)),
3838                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3839
3840   return "brcth";
3841}
3842
3843static const HChar *
3844s390_irgen_BRCTG(UChar r1, UShort i2)
3845{
3846   put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3847   if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3848                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3849
3850   return "brctg";
3851}
3852
3853static const HChar *
3854s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3855{
3856   IRTemp value = newTemp(Ity_I32);
3857
3858   assign(value, get_gpr_w1(r3 | 1));
3859   put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3860   if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3861                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3862
3863   return "brxh";
3864}
3865
3866static const HChar *
3867s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3868{
3869   IRTemp value = newTemp(Ity_I64);
3870
3871   assign(value, get_gpr_dw0(r3 | 1));
3872   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3873   if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3874                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3875
3876   return "brxhg";
3877}
3878
3879static const HChar *
3880s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3881{
3882   IRTemp value = newTemp(Ity_I32);
3883
3884   assign(value, get_gpr_w1(r3 | 1));
3885   put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3886   if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3887                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3888
3889   return "brxle";
3890}
3891
3892static const HChar *
3893s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3894{
3895   IRTemp value = newTemp(Ity_I64);
3896
3897   assign(value, get_gpr_dw0(r3 | 1));
3898   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3899   if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3900                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3901
3902   return "brxlg";
3903}
3904
3905static const HChar *
3906s390_irgen_CR(UChar r1, UChar r2)
3907{
3908   IRTemp op1 = newTemp(Ity_I32);
3909   IRTemp op2 = newTemp(Ity_I32);
3910
3911   assign(op1, get_gpr_w1(r1));
3912   assign(op2, get_gpr_w1(r2));
3913   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3914
3915   return "cr";
3916}
3917
3918static const HChar *
3919s390_irgen_CGR(UChar r1, UChar r2)
3920{
3921   IRTemp op1 = newTemp(Ity_I64);
3922   IRTemp op2 = newTemp(Ity_I64);
3923
3924   assign(op1, get_gpr_dw0(r1));
3925   assign(op2, get_gpr_dw0(r2));
3926   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3927
3928   return "cgr";
3929}
3930
3931static const HChar *
3932s390_irgen_CGFR(UChar r1, UChar r2)
3933{
3934   IRTemp op1 = newTemp(Ity_I64);
3935   IRTemp op2 = newTemp(Ity_I64);
3936
3937   assign(op1, get_gpr_dw0(r1));
3938   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3939   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3940
3941   return "cgfr";
3942}
3943
3944static const HChar *
3945s390_irgen_C(UChar r1, IRTemp op2addr)
3946{
3947   IRTemp op1 = newTemp(Ity_I32);
3948   IRTemp op2 = newTemp(Ity_I32);
3949
3950   assign(op1, get_gpr_w1(r1));
3951   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3952   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3953
3954   return "c";
3955}
3956
3957static const HChar *
3958s390_irgen_CY(UChar r1, IRTemp op2addr)
3959{
3960   IRTemp op1 = newTemp(Ity_I32);
3961   IRTemp op2 = newTemp(Ity_I32);
3962
3963   assign(op1, get_gpr_w1(r1));
3964   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3965   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3966
3967   return "cy";
3968}
3969
3970static const HChar *
3971s390_irgen_CG(UChar r1, IRTemp op2addr)
3972{
3973   IRTemp op1 = newTemp(Ity_I64);
3974   IRTemp op2 = newTemp(Ity_I64);
3975
3976   assign(op1, get_gpr_dw0(r1));
3977   assign(op2, load(Ity_I64, mkexpr(op2addr)));
3978   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3979
3980   return "cg";
3981}
3982
3983static const HChar *
3984s390_irgen_CGF(UChar r1, IRTemp op2addr)
3985{
3986   IRTemp op1 = newTemp(Ity_I64);
3987   IRTemp op2 = newTemp(Ity_I64);
3988
3989   assign(op1, get_gpr_dw0(r1));
3990   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3991   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3992
3993   return "cgf";
3994}
3995
3996static const HChar *
3997s390_irgen_CFI(UChar r1, UInt i2)
3998{
3999   IRTemp op1 = newTemp(Ity_I32);
4000   Int op2;
4001
4002   assign(op1, get_gpr_w1(r1));
4003   op2 = (Int)i2;
4004   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4005                       mkU32((UInt)op2)));
4006
4007   return "cfi";
4008}
4009
4010static const HChar *
4011s390_irgen_CGFI(UChar r1, UInt i2)
4012{
4013   IRTemp op1 = newTemp(Ity_I64);
4014   Long op2;
4015
4016   assign(op1, get_gpr_dw0(r1));
4017   op2 = (Long)(Int)i2;
4018   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4019                       mkU64((ULong)op2)));
4020
4021   return "cgfi";
4022}
4023
4024static const HChar *
4025s390_irgen_CRL(UChar r1, UInt i2)
4026{
4027   IRTemp op1 = newTemp(Ity_I32);
4028   IRTemp op2 = newTemp(Ity_I32);
4029
4030   assign(op1, get_gpr_w1(r1));
4031   assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4032          i2 << 1))));
4033   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4034
4035   return "crl";
4036}
4037
4038static const HChar *
4039s390_irgen_CGRL(UChar r1, UInt i2)
4040{
4041   IRTemp op1 = newTemp(Ity_I64);
4042   IRTemp op2 = newTemp(Ity_I64);
4043
4044   assign(op1, get_gpr_dw0(r1));
4045   assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4046          i2 << 1))));
4047   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4048
4049   return "cgrl";
4050}
4051
4052static const HChar *
4053s390_irgen_CGFRL(UChar r1, UInt i2)
4054{
4055   IRTemp op1 = newTemp(Ity_I64);
4056   IRTemp op2 = newTemp(Ity_I64);
4057
4058   assign(op1, get_gpr_dw0(r1));
4059   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4060          ((ULong)(Long)(Int)i2 << 1)))));
4061   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4062
4063   return "cgfrl";
4064}
4065
4066static const HChar *
4067s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4068{
4069   IRTemp op1 = newTemp(Ity_I32);
4070   IRTemp op2 = newTemp(Ity_I32);
4071   IRTemp cond = newTemp(Ity_I32);
4072
4073   if (m3 == 0) {
4074   } else {
4075      if (m3 == 14) {
4076         always_goto(mkexpr(op4addr));
4077      } else {
4078         assign(op1, get_gpr_w1(r1));
4079         assign(op2, get_gpr_w1(r2));
4080         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4081                                              op1, op2));
4082         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4083                                          mkU32(0)), mkexpr(op4addr));
4084      }
4085   }
4086
4087   return "crb";
4088}
4089
4090static const HChar *
4091s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4092{
4093   IRTemp op1 = newTemp(Ity_I64);
4094   IRTemp op2 = newTemp(Ity_I64);
4095   IRTemp cond = newTemp(Ity_I32);
4096
4097   if (m3 == 0) {
4098   } else {
4099      if (m3 == 14) {
4100         always_goto(mkexpr(op4addr));
4101      } else {
4102         assign(op1, get_gpr_dw0(r1));
4103         assign(op2, get_gpr_dw0(r2));
4104         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4105                                              op1, op2));
4106         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4107                                          mkU32(0)), mkexpr(op4addr));
4108      }
4109   }
4110
4111   return "cgrb";
4112}
4113
4114static const HChar *
4115s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4116{
4117   IRTemp op1 = newTemp(Ity_I32);
4118   IRTemp op2 = newTemp(Ity_I32);
4119   IRTemp cond = newTemp(Ity_I32);
4120
4121   if (m3 == 0) {
4122   } else {
4123      if (m3 == 14) {
4124         always_goto_and_chase(
4125                guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4126      } else {
4127         assign(op1, get_gpr_w1(r1));
4128         assign(op2, get_gpr_w1(r2));
4129         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4130                                              op1, op2));
4131         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4132                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4133
4134      }
4135   }
4136
4137   return "crj";
4138}
4139
4140static const HChar *
4141s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4142{
4143   IRTemp op1 = newTemp(Ity_I64);
4144   IRTemp op2 = newTemp(Ity_I64);
4145   IRTemp cond = newTemp(Ity_I32);
4146
4147   if (m3 == 0) {
4148   } else {
4149      if (m3 == 14) {
4150         always_goto_and_chase(
4151                guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4152      } else {
4153         assign(op1, get_gpr_dw0(r1));
4154         assign(op2, get_gpr_dw0(r2));
4155         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4156                                              op1, op2));
4157         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4158                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4159
4160      }
4161   }
4162
4163   return "cgrj";
4164}
4165
4166static const HChar *
4167s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4168{
4169   IRTemp op1 = newTemp(Ity_I32);
4170   Int op2;
4171   IRTemp cond = newTemp(Ity_I32);
4172
4173   if (m3 == 0) {
4174   } else {
4175      if (m3 == 14) {
4176         always_goto(mkexpr(op4addr));
4177      } else {
4178         assign(op1, get_gpr_w1(r1));
4179         op2 = (Int)(Char)i2;
4180         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4181                                              mktemp(Ity_I32, mkU32((UInt)op2))));
4182         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4183                                    mkexpr(op4addr));
4184      }
4185   }
4186
4187   return "cib";
4188}
4189
4190static const HChar *
4191s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4192{
4193   IRTemp op1 = newTemp(Ity_I64);
4194   Long op2;
4195   IRTemp cond = newTemp(Ity_I32);
4196
4197   if (m3 == 0) {
4198   } else {
4199      if (m3 == 14) {
4200         always_goto(mkexpr(op4addr));
4201      } else {
4202         assign(op1, get_gpr_dw0(r1));
4203         op2 = (Long)(Char)i2;
4204         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4205                                              mktemp(Ity_I64, mkU64((ULong)op2))));
4206         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4207                                    mkexpr(op4addr));
4208      }
4209   }
4210
4211   return "cgib";
4212}
4213
4214static const HChar *
4215s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4216{
4217   IRTemp op1 = newTemp(Ity_I32);
4218   Int op2;
4219   IRTemp cond = newTemp(Ity_I32);
4220
4221   if (m3 == 0) {
4222   } else {
4223      if (m3 == 14) {
4224         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4225      } else {
4226         assign(op1, get_gpr_w1(r1));
4227         op2 = (Int)(Char)i2;
4228         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4229                                              mktemp(Ity_I32, mkU32((UInt)op2))));
4230         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4231                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4232
4233      }
4234   }
4235
4236   return "cij";
4237}
4238
4239static const HChar *
4240s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4241{
4242   IRTemp op1 = newTemp(Ity_I64);
4243   Long op2;
4244   IRTemp cond = newTemp(Ity_I32);
4245
4246   if (m3 == 0) {
4247   } else {
4248      if (m3 == 14) {
4249         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4250      } else {
4251         assign(op1, get_gpr_dw0(r1));
4252         op2 = (Long)(Char)i2;
4253         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4254                                              mktemp(Ity_I64, mkU64((ULong)op2))));
4255         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4256                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4257
4258      }
4259   }
4260
4261   return "cgij";
4262}
4263
4264static const HChar *
4265s390_irgen_CH(UChar r1, IRTemp op2addr)
4266{
4267   IRTemp op1 = newTemp(Ity_I32);
4268   IRTemp op2 = newTemp(Ity_I32);
4269
4270   assign(op1, get_gpr_w1(r1));
4271   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4272   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4273
4274   return "ch";
4275}
4276
4277static const HChar *
4278s390_irgen_CHY(UChar r1, IRTemp op2addr)
4279{
4280   IRTemp op1 = newTemp(Ity_I32);
4281   IRTemp op2 = newTemp(Ity_I32);
4282
4283   assign(op1, get_gpr_w1(r1));
4284   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4285   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4286
4287   return "chy";
4288}
4289
4290static const HChar *
4291s390_irgen_CGH(UChar r1, IRTemp op2addr)
4292{
4293   IRTemp op1 = newTemp(Ity_I64);
4294   IRTemp op2 = newTemp(Ity_I64);
4295
4296   assign(op1, get_gpr_dw0(r1));
4297   assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4298   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4299
4300   return "cgh";
4301}
4302
4303static const HChar *
4304s390_irgen_CHI(UChar r1, UShort i2)
4305{
4306   IRTemp op1 = newTemp(Ity_I32);
4307   Int op2;
4308
4309   assign(op1, get_gpr_w1(r1));
4310   op2 = (Int)(Short)i2;
4311   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4312                       mkU32((UInt)op2)));
4313
4314   return "chi";
4315}
4316
4317static const HChar *
4318s390_irgen_CGHI(UChar r1, UShort i2)
4319{
4320   IRTemp op1 = newTemp(Ity_I64);
4321   Long op2;
4322
4323   assign(op1, get_gpr_dw0(r1));
4324   op2 = (Long)(Short)i2;
4325   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4326                       mkU64((ULong)op2)));
4327
4328   return "cghi";
4329}
4330
4331static const HChar *
4332s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4333{
4334   IRTemp op1 = newTemp(Ity_I16);
4335   Short op2;
4336
4337   assign(op1, load(Ity_I16, mkexpr(op1addr)));
4338   op2 = (Short)i2;
4339   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4340                       mkU16((UShort)op2)));
4341
4342   return "chhsi";
4343}
4344
4345static const HChar *
4346s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4347{
4348   IRTemp op1 = newTemp(Ity_I32);
4349   Int op2;
4350
4351   assign(op1, load(Ity_I32, mkexpr(op1addr)));
4352   op2 = (Int)(Short)i2;
4353   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4354                       mkU32((UInt)op2)));
4355
4356   return "chsi";
4357}
4358
4359static const HChar *
4360s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4361{
4362   IRTemp op1 = newTemp(Ity_I64);
4363   Long op2;
4364
4365   assign(op1, load(Ity_I64, mkexpr(op1addr)));
4366   op2 = (Long)(Short)i2;
4367   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4368                       mkU64((ULong)op2)));
4369
4370   return "cghsi";
4371}
4372
4373static const HChar *
4374s390_irgen_CHRL(UChar r1, UInt i2)
4375{
4376   IRTemp op1 = newTemp(Ity_I32);
4377   IRTemp op2 = newTemp(Ity_I32);
4378
4379   assign(op1, get_gpr_w1(r1));
4380   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4381          ((ULong)(Long)(Int)i2 << 1)))));
4382   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4383
4384   return "chrl";
4385}
4386
4387static const HChar *
4388s390_irgen_CGHRL(UChar r1, UInt i2)
4389{
4390   IRTemp op1 = newTemp(Ity_I64);
4391   IRTemp op2 = newTemp(Ity_I64);
4392
4393   assign(op1, get_gpr_dw0(r1));
4394   assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4395          ((ULong)(Long)(Int)i2 << 1)))));
4396   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4397
4398   return "cghrl";
4399}
4400
4401static const HChar *
4402s390_irgen_CHHR(UChar r1, UChar r2)
4403{
4404   IRTemp op1 = newTemp(Ity_I32);
4405   IRTemp op2 = newTemp(Ity_I32);
4406
4407   assign(op1, get_gpr_w0(r1));
4408   assign(op2, get_gpr_w0(r2));
4409   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4410
4411   return "chhr";
4412}
4413
4414static const HChar *
4415s390_irgen_CHLR(UChar r1, UChar r2)
4416{
4417   IRTemp op1 = newTemp(Ity_I32);
4418   IRTemp op2 = newTemp(Ity_I32);
4419
4420   assign(op1, get_gpr_w0(r1));
4421   assign(op2, get_gpr_w1(r2));
4422   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4423
4424   return "chlr";
4425}
4426
4427static const HChar *
4428s390_irgen_CHF(UChar r1, IRTemp op2addr)
4429{
4430   IRTemp op1 = newTemp(Ity_I32);
4431   IRTemp op2 = newTemp(Ity_I32);
4432
4433   assign(op1, get_gpr_w0(r1));
4434   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4435   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4436
4437   return "chf";
4438}
4439
4440static const HChar *
4441s390_irgen_CIH(UChar r1, UInt i2)
4442{
4443   IRTemp op1 = newTemp(Ity_I32);
4444   Int op2;
4445
4446   assign(op1, get_gpr_w0(r1));
4447   op2 = (Int)i2;
4448   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4449                       mkU32((UInt)op2)));
4450
4451   return "cih";
4452}
4453
4454static const HChar *
4455s390_irgen_CLR(UChar r1, UChar r2)
4456{
4457   IRTemp op1 = newTemp(Ity_I32);
4458   IRTemp op2 = newTemp(Ity_I32);
4459
4460   assign(op1, get_gpr_w1(r1));
4461   assign(op2, get_gpr_w1(r2));
4462   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4463
4464   return "clr";
4465}
4466
4467static const HChar *
4468s390_irgen_CLGR(UChar r1, UChar r2)
4469{
4470   IRTemp op1 = newTemp(Ity_I64);
4471   IRTemp op2 = newTemp(Ity_I64);
4472
4473   assign(op1, get_gpr_dw0(r1));
4474   assign(op2, get_gpr_dw0(r2));
4475   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4476
4477   return "clgr";
4478}
4479
4480static const HChar *
4481s390_irgen_CLGFR(UChar r1, UChar r2)
4482{
4483   IRTemp op1 = newTemp(Ity_I64);
4484   IRTemp op2 = newTemp(Ity_I64);
4485
4486   assign(op1, get_gpr_dw0(r1));
4487   assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4488   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4489
4490   return "clgfr";
4491}
4492
4493static const HChar *
4494s390_irgen_CL(UChar r1, IRTemp op2addr)
4495{
4496   IRTemp op1 = newTemp(Ity_I32);
4497   IRTemp op2 = newTemp(Ity_I32);
4498
4499   assign(op1, get_gpr_w1(r1));
4500   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4501   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4502
4503   return "cl";
4504}
4505
4506static const HChar *
4507s390_irgen_CLY(UChar r1, IRTemp op2addr)
4508{
4509   IRTemp op1 = newTemp(Ity_I32);
4510   IRTemp op2 = newTemp(Ity_I32);
4511
4512   assign(op1, get_gpr_w1(r1));
4513   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4514   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4515
4516   return "cly";
4517}
4518
4519static const HChar *
4520s390_irgen_CLG(UChar r1, IRTemp op2addr)
4521{
4522   IRTemp op1 = newTemp(Ity_I64);
4523   IRTemp op2 = newTemp(Ity_I64);
4524
4525   assign(op1, get_gpr_dw0(r1));
4526   assign(op2, load(Ity_I64, mkexpr(op2addr)));
4527   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4528
4529   return "clg";
4530}
4531
4532static const HChar *
4533s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4534{
4535   IRTemp op1 = newTemp(Ity_I64);
4536   IRTemp op2 = newTemp(Ity_I64);
4537
4538   assign(op1, get_gpr_dw0(r1));
4539   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4540   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4541
4542   return "clgf";
4543}
4544
4545static const HChar *
4546s390_irgen_CLFI(UChar r1, UInt i2)
4547{
4548   IRTemp op1 = newTemp(Ity_I32);
4549   UInt op2;
4550
4551   assign(op1, get_gpr_w1(r1));
4552   op2 = i2;
4553   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4554                       mkU32(op2)));
4555
4556   return "clfi";
4557}
4558
4559static const HChar *
4560s390_irgen_CLGFI(UChar r1, UInt i2)
4561{
4562   IRTemp op1 = newTemp(Ity_I64);
4563   ULong op2;
4564
4565   assign(op1, get_gpr_dw0(r1));
4566   op2 = (ULong)i2;
4567   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4568                       mkU64(op2)));
4569
4570   return "clgfi";
4571}
4572
4573static const HChar *
4574s390_irgen_CLI(UChar i2, IRTemp op1addr)
4575{
4576   IRTemp op1 = newTemp(Ity_I8);
4577   UChar op2;
4578
4579   assign(op1, load(Ity_I8, mkexpr(op1addr)));
4580   op2 = i2;
4581   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4582                       mkU8(op2)));
4583
4584   return "cli";
4585}
4586
4587static const HChar *
4588s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4589{
4590   IRTemp op1 = newTemp(Ity_I8);
4591   UChar op2;
4592
4593   assign(op1, load(Ity_I8, mkexpr(op1addr)));
4594   op2 = i2;
4595   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4596                       mkU8(op2)));
4597
4598   return "cliy";
4599}
4600
4601static const HChar *
4602s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4603{
4604   IRTemp op1 = newTemp(Ity_I32);
4605   UInt op2;
4606
4607   assign(op1, load(Ity_I32, mkexpr(op1addr)));
4608   op2 = (UInt)i2;
4609   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4610                       mkU32(op2)));
4611
4612   return "clfhsi";
4613}
4614
4615static const HChar *
4616s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4617{
4618   IRTemp op1 = newTemp(Ity_I64);
4619   ULong op2;
4620
4621   assign(op1, load(Ity_I64, mkexpr(op1addr)));
4622   op2 = (ULong)i2;
4623   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4624                       mkU64(op2)));
4625
4626   return "clghsi";
4627}
4628
4629static const HChar *
4630s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4631{
4632   IRTemp op1 = newTemp(Ity_I16);
4633   UShort op2;
4634
4635   assign(op1, load(Ity_I16, mkexpr(op1addr)));
4636   op2 = i2;
4637   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4638                       mkU16(op2)));
4639
4640   return "clhhsi";
4641}
4642
4643static const HChar *
4644s390_irgen_CLRL(UChar r1, UInt i2)
4645{
4646   IRTemp op1 = newTemp(Ity_I32);
4647   IRTemp op2 = newTemp(Ity_I32);
4648
4649   assign(op1, get_gpr_w1(r1));
4650   assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4651          i2 << 1))));
4652   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4653
4654   return "clrl";
4655}
4656
4657static const HChar *
4658s390_irgen_CLGRL(UChar r1, UInt i2)
4659{
4660   IRTemp op1 = newTemp(Ity_I64);
4661   IRTemp op2 = newTemp(Ity_I64);
4662
4663   assign(op1, get_gpr_dw0(r1));
4664   assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4665          i2 << 1))));
4666   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4667
4668   return "clgrl";
4669}
4670
4671static const HChar *
4672s390_irgen_CLGFRL(UChar r1, UInt i2)
4673{
4674   IRTemp op1 = newTemp(Ity_I64);
4675   IRTemp op2 = newTemp(Ity_I64);
4676
4677   assign(op1, get_gpr_dw0(r1));
4678   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4679          ((ULong)(Long)(Int)i2 << 1)))));
4680   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4681
4682   return "clgfrl";
4683}
4684
4685static const HChar *
4686s390_irgen_CLHRL(UChar r1, UInt i2)
4687{
4688   IRTemp op1 = newTemp(Ity_I32);
4689   IRTemp op2 = newTemp(Ity_I32);
4690
4691   assign(op1, get_gpr_w1(r1));
4692   assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4693          ((ULong)(Long)(Int)i2 << 1)))));
4694   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4695
4696   return "clhrl";
4697}
4698
4699static const HChar *
4700s390_irgen_CLGHRL(UChar r1, UInt i2)
4701{
4702   IRTemp op1 = newTemp(Ity_I64);
4703   IRTemp op2 = newTemp(Ity_I64);
4704
4705   assign(op1, get_gpr_dw0(r1));
4706   assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4707          ((ULong)(Long)(Int)i2 << 1)))));
4708   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4709
4710   return "clghrl";
4711}
4712
4713static const HChar *
4714s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4715{
4716   IRTemp op1 = newTemp(Ity_I32);
4717   IRTemp op2 = newTemp(Ity_I32);
4718   IRTemp cond = newTemp(Ity_I32);
4719
4720   if (m3 == 0) {
4721   } else {
4722      if (m3 == 14) {
4723         always_goto(mkexpr(op4addr));
4724      } else {
4725         assign(op1, get_gpr_w1(r1));
4726         assign(op2, get_gpr_w1(r2));
4727         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4728                                              op1, op2));
4729         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4730                                    mkexpr(op4addr));
4731      }
4732   }
4733
4734   return "clrb";
4735}
4736
4737static const HChar *
4738s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4739{
4740   IRTemp op1 = newTemp(Ity_I64);
4741   IRTemp op2 = newTemp(Ity_I64);
4742   IRTemp cond = newTemp(Ity_I32);
4743
4744   if (m3 == 0) {
4745   } else {
4746      if (m3 == 14) {
4747         always_goto(mkexpr(op4addr));
4748      } else {
4749         assign(op1, get_gpr_dw0(r1));
4750         assign(op2, get_gpr_dw0(r2));
4751         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4752                                              op1, op2));
4753         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4754                                    mkexpr(op4addr));
4755      }
4756   }
4757
4758   return "clgrb";
4759}
4760
4761static const HChar *
4762s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4763{
4764   IRTemp op1 = newTemp(Ity_I32);
4765   IRTemp op2 = newTemp(Ity_I32);
4766   IRTemp cond = newTemp(Ity_I32);
4767
4768   if (m3 == 0) {
4769   } else {
4770      if (m3 == 14) {
4771         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4772      } else {
4773         assign(op1, get_gpr_w1(r1));
4774         assign(op2, get_gpr_w1(r2));
4775         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4776                                              op1, op2));
4777         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4778                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4779
4780      }
4781   }
4782
4783   return "clrj";
4784}
4785
4786static const HChar *
4787s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4788{
4789   IRTemp op1 = newTemp(Ity_I64);
4790   IRTemp op2 = newTemp(Ity_I64);
4791   IRTemp cond = newTemp(Ity_I32);
4792
4793   if (m3 == 0) {
4794   } else {
4795      if (m3 == 14) {
4796         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4797      } else {
4798         assign(op1, get_gpr_dw0(r1));
4799         assign(op2, get_gpr_dw0(r2));
4800         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4801                                              op1, op2));
4802         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4803                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4804
4805      }
4806   }
4807
4808   return "clgrj";
4809}
4810
4811static const HChar *
4812s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4813{
4814   IRTemp op1 = newTemp(Ity_I32);
4815   UInt op2;
4816   IRTemp cond = newTemp(Ity_I32);
4817
4818   if (m3 == 0) {
4819   } else {
4820      if (m3 == 14) {
4821         always_goto(mkexpr(op4addr));
4822      } else {
4823         assign(op1, get_gpr_w1(r1));
4824         op2 = (UInt)i2;
4825         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4826                                              mktemp(Ity_I32, mkU32(op2))));
4827         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4828                                    mkexpr(op4addr));
4829      }
4830   }
4831
4832   return "clib";
4833}
4834
4835static const HChar *
4836s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4837{
4838   IRTemp op1 = newTemp(Ity_I64);
4839   ULong op2;
4840   IRTemp cond = newTemp(Ity_I32);
4841
4842   if (m3 == 0) {
4843   } else {
4844      if (m3 == 14) {
4845         always_goto(mkexpr(op4addr));
4846      } else {
4847         assign(op1, get_gpr_dw0(r1));
4848         op2 = (ULong)i2;
4849         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4850                                              mktemp(Ity_I64, mkU64(op2))));
4851         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4852                                    mkexpr(op4addr));
4853      }
4854   }
4855
4856   return "clgib";
4857}
4858
4859static const HChar *
4860s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4861{
4862   IRTemp op1 = newTemp(Ity_I32);
4863   UInt op2;
4864   IRTemp cond = newTemp(Ity_I32);
4865
4866   if (m3 == 0) {
4867   } else {
4868      if (m3 == 14) {
4869         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4870      } else {
4871         assign(op1, get_gpr_w1(r1));
4872         op2 = (UInt)i2;
4873         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4874                                              mktemp(Ity_I32, mkU32(op2))));
4875         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4876                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4877
4878      }
4879   }
4880
4881   return "clij";
4882}
4883
4884static const HChar *
4885s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4886{
4887   IRTemp op1 = newTemp(Ity_I64);
4888   ULong op2;
4889   IRTemp cond = newTemp(Ity_I32);
4890
4891   if (m3 == 0) {
4892   } else {
4893      if (m3 == 14) {
4894         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4895      } else {
4896         assign(op1, get_gpr_dw0(r1));
4897         op2 = (ULong)i2;
4898         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4899                                              mktemp(Ity_I64, mkU64(op2))));
4900         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4901                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4902
4903      }
4904   }
4905
4906   return "clgij";
4907}
4908
4909static const HChar *
4910s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4911{
4912   IRTemp op1 = newTemp(Ity_I32);
4913   IRTemp op2 = newTemp(Ity_I32);
4914   IRTemp b0 = newTemp(Ity_I32);
4915   IRTemp b1 = newTemp(Ity_I32);
4916   IRTemp b2 = newTemp(Ity_I32);
4917   IRTemp b3 = newTemp(Ity_I32);
4918   IRTemp c0 = newTemp(Ity_I32);
4919   IRTemp c1 = newTemp(Ity_I32);
4920   IRTemp c2 = newTemp(Ity_I32);
4921   IRTemp c3 = newTemp(Ity_I32);
4922   UChar n;
4923
4924   n = 0;
4925   if ((r3 & 8) != 0) {
4926      assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4927      assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4928      n = n + 1;
4929   } else {
4930      assign(b0, mkU32(0));
4931      assign(c0, mkU32(0));
4932   }
4933   if ((r3 & 4) != 0) {
4934      assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4935      assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4936             mkU64(n)))));
4937      n = n + 1;
4938   } else {
4939      assign(b1, mkU32(0));
4940      assign(c1, mkU32(0));
4941   }
4942   if ((r3 & 2) != 0) {
4943      assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4944      assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4945             mkU64(n)))));
4946      n = n + 1;
4947   } else {
4948      assign(b2, mkU32(0));
4949      assign(c2, mkU32(0));
4950   }
4951   if ((r3 & 1) != 0) {
4952      assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4953      assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4954             mkU64(n)))));
4955      n = n + 1;
4956   } else {
4957      assign(b3, mkU32(0));
4958      assign(c3, mkU32(0));
4959   }
4960   assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4961          mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4962          binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4963   assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4964          mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4965          binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4966   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4967
4968   return "clm";
4969}
4970
4971static const HChar *
4972s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4973{
4974   IRTemp op1 = newTemp(Ity_I32);
4975   IRTemp op2 = newTemp(Ity_I32);
4976   IRTemp b0 = newTemp(Ity_I32);
4977   IRTemp b1 = newTemp(Ity_I32);
4978   IRTemp b2 = newTemp(Ity_I32);
4979   IRTemp b3 = newTemp(Ity_I32);
4980   IRTemp c0 = newTemp(Ity_I32);
4981   IRTemp c1 = newTemp(Ity_I32);
4982   IRTemp c2 = newTemp(Ity_I32);
4983   IRTemp c3 = newTemp(Ity_I32);
4984   UChar n;
4985
4986   n = 0;
4987   if ((r3 & 8) != 0) {
4988      assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4989      assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4990      n = n + 1;
4991   } else {
4992      assign(b0, mkU32(0));
4993      assign(c0, mkU32(0));
4994   }
4995   if ((r3 & 4) != 0) {
4996      assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4997      assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4998             mkU64(n)))));
4999      n = n + 1;
5000   } else {
5001      assign(b1, mkU32(0));
5002      assign(c1, mkU32(0));
5003   }
5004   if ((r3 & 2) != 0) {
5005      assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
5006      assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5007             mkU64(n)))));
5008      n = n + 1;
5009   } else {
5010      assign(b2, mkU32(0));
5011      assign(c2, mkU32(0));
5012   }
5013   if ((r3 & 1) != 0) {
5014      assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
5015      assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5016             mkU64(n)))));
5017      n = n + 1;
5018   } else {
5019      assign(b3, mkU32(0));
5020      assign(c3, mkU32(0));
5021   }
5022   assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5023          mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5024          binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5025   assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5026          mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5027          binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5028   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5029
5030   return "clmy";
5031}
5032
5033static const HChar *
5034s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5035{
5036   IRTemp op1 = newTemp(Ity_I32);
5037   IRTemp op2 = newTemp(Ity_I32);
5038   IRTemp b0 = newTemp(Ity_I32);
5039   IRTemp b1 = newTemp(Ity_I32);
5040   IRTemp b2 = newTemp(Ity_I32);
5041   IRTemp b3 = newTemp(Ity_I32);
5042   IRTemp c0 = newTemp(Ity_I32);
5043   IRTemp c1 = newTemp(Ity_I32);
5044   IRTemp c2 = newTemp(Ity_I32);
5045   IRTemp c3 = newTemp(Ity_I32);
5046   UChar n;
5047
5048   n = 0;
5049   if ((r3 & 8) != 0) {
5050      assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5051      assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5052      n = n + 1;
5053   } else {
5054      assign(b0, mkU32(0));
5055      assign(c0, mkU32(0));
5056   }
5057   if ((r3 & 4) != 0) {
5058      assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5059      assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5060             mkU64(n)))));
5061      n = n + 1;
5062   } else {
5063      assign(b1, mkU32(0));
5064      assign(c1, mkU32(0));
5065   }
5066   if ((r3 & 2) != 0) {
5067      assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5068      assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5069             mkU64(n)))));
5070      n = n + 1;
5071   } else {
5072      assign(b2, mkU32(0));
5073      assign(c2, mkU32(0));
5074   }
5075   if ((r3 & 1) != 0) {
5076      assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5077      assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5078             mkU64(n)))));
5079      n = n + 1;
5080   } else {
5081      assign(b3, mkU32(0));
5082      assign(c3, mkU32(0));
5083   }
5084   assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5085          mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5086          binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5087   assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5088          mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5089          binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5090   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5091
5092   return "clmh";
5093}
5094
5095static const HChar *
5096s390_irgen_CLHHR(UChar r1, UChar r2)
5097{
5098   IRTemp op1 = newTemp(Ity_I32);
5099   IRTemp op2 = newTemp(Ity_I32);
5100
5101   assign(op1, get_gpr_w0(r1));
5102   assign(op2, get_gpr_w0(r2));
5103   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5104
5105   return "clhhr";
5106}
5107
5108static const HChar *
5109s390_irgen_CLHLR(UChar r1, UChar r2)
5110{
5111   IRTemp op1 = newTemp(Ity_I32);
5112   IRTemp op2 = newTemp(Ity_I32);
5113
5114   assign(op1, get_gpr_w0(r1));
5115   assign(op2, get_gpr_w1(r2));
5116   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5117
5118   return "clhlr";
5119}
5120
5121static const HChar *
5122s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5123{
5124   IRTemp op1 = newTemp(Ity_I32);
5125   IRTemp op2 = newTemp(Ity_I32);
5126
5127   assign(op1, get_gpr_w0(r1));
5128   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5129   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5130
5131   return "clhf";
5132}
5133
5134static const HChar *
5135s390_irgen_CLIH(UChar r1, UInt i2)
5136{
5137   IRTemp op1 = newTemp(Ity_I32);
5138   UInt op2;
5139
5140   assign(op1, get_gpr_w0(r1));
5141   op2 = i2;
5142   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5143                       mkU32(op2)));
5144
5145   return "clih";
5146}
5147
5148static const HChar *
5149s390_irgen_CPYA(UChar r1, UChar r2)
5150{
5151   put_ar_w0(r1, get_ar_w0(r2));
5152   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5153      s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5154
5155   return "cpya";
5156}
5157
5158static const HChar *
5159s390_irgen_XR(UChar r1, UChar r2)
5160{
5161   IRTemp op1 = newTemp(Ity_I32);
5162   IRTemp op2 = newTemp(Ity_I32);
5163   IRTemp result = newTemp(Ity_I32);
5164
5165   if (r1 == r2) {
5166      assign(result, mkU32(0));
5167   } else {
5168      assign(op1, get_gpr_w1(r1));
5169      assign(op2, get_gpr_w1(r2));
5170      assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5171   }
5172   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5173   put_gpr_w1(r1, mkexpr(result));
5174
5175   return "xr";
5176}
5177
5178static const HChar *
5179s390_irgen_XGR(UChar r1, UChar r2)
5180{
5181   IRTemp op1 = newTemp(Ity_I64);
5182   IRTemp op2 = newTemp(Ity_I64);
5183   IRTemp result = newTemp(Ity_I64);
5184
5185   if (r1 == r2) {
5186      assign(result, mkU64(0));
5187   } else {
5188      assign(op1, get_gpr_dw0(r1));
5189      assign(op2, get_gpr_dw0(r2));
5190      assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5191   }
5192   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5193   put_gpr_dw0(r1, mkexpr(result));
5194
5195   return "xgr";
5196}
5197
5198static const HChar *
5199s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5200{
5201   IRTemp op2 = newTemp(Ity_I32);
5202   IRTemp op3 = newTemp(Ity_I32);
5203   IRTemp result = newTemp(Ity_I32);
5204
5205   assign(op2, get_gpr_w1(r2));
5206   assign(op3, get_gpr_w1(r3));
5207   assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5208   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5209   put_gpr_w1(r1, mkexpr(result));
5210
5211   return "xrk";
5212}
5213
5214static const HChar *
5215s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5216{
5217   IRTemp op2 = newTemp(Ity_I64);
5218   IRTemp op3 = newTemp(Ity_I64);
5219   IRTemp result = newTemp(Ity_I64);
5220
5221   assign(op2, get_gpr_dw0(r2));
5222   assign(op3, get_gpr_dw0(r3));
5223   assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5224   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5225   put_gpr_dw0(r1, mkexpr(result));
5226
5227   return "xgrk";
5228}
5229
5230static const HChar *
5231s390_irgen_X(UChar r1, IRTemp op2addr)
5232{
5233   IRTemp op1 = newTemp(Ity_I32);
5234   IRTemp op2 = newTemp(Ity_I32);
5235   IRTemp result = newTemp(Ity_I32);
5236
5237   assign(op1, get_gpr_w1(r1));
5238   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5239   assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5240   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5241   put_gpr_w1(r1, mkexpr(result));
5242
5243   return "x";
5244}
5245
5246static const HChar *
5247s390_irgen_XY(UChar r1, IRTemp op2addr)
5248{
5249   IRTemp op1 = newTemp(Ity_I32);
5250   IRTemp op2 = newTemp(Ity_I32);
5251   IRTemp result = newTemp(Ity_I32);
5252
5253   assign(op1, get_gpr_w1(r1));
5254   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5255   assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5256   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5257   put_gpr_w1(r1, mkexpr(result));
5258
5259   return "xy";
5260}
5261
5262static const HChar *
5263s390_irgen_XG(UChar r1, IRTemp op2addr)
5264{
5265   IRTemp op1 = newTemp(Ity_I64);
5266   IRTemp op2 = newTemp(Ity_I64);
5267   IRTemp result = newTemp(Ity_I64);
5268
5269   assign(op1, get_gpr_dw0(r1));
5270   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5271   assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5272   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5273   put_gpr_dw0(r1, mkexpr(result));
5274
5275   return "xg";
5276}
5277
5278static const HChar *
5279s390_irgen_XI(UChar i2, IRTemp op1addr)
5280{
5281   IRTemp op1 = newTemp(Ity_I8);
5282   UChar op2;
5283   IRTemp result = newTemp(Ity_I8);
5284
5285   assign(op1, load(Ity_I8, mkexpr(op1addr)));
5286   op2 = i2;
5287   assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5288   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5289   store(mkexpr(op1addr), mkexpr(result));
5290
5291   return "xi";
5292}
5293
5294static const HChar *
5295s390_irgen_XIY(UChar i2, IRTemp op1addr)
5296{
5297   IRTemp op1 = newTemp(Ity_I8);
5298   UChar op2;
5299   IRTemp result = newTemp(Ity_I8);
5300
5301   assign(op1, load(Ity_I8, mkexpr(op1addr)));
5302   op2 = i2;
5303   assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5304   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5305   store(mkexpr(op1addr), mkexpr(result));
5306
5307   return "xiy";
5308}
5309
5310static const HChar *
5311s390_irgen_XIHF(UChar r1, UInt i2)
5312{
5313   IRTemp op1 = newTemp(Ity_I32);
5314   UInt op2;
5315   IRTemp result = newTemp(Ity_I32);
5316
5317   assign(op1, get_gpr_w0(r1));
5318   op2 = i2;
5319   assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5320   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5321   put_gpr_w0(r1, mkexpr(result));
5322
5323   return "xihf";
5324}
5325
5326static const HChar *
5327s390_irgen_XILF(UChar r1, UInt i2)
5328{
5329   IRTemp op1 = newTemp(Ity_I32);
5330   UInt op2;
5331   IRTemp result = newTemp(Ity_I32);
5332
5333   assign(op1, get_gpr_w1(r1));
5334   op2 = i2;
5335   assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5336   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5337   put_gpr_w1(r1, mkexpr(result));
5338
5339   return "xilf";
5340}
5341
5342static const HChar *
5343s390_irgen_EAR(UChar r1, UChar r2)
5344{
5345   put_gpr_w1(r1, get_ar_w0(r2));
5346   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5347      s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5348
5349   return "ear";
5350}
5351
5352static const HChar *
5353s390_irgen_IC(UChar r1, IRTemp op2addr)
5354{
5355   put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5356
5357   return "ic";
5358}
5359
5360static const HChar *
5361s390_irgen_ICY(UChar r1, IRTemp op2addr)
5362{
5363   put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5364
5365   return "icy";
5366}
5367
5368static const HChar *
5369s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5370{
5371   UChar n;
5372   IRTemp result = newTemp(Ity_I32);
5373   UInt mask;
5374
5375   n = 0;
5376   mask = (UInt)r3;
5377   if ((mask & 8) != 0) {
5378      put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5379      n = n + 1;
5380   }
5381   if ((mask & 4) != 0) {
5382      put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5383
5384      n = n + 1;
5385   }
5386   if ((mask & 2) != 0) {
5387      put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5388
5389      n = n + 1;
5390   }
5391   if ((mask & 1) != 0) {
5392      put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5393
5394      n = n + 1;
5395   }
5396   assign(result, get_gpr_w1(r1));
5397   s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5398                       mkU32(mask)));
5399
5400   return "icm";
5401}
5402
5403static const HChar *
5404s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5405{
5406   UChar n;
5407   IRTemp result = newTemp(Ity_I32);
5408   UInt mask;
5409
5410   n = 0;
5411   mask = (UInt)r3;
5412   if ((mask & 8) != 0) {
5413      put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5414      n = n + 1;
5415   }
5416   if ((mask & 4) != 0) {
5417      put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5418
5419      n = n + 1;
5420   }
5421   if ((mask & 2) != 0) {
5422      put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5423
5424      n = n + 1;
5425   }
5426   if ((mask & 1) != 0) {
5427      put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5428
5429      n = n + 1;
5430   }
5431   assign(result, get_gpr_w1(r1));
5432   s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5433                       mkU32(mask)));
5434
5435   return "icmy";
5436}
5437
5438static const HChar *
5439s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5440{
5441   UChar n;
5442   IRTemp result = newTemp(Ity_I32);
5443   UInt mask;
5444
5445   n = 0;
5446   mask = (UInt)r3;
5447   if ((mask & 8) != 0) {
5448      put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5449      n = n + 1;
5450   }
5451   if ((mask & 4) != 0) {
5452      put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5453
5454      n = n + 1;
5455   }
5456   if ((mask & 2) != 0) {
5457      put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5458
5459      n = n + 1;
5460   }
5461   if ((mask & 1) != 0) {
5462      put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5463
5464      n = n + 1;
5465   }
5466   assign(result, get_gpr_w0(r1));
5467   s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5468                       mkU32(mask)));
5469
5470   return "icmh";
5471}
5472
5473static const HChar *
5474s390_irgen_IIHF(UChar r1, UInt i2)
5475{
5476   put_gpr_w0(r1, mkU32(i2));
5477
5478   return "iihf";
5479}
5480
5481static const HChar *
5482s390_irgen_IIHH(UChar r1, UShort i2)
5483{
5484   put_gpr_hw0(r1, mkU16(i2));
5485
5486   return "iihh";
5487}
5488
5489static const HChar *
5490s390_irgen_IIHL(UChar r1, UShort i2)
5491{
5492   put_gpr_hw1(r1, mkU16(i2));
5493
5494   return "iihl";
5495}
5496
5497static const HChar *
5498s390_irgen_IILF(UChar r1, UInt i2)
5499{
5500   put_gpr_w1(r1, mkU32(i2));
5501
5502   return "iilf";
5503}
5504
5505static const HChar *
5506s390_irgen_IILH(UChar r1, UShort i2)
5507{
5508   put_gpr_hw2(r1, mkU16(i2));
5509
5510   return "iilh";
5511}
5512
5513static const HChar *
5514s390_irgen_IILL(UChar r1, UShort i2)
5515{
5516   put_gpr_hw3(r1, mkU16(i2));
5517
5518   return "iill";
5519}
5520
5521static const HChar *
5522s390_irgen_LR(UChar r1, UChar r2)
5523{
5524   put_gpr_w1(r1, get_gpr_w1(r2));
5525
5526   return "lr";
5527}
5528
5529static const HChar *
5530s390_irgen_LGR(UChar r1, UChar r2)
5531{
5532   put_gpr_dw0(r1, get_gpr_dw0(r2));
5533
5534   return "lgr";
5535}
5536
5537static const HChar *
5538s390_irgen_LGFR(UChar r1, UChar r2)
5539{
5540   put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5541
5542   return "lgfr";
5543}
5544
5545static const HChar *
5546s390_irgen_L(UChar r1, IRTemp op2addr)
5547{
5548   put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5549
5550   return "l";
5551}
5552
5553static const HChar *
5554s390_irgen_LY(UChar r1, IRTemp op2addr)
5555{
5556   put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5557
5558   return "ly";
5559}
5560
5561static const HChar *
5562s390_irgen_LG(UChar r1, IRTemp op2addr)
5563{
5564   put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5565
5566   return "lg";
5567}
5568
5569static const HChar *
5570s390_irgen_LGF(UChar r1, IRTemp op2addr)
5571{
5572   put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5573
5574   return "lgf";
5575}
5576
5577static const HChar *
5578s390_irgen_LGFI(UChar r1, UInt i2)
5579{
5580   put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5581
5582   return "lgfi";
5583}
5584
5585static const HChar *
5586s390_irgen_LRL(UChar r1, UInt i2)
5587{
5588   put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5589              i2 << 1))));
5590
5591   return "lrl";
5592}
5593
5594static const HChar *
5595s390_irgen_LGRL(UChar r1, UInt i2)
5596{
5597   put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5598               i2 << 1))));
5599
5600   return "lgrl";
5601}
5602
5603static const HChar *
5604s390_irgen_LGFRL(UChar r1, UInt i2)
5605{
5606   put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5607               ((ULong)(Long)(Int)i2 << 1)))));
5608
5609   return "lgfrl";
5610}
5611
5612static const HChar *
5613s390_irgen_LA(UChar r1, IRTemp op2addr)
5614{
5615   put_gpr_dw0(r1, mkexpr(op2addr));
5616
5617   return "la";
5618}
5619
5620static const HChar *
5621s390_irgen_LAY(UChar r1, IRTemp op2addr)
5622{
5623   put_gpr_dw0(r1, mkexpr(op2addr));
5624
5625   return "lay";
5626}
5627
5628static const HChar *
5629s390_irgen_LAE(UChar r1, IRTemp op2addr)
5630{
5631   put_gpr_dw0(r1, mkexpr(op2addr));
5632
5633   return "lae";
5634}
5635
5636static const HChar *
5637s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5638{
5639   put_gpr_dw0(r1, mkexpr(op2addr));
5640
5641   return "laey";
5642}
5643
5644static const HChar *
5645s390_irgen_LARL(UChar r1, UInt i2)
5646{
5647   put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5648
5649   return "larl";
5650}
5651
5652/* The IR representation of LAA and friends is an approximation of what
5653   happens natively. Essentially a loop containing a compare-and-swap is
5654   constructed which will iterate until the CAS succeeds. As a consequence,
5655   instrumenters may see more memory accesses than happen natively. See also
5656   discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
5657static void
5658s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5659{
5660   IRCAS *cas;
5661   IRTemp old_mem = newTemp(Ity_I32);
5662   IRTemp op2 = newTemp(Ity_I32);
5663   IRTemp op3 = newTemp(Ity_I32);
5664   IRTemp result = newTemp(Ity_I32);
5665
5666   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5667   assign(op3, get_gpr_w1(r3));
5668   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5669
5670   /* Place the addition of second operand and third operand at the
5671      second-operand location everytime */
5672   cas = mkIRCAS(IRTemp_INVALID, old_mem,
5673                 Iend_BE, mkexpr(op2addr),
5674                 NULL, mkexpr(op2), /* expected value */
5675                 NULL, mkexpr(result)  /* new value */);
5676   stmt(IRStmt_CAS(cas));
5677
5678   /* Set CC according to 32-bit addition */
5679   if (is_signed) {
5680      s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5681   } else {
5682      s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5683   }
5684
5685   /* If old_mem contains the expected value, then the CAS succeeded.
5686      Otherwise, it did not */
5687   yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5688   put_gpr_w1(r1, mkexpr(old_mem));
5689}
5690
5691static void
5692s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5693{
5694   IRCAS *cas;
5695   IRTemp old_mem = newTemp(Ity_I64);
5696   IRTemp op2 = newTemp(Ity_I64);
5697   IRTemp op3 = newTemp(Ity_I64);
5698   IRTemp result = newTemp(Ity_I64);
5699
5700   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5701   assign(op3, get_gpr_dw0(r3));
5702   assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5703
5704   /* Place the addition of second operand and third operand at the
5705      second-operand location everytime */
5706   cas = mkIRCAS(IRTemp_INVALID, old_mem,
5707                 Iend_BE, mkexpr(op2addr),
5708                 NULL, mkexpr(op2), /* expected value */
5709                 NULL, mkexpr(result)  /* new value */);
5710   stmt(IRStmt_CAS(cas));
5711
5712   /* Set CC according to 64-bit addition */
5713   if (is_signed) {
5714      s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5715   } else {
5716      s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5717   }
5718
5719   /* If old_mem contains the expected value, then the CAS succeeded.
5720      Otherwise, it did not */
5721   yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5722   put_gpr_dw0(r1, mkexpr(old_mem));
5723}
5724
5725static void
5726s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5727{
5728   IRCAS *cas;
5729   IRTemp old_mem = newTemp(Ity_I32);
5730   IRTemp op2 = newTemp(Ity_I32);
5731   IRTemp op3 = newTemp(Ity_I32);
5732   IRTemp result = newTemp(Ity_I32);
5733
5734   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5735   assign(op3, get_gpr_w1(r3));
5736   assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5737
5738   /* Place the addition of second operand and third operand at the
5739      second-operand location everytime */
5740   cas = mkIRCAS(IRTemp_INVALID, old_mem,
5741                 Iend_BE, mkexpr(op2addr),
5742                 NULL, mkexpr(op2), /* expected value */
5743                 NULL, mkexpr(result)  /* new value */);
5744   stmt(IRStmt_CAS(cas));
5745
5746   /* Set CC according to bitwise operation */
5747   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5748
5749   /* If old_mem contains the expected value, then the CAS succeeded.
5750      Otherwise, it did not */
5751   yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5752   put_gpr_w1(r1, mkexpr(old_mem));
5753}
5754
5755static void
5756s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5757{
5758   IRCAS *cas;
5759   IRTemp old_mem = newTemp(Ity_I64);
5760   IRTemp op2 = newTemp(Ity_I64);
5761   IRTemp op3 = newTemp(Ity_I64);
5762   IRTemp result = newTemp(Ity_I64);
5763
5764   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5765   assign(op3, get_gpr_dw0(r3));
5766   assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5767
5768   /* Place the addition of second operand and third operand at the
5769      second-operand location everytime */
5770   cas = mkIRCAS(IRTemp_INVALID, old_mem,
5771                 Iend_BE, mkexpr(op2addr),
5772                 NULL, mkexpr(op2), /* expected value */
5773                 NULL, mkexpr(result)  /* new value */);
5774   stmt(IRStmt_CAS(cas));
5775
5776   /* Set CC according to bitwise operation */
5777   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5778
5779   /* If old_mem contains the expected value, then the CAS succeeded.
5780      Otherwise, it did not */
5781   yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5782   put_gpr_dw0(r1, mkexpr(old_mem));
5783}
5784
5785static const HChar *
5786s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5787{
5788   s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
5789
5790   return "laa";
5791}
5792
5793static const HChar *
5794s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5795{
5796   s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
5797
5798   return "laag";
5799}
5800
5801static const HChar *
5802s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5803{
5804   s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
5805
5806   return "laal";
5807}
5808
5809static const HChar *
5810s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5811{
5812   s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
5813
5814   return "laalg";
5815}
5816
5817static const HChar *
5818s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5819{
5820   s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
5821
5822   return "lan";
5823}
5824
5825static const HChar *
5826s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5827{
5828   s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
5829
5830   return "lang";
5831}
5832
5833static const HChar *
5834s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5835{
5836   s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
5837
5838   return "lax";
5839}
5840
5841static const HChar *
5842s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5843{
5844   s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
5845
5846   return "laxg";
5847}
5848
5849static const HChar *
5850s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5851{
5852   s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
5853
5854   return "lao";
5855}
5856
5857static const HChar *
5858s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5859{
5860   s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
5861
5862   return "laog";
5863}
5864
5865static const HChar *
5866s390_irgen_LTR(UChar r1, UChar r2)
5867{
5868   IRTemp op2 = newTemp(Ity_I32);
5869
5870   assign(op2, get_gpr_w1(r2));
5871   put_gpr_w1(r1, mkexpr(op2));
5872   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5873
5874   return "ltr";
5875}
5876
5877static const HChar *
5878s390_irgen_LTGR(UChar r1, UChar r2)
5879{
5880   IRTemp op2 = newTemp(Ity_I64);
5881
5882   assign(op2, get_gpr_dw0(r2));
5883   put_gpr_dw0(r1, mkexpr(op2));
5884   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5885
5886   return "ltgr";
5887}
5888
5889static const HChar *
5890s390_irgen_LTGFR(UChar r1, UChar r2)
5891{
5892   IRTemp op2 = newTemp(Ity_I64);
5893
5894   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5895   put_gpr_dw0(r1, mkexpr(op2));
5896   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5897
5898   return "ltgfr";
5899}
5900
5901static const HChar *
5902s390_irgen_LT(UChar r1, IRTemp op2addr)
5903{
5904   IRTemp op2 = newTemp(Ity_I32);
5905
5906   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5907   put_gpr_w1(r1, mkexpr(op2));
5908   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5909
5910   return "lt";
5911}
5912
5913static const HChar *
5914s390_irgen_LTG(UChar r1, IRTemp op2addr)
5915{
5916   IRTemp op2 = newTemp(Ity_I64);
5917
5918   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5919   put_gpr_dw0(r1, mkexpr(op2));
5920   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5921
5922   return "ltg";
5923}
5924
5925static const HChar *
5926s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5927{
5928   IRTemp op2 = newTemp(Ity_I64);
5929
5930   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5931   put_gpr_dw0(r1, mkexpr(op2));
5932   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5933
5934   return "ltgf";
5935}
5936
5937static const HChar *
5938s390_irgen_LBR(UChar r1, UChar r2)
5939{
5940   put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5941
5942   return "lbr";
5943}
5944
5945static const HChar *
5946s390_irgen_LGBR(UChar r1, UChar r2)
5947{
5948   put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5949
5950   return "lgbr";
5951}
5952
5953static const HChar *
5954s390_irgen_LB(UChar r1, IRTemp op2addr)
5955{
5956   put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5957
5958   return "lb";
5959}
5960
5961static const HChar *
5962s390_irgen_LGB(UChar r1, IRTemp op2addr)
5963{
5964   put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5965
5966   return "lgb";
5967}
5968
5969static const HChar *
5970s390_irgen_LBH(UChar r1, IRTemp op2addr)
5971{
5972   put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5973
5974   return "lbh";
5975}
5976
5977static const HChar *
5978s390_irgen_LCR(UChar r1, UChar r2)
5979{
5980   Int op1;
5981   IRTemp op2 = newTemp(Ity_I32);
5982   IRTemp result = newTemp(Ity_I32);
5983
5984   op1 = 0;
5985   assign(op2, get_gpr_w1(r2));
5986   assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5987   put_gpr_w1(r1, mkexpr(result));
5988   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5989                       op1)), op2);
5990
5991   return "lcr";
5992}
5993
5994static const HChar *
5995s390_irgen_LCGR(UChar r1, UChar r2)
5996{
5997   Long op1;
5998   IRTemp op2 = newTemp(Ity_I64);
5999   IRTemp result = newTemp(Ity_I64);
6000
6001   op1 = 0ULL;
6002   assign(op2, get_gpr_dw0(r2));
6003   assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6004   put_gpr_dw0(r1, mkexpr(result));
6005   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6006                       op1)), op2);
6007
6008   return "lcgr";
6009}
6010
6011static const HChar *
6012s390_irgen_LCGFR(UChar r1, UChar r2)
6013{
6014   Long op1;
6015   IRTemp op2 = newTemp(Ity_I64);
6016   IRTemp result = newTemp(Ity_I64);
6017
6018   op1 = 0ULL;
6019   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6020   assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6021   put_gpr_dw0(r1, mkexpr(result));
6022   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6023                       op1)), op2);
6024
6025   return "lcgfr";
6026}
6027
6028static const HChar *
6029s390_irgen_LHR(UChar r1, UChar r2)
6030{
6031   put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
6032
6033   return "lhr";
6034}
6035
6036static const HChar *
6037s390_irgen_LGHR(UChar r1, UChar r2)
6038{
6039   put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6040
6041   return "lghr";
6042}
6043
6044static const HChar *
6045s390_irgen_LH(UChar r1, IRTemp op2addr)
6046{
6047   put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6048
6049   return "lh";
6050}
6051
6052static const HChar *
6053s390_irgen_LHY(UChar r1, IRTemp op2addr)
6054{
6055   put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6056
6057   return "lhy";
6058}
6059
6060static const HChar *
6061s390_irgen_LGH(UChar r1, IRTemp op2addr)
6062{
6063   put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6064
6065   return "lgh";
6066}
6067
6068static const HChar *
6069s390_irgen_LHI(UChar r1, UShort i2)
6070{
6071   put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6072
6073   return "lhi";
6074}
6075
6076static const HChar *
6077s390_irgen_LGHI(UChar r1, UShort i2)
6078{
6079   put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6080
6081   return "lghi";
6082}
6083
6084static const HChar *
6085s390_irgen_LHRL(UChar r1, UInt i2)
6086{
6087   put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6088              ((ULong)(Long)(Int)i2 << 1)))));
6089
6090   return "lhrl";
6091}
6092
6093static const HChar *
6094s390_irgen_LGHRL(UChar r1, UInt i2)
6095{
6096   put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6097               ((ULong)(Long)(Int)i2 << 1)))));
6098
6099   return "lghrl";
6100}
6101
6102static const HChar *
6103s390_irgen_LHH(UChar r1, IRTemp op2addr)
6104{
6105   put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6106
6107   return "lhh";
6108}
6109
6110static const HChar *
6111s390_irgen_LFH(UChar r1, IRTemp op2addr)
6112{
6113   put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6114
6115   return "lfh";
6116}
6117
6118static const HChar *
6119s390_irgen_LLGFR(UChar r1, UChar r2)
6120{
6121   put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6122
6123   return "llgfr";
6124}
6125
6126static const HChar *
6127s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6128{
6129   put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6130
6131   return "llgf";
6132}
6133
6134static const HChar *
6135s390_irgen_LLGFRL(UChar r1, UInt i2)
6136{
6137   put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6138               ((ULong)(Long)(Int)i2 << 1)))));
6139
6140   return "llgfrl";
6141}
6142
6143static const HChar *
6144s390_irgen_LLCR(UChar r1, UChar r2)
6145{
6146   put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6147
6148   return "llcr";
6149}
6150
6151static const HChar *
6152s390_irgen_LLGCR(UChar r1, UChar r2)
6153{
6154   put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6155
6156   return "llgcr";
6157}
6158
6159static const HChar *
6160s390_irgen_LLC(UChar r1, IRTemp op2addr)
6161{
6162   put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6163
6164   return "llc";
6165}
6166
6167static const HChar *
6168s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6169{
6170   put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6171
6172   return "llgc";
6173}
6174
6175static const HChar *
6176s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6177{
6178   put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6179
6180   return "llch";
6181}
6182
6183static const HChar *
6184s390_irgen_LLHR(UChar r1, UChar r2)
6185{
6186   put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6187
6188   return "llhr";
6189}
6190
6191static const HChar *
6192s390_irgen_LLGHR(UChar r1, UChar r2)
6193{
6194   put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6195
6196   return "llghr";
6197}
6198
6199static const HChar *
6200s390_irgen_LLH(UChar r1, IRTemp op2addr)
6201{
6202   put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6203
6204   return "llh";
6205}
6206
6207static const HChar *
6208s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6209{
6210   put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6211
6212   return "llgh";
6213}
6214
6215static const HChar *
6216s390_irgen_LLHRL(UChar r1, UInt i2)
6217{
6218   put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6219              ((ULong)(Long)(Int)i2 << 1)))));
6220
6221   return "llhrl";
6222}
6223
6224static const HChar *
6225s390_irgen_LLGHRL(UChar r1, UInt i2)
6226{
6227   put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6228               ((ULong)(Long)(Int)i2 << 1)))));
6229
6230   return "llghrl";
6231}
6232
6233static const HChar *
6234s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6235{
6236   put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6237
6238   return "llhh";
6239}
6240
6241static const HChar *
6242s390_irgen_LLIHF(UChar r1, UInt i2)
6243{
6244   put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6245
6246   return "llihf";
6247}
6248
6249static const HChar *
6250s390_irgen_LLIHH(UChar r1, UShort i2)
6251{
6252   put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6253
6254   return "llihh";
6255}
6256
6257static const HChar *
6258s390_irgen_LLIHL(UChar r1, UShort i2)
6259{
6260   put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6261
6262   return "llihl";
6263}
6264
6265static const HChar *
6266s390_irgen_LLILF(UChar r1, UInt i2)
6267{
6268   put_gpr_dw0(r1, mkU64(i2));
6269
6270   return "llilf";
6271}
6272
6273static const HChar *
6274s390_irgen_LLILH(UChar r1, UShort i2)
6275{
6276   put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6277
6278   return "llilh";
6279}
6280
6281static const HChar *
6282s390_irgen_LLILL(UChar r1, UShort i2)
6283{
6284   put_gpr_dw0(r1, mkU64(i2));
6285
6286   return "llill";
6287}
6288
6289static const HChar *
6290s390_irgen_LLGTR(UChar r1, UChar r2)
6291{
6292   put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6293               mkU32(2147483647))));
6294
6295   return "llgtr";
6296}
6297
6298static const HChar *
6299s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6300{
6301   put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6302               mkexpr(op2addr)), mkU32(2147483647))));
6303
6304   return "llgt";
6305}
6306
6307static const HChar *
6308s390_irgen_LNR(UChar r1, UChar r2)
6309{
6310   IRTemp op2 = newTemp(Ity_I32);
6311   IRTemp result = newTemp(Ity_I32);
6312
6313   assign(op2, get_gpr_w1(r2));
6314   assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6315          binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6316   put_gpr_w1(r1, mkexpr(result));
6317   s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6318
6319   return "lnr";
6320}
6321
6322static const HChar *
6323s390_irgen_LNGR(UChar r1, UChar r2)
6324{
6325   IRTemp op2 = newTemp(Ity_I64);
6326   IRTemp result = newTemp(Ity_I64);
6327
6328   assign(op2, get_gpr_dw0(r2));
6329   assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6330          binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6331   put_gpr_dw0(r1, mkexpr(result));
6332   s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6333
6334   return "lngr";
6335}
6336
6337static const HChar *
6338s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6339{
6340   IRTemp op2 = newTemp(Ity_I64);
6341   IRTemp result = newTemp(Ity_I64);
6342
6343   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6344   assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6345          binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6346   put_gpr_dw0(r1, mkexpr(result));
6347   s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6348
6349   return "lngfr";
6350}
6351
6352static const HChar *
6353s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6354{
6355   next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
6356   put_gpr_w1(r1, get_gpr_w1(r2));
6357
6358   return "locr";
6359}
6360
6361static const HChar *
6362s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6363{
6364   next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
6365   put_gpr_dw0(r1, get_gpr_dw0(r2));
6366
6367   return "locgr";
6368}
6369
6370static const HChar *
6371s390_irgen_LOC(UChar r1, IRTemp op2addr)
6372{
6373   /* condition is checked in format handler */
6374   put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6375
6376   return "loc";
6377}
6378
6379static const HChar *
6380s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6381{
6382   /* condition is checked in format handler */
6383   put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6384
6385   return "locg";
6386}
6387
6388static const HChar *
6389s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6390{
6391   put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6392   put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6393               ));
6394
6395   return "lpq";
6396}
6397
6398static const HChar *
6399s390_irgen_LPR(UChar r1, UChar r2)
6400{
6401   IRTemp op2 = newTemp(Ity_I32);
6402   IRTemp result = newTemp(Ity_I32);
6403
6404   assign(op2, get_gpr_w1(r2));
6405   assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6406          binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6407   put_gpr_w1(r1, mkexpr(result));
6408   s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6409
6410   return "lpr";
6411}
6412
6413static const HChar *
6414s390_irgen_LPGR(UChar r1, UChar r2)
6415{
6416   IRTemp op2 = newTemp(Ity_I64);
6417   IRTemp result = newTemp(Ity_I64);
6418
6419   assign(op2, get_gpr_dw0(r2));
6420   assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6421          binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6422   put_gpr_dw0(r1, mkexpr(result));
6423   s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6424
6425   return "lpgr";
6426}
6427
6428static const HChar *
6429s390_irgen_LPGFR(UChar r1, UChar r2)
6430{
6431   IRTemp op2 = newTemp(Ity_I64);
6432   IRTemp result = newTemp(Ity_I64);
6433
6434   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6435   assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6436          binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6437   put_gpr_dw0(r1, mkexpr(result));
6438   s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6439
6440   return "lpgfr";
6441}
6442
6443static const HChar *
6444s390_irgen_LRVR(UChar r1, UChar r2)
6445{
6446   IRTemp b0 = newTemp(Ity_I8);
6447   IRTemp b1 = newTemp(Ity_I8);
6448   IRTemp b2 = newTemp(Ity_I8);
6449   IRTemp b3 = newTemp(Ity_I8);
6450
6451   assign(b3, get_gpr_b7(r2));
6452   assign(b2, get_gpr_b6(r2));
6453   assign(b1, get_gpr_b5(r2));
6454   assign(b0, get_gpr_b4(r2));
6455   put_gpr_b4(r1, mkexpr(b3));
6456   put_gpr_b5(r1, mkexpr(b2));
6457   put_gpr_b6(r1, mkexpr(b1));
6458   put_gpr_b7(r1, mkexpr(b0));
6459
6460   return "lrvr";
6461}
6462
6463static const HChar *
6464s390_irgen_LRVGR(UChar r1, UChar r2)
6465{
6466   IRTemp b0 = newTemp(Ity_I8);
6467   IRTemp b1 = newTemp(Ity_I8);
6468   IRTemp b2 = newTemp(Ity_I8);
6469   IRTemp b3 = newTemp(Ity_I8);
6470   IRTemp b4 = newTemp(Ity_I8);
6471   IRTemp b5 = newTemp(Ity_I8);
6472   IRTemp b6 = newTemp(Ity_I8);
6473   IRTemp b7 = newTemp(Ity_I8);
6474
6475   assign(b7, get_gpr_b7(r2));
6476   assign(b6, get_gpr_b6(r2));
6477   assign(b5, get_gpr_b5(r2));
6478   assign(b4, get_gpr_b4(r2));
6479   assign(b3, get_gpr_b3(r2));
6480   assign(b2, get_gpr_b2(r2));
6481   assign(b1, get_gpr_b1(r2));
6482   assign(b0, get_gpr_b0(r2));
6483   put_gpr_b0(r1, mkexpr(b7));
6484   put_gpr_b1(r1, mkexpr(b6));
6485   put_gpr_b2(r1, mkexpr(b5));
6486   put_gpr_b3(r1, mkexpr(b4));
6487   put_gpr_b4(r1, mkexpr(b3));
6488   put_gpr_b5(r1, mkexpr(b2));
6489   put_gpr_b6(r1, mkexpr(b1));
6490   put_gpr_b7(r1, mkexpr(b0));
6491
6492   return "lrvgr";
6493}
6494
6495static const HChar *
6496s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6497{
6498   IRTemp op2 = newTemp(Ity_I16);
6499
6500   assign(op2, load(Ity_I16, mkexpr(op2addr)));
6501   put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6502   put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6503
6504   return "lrvh";
6505}
6506
6507static const HChar *
6508s390_irgen_LRV(UChar r1, IRTemp op2addr)
6509{
6510   IRTemp op2 = newTemp(Ity_I32);
6511
6512   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6513   put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6514   put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6515              mkU8(8)), mkU32(255))));
6516   put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6517              mkU8(16)), mkU32(255))));
6518   put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6519              mkU8(24)), mkU32(255))));
6520
6521   return "lrv";
6522}
6523
6524static const HChar *
6525s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6526{
6527   IRTemp op2 = newTemp(Ity_I64);
6528
6529   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6530   put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6531   put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6532              mkU8(8)), mkU64(255))));
6533   put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6534              mkU8(16)), mkU64(255))));
6535   put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6536              mkU8(24)), mkU64(255))));
6537   put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6538              mkU8(32)), mkU64(255))));
6539   put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6540              mkU8(40)), mkU64(255))));
6541   put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6542              mkU8(48)), mkU64(255))));
6543   put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6544              mkU8(56)), mkU64(255))));
6545
6546   return "lrvg";
6547}
6548
6549static const HChar *
6550s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6551{
6552   store(mkexpr(op1addr), mkU16(i2));
6553
6554   return "mvhhi";
6555}
6556
6557static const HChar *
6558s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6559{
6560   store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6561
6562   return "mvhi";
6563}
6564
6565static const HChar *
6566s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6567{
6568   store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6569
6570   return "mvghi";
6571}
6572
6573static const HChar *
6574s390_irgen_MVI(UChar i2, IRTemp op1addr)
6575{
6576   store(mkexpr(op1addr), mkU8(i2));
6577
6578   return "mvi";
6579}
6580
6581static const HChar *
6582s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6583{
6584   store(mkexpr(op1addr), mkU8(i2));
6585
6586   return "mviy";
6587}
6588
6589static const HChar *
6590s390_irgen_MR(UChar r1, UChar r2)
6591{
6592   IRTemp op1 = newTemp(Ity_I32);
6593   IRTemp op2 = newTemp(Ity_I32);
6594   IRTemp result = newTemp(Ity_I64);
6595
6596   assign(op1, get_gpr_w1(r1 + 1));
6597   assign(op2, get_gpr_w1(r2));
6598   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6599   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6600   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6601
6602   return "mr";
6603}
6604
6605static const HChar *
6606s390_irgen_M(UChar r1, IRTemp op2addr)
6607{
6608   IRTemp op1 = newTemp(Ity_I32);
6609   IRTemp op2 = newTemp(Ity_I32);
6610   IRTemp result = newTemp(Ity_I64);
6611
6612   assign(op1, get_gpr_w1(r1 + 1));
6613   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6614   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6615   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6616   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6617
6618   return "m";
6619}
6620
6621static const HChar *
6622s390_irgen_MFY(UChar r1, IRTemp op2addr)
6623{
6624   IRTemp op1 = newTemp(Ity_I32);
6625   IRTemp op2 = newTemp(Ity_I32);
6626   IRTemp result = newTemp(Ity_I64);
6627
6628   assign(op1, get_gpr_w1(r1 + 1));
6629   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6630   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6631   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6632   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6633
6634   return "mfy";
6635}
6636
6637static const HChar *
6638s390_irgen_MH(UChar r1, IRTemp op2addr)
6639{
6640   IRTemp op1 = newTemp(Ity_I32);
6641   IRTemp op2 = newTemp(Ity_I16);
6642   IRTemp result = newTemp(Ity_I64);
6643
6644   assign(op1, get_gpr_w1(r1));
6645   assign(op2, load(Ity_I16, mkexpr(op2addr)));
6646   assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6647          ));
6648   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6649
6650   return "mh";
6651}
6652
6653static const HChar *
6654s390_irgen_MHY(UChar r1, IRTemp op2addr)
6655{
6656   IRTemp op1 = newTemp(Ity_I32);
6657   IRTemp op2 = newTemp(Ity_I16);
6658   IRTemp result = newTemp(Ity_I64);
6659
6660   assign(op1, get_gpr_w1(r1));
6661   assign(op2, load(Ity_I16, mkexpr(op2addr)));
6662   assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6663          ));
6664   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6665
6666   return "mhy";
6667}
6668
6669static const HChar *
6670s390_irgen_MHI(UChar r1, UShort i2)
6671{
6672   IRTemp op1 = newTemp(Ity_I32);
6673   Short op2;
6674   IRTemp result = newTemp(Ity_I64);
6675
6676   assign(op1, get_gpr_w1(r1));
6677   op2 = (Short)i2;
6678   assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6679          mkU16((UShort)op2))));
6680   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6681
6682   return "mhi";
6683}
6684
6685static const HChar *
6686s390_irgen_MGHI(UChar r1, UShort i2)
6687{
6688   IRTemp op1 = newTemp(Ity_I64);
6689   Short op2;
6690   IRTemp result = newTemp(Ity_I128);
6691
6692   assign(op1, get_gpr_dw0(r1));
6693   op2 = (Short)i2;
6694   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6695          mkU16((UShort)op2))));
6696   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6697
6698   return "mghi";
6699}
6700
6701static const HChar *
6702s390_irgen_MLR(UChar r1, UChar r2)
6703{
6704   IRTemp op1 = newTemp(Ity_I32);
6705   IRTemp op2 = newTemp(Ity_I32);
6706   IRTemp result = newTemp(Ity_I64);
6707
6708   assign(op1, get_gpr_w1(r1 + 1));
6709   assign(op2, get_gpr_w1(r2));
6710   assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6711   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6712   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6713
6714   return "mlr";
6715}
6716
6717static const HChar *
6718s390_irgen_MLGR(UChar r1, UChar r2)
6719{
6720   IRTemp op1 = newTemp(Ity_I64);
6721   IRTemp op2 = newTemp(Ity_I64);
6722   IRTemp result = newTemp(Ity_I128);
6723
6724   assign(op1, get_gpr_dw0(r1 + 1));
6725   assign(op2, get_gpr_dw0(r2));
6726   assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6727   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6728   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6729
6730   return "mlgr";
6731}
6732
6733static const HChar *
6734s390_irgen_ML(UChar r1, IRTemp op2addr)
6735{
6736   IRTemp op1 = newTemp(Ity_I32);
6737   IRTemp op2 = newTemp(Ity_I32);
6738   IRTemp result = newTemp(Ity_I64);
6739
6740   assign(op1, get_gpr_w1(r1 + 1));
6741   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6742   assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6743   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6744   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6745
6746   return "ml";
6747}
6748
6749static const HChar *
6750s390_irgen_MLG(UChar r1, IRTemp op2addr)
6751{
6752   IRTemp op1 = newTemp(Ity_I64);
6753   IRTemp op2 = newTemp(Ity_I64);
6754   IRTemp result = newTemp(Ity_I128);
6755
6756   assign(op1, get_gpr_dw0(r1 + 1));
6757   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6758   assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6759   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6760   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6761
6762   return "mlg";
6763}
6764
6765static const HChar *
6766s390_irgen_MSR(UChar r1, UChar r2)
6767{
6768   IRTemp op1 = newTemp(Ity_I32);
6769   IRTemp op2 = newTemp(Ity_I32);
6770   IRTemp result = newTemp(Ity_I64);
6771
6772   assign(op1, get_gpr_w1(r1));
6773   assign(op2, get_gpr_w1(r2));
6774   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6775   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6776
6777   return "msr";
6778}
6779
6780static const HChar *
6781s390_irgen_MSGR(UChar r1, UChar r2)
6782{
6783   IRTemp op1 = newTemp(Ity_I64);
6784   IRTemp op2 = newTemp(Ity_I64);
6785   IRTemp result = newTemp(Ity_I128);
6786
6787   assign(op1, get_gpr_dw0(r1));
6788   assign(op2, get_gpr_dw0(r2));
6789   assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6790   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6791
6792   return "msgr";
6793}
6794
6795static const HChar *
6796s390_irgen_MSGFR(UChar r1, UChar r2)
6797{
6798   IRTemp op1 = newTemp(Ity_I64);
6799   IRTemp op2 = newTemp(Ity_I32);
6800   IRTemp result = newTemp(Ity_I128);
6801
6802   assign(op1, get_gpr_dw0(r1));
6803   assign(op2, get_gpr_w1(r2));
6804   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6805          ));
6806   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6807
6808   return "msgfr";
6809}
6810
6811static const HChar *
6812s390_irgen_MS(UChar r1, IRTemp op2addr)
6813{
6814   IRTemp op1 = newTemp(Ity_I32);
6815   IRTemp op2 = newTemp(Ity_I32);
6816   IRTemp result = newTemp(Ity_I64);
6817
6818   assign(op1, get_gpr_w1(r1));
6819   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6820   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6821   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6822
6823   return "ms";
6824}
6825
6826static const HChar *
6827s390_irgen_MSY(UChar r1, IRTemp op2addr)
6828{
6829   IRTemp op1 = newTemp(Ity_I32);
6830   IRTemp op2 = newTemp(Ity_I32);
6831   IRTemp result = newTemp(Ity_I64);
6832
6833   assign(op1, get_gpr_w1(r1));
6834   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6835   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6836   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6837
6838   return "msy";
6839}
6840
6841static const HChar *
6842s390_irgen_MSG(UChar r1, IRTemp op2addr)
6843{
6844   IRTemp op1 = newTemp(Ity_I64);
6845   IRTemp op2 = newTemp(Ity_I64);
6846   IRTemp result = newTemp(Ity_I128);
6847
6848   assign(op1, get_gpr_dw0(r1));
6849   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6850   assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6851   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6852
6853   return "msg";
6854}
6855
6856static const HChar *
6857s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6858{
6859   IRTemp op1 = newTemp(Ity_I64);
6860   IRTemp op2 = newTemp(Ity_I32);
6861   IRTemp result = newTemp(Ity_I128);
6862
6863   assign(op1, get_gpr_dw0(r1));
6864   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6865   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6866          ));
6867   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6868
6869   return "msgf";
6870}
6871
6872static const HChar *
6873s390_irgen_MSFI(UChar r1, UInt i2)
6874{
6875   IRTemp op1 = newTemp(Ity_I32);
6876   Int op2;
6877   IRTemp result = newTemp(Ity_I64);
6878
6879   assign(op1, get_gpr_w1(r1));
6880   op2 = (Int)i2;
6881   assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6882   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6883
6884   return "msfi";
6885}
6886
6887static const HChar *
6888s390_irgen_MSGFI(UChar r1, UInt i2)
6889{
6890   IRTemp op1 = newTemp(Ity_I64);
6891   Int op2;
6892   IRTemp result = newTemp(Ity_I128);
6893
6894   assign(op1, get_gpr_dw0(r1));
6895   op2 = (Int)i2;
6896   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6897          op2))));
6898   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6899
6900   return "msgfi";
6901}
6902
6903static const HChar *
6904s390_irgen_OR(UChar r1, UChar r2)
6905{
6906   IRTemp op1 = newTemp(Ity_I32);
6907   IRTemp op2 = newTemp(Ity_I32);
6908   IRTemp result = newTemp(Ity_I32);
6909
6910   assign(op1, get_gpr_w1(r1));
6911   assign(op2, get_gpr_w1(r2));
6912   assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6913   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6914   put_gpr_w1(r1, mkexpr(result));
6915
6916   return "or";
6917}
6918
6919static const HChar *
6920s390_irgen_OGR(UChar r1, UChar r2)
6921{
6922   IRTemp op1 = newTemp(Ity_I64);
6923   IRTemp op2 = newTemp(Ity_I64);
6924   IRTemp result = newTemp(Ity_I64);
6925
6926   assign(op1, get_gpr_dw0(r1));
6927   assign(op2, get_gpr_dw0(r2));
6928   assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6929   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6930   put_gpr_dw0(r1, mkexpr(result));
6931
6932   return "ogr";
6933}
6934
6935static const HChar *
6936s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6937{
6938   IRTemp op2 = newTemp(Ity_I32);
6939   IRTemp op3 = newTemp(Ity_I32);
6940   IRTemp result = newTemp(Ity_I32);
6941
6942   assign(op2, get_gpr_w1(r2));
6943   assign(op3, get_gpr_w1(r3));
6944   assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6945   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6946   put_gpr_w1(r1, mkexpr(result));
6947
6948   return "ork";
6949}
6950
6951static const HChar *
6952s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6953{
6954   IRTemp op2 = newTemp(Ity_I64);
6955   IRTemp op3 = newTemp(Ity_I64);
6956   IRTemp result = newTemp(Ity_I64);
6957
6958   assign(op2, get_gpr_dw0(r2));
6959   assign(op3, get_gpr_dw0(r3));
6960   assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6961   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6962   put_gpr_dw0(r1, mkexpr(result));
6963
6964   return "ogrk";
6965}
6966
6967static const HChar *
6968s390_irgen_O(UChar r1, IRTemp op2addr)
6969{
6970   IRTemp op1 = newTemp(Ity_I32);
6971   IRTemp op2 = newTemp(Ity_I32);
6972   IRTemp result = newTemp(Ity_I32);
6973
6974   assign(op1, get_gpr_w1(r1));
6975   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6976   assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6977   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6978   put_gpr_w1(r1, mkexpr(result));
6979
6980   return "o";
6981}
6982
6983static const HChar *
6984s390_irgen_OY(UChar r1, IRTemp op2addr)
6985{
6986   IRTemp op1 = newTemp(Ity_I32);
6987   IRTemp op2 = newTemp(Ity_I32);
6988   IRTemp result = newTemp(Ity_I32);
6989
6990   assign(op1, get_gpr_w1(r1));
6991   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6992   assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6993   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6994   put_gpr_w1(r1, mkexpr(result));
6995
6996   return "oy";
6997}
6998
6999static const HChar *
7000s390_irgen_OG(UChar r1, IRTemp op2addr)
7001{
7002   IRTemp op1 = newTemp(Ity_I64);
7003   IRTemp op2 = newTemp(Ity_I64);
7004   IRTemp result = newTemp(Ity_I64);
7005
7006   assign(op1, get_gpr_dw0(r1));
7007   assign(op2, load(Ity_I64, mkexpr(op2addr)));
7008   assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
7009   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7010   put_gpr_dw0(r1, mkexpr(result));
7011
7012   return "og";
7013}
7014
7015static const HChar *
7016s390_irgen_OI(UChar i2, IRTemp op1addr)
7017{
7018   IRTemp op1 = newTemp(Ity_I8);
7019   UChar op2;
7020   IRTemp result = newTemp(Ity_I8);
7021
7022   assign(op1, load(Ity_I8, mkexpr(op1addr)));
7023   op2 = i2;
7024   assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7025   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7026   store(mkexpr(op1addr), mkexpr(result));
7027
7028   return "oi";
7029}
7030
7031static const HChar *
7032s390_irgen_OIY(UChar i2, IRTemp op1addr)
7033{
7034   IRTemp op1 = newTemp(Ity_I8);
7035   UChar op2;
7036   IRTemp result = newTemp(Ity_I8);
7037
7038   assign(op1, load(Ity_I8, mkexpr(op1addr)));
7039   op2 = i2;
7040   assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7041   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7042   store(mkexpr(op1addr), mkexpr(result));
7043
7044   return "oiy";
7045}
7046
7047static const HChar *
7048s390_irgen_OIHF(UChar r1, UInt i2)
7049{
7050   IRTemp op1 = newTemp(Ity_I32);
7051   UInt op2;
7052   IRTemp result = newTemp(Ity_I32);
7053
7054   assign(op1, get_gpr_w0(r1));
7055   op2 = i2;
7056   assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7057   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7058   put_gpr_w0(r1, mkexpr(result));
7059
7060   return "oihf";
7061}
7062
7063static const HChar *
7064s390_irgen_OIHH(UChar r1, UShort i2)
7065{
7066   IRTemp op1 = newTemp(Ity_I16);
7067   UShort op2;
7068   IRTemp result = newTemp(Ity_I16);
7069
7070   assign(op1, get_gpr_hw0(r1));
7071   op2 = i2;
7072   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7073   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7074   put_gpr_hw0(r1, mkexpr(result));
7075
7076   return "oihh";
7077}
7078
7079static const HChar *
7080s390_irgen_OIHL(UChar r1, UShort i2)
7081{
7082   IRTemp op1 = newTemp(Ity_I16);
7083   UShort op2;
7084   IRTemp result = newTemp(Ity_I16);
7085
7086   assign(op1, get_gpr_hw1(r1));
7087   op2 = i2;
7088   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7089   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7090   put_gpr_hw1(r1, mkexpr(result));
7091
7092   return "oihl";
7093}
7094
7095static const HChar *
7096s390_irgen_OILF(UChar r1, UInt i2)
7097{
7098   IRTemp op1 = newTemp(Ity_I32);
7099   UInt op2;
7100   IRTemp result = newTemp(Ity_I32);
7101
7102   assign(op1, get_gpr_w1(r1));
7103   op2 = i2;
7104   assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7105   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7106   put_gpr_w1(r1, mkexpr(result));
7107
7108   return "oilf";
7109}
7110
7111static const HChar *
7112s390_irgen_OILH(UChar r1, UShort i2)
7113{
7114   IRTemp op1 = newTemp(Ity_I16);
7115   UShort op2;
7116   IRTemp result = newTemp(Ity_I16);
7117
7118   assign(op1, get_gpr_hw2(r1));
7119   op2 = i2;
7120   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7121   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7122   put_gpr_hw2(r1, mkexpr(result));
7123
7124   return "oilh";
7125}
7126
7127static const HChar *
7128s390_irgen_OILL(UChar r1, UShort i2)
7129{
7130   IRTemp op1 = newTemp(Ity_I16);
7131   UShort op2;
7132   IRTemp result = newTemp(Ity_I16);
7133
7134   assign(op1, get_gpr_hw3(r1));
7135   op2 = i2;
7136   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7137   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7138   put_gpr_hw3(r1, mkexpr(result));
7139
7140   return "oill";
7141}
7142
7143static const HChar *
7144s390_irgen_PFD(void)
7145{
7146
7147   return "pfd";
7148}
7149
7150static const HChar *
7151s390_irgen_PFDRL(void)
7152{
7153
7154   return "pfdrl";
7155}
7156
7157static IRExpr *
7158get_rounding_mode_from_gr0(void)
7159{
7160   IRTemp rm_bits = newTemp(Ity_I32);
7161   IRExpr *s390rm;
7162   IRExpr *irrm;
7163
7164   /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7165      when PFPO insn is called. So, extract the bits at [60:63] */
7166   assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7167   s390rm = mkexpr(rm_bits);
7168   irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7169            mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7170            mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7171              mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7172              mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7173                mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7174                mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7175                  mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7176                  mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7177                    mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7178                    mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7179                      mkexpr(encode_dfp_rounding_mode(
7180                               S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7181                      mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7182                        mkexpr(encode_dfp_rounding_mode(
7183                                 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7184                        mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7185                          mkexpr(encode_dfp_rounding_mode(
7186                                   S390_DFP_ROUND_AWAY_0)),
7187                          mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7188                            mkexpr(encode_dfp_rounding_mode(
7189                                     S390_DFP_ROUND_PREPARE_SHORT_15)),
7190                                /* if rounding mode is 0 or invalid (2-7)
7191                                   set S390_DFP_ROUND_PER_FPC_0 */
7192                            mkexpr(encode_dfp_rounding_mode(
7193                                     S390_DFP_ROUND_PER_FPC_0)))))))))));
7194
7195   return irrm;
7196}
7197
7198static IRExpr *
7199s390_call_pfpo_helper(IRExpr *gr0)
7200{
7201   IRExpr **args, *call;
7202
7203   args = mkIRExprVec_1(gr0);
7204   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7205                        "s390_do_pfpo", &s390_do_pfpo, args);
7206   /* Nothing is excluded from definedness checking. */
7207   call->Iex.CCall.cee->mcx_mask = 0;
7208
7209   return call;
7210}
7211
7212static const HChar *
7213s390_irgen_PFPO(void)
7214{
7215   IRTemp gr0 = newTemp(Ity_I32);     /* word 1 [32:63] of GR 0 */
7216   IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7217   IRTemp fn = newTemp(Ity_I32);       /* [33:55] of GR 0 - function code */
7218   IRTemp ef = newTemp(Ity_I32);       /* Emulation Failure */
7219   IRTemp src1 = newTemp(Ity_F32);
7220   IRTemp dst1 = newTemp(Ity_D32);
7221   IRTemp src2 = newTemp(Ity_F32);
7222   IRTemp dst2 = newTemp(Ity_D64);
7223   IRTemp src3 = newTemp(Ity_F32);
7224   IRTemp dst3 = newTemp(Ity_D128);
7225   IRTemp src4 = newTemp(Ity_F64);
7226   IRTemp dst4 = newTemp(Ity_D32);
7227   IRTemp src5 = newTemp(Ity_F64);
7228   IRTemp dst5 = newTemp(Ity_D64);
7229   IRTemp src6 = newTemp(Ity_F64);
7230   IRTemp dst6 = newTemp(Ity_D128);
7231   IRTemp src7 = newTemp(Ity_F128);
7232   IRTemp dst7 = newTemp(Ity_D32);
7233   IRTemp src8 = newTemp(Ity_F128);
7234   IRTemp dst8 = newTemp(Ity_D64);
7235   IRTemp src9 = newTemp(Ity_F128);
7236   IRTemp dst9 = newTemp(Ity_D128);
7237   IRTemp src10 = newTemp(Ity_D32);
7238   IRTemp dst10 = newTemp(Ity_F32);
7239   IRTemp src11 = newTemp(Ity_D32);
7240   IRTemp dst11 = newTemp(Ity_F64);
7241   IRTemp src12 = newTemp(Ity_D32);
7242   IRTemp dst12 = newTemp(Ity_F128);
7243   IRTemp src13 = newTemp(Ity_D64);
7244   IRTemp dst13 = newTemp(Ity_F32);
7245   IRTemp src14 = newTemp(Ity_D64);
7246   IRTemp dst14 = newTemp(Ity_F64);
7247   IRTemp src15 = newTemp(Ity_D64);
7248   IRTemp dst15 = newTemp(Ity_F128);
7249   IRTemp src16 = newTemp(Ity_D128);
7250   IRTemp dst16 = newTemp(Ity_F32);
7251   IRTemp src17 = newTemp(Ity_D128);
7252   IRTemp dst17 = newTemp(Ity_F64);
7253   IRTemp src18 = newTemp(Ity_D128);
7254   IRTemp dst18 = newTemp(Ity_F128);
7255   IRExpr *irrm;
7256
7257   if (! s390_host_has_pfpo) {
7258      emulation_failure(EmFail_S390X_pfpo);
7259      goto done;
7260   }
7261
7262   assign(gr0, get_gpr_w1(0));
7263   /* get function code */
7264   assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7265                    mkU32(0x7fffff)));
7266   /* get validity test bit */
7267   assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7268                          mkU32(0x1)));
7269   irrm = get_rounding_mode_from_gr0();
7270
7271   /* test_bit is 1 */
7272   assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
7273   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7274
7275   /* Return code set in GR1 is usually 0. Non-zero value is set only
7276      when exceptions are raised. See Programming Notes point 5 in the
7277      instrcution description of pfpo in POP. Since valgrind does not
7278      model exception, it might be safe to just set 0 to GR 1. */
7279   put_gpr_w1(1, mkU32(0x0));
7280   next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7281
7282   /* Check validity of function code in GR 0 */
7283   assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
7284   emulation_failure_with_expr(mkexpr(ef));
7285
7286   stmt(
7287        IRStmt_Exit(
7288                    binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7289                    Ijk_EmFail,
7290                    IRConst_U64(guest_IA_next_instr),
7291                    S390X_GUEST_OFFSET(guest_IA)
7292                    )
7293        );
7294
7295   /* F32 -> D32 */
7296   /* get source from FPR 4,6 - already set in src1 */
7297   assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
7298   put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
7299   put_gpr_w1(1, mkU32(0x0));
7300   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
7301   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
7302
7303   /* F32 -> D64 */
7304   assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
7305   assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
7306   put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
7307   put_gpr_w1(1, mkU32(0x0));
7308   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
7309   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
7310
7311   /* F32 -> D128 */
7312   assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
7313   assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
7314   put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7315   put_gpr_w1(1, mkU32(0x0));
7316   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
7317   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
7318
7319   /* F64 -> D32 */
7320   assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7321   assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
7322   put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7323   put_gpr_w1(1, mkU32(0x0));
7324   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
7325   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
7326
7327   /* F64 -> D64 */
7328   assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7329   assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
7330   put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7331   put_gpr_w1(1, mkU32(0x0));
7332   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
7333   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7334
7335   /* F64 -> D128 */
7336   assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7337   assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
7338   put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7339   put_gpr_w1(1, mkU32(0x0));
7340   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
7341   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7342
7343   /* F128 -> D32 */
7344   assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
7345   assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
7346   put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
7347   put_gpr_w1(1, mkU32(0x0));
7348   s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
7349   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
7350
7351   /* F128 -> D64 */
7352   assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
7353   assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
7354   put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
7355   put_gpr_w1(1, mkU32(0x0));
7356   s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
7357   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
7358
7359   /* F128 -> D128 */
7360   assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
7361   assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
7362   put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
7363   put_gpr_w1(1, mkU32(0x0));
7364   s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
7365   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7366
7367   /* D32 -> F32 */
7368   assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
7369   assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
7370   put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
7371   put_gpr_w1(1, mkU32(0x0));
7372   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
7373   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
7374
7375   /* D32 -> F64 */
7376   assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
7377   assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
7378   put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
7379   put_gpr_w1(1, mkU32(0x0));
7380   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
7381   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
7382
7383   /* D32 -> F128 */
7384   assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
7385   assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
7386   put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
7387   put_gpr_w1(1, mkU32(0x0));
7388   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
7389   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
7390
7391   /* D64 -> F32 */
7392   assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7393   assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
7394   put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
7395   put_gpr_w1(1, mkU32(0x0));
7396   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
7397   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
7398
7399   /* D64 -> F64 */
7400   assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7401   assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
7402   put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
7403   put_gpr_w1(1, mkU32(0x0));
7404   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
7405   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7406
7407   /* D64 -> F128 */
7408   assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7409   assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
7410   put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
7411   put_gpr_w1(1, mkU32(0x0));
7412   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
7413   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
7414
7415   /* D128 -> F32 */
7416   assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
7417   assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
7418   put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
7419   put_gpr_w1(1, mkU32(0x0));
7420   s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
7421   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
7422
7423   /* D128 -> F64 */
7424   assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
7425   assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
7426   put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
7427   put_gpr_w1(1, mkU32(0x0));
7428   s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
7429   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7430
7431   /* D128 -> F128 */
7432   assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
7433   assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
7434   put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
7435   put_gpr_w1(1, mkU32(0x0));
7436   s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
7437   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7438
7439 done:
7440   return "pfpo";
7441}
7442
7443static const HChar *
7444s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7445{
7446   IRTemp amount = newTemp(Ity_I64);
7447   IRTemp op = newTemp(Ity_I32);
7448
7449   assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7450   assign(op, get_gpr_w1(r3));
7451   put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7452              mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7453              binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7454
7455   return "rll";
7456}
7457
7458static const HChar *
7459s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7460{
7461   IRTemp amount = newTemp(Ity_I64);
7462   IRTemp op = newTemp(Ity_I64);
7463
7464   assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7465   assign(op, get_gpr_dw0(r3));
7466   put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7467               mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7468               binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7469
7470   return "rllg";
7471}
7472
7473static const HChar *
7474s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7475{
7476   UChar from;
7477   UChar to;
7478   UChar rot;
7479   UChar t_bit;
7480   ULong mask;
7481   ULong maskc;
7482   IRTemp result = newTemp(Ity_I64);
7483   IRTemp op2 = newTemp(Ity_I64);
7484
7485   from = i3 & 63;
7486   to = i4 & 63;
7487   rot = i5 & 63;
7488   t_bit = i3 & 128;
7489   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7490          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7491          mkU8(64 - rot))));
7492   if (from <= to) {
7493      mask = ~0ULL;
7494      mask = (mask >> from) & (mask << (63 - to));
7495      maskc = ~mask;
7496   } else {
7497      maskc = ~0ULL;
7498      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7499      mask = ~maskc;
7500   }
7501   assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7502          ), mkU64(mask)));
7503   if (t_bit == 0) {
7504      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7505                  mkU64(maskc)), mkexpr(result)));
7506   }
7507   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7508
7509   return "rnsbg";
7510}
7511
7512static const HChar *
7513s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7514{
7515   UChar from;
7516   UChar to;
7517   UChar rot;
7518   UChar t_bit;
7519   ULong mask;
7520   ULong maskc;
7521   IRTemp result = newTemp(Ity_I64);
7522   IRTemp op2 = newTemp(Ity_I64);
7523
7524   from = i3 & 63;
7525   to = i4 & 63;
7526   rot = i5 & 63;
7527   t_bit = i3 & 128;
7528   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7529          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7530          mkU8(64 - rot))));
7531   if (from <= to) {
7532      mask = ~0ULL;
7533      mask = (mask >> from) & (mask << (63 - to));
7534      maskc = ~mask;
7535   } else {
7536      maskc = ~0ULL;
7537      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7538      mask = ~maskc;
7539   }
7540   assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7541          ), mkU64(mask)));
7542   if (t_bit == 0) {
7543      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7544                  mkU64(maskc)), mkexpr(result)));
7545   }
7546   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7547
7548   return "rxsbg";
7549}
7550
7551static const HChar *
7552s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7553{
7554   UChar from;
7555   UChar to;
7556   UChar rot;
7557   UChar t_bit;
7558   ULong mask;
7559   ULong maskc;
7560   IRTemp result = newTemp(Ity_I64);
7561   IRTemp op2 = newTemp(Ity_I64);
7562
7563   from = i3 & 63;
7564   to = i4 & 63;
7565   rot = i5 & 63;
7566   t_bit = i3 & 128;
7567   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7568          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7569          mkU8(64 - rot))));
7570   if (from <= to) {
7571      mask = ~0ULL;
7572      mask = (mask >> from) & (mask << (63 - to));
7573      maskc = ~mask;
7574   } else {
7575      maskc = ~0ULL;
7576      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7577      mask = ~maskc;
7578   }
7579   assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7580          ), mkU64(mask)));
7581   if (t_bit == 0) {
7582      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7583                  mkU64(maskc)), mkexpr(result)));
7584   }
7585   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7586
7587   return "rosbg";
7588}
7589
7590static const HChar *
7591s390_irgen_RISBGx(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
7592                  Bool set_cc)
7593{
7594   UChar from;
7595   UChar to;
7596   UChar rot;
7597   UChar z_bit;
7598   ULong mask;
7599   ULong maskc;
7600   IRTemp op2 = newTemp(Ity_I64);
7601   IRTemp result = newTemp(Ity_I64);
7602
7603   from = i3 & 63;
7604   to = i4 & 63;
7605   rot = i5 & 63;
7606   z_bit = i4 & 128;
7607   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7608          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7609          mkU8(64 - rot))));
7610   if (from <= to) {
7611      mask = ~0ULL;
7612      mask = (mask >> from) & (mask << (63 - to));
7613      maskc = ~mask;
7614   } else {
7615      maskc = ~0ULL;
7616      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7617      mask = ~maskc;
7618   }
7619   if (z_bit == 0) {
7620      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7621                  mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7622   } else {
7623      put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7624   }
7625   assign(result, get_gpr_dw0(r1));
7626   if (set_cc) {
7627      s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7628      return "risbg";
7629   }
7630
7631   return "risbgn";
7632}
7633
7634static const HChar *
7635s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7636{
7637   return s390_irgen_RISBGx(r1, r2, i3, i4, i5, True);
7638}
7639
7640static const HChar *
7641s390_irgen_RISBGN(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7642{
7643   return s390_irgen_RISBGx(r1, r2, i3, i4, i5, False);
7644}
7645
7646static IRExpr *
7647s390_irgen_RISBxG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
7648                  Bool high)
7649{
7650   UChar from;
7651   UChar to;
7652   UChar rot;
7653   UChar z_bit;
7654   UInt mask;
7655   UInt maskc;
7656   IRTemp op2 = newTemp(Ity_I32);
7657
7658   from = i3 & 31;
7659   to = i4 & 31;
7660   rot = i5 & 63;
7661   z_bit = i4 & 128;
7662   if (rot == 0) {
7663      assign(op2, high ? get_gpr_w0(r2) : get_gpr_w1(r2));
7664   } else if (rot == 32) {
7665      assign(op2, high ? get_gpr_w1(r2) : get_gpr_w0(r2));
7666   } else {
7667      assign(op2,
7668             unop(high ? Iop_64HIto32 : Iop_64to32,
7669                  binop(Iop_Or64,
7670                        binop(Iop_Shl64, get_gpr_dw0(r2), mkU8(rot)),
7671                        binop(Iop_Shr64, get_gpr_dw0(r2), mkU8(64 - rot)))));
7672   }
7673   if (from <= to) {
7674      mask = ~0U;
7675      mask = (mask >> from) & (mask << (31 - to));
7676      maskc = ~mask;
7677   } else {
7678      maskc = ~0U;
7679      maskc = (maskc >> (to + 1)) & (maskc << (32 - from));
7680      mask = ~maskc;
7681   }
7682   if (z_bit) {
7683      return binop(Iop_And32, mkexpr(op2), mkU32(mask));
7684   }
7685   return binop(Iop_Or32,
7686                binop(Iop_And32, high ? get_gpr_w0(r1) : get_gpr_w1(r1),
7687                      mkU32(maskc)),
7688                binop(Iop_And32, mkexpr(op2), mkU32(mask)));
7689}
7690
7691static const HChar *
7692s390_irgen_RISBHG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7693{
7694   put_gpr_w0(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, True));
7695   return "risbhg";
7696}
7697
7698static const HChar *
7699s390_irgen_RISBLG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7700{
7701   put_gpr_w1(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, False));
7702   return "risblg";
7703}
7704
7705static const HChar *
7706s390_irgen_SAR(UChar r1, UChar r2)
7707{
7708   put_ar_w0(r1, get_gpr_w1(r2));
7709   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
7710      s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7711
7712   return "sar";
7713}
7714
7715static const HChar *
7716s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7717{
7718   IRTemp p1 = newTemp(Ity_I64);
7719   IRTemp p2 = newTemp(Ity_I64);
7720   IRTemp op = newTemp(Ity_I64);
7721   IRTemp result = newTemp(Ity_I64);
7722   ULong sign_mask;
7723   IRTemp shift_amount = newTemp(Ity_I64);
7724
7725   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7726   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7727   assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7728          ));
7729   sign_mask = 1ULL << 63;
7730   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7731   assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
7732          unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7733          binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
7734   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7735   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7736   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7737
7738   return "slda";
7739}
7740
7741static const HChar *
7742s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7743{
7744   IRTemp p1 = newTemp(Ity_I64);
7745   IRTemp p2 = newTemp(Ity_I64);
7746   IRTemp result = newTemp(Ity_I64);
7747
7748   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7749   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7750   assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7751          mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7752          mkexpr(op2addr), mkU64(63)))));
7753   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7754   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7755
7756   return "sldl";
7757}
7758
7759static const HChar *
7760s390_irgen_SLA(UChar r1, IRTemp op2addr)
7761{
7762   IRTemp uop = newTemp(Ity_I32);
7763   IRTemp result = newTemp(Ity_I32);
7764   UInt sign_mask;
7765   IRTemp shift_amount = newTemp(Ity_I64);
7766   IRTemp op = newTemp(Ity_I32);
7767
7768   assign(op, get_gpr_w1(r1));
7769   assign(uop, get_gpr_w1(r1));
7770   sign_mask = 2147483648U;
7771   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7772   assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7773          unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7774          binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7775   put_gpr_w1(r1, mkexpr(result));
7776   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7777
7778   return "sla";
7779}
7780
7781static const HChar *
7782s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7783{
7784   IRTemp uop = newTemp(Ity_I32);
7785   IRTemp result = newTemp(Ity_I32);
7786   UInt sign_mask;
7787   IRTemp shift_amount = newTemp(Ity_I64);
7788   IRTemp op = newTemp(Ity_I32);
7789
7790   assign(op, get_gpr_w1(r3));
7791   assign(uop, get_gpr_w1(r3));
7792   sign_mask = 2147483648U;
7793   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7794   assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7795          unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7796          binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7797   put_gpr_w1(r1, mkexpr(result));
7798   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7799
7800   return "slak";
7801}
7802
7803static const HChar *
7804s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7805{
7806   IRTemp uop = newTemp(Ity_I64);
7807   IRTemp result = newTemp(Ity_I64);
7808   ULong sign_mask;
7809   IRTemp shift_amount = newTemp(Ity_I64);
7810   IRTemp op = newTemp(Ity_I64);
7811
7812   assign(op, get_gpr_dw0(r3));
7813   assign(uop, get_gpr_dw0(r3));
7814   sign_mask = 9223372036854775808ULL;
7815   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7816   assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7817          unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7818          binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7819   put_gpr_dw0(r1, mkexpr(result));
7820   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7821
7822   return "slag";
7823}
7824
7825static const HChar *
7826s390_irgen_SLL(UChar r1, IRTemp op2addr)
7827{
7828   put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7829              binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7830
7831   return "sll";
7832}
7833
7834static const HChar *
7835s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7836{
7837   put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7838              binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7839
7840   return "sllk";
7841}
7842
7843static const HChar *
7844s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7845{
7846   put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7847               binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7848
7849   return "sllg";
7850}
7851
7852static const HChar *
7853s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7854{
7855   IRTemp p1 = newTemp(Ity_I64);
7856   IRTemp p2 = newTemp(Ity_I64);
7857   IRTemp result = newTemp(Ity_I64);
7858
7859   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7860   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7861   assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7862          mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7863          mkexpr(op2addr), mkU64(63)))));
7864   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7865   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7866   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7867
7868   return "srda";
7869}
7870
7871static const HChar *
7872s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7873{
7874   IRTemp p1 = newTemp(Ity_I64);
7875   IRTemp p2 = newTemp(Ity_I64);
7876   IRTemp result = newTemp(Ity_I64);
7877
7878   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7879   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7880   assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7881          mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7882          mkexpr(op2addr), mkU64(63)))));
7883   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7884   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7885
7886   return "srdl";
7887}
7888
7889static const HChar *
7890s390_irgen_SRA(UChar r1, IRTemp op2addr)
7891{
7892   IRTemp result = newTemp(Ity_I32);
7893   IRTemp op = newTemp(Ity_I32);
7894
7895   assign(op, get_gpr_w1(r1));
7896   assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7897          mkexpr(op2addr), mkU64(63)))));
7898   put_gpr_w1(r1, mkexpr(result));
7899   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7900
7901   return "sra";
7902}
7903
7904static const HChar *
7905s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7906{
7907   IRTemp result = newTemp(Ity_I32);
7908   IRTemp op = newTemp(Ity_I32);
7909
7910   assign(op, get_gpr_w1(r3));
7911   assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7912          mkexpr(op2addr), mkU64(63)))));
7913   put_gpr_w1(r1, mkexpr(result));
7914   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7915
7916   return "srak";
7917}
7918
7919static const HChar *
7920s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7921{
7922   IRTemp result = newTemp(Ity_I64);
7923   IRTemp op = newTemp(Ity_I64);
7924
7925   assign(op, get_gpr_dw0(r3));
7926   assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7927          mkexpr(op2addr), mkU64(63)))));
7928   put_gpr_dw0(r1, mkexpr(result));
7929   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7930
7931   return "srag";
7932}
7933
7934static const HChar *
7935s390_irgen_SRL(UChar r1, IRTemp op2addr)
7936{
7937   IRTemp op = newTemp(Ity_I32);
7938
7939   assign(op, get_gpr_w1(r1));
7940   put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7941              mkexpr(op2addr), mkU64(63)))));
7942
7943   return "srl";
7944}
7945
7946static const HChar *
7947s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7948{
7949   IRTemp op = newTemp(Ity_I32);
7950
7951   assign(op, get_gpr_w1(r3));
7952   put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7953              mkexpr(op2addr), mkU64(63)))));
7954
7955   return "srlk";
7956}
7957
7958static const HChar *
7959s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7960{
7961   IRTemp op = newTemp(Ity_I64);
7962
7963   assign(op, get_gpr_dw0(r3));
7964   put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7965               mkexpr(op2addr), mkU64(63)))));
7966
7967   return "srlg";
7968}
7969
7970static const HChar *
7971s390_irgen_ST(UChar r1, IRTemp op2addr)
7972{
7973   store(mkexpr(op2addr), get_gpr_w1(r1));
7974
7975   return "st";
7976}
7977
7978static const HChar *
7979s390_irgen_STY(UChar r1, IRTemp op2addr)
7980{
7981   store(mkexpr(op2addr), get_gpr_w1(r1));
7982
7983   return "sty";
7984}
7985
7986static const HChar *
7987s390_irgen_STG(UChar r1, IRTemp op2addr)
7988{
7989   store(mkexpr(op2addr), get_gpr_dw0(r1));
7990
7991   return "stg";
7992}
7993
7994static const HChar *
7995s390_irgen_STRL(UChar r1, UInt i2)
7996{
7997   store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7998         get_gpr_w1(r1));
7999
8000   return "strl";
8001}
8002
8003static const HChar *
8004s390_irgen_STGRL(UChar r1, UInt i2)
8005{
8006   store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8007         get_gpr_dw0(r1));
8008
8009   return "stgrl";
8010}
8011
8012static const HChar *
8013s390_irgen_STC(UChar r1, IRTemp op2addr)
8014{
8015   store(mkexpr(op2addr), get_gpr_b7(r1));
8016
8017   return "stc";
8018}
8019
8020static const HChar *
8021s390_irgen_STCY(UChar r1, IRTemp op2addr)
8022{
8023   store(mkexpr(op2addr), get_gpr_b7(r1));
8024
8025   return "stcy";
8026}
8027
8028static const HChar *
8029s390_irgen_STCH(UChar r1, IRTemp op2addr)
8030{
8031   store(mkexpr(op2addr), get_gpr_b3(r1));
8032
8033   return "stch";
8034}
8035
8036static const HChar *
8037s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
8038{
8039   UChar mask;
8040   UChar n;
8041
8042   mask = (UChar)r3;
8043   n = 0;
8044   if ((mask & 8) != 0) {
8045      store(mkexpr(op2addr), get_gpr_b4(r1));
8046      n = n + 1;
8047   }
8048   if ((mask & 4) != 0) {
8049      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
8050      n = n + 1;
8051   }
8052   if ((mask & 2) != 0) {
8053      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
8054      n = n + 1;
8055   }
8056   if ((mask & 1) != 0) {
8057      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
8058   }
8059
8060   return "stcm";
8061}
8062
8063static const HChar *
8064s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
8065{
8066   UChar mask;
8067   UChar n;
8068
8069   mask = (UChar)r3;
8070   n = 0;
8071   if ((mask & 8) != 0) {
8072      store(mkexpr(op2addr), get_gpr_b4(r1));
8073      n = n + 1;
8074   }
8075   if ((mask & 4) != 0) {
8076      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
8077      n = n + 1;
8078   }
8079   if ((mask & 2) != 0) {
8080      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
8081      n = n + 1;
8082   }
8083   if ((mask & 1) != 0) {
8084      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
8085   }
8086
8087   return "stcmy";
8088}
8089
8090static const HChar *
8091s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
8092{
8093   UChar mask;
8094   UChar n;
8095
8096   mask = (UChar)r3;
8097   n = 0;
8098   if ((mask & 8) != 0) {
8099      store(mkexpr(op2addr), get_gpr_b0(r1));
8100      n = n + 1;
8101   }
8102   if ((mask & 4) != 0) {
8103      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
8104      n = n + 1;
8105   }
8106   if ((mask & 2) != 0) {
8107      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
8108      n = n + 1;
8109   }
8110   if ((mask & 1) != 0) {
8111      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
8112   }
8113
8114   return "stcmh";
8115}
8116
8117static const HChar *
8118s390_irgen_STH(UChar r1, IRTemp op2addr)
8119{
8120   store(mkexpr(op2addr), get_gpr_hw3(r1));
8121
8122   return "sth";
8123}
8124
8125static const HChar *
8126s390_irgen_STHY(UChar r1, IRTemp op2addr)
8127{
8128   store(mkexpr(op2addr), get_gpr_hw3(r1));
8129
8130   return "sthy";
8131}
8132
8133static const HChar *
8134s390_irgen_STHRL(UChar r1, UInt i2)
8135{
8136   store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8137         get_gpr_hw3(r1));
8138
8139   return "sthrl";
8140}
8141
8142static const HChar *
8143s390_irgen_STHH(UChar r1, IRTemp op2addr)
8144{
8145   store(mkexpr(op2addr), get_gpr_hw1(r1));
8146
8147   return "sthh";
8148}
8149
8150static const HChar *
8151s390_irgen_STFH(UChar r1, IRTemp op2addr)
8152{
8153   store(mkexpr(op2addr), get_gpr_w0(r1));
8154
8155   return "stfh";
8156}
8157
8158static const HChar *
8159s390_irgen_STOC(UChar r1, IRTemp op2addr)
8160{
8161   /* condition is checked in format handler */
8162   store(mkexpr(op2addr), get_gpr_w1(r1));
8163
8164   return "stoc";
8165}
8166
8167static const HChar *
8168s390_irgen_STOCG(UChar r1, IRTemp op2addr)
8169{
8170   /* condition is checked in format handler */
8171   store(mkexpr(op2addr), get_gpr_dw0(r1));
8172
8173   return "stocg";
8174}
8175
8176static const HChar *
8177s390_irgen_STPQ(UChar r1, IRTemp op2addr)
8178{
8179   store(mkexpr(op2addr), get_gpr_dw0(r1));
8180   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
8181
8182   return "stpq";
8183}
8184
8185static const HChar *
8186s390_irgen_STRVH(UChar r1, IRTemp op2addr)
8187{
8188   store(mkexpr(op2addr), get_gpr_b7(r1));
8189   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8190
8191   return "strvh";
8192}
8193
8194static const HChar *
8195s390_irgen_STRV(UChar r1, IRTemp op2addr)
8196{
8197   store(mkexpr(op2addr), get_gpr_b7(r1));
8198   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8199   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8200   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8201
8202   return "strv";
8203}
8204
8205static const HChar *
8206s390_irgen_STRVG(UChar r1, IRTemp op2addr)
8207{
8208   store(mkexpr(op2addr), get_gpr_b7(r1));
8209   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8210   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8211   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8212   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
8213   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
8214   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
8215   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
8216
8217   return "strvg";
8218}
8219
8220static const HChar *
8221s390_irgen_SR(UChar r1, UChar r2)
8222{
8223   IRTemp op1 = newTemp(Ity_I32);
8224   IRTemp op2 = newTemp(Ity_I32);
8225   IRTemp result = newTemp(Ity_I32);
8226
8227   assign(op1, get_gpr_w1(r1));
8228   assign(op2, get_gpr_w1(r2));
8229   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8230   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8231   put_gpr_w1(r1, mkexpr(result));
8232
8233   return "sr";
8234}
8235
8236static const HChar *
8237s390_irgen_SGR(UChar r1, UChar r2)
8238{
8239   IRTemp op1 = newTemp(Ity_I64);
8240   IRTemp op2 = newTemp(Ity_I64);
8241   IRTemp result = newTemp(Ity_I64);
8242
8243   assign(op1, get_gpr_dw0(r1));
8244   assign(op2, get_gpr_dw0(r2));
8245   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8246   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8247   put_gpr_dw0(r1, mkexpr(result));
8248
8249   return "sgr";
8250}
8251
8252static const HChar *
8253s390_irgen_SGFR(UChar r1, UChar r2)
8254{
8255   IRTemp op1 = newTemp(Ity_I64);
8256   IRTemp op2 = newTemp(Ity_I64);
8257   IRTemp result = newTemp(Ity_I64);
8258
8259   assign(op1, get_gpr_dw0(r1));
8260   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8261   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8262   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8263   put_gpr_dw0(r1, mkexpr(result));
8264
8265   return "sgfr";
8266}
8267
8268static const HChar *
8269s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8270{
8271   IRTemp op2 = newTemp(Ity_I32);
8272   IRTemp op3 = newTemp(Ity_I32);
8273   IRTemp result = newTemp(Ity_I32);
8274
8275   assign(op2, get_gpr_w1(r2));
8276   assign(op3, get_gpr_w1(r3));
8277   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8278   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8279   put_gpr_w1(r1, mkexpr(result));
8280
8281   return "srk";
8282}
8283
8284static const HChar *
8285s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8286{
8287   IRTemp op2 = newTemp(Ity_I64);
8288   IRTemp op3 = newTemp(Ity_I64);
8289   IRTemp result = newTemp(Ity_I64);
8290
8291   assign(op2, get_gpr_dw0(r2));
8292   assign(op3, get_gpr_dw0(r3));
8293   assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8294   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8295   put_gpr_dw0(r1, mkexpr(result));
8296
8297   return "sgrk";
8298}
8299
8300static const HChar *
8301s390_irgen_S(UChar r1, IRTemp op2addr)
8302{
8303   IRTemp op1 = newTemp(Ity_I32);
8304   IRTemp op2 = newTemp(Ity_I32);
8305   IRTemp result = newTemp(Ity_I32);
8306
8307   assign(op1, get_gpr_w1(r1));
8308   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8309   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8310   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8311   put_gpr_w1(r1, mkexpr(result));
8312
8313   return "s";
8314}
8315
8316static const HChar *
8317s390_irgen_SY(UChar r1, IRTemp op2addr)
8318{
8319   IRTemp op1 = newTemp(Ity_I32);
8320   IRTemp op2 = newTemp(Ity_I32);
8321   IRTemp result = newTemp(Ity_I32);
8322
8323   assign(op1, get_gpr_w1(r1));
8324   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8325   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8326   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8327   put_gpr_w1(r1, mkexpr(result));
8328
8329   return "sy";
8330}
8331
8332static const HChar *
8333s390_irgen_SG(UChar r1, IRTemp op2addr)
8334{
8335   IRTemp op1 = newTemp(Ity_I64);
8336   IRTemp op2 = newTemp(Ity_I64);
8337   IRTemp result = newTemp(Ity_I64);
8338
8339   assign(op1, get_gpr_dw0(r1));
8340   assign(op2, load(Ity_I64, mkexpr(op2addr)));
8341   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8342   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8343   put_gpr_dw0(r1, mkexpr(result));
8344
8345   return "sg";
8346}
8347
8348static const HChar *
8349s390_irgen_SGF(UChar r1, IRTemp op2addr)
8350{
8351   IRTemp op1 = newTemp(Ity_I64);
8352   IRTemp op2 = newTemp(Ity_I64);
8353   IRTemp result = newTemp(Ity_I64);
8354
8355   assign(op1, get_gpr_dw0(r1));
8356   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8357   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8358   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8359   put_gpr_dw0(r1, mkexpr(result));
8360
8361   return "sgf";
8362}
8363
8364static const HChar *
8365s390_irgen_SH(UChar r1, IRTemp op2addr)
8366{
8367   IRTemp op1 = newTemp(Ity_I32);
8368   IRTemp op2 = newTemp(Ity_I32);
8369   IRTemp result = newTemp(Ity_I32);
8370
8371   assign(op1, get_gpr_w1(r1));
8372   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8373   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8374   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8375   put_gpr_w1(r1, mkexpr(result));
8376
8377   return "sh";
8378}
8379
8380static const HChar *
8381s390_irgen_SHY(UChar r1, IRTemp op2addr)
8382{
8383   IRTemp op1 = newTemp(Ity_I32);
8384   IRTemp op2 = newTemp(Ity_I32);
8385   IRTemp result = newTemp(Ity_I32);
8386
8387   assign(op1, get_gpr_w1(r1));
8388   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8389   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8390   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8391   put_gpr_w1(r1, mkexpr(result));
8392
8393   return "shy";
8394}
8395
8396static const HChar *
8397s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8398{
8399   IRTemp op2 = newTemp(Ity_I32);
8400   IRTemp op3 = newTemp(Ity_I32);
8401   IRTemp result = newTemp(Ity_I32);
8402
8403   assign(op2, get_gpr_w0(r1));
8404   assign(op3, get_gpr_w0(r2));
8405   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8406   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8407   put_gpr_w0(r1, mkexpr(result));
8408
8409   return "shhhr";
8410}
8411
8412static const HChar *
8413s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8414{
8415   IRTemp op2 = newTemp(Ity_I32);
8416   IRTemp op3 = newTemp(Ity_I32);
8417   IRTemp result = newTemp(Ity_I32);
8418
8419   assign(op2, get_gpr_w0(r1));
8420   assign(op3, get_gpr_w1(r2));
8421   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8422   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8423   put_gpr_w0(r1, mkexpr(result));
8424
8425   return "shhlr";
8426}
8427
8428static const HChar *
8429s390_irgen_SLR(UChar r1, UChar r2)
8430{
8431   IRTemp op1 = newTemp(Ity_I32);
8432   IRTemp op2 = newTemp(Ity_I32);
8433   IRTemp result = newTemp(Ity_I32);
8434
8435   assign(op1, get_gpr_w1(r1));
8436   assign(op2, get_gpr_w1(r2));
8437   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8438   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8439   put_gpr_w1(r1, mkexpr(result));
8440
8441   return "slr";
8442}
8443
8444static const HChar *
8445s390_irgen_SLGR(UChar r1, UChar r2)
8446{
8447   IRTemp op1 = newTemp(Ity_I64);
8448   IRTemp op2 = newTemp(Ity_I64);
8449   IRTemp result = newTemp(Ity_I64);
8450
8451   assign(op1, get_gpr_dw0(r1));
8452   assign(op2, get_gpr_dw0(r2));
8453   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8454   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8455   put_gpr_dw0(r1, mkexpr(result));
8456
8457   return "slgr";
8458}
8459
8460static const HChar *
8461s390_irgen_SLGFR(UChar r1, UChar r2)
8462{
8463   IRTemp op1 = newTemp(Ity_I64);
8464   IRTemp op2 = newTemp(Ity_I64);
8465   IRTemp result = newTemp(Ity_I64);
8466
8467   assign(op1, get_gpr_dw0(r1));
8468   assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8469   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8470   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8471   put_gpr_dw0(r1, mkexpr(result));
8472
8473   return "slgfr";
8474}
8475
8476static const HChar *
8477s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8478{
8479   IRTemp op2 = newTemp(Ity_I32);
8480   IRTemp op3 = newTemp(Ity_I32);
8481   IRTemp result = newTemp(Ity_I32);
8482
8483   assign(op2, get_gpr_w1(r2));
8484   assign(op3, get_gpr_w1(r3));
8485   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8486   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8487   put_gpr_w1(r1, mkexpr(result));
8488
8489   return "slrk";
8490}
8491
8492static const HChar *
8493s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8494{
8495   IRTemp op2 = newTemp(Ity_I64);
8496   IRTemp op3 = newTemp(Ity_I64);
8497   IRTemp result = newTemp(Ity_I64);
8498
8499   assign(op2, get_gpr_dw0(r2));
8500   assign(op3, get_gpr_dw0(r3));
8501   assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8502   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8503   put_gpr_dw0(r1, mkexpr(result));
8504
8505   return "slgrk";
8506}
8507
8508static const HChar *
8509s390_irgen_SL(UChar r1, IRTemp op2addr)
8510{
8511   IRTemp op1 = newTemp(Ity_I32);
8512   IRTemp op2 = newTemp(Ity_I32);
8513   IRTemp result = newTemp(Ity_I32);
8514
8515   assign(op1, get_gpr_w1(r1));
8516   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8517   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8518   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8519   put_gpr_w1(r1, mkexpr(result));
8520
8521   return "sl";
8522}
8523
8524static const HChar *
8525s390_irgen_SLY(UChar r1, IRTemp op2addr)
8526{
8527   IRTemp op1 = newTemp(Ity_I32);
8528   IRTemp op2 = newTemp(Ity_I32);
8529   IRTemp result = newTemp(Ity_I32);
8530
8531   assign(op1, get_gpr_w1(r1));
8532   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8533   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8534   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8535   put_gpr_w1(r1, mkexpr(result));
8536
8537   return "sly";
8538}
8539
8540static const HChar *
8541s390_irgen_SLG(UChar r1, IRTemp op2addr)
8542{
8543   IRTemp op1 = newTemp(Ity_I64);
8544   IRTemp op2 = newTemp(Ity_I64);
8545   IRTemp result = newTemp(Ity_I64);
8546
8547   assign(op1, get_gpr_dw0(r1));
8548   assign(op2, load(Ity_I64, mkexpr(op2addr)));
8549   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8550   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8551   put_gpr_dw0(r1, mkexpr(result));
8552
8553   return "slg";
8554}
8555
8556static const HChar *
8557s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8558{
8559   IRTemp op1 = newTemp(Ity_I64);
8560   IRTemp op2 = newTemp(Ity_I64);
8561   IRTemp result = newTemp(Ity_I64);
8562
8563   assign(op1, get_gpr_dw0(r1));
8564   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8565   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8566   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8567   put_gpr_dw0(r1, mkexpr(result));
8568
8569   return "slgf";
8570}
8571
8572static const HChar *
8573s390_irgen_SLFI(UChar r1, UInt i2)
8574{
8575   IRTemp op1 = newTemp(Ity_I32);
8576   UInt op2;
8577   IRTemp result = newTemp(Ity_I32);
8578
8579   assign(op1, get_gpr_w1(r1));
8580   op2 = i2;
8581   assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8582   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8583                       mkU32(op2)));
8584   put_gpr_w1(r1, mkexpr(result));
8585
8586   return "slfi";
8587}
8588
8589static const HChar *
8590s390_irgen_SLGFI(UChar r1, UInt i2)
8591{
8592   IRTemp op1 = newTemp(Ity_I64);
8593   ULong op2;
8594   IRTemp result = newTemp(Ity_I64);
8595
8596   assign(op1, get_gpr_dw0(r1));
8597   op2 = (ULong)i2;
8598   assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8599   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8600                       mkU64(op2)));
8601   put_gpr_dw0(r1, mkexpr(result));
8602
8603   return "slgfi";
8604}
8605
8606static const HChar *
8607s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8608{
8609   IRTemp op2 = newTemp(Ity_I32);
8610   IRTemp op3 = newTemp(Ity_I32);
8611   IRTemp result = newTemp(Ity_I32);
8612
8613   assign(op2, get_gpr_w0(r1));
8614   assign(op3, get_gpr_w0(r2));
8615   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8616   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8617   put_gpr_w0(r1, mkexpr(result));
8618
8619   return "slhhhr";
8620}
8621
8622static const HChar *
8623s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8624{
8625   IRTemp op2 = newTemp(Ity_I32);
8626   IRTemp op3 = newTemp(Ity_I32);
8627   IRTemp result = newTemp(Ity_I32);
8628
8629   assign(op2, get_gpr_w0(r1));
8630   assign(op3, get_gpr_w1(r2));
8631   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8632   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8633   put_gpr_w0(r1, mkexpr(result));
8634
8635   return "slhhlr";
8636}
8637
8638static const HChar *
8639s390_irgen_SLBR(UChar r1, UChar r2)
8640{
8641   IRTemp op1 = newTemp(Ity_I32);
8642   IRTemp op2 = newTemp(Ity_I32);
8643   IRTemp result = newTemp(Ity_I32);
8644   IRTemp borrow_in = newTemp(Ity_I32);
8645
8646   assign(op1, get_gpr_w1(r1));
8647   assign(op2, get_gpr_w1(r2));
8648   assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8649          s390_call_calculate_cc(), mkU8(1))));
8650   assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8651          mkexpr(borrow_in)));
8652   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8653   put_gpr_w1(r1, mkexpr(result));
8654
8655   return "slbr";
8656}
8657
8658static const HChar *
8659s390_irgen_SLBGR(UChar r1, UChar r2)
8660{
8661   IRTemp op1 = newTemp(Ity_I64);
8662   IRTemp op2 = newTemp(Ity_I64);
8663   IRTemp result = newTemp(Ity_I64);
8664   IRTemp borrow_in = newTemp(Ity_I64);
8665
8666   assign(op1, get_gpr_dw0(r1));
8667   assign(op2, get_gpr_dw0(r2));
8668   assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8669          binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8670   assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8671          mkexpr(borrow_in)));
8672   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8673   put_gpr_dw0(r1, mkexpr(result));
8674
8675   return "slbgr";
8676}
8677
8678static const HChar *
8679s390_irgen_SLB(UChar r1, IRTemp op2addr)
8680{
8681   IRTemp op1 = newTemp(Ity_I32);
8682   IRTemp op2 = newTemp(Ity_I32);
8683   IRTemp result = newTemp(Ity_I32);
8684   IRTemp borrow_in = newTemp(Ity_I32);
8685
8686   assign(op1, get_gpr_w1(r1));
8687   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8688   assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8689          s390_call_calculate_cc(), mkU8(1))));
8690   assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8691          mkexpr(borrow_in)));
8692   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8693   put_gpr_w1(r1, mkexpr(result));
8694
8695   return "slb";
8696}
8697
8698static const HChar *
8699s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8700{
8701   IRTemp op1 = newTemp(Ity_I64);
8702   IRTemp op2 = newTemp(Ity_I64);
8703   IRTemp result = newTemp(Ity_I64);
8704   IRTemp borrow_in = newTemp(Ity_I64);
8705
8706   assign(op1, get_gpr_dw0(r1));
8707   assign(op2, load(Ity_I64, mkexpr(op2addr)));
8708   assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8709          binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8710   assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8711          mkexpr(borrow_in)));
8712   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8713   put_gpr_dw0(r1, mkexpr(result));
8714
8715   return "slbg";
8716}
8717
8718static const HChar *
8719s390_irgen_SVC(UChar i)
8720{
8721   IRTemp sysno = newTemp(Ity_I64);
8722
8723   if (i != 0) {
8724      assign(sysno, mkU64(i));
8725   } else {
8726      assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8727   }
8728   system_call(mkexpr(sysno));
8729
8730   return "svc";
8731}
8732
8733static const HChar *
8734s390_irgen_TM(UChar i2, IRTemp op1addr)
8735{
8736   UChar mask;
8737   IRTemp value = newTemp(Ity_I8);
8738
8739   mask = i2;
8740   assign(value, load(Ity_I8, mkexpr(op1addr)));
8741   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8742                       mkU8(mask)));
8743
8744   return "tm";
8745}
8746
8747static const HChar *
8748s390_irgen_TMY(UChar i2, IRTemp op1addr)
8749{
8750   UChar mask;
8751   IRTemp value = newTemp(Ity_I8);
8752
8753   mask = i2;
8754   assign(value, load(Ity_I8, mkexpr(op1addr)));
8755   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8756                       mkU8(mask)));
8757
8758   return "tmy";
8759}
8760
8761static const HChar *
8762s390_irgen_TMHH(UChar r1, UShort i2)
8763{
8764   UShort mask;
8765   IRTemp value = newTemp(Ity_I16);
8766
8767   mask = i2;
8768   assign(value, get_gpr_hw0(r1));
8769   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8770                       mkU16(mask)));
8771
8772   return "tmhh";
8773}
8774
8775static const HChar *
8776s390_irgen_TMHL(UChar r1, UShort i2)
8777{
8778   UShort mask;
8779   IRTemp value = newTemp(Ity_I16);
8780
8781   mask = i2;
8782   assign(value, get_gpr_hw1(r1));
8783   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8784                       mkU16(mask)));
8785
8786   return "tmhl";
8787}
8788
8789static const HChar *
8790s390_irgen_TMLH(UChar r1, UShort i2)
8791{
8792   UShort mask;
8793   IRTemp value = newTemp(Ity_I16);
8794
8795   mask = i2;
8796   assign(value, get_gpr_hw2(r1));
8797   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8798                       mkU16(mask)));
8799
8800   return "tmlh";
8801}
8802
8803static const HChar *
8804s390_irgen_TMLL(UChar r1, UShort i2)
8805{
8806   UShort mask;
8807   IRTemp value = newTemp(Ity_I16);
8808
8809   mask = i2;
8810   assign(value, get_gpr_hw3(r1));
8811   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8812                       mkU16(mask)));
8813
8814   return "tmll";
8815}
8816
8817static const HChar *
8818s390_irgen_EFPC(UChar r1)
8819{
8820   put_gpr_w1(r1, get_fpc_w0());
8821
8822   return "efpc";
8823}
8824
8825static const HChar *
8826s390_irgen_LER(UChar r1, UChar r2)
8827{
8828   put_fpr_w0(r1, get_fpr_w0(r2));
8829
8830   return "ler";
8831}
8832
8833static const HChar *
8834s390_irgen_LDR(UChar r1, UChar r2)
8835{
8836   put_fpr_dw0(r1, get_fpr_dw0(r2));
8837
8838   return "ldr";
8839}
8840
8841static const HChar *
8842s390_irgen_LDER(UChar r1, UChar r2)
8843{
8844   put_fpr_dw0(r1, mkF64i(0x0));
8845   put_fpr_w0(r1, get_fpr_w0(r2));
8846
8847   return "lder";
8848}
8849
8850static const HChar *
8851s390_irgen_LXR(UChar r1, UChar r2)
8852{
8853   put_fpr_dw0(r1, get_fpr_dw0(r2));
8854   put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8855
8856   return "lxr";
8857}
8858
8859static const HChar *
8860s390_irgen_LE(UChar r1, IRTemp op2addr)
8861{
8862   put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8863
8864   return "le";
8865}
8866
8867static const HChar *
8868s390_irgen_LD(UChar r1, IRTemp op2addr)
8869{
8870   put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8871
8872   return "ld";
8873}
8874
8875static const HChar *
8876s390_irgen_LDE(UChar r1, IRTemp op2addr)
8877{
8878   put_fpr_dw0(r1, mkF64i(0x0));
8879   put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8880
8881   return "lde";
8882}
8883
8884static const HChar *
8885s390_irgen_LEY(UChar r1, IRTemp op2addr)
8886{
8887   put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8888
8889   return "ley";
8890}
8891
8892static const HChar *
8893s390_irgen_LDY(UChar r1, IRTemp op2addr)
8894{
8895   put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8896
8897   return "ldy";
8898}
8899
8900static const HChar *
8901s390_irgen_LFPC(IRTemp op2addr)
8902{
8903   put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8904
8905   return "lfpc";
8906}
8907
8908static const HChar *
8909s390_irgen_LZER(UChar r1)
8910{
8911   put_fpr_w0(r1, mkF32i(0x0));
8912
8913   return "lzer";
8914}
8915
8916static const HChar *
8917s390_irgen_LZDR(UChar r1)
8918{
8919   put_fpr_dw0(r1, mkF64i(0x0));
8920
8921   return "lzdr";
8922}
8923
8924static const HChar *
8925s390_irgen_LZXR(UChar r1)
8926{
8927   put_fpr_dw0(r1, mkF64i(0x0));
8928   put_fpr_dw0(r1 + 2, mkF64i(0x0));
8929
8930   return "lzxr";
8931}
8932
8933static const HChar *
8934s390_irgen_SRNM(IRTemp op2addr)
8935{
8936   UInt input_mask, fpc_mask;
8937
8938   input_mask = 3;
8939   fpc_mask = s390_host_has_fpext ? 7 : 3;
8940
8941   put_fpc_w0(binop(Iop_Or32,
8942                    binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8943                    binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8944                          mkU32(input_mask))));
8945   return "srnm";
8946}
8947
8948static const HChar *
8949s390_irgen_SRNMB(IRTemp op2addr)
8950{
8951   UInt input_mask, fpc_mask;
8952
8953   input_mask = 7;
8954   fpc_mask = 7;
8955
8956   put_fpc_w0(binop(Iop_Or32,
8957                    binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8958                    binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8959                          mkU32(input_mask))));
8960   return "srnmb";
8961}
8962
8963static void
8964s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8965{
8966   if (b2 == 0) {  /* This is the typical case */
8967      if (d2 > 3) {
8968         if (s390_host_has_fpext && d2 == 7) {
8969            /* ok */
8970         } else {
8971            emulation_warning(EmWarn_S390X_invalid_rounding);
8972            d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
8973         }
8974      }
8975   }
8976
8977   s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8978}
8979
8980/* Wrapper to validate the parameter as in SRNMB is not required, as all
8981   the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8982static const HChar *
8983s390_irgen_SRNMT(IRTemp op2addr)
8984{
8985   UInt input_mask, fpc_mask;
8986
8987   input_mask = 7;
8988   fpc_mask = 0x70;
8989
8990   /* fpc[25:27] <- op2addr[61:63]
8991      fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8992   put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8993                    binop(Iop_Shl32, binop(Iop_And32,
8994                                           unop(Iop_64to32, mkexpr(op2addr)),
8995                                           mkU32(input_mask)), mkU8(4))));
8996   return "srnmt";
8997}
8998
8999
9000static const HChar *
9001s390_irgen_SFPC(UChar r1)
9002{
9003   put_fpc_w0(get_gpr_w1(r1));
9004
9005   return "sfpc";
9006}
9007
9008static const HChar *
9009s390_irgen_STE(UChar r1, IRTemp op2addr)
9010{
9011   store(mkexpr(op2addr), get_fpr_w0(r1));
9012
9013   return "ste";
9014}
9015
9016static const HChar *
9017s390_irgen_STD(UChar r1, IRTemp op2addr)
9018{
9019   store(mkexpr(op2addr), get_fpr_dw0(r1));
9020
9021   return "std";
9022}
9023
9024static const HChar *
9025s390_irgen_STEY(UChar r1, IRTemp op2addr)
9026{
9027   store(mkexpr(op2addr), get_fpr_w0(r1));
9028
9029   return "stey";
9030}
9031
9032static const HChar *
9033s390_irgen_STDY(UChar r1, IRTemp op2addr)
9034{
9035   store(mkexpr(op2addr), get_fpr_dw0(r1));
9036
9037   return "stdy";
9038}
9039
9040static const HChar *
9041s390_irgen_STFPC(IRTemp op2addr)
9042{
9043   store(mkexpr(op2addr), get_fpc_w0());
9044
9045   return "stfpc";
9046}
9047
9048static const HChar *
9049s390_irgen_AEBR(UChar r1, UChar r2)
9050{
9051   IRTemp op1 = newTemp(Ity_F32);
9052   IRTemp op2 = newTemp(Ity_F32);
9053   IRTemp result = newTemp(Ity_F32);
9054   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9055
9056   assign(op1, get_fpr_w0(r1));
9057   assign(op2, get_fpr_w0(r2));
9058   assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
9059          mkexpr(op2)));
9060   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9061   put_fpr_w0(r1, mkexpr(result));
9062
9063   return "aebr";
9064}
9065
9066static const HChar *
9067s390_irgen_ADBR(UChar r1, UChar r2)
9068{
9069   IRTemp op1 = newTemp(Ity_F64);
9070   IRTemp op2 = newTemp(Ity_F64);
9071   IRTemp result = newTemp(Ity_F64);
9072   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9073
9074   assign(op1, get_fpr_dw0(r1));
9075   assign(op2, get_fpr_dw0(r2));
9076   assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
9077          mkexpr(op2)));
9078   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9079   put_fpr_dw0(r1, mkexpr(result));
9080
9081   return "adbr";
9082}
9083
9084static const HChar *
9085s390_irgen_AEB(UChar r1, IRTemp op2addr)
9086{
9087   IRTemp op1 = newTemp(Ity_F32);
9088   IRTemp op2 = newTemp(Ity_F32);
9089   IRTemp result = newTemp(Ity_F32);
9090   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9091
9092   assign(op1, get_fpr_w0(r1));
9093   assign(op2, load(Ity_F32, mkexpr(op2addr)));
9094   assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
9095          mkexpr(op2)));
9096   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9097   put_fpr_w0(r1, mkexpr(result));
9098
9099   return "aeb";
9100}
9101
9102static const HChar *
9103s390_irgen_ADB(UChar r1, IRTemp op2addr)
9104{
9105   IRTemp op1 = newTemp(Ity_F64);
9106   IRTemp op2 = newTemp(Ity_F64);
9107   IRTemp result = newTemp(Ity_F64);
9108   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9109
9110   assign(op1, get_fpr_dw0(r1));
9111   assign(op2, load(Ity_F64, mkexpr(op2addr)));
9112   assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
9113          mkexpr(op2)));
9114   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9115   put_fpr_dw0(r1, mkexpr(result));
9116
9117   return "adb";
9118}
9119
9120static const HChar *
9121s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
9122                 UChar r1, UChar r2)
9123{
9124   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9125      emulation_warning(EmWarn_S390X_fpext_rounding);
9126      m3 = S390_BFP_ROUND_PER_FPC;
9127   }
9128   IRTemp op2 = newTemp(Ity_I32);
9129
9130   assign(op2, get_gpr_w1(r2));
9131   put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9132                        mkexpr(op2)));
9133
9134   return "cefbr";
9135}
9136
9137static const HChar *
9138s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
9139                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9140{
9141   IRTemp op2 = newTemp(Ity_I32);
9142
9143   assign(op2, get_gpr_w1(r2));
9144   put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
9145
9146   return "cdfbr";
9147}
9148
9149static const HChar *
9150s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
9151                 UChar r1, UChar r2)
9152{
9153   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9154      emulation_warning(EmWarn_S390X_fpext_rounding);
9155      m3 = S390_BFP_ROUND_PER_FPC;
9156   }
9157   IRTemp op2 = newTemp(Ity_I64);
9158
9159   assign(op2, get_gpr_dw0(r2));
9160   put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9161                        mkexpr(op2)));
9162
9163   return "cegbr";
9164}
9165
9166static const HChar *
9167s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
9168                 UChar r1, UChar r2)
9169{
9170   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9171      emulation_warning(EmWarn_S390X_fpext_rounding);
9172      m3 = S390_BFP_ROUND_PER_FPC;
9173   }
9174   IRTemp op2 = newTemp(Ity_I64);
9175
9176   assign(op2, get_gpr_dw0(r2));
9177   put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
9178                         mkexpr(op2)));
9179
9180   return "cdgbr";
9181}
9182
9183static const HChar *
9184s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
9185                  UChar r1, UChar r2)
9186{
9187   if (! s390_host_has_fpext) {
9188      emulation_failure(EmFail_S390X_fpext);
9189   } else {
9190      IRTemp op2 = newTemp(Ity_I32);
9191
9192      assign(op2, get_gpr_w1(r2));
9193      put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9194                           mkexpr(op2)));
9195   }
9196   return "celfbr";
9197}
9198
9199static const HChar *
9200s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
9201                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9202{
9203   if (! s390_host_has_fpext) {
9204      emulation_failure(EmFail_S390X_fpext);
9205   } else {
9206      IRTemp op2 = newTemp(Ity_I32);
9207
9208      assign(op2, get_gpr_w1(r2));
9209      put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
9210   }
9211   return "cdlfbr";
9212}
9213
9214static const HChar *
9215s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
9216                  UChar r1, UChar r2)
9217{
9218   if (! s390_host_has_fpext) {
9219      emulation_failure(EmFail_S390X_fpext);
9220   } else {
9221      IRTemp op2 = newTemp(Ity_I64);
9222
9223      assign(op2, get_gpr_dw0(r2));
9224      put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9225                           mkexpr(op2)));
9226   }
9227   return "celgbr";
9228}
9229
9230static const HChar *
9231s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
9232                  UChar r1, UChar r2)
9233{
9234   if (! s390_host_has_fpext) {
9235      emulation_failure(EmFail_S390X_fpext);
9236   } else {
9237      IRTemp op2 = newTemp(Ity_I64);
9238
9239      assign(op2, get_gpr_dw0(r2));
9240      put_fpr_dw0(r1, binop(Iop_I64UtoF64,
9241                            mkexpr(encode_bfp_rounding_mode(m3)),
9242                            mkexpr(op2)));
9243   }
9244   return "cdlgbr";
9245}
9246
9247static const HChar *
9248s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9249                  UChar r1, UChar r2)
9250{
9251   if (! s390_host_has_fpext) {
9252      emulation_failure(EmFail_S390X_fpext);
9253   } else {
9254      IRTemp op = newTemp(Ity_F32);
9255      IRTemp result = newTemp(Ity_I32);
9256      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9257
9258      assign(op, get_fpr_w0(r2));
9259      assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
9260                           mkexpr(op)));
9261      put_gpr_w1(r1, mkexpr(result));
9262      s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
9263   }
9264   return "clfebr";
9265}
9266
9267static const HChar *
9268s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9269                  UChar r1, UChar r2)
9270{
9271   if (! s390_host_has_fpext) {
9272      emulation_failure(EmFail_S390X_fpext);
9273   } else {
9274      IRTemp op = newTemp(Ity_F64);
9275      IRTemp result = newTemp(Ity_I32);
9276      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9277
9278      assign(op, get_fpr_dw0(r2));
9279      assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
9280                           mkexpr(op)));
9281      put_gpr_w1(r1, mkexpr(result));
9282      s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
9283   }
9284   return "clfdbr";
9285}
9286
9287static const HChar *
9288s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9289                  UChar r1, UChar r2)
9290{
9291   if (! s390_host_has_fpext) {
9292      emulation_failure(EmFail_S390X_fpext);
9293   } else {
9294      IRTemp op = newTemp(Ity_F32);
9295      IRTemp result = newTemp(Ity_I64);
9296      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9297
9298      assign(op, get_fpr_w0(r2));
9299      assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
9300                           mkexpr(op)));
9301      put_gpr_dw0(r1, mkexpr(result));
9302      s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
9303   }
9304   return "clgebr";
9305}
9306
9307static const HChar *
9308s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9309                  UChar r1, UChar r2)
9310{
9311   if (! s390_host_has_fpext) {
9312      emulation_failure(EmFail_S390X_fpext);
9313   } else {
9314      IRTemp op = newTemp(Ity_F64);
9315      IRTemp result = newTemp(Ity_I64);
9316      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9317
9318      assign(op, get_fpr_dw0(r2));
9319      assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
9320                           mkexpr(op)));
9321      put_gpr_dw0(r1, mkexpr(result));
9322      s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
9323   }
9324   return "clgdbr";
9325}
9326
9327static const HChar *
9328s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9329                 UChar r1, UChar r2)
9330{
9331   IRTemp op = newTemp(Ity_F32);
9332   IRTemp result = newTemp(Ity_I32);
9333   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9334
9335   assign(op, get_fpr_w0(r2));
9336   assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
9337          mkexpr(op)));
9338   put_gpr_w1(r1, mkexpr(result));
9339   s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
9340
9341   return "cfebr";
9342}
9343
9344static const HChar *
9345s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9346                 UChar r1, UChar r2)
9347{
9348   IRTemp op = newTemp(Ity_F64);
9349   IRTemp result = newTemp(Ity_I32);
9350   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9351
9352   assign(op, get_fpr_dw0(r2));
9353   assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
9354          mkexpr(op)));
9355   put_gpr_w1(r1, mkexpr(result));
9356   s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
9357
9358   return "cfdbr";
9359}
9360
9361static const HChar *
9362s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9363                 UChar r1, UChar r2)
9364{
9365   IRTemp op = newTemp(Ity_F32);
9366   IRTemp result = newTemp(Ity_I64);
9367   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9368
9369   assign(op, get_fpr_w0(r2));
9370   assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
9371          mkexpr(op)));
9372   put_gpr_dw0(r1, mkexpr(result));
9373   s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
9374
9375   return "cgebr";
9376}
9377
9378static const HChar *
9379s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9380                 UChar r1, UChar r2)
9381{
9382   IRTemp op = newTemp(Ity_F64);
9383   IRTemp result = newTemp(Ity_I64);
9384   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9385
9386   assign(op, get_fpr_dw0(r2));
9387   assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
9388          mkexpr(op)));
9389   put_gpr_dw0(r1, mkexpr(result));
9390   s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
9391
9392   return "cgdbr";
9393}
9394
9395static const HChar *
9396s390_irgen_DEBR(UChar r1, UChar r2)
9397{
9398   IRTemp op1 = newTemp(Ity_F32);
9399   IRTemp op2 = newTemp(Ity_F32);
9400   IRTemp result = newTemp(Ity_F32);
9401   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9402
9403   assign(op1, get_fpr_w0(r1));
9404   assign(op2, get_fpr_w0(r2));
9405   assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
9406          mkexpr(op2)));
9407   put_fpr_w0(r1, mkexpr(result));
9408
9409   return "debr";
9410}
9411
9412static const HChar *
9413s390_irgen_DDBR(UChar r1, UChar r2)
9414{
9415   IRTemp op1 = newTemp(Ity_F64);
9416   IRTemp op2 = newTemp(Ity_F64);
9417   IRTemp result = newTemp(Ity_F64);
9418   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9419
9420   assign(op1, get_fpr_dw0(r1));
9421   assign(op2, get_fpr_dw0(r2));
9422   assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
9423          mkexpr(op2)));
9424   put_fpr_dw0(r1, mkexpr(result));
9425
9426   return "ddbr";
9427}
9428
9429static const HChar *
9430s390_irgen_DEB(UChar r1, IRTemp op2addr)
9431{
9432   IRTemp op1 = newTemp(Ity_F32);
9433   IRTemp op2 = newTemp(Ity_F32);
9434   IRTemp result = newTemp(Ity_F32);
9435   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9436
9437   assign(op1, get_fpr_w0(r1));
9438   assign(op2, load(Ity_F32, mkexpr(op2addr)));
9439   assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
9440          mkexpr(op2)));
9441   put_fpr_w0(r1, mkexpr(result));
9442
9443   return "deb";
9444}
9445
9446static const HChar *
9447s390_irgen_DDB(UChar r1, IRTemp op2addr)
9448{
9449   IRTemp op1 = newTemp(Ity_F64);
9450   IRTemp op2 = newTemp(Ity_F64);
9451   IRTemp result = newTemp(Ity_F64);
9452   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9453
9454   assign(op1, get_fpr_dw0(r1));
9455   assign(op2, load(Ity_F64, mkexpr(op2addr)));
9456   assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
9457          mkexpr(op2)));
9458   put_fpr_dw0(r1, mkexpr(result));
9459
9460   return "ddb";
9461}
9462
9463static const HChar *
9464s390_irgen_LTEBR(UChar r1, UChar r2)
9465{
9466   IRTemp result = newTemp(Ity_F32);
9467
9468   assign(result, get_fpr_w0(r2));
9469   put_fpr_w0(r1, mkexpr(result));
9470   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9471
9472   return "ltebr";
9473}
9474
9475static const HChar *
9476s390_irgen_LTDBR(UChar r1, UChar r2)
9477{
9478   IRTemp result = newTemp(Ity_F64);
9479
9480   assign(result, get_fpr_dw0(r2));
9481   put_fpr_dw0(r1, mkexpr(result));
9482   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9483
9484   return "ltdbr";
9485}
9486
9487static const HChar *
9488s390_irgen_LCEBR(UChar r1, UChar r2)
9489{
9490   IRTemp result = newTemp(Ity_F32);
9491
9492   assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9493   put_fpr_w0(r1, mkexpr(result));
9494   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9495
9496   return "lcebr";
9497}
9498
9499static const HChar *
9500s390_irgen_LCDBR(UChar r1, UChar r2)
9501{
9502   IRTemp result = newTemp(Ity_F64);
9503
9504   assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9505   put_fpr_dw0(r1, mkexpr(result));
9506   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9507
9508   return "lcdbr";
9509}
9510
9511static const HChar *
9512s390_irgen_LDEBR(UChar r1, UChar r2)
9513{
9514   IRTemp op = newTemp(Ity_F32);
9515
9516   assign(op, get_fpr_w0(r2));
9517   put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9518
9519   return "ldebr";
9520}
9521
9522static const HChar *
9523s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9524{
9525   IRTemp op = newTemp(Ity_F32);
9526
9527   assign(op, load(Ity_F32, mkexpr(op2addr)));
9528   put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9529
9530   return "ldeb";
9531}
9532
9533static const HChar *
9534s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9535                 UChar r1, UChar r2)
9536{
9537   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9538      emulation_warning(EmWarn_S390X_fpext_rounding);
9539      m3 = S390_BFP_ROUND_PER_FPC;
9540   }
9541   IRTemp op = newTemp(Ity_F64);
9542
9543   assign(op, get_fpr_dw0(r2));
9544   put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
9545                        mkexpr(op)));
9546
9547   return "ledbr";
9548}
9549
9550static const HChar *
9551s390_irgen_MEEBR(UChar r1, UChar r2)
9552{
9553   IRTemp op1 = newTemp(Ity_F32);
9554   IRTemp op2 = newTemp(Ity_F32);
9555   IRTemp result = newTemp(Ity_F32);
9556   IRRoundingMode rounding_mode =
9557      encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9558
9559   assign(op1, get_fpr_w0(r1));
9560   assign(op2, get_fpr_w0(r2));
9561   assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
9562          mkexpr(op2)));
9563   put_fpr_w0(r1, mkexpr(result));
9564
9565   return "meebr";
9566}
9567
9568static const HChar *
9569s390_irgen_MDBR(UChar r1, UChar r2)
9570{
9571   IRTemp op1 = newTemp(Ity_F64);
9572   IRTemp op2 = newTemp(Ity_F64);
9573   IRTemp result = newTemp(Ity_F64);
9574   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9575
9576   assign(op1, get_fpr_dw0(r1));
9577   assign(op2, get_fpr_dw0(r2));
9578   assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
9579          mkexpr(op2)));
9580   put_fpr_dw0(r1, mkexpr(result));
9581
9582   return "mdbr";
9583}
9584
9585static const HChar *
9586s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9587{
9588   IRTemp op1 = newTemp(Ity_F32);
9589   IRTemp op2 = newTemp(Ity_F32);
9590   IRTemp result = newTemp(Ity_F32);
9591   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9592
9593   assign(op1, get_fpr_w0(r1));
9594   assign(op2, load(Ity_F32, mkexpr(op2addr)));
9595   assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
9596          mkexpr(op2)));
9597   put_fpr_w0(r1, mkexpr(result));
9598
9599   return "meeb";
9600}
9601
9602static const HChar *
9603s390_irgen_MDB(UChar r1, IRTemp op2addr)
9604{
9605   IRTemp op1 = newTemp(Ity_F64);
9606   IRTemp op2 = newTemp(Ity_F64);
9607   IRTemp result = newTemp(Ity_F64);
9608   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9609
9610   assign(op1, get_fpr_dw0(r1));
9611   assign(op2, load(Ity_F64, mkexpr(op2addr)));
9612   assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
9613          mkexpr(op2)));
9614   put_fpr_dw0(r1, mkexpr(result));
9615
9616   return "mdb";
9617}
9618
9619static const HChar *
9620s390_irgen_SEBR(UChar r1, UChar r2)
9621{
9622   IRTemp op1 = newTemp(Ity_F32);
9623   IRTemp op2 = newTemp(Ity_F32);
9624   IRTemp result = newTemp(Ity_F32);
9625   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9626
9627   assign(op1, get_fpr_w0(r1));
9628   assign(op2, get_fpr_w0(r2));
9629   assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
9630          mkexpr(op2)));
9631   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9632   put_fpr_w0(r1, mkexpr(result));
9633
9634   return "sebr";
9635}
9636
9637static const HChar *
9638s390_irgen_SDBR(UChar r1, UChar r2)
9639{
9640   IRTemp op1 = newTemp(Ity_F64);
9641   IRTemp op2 = newTemp(Ity_F64);
9642   IRTemp result = newTemp(Ity_F64);
9643   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9644
9645   assign(op1, get_fpr_dw0(r1));
9646   assign(op2, get_fpr_dw0(r2));
9647   assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
9648          mkexpr(op2)));
9649   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9650   put_fpr_dw0(r1, mkexpr(result));
9651
9652   return "sdbr";
9653}
9654
9655static const HChar *
9656s390_irgen_SEB(UChar r1, IRTemp op2addr)
9657{
9658   IRTemp op1 = newTemp(Ity_F32);
9659   IRTemp op2 = newTemp(Ity_F32);
9660   IRTemp result = newTemp(Ity_F32);
9661   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9662
9663   assign(op1, get_fpr_w0(r1));
9664   assign(op2, load(Ity_F32, mkexpr(op2addr)));
9665   assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
9666          mkexpr(op2)));
9667   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9668   put_fpr_w0(r1, mkexpr(result));
9669
9670   return "seb";
9671}
9672
9673static const HChar *
9674s390_irgen_SDB(UChar r1, IRTemp op2addr)
9675{
9676   IRTemp op1 = newTemp(Ity_F64);
9677   IRTemp op2 = newTemp(Ity_F64);
9678   IRTemp result = newTemp(Ity_F64);
9679   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9680
9681   assign(op1, get_fpr_dw0(r1));
9682   assign(op2, load(Ity_F64, mkexpr(op2addr)));
9683   assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
9684          mkexpr(op2)));
9685   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9686   put_fpr_dw0(r1, mkexpr(result));
9687
9688   return "sdb";
9689}
9690
9691static const HChar *
9692s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9693{
9694   if (! s390_host_has_dfp) {
9695      emulation_failure(EmFail_S390X_DFP_insn);
9696   } else {
9697      IRTemp op1 = newTemp(Ity_D64);
9698      IRTemp op2 = newTemp(Ity_D64);
9699      IRTemp result = newTemp(Ity_D64);
9700      IRTemp rounding_mode;
9701
9702      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9703         emulation_warning(EmWarn_S390X_fpext_rounding);
9704         m4 = S390_DFP_ROUND_PER_FPC_0;
9705      }
9706
9707      rounding_mode = encode_dfp_rounding_mode(m4);
9708      assign(op1, get_dpr_dw0(r2));
9709      assign(op2, get_dpr_dw0(r3));
9710      assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9711                           mkexpr(op2)));
9712      s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9713      put_dpr_dw0(r1, mkexpr(result));
9714   }
9715   return (m4 == 0) ? "adtr" : "adtra";
9716}
9717
9718static const HChar *
9719s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9720{
9721   if (! s390_host_has_dfp) {
9722      emulation_failure(EmFail_S390X_DFP_insn);
9723   } else {
9724      IRTemp op1 = newTemp(Ity_D128);
9725      IRTemp op2 = newTemp(Ity_D128);
9726      IRTemp result = newTemp(Ity_D128);
9727      IRTemp rounding_mode;
9728
9729      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9730         emulation_warning(EmWarn_S390X_fpext_rounding);
9731         m4 = S390_DFP_ROUND_PER_FPC_0;
9732      }
9733
9734      rounding_mode = encode_dfp_rounding_mode(m4);
9735      assign(op1, get_dpr_pair(r2));
9736      assign(op2, get_dpr_pair(r3));
9737      assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9738                           mkexpr(op2)));
9739      put_dpr_pair(r1, mkexpr(result));
9740
9741      s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9742   }
9743   return (m4 == 0) ? "axtr" : "axtra";
9744}
9745
9746static const HChar *
9747s390_irgen_CDTR(UChar r1, UChar r2)
9748{
9749   IRTemp op1 = newTemp(Ity_D64);
9750   IRTemp op2 = newTemp(Ity_D64);
9751   IRTemp cc_vex  = newTemp(Ity_I32);
9752   IRTemp cc_s390 = newTemp(Ity_I32);
9753
9754   assign(op1, get_dpr_dw0(r1));
9755   assign(op2, get_dpr_dw0(r2));
9756   assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9757
9758   assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9759   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9760
9761   return "cdtr";
9762}
9763
9764static const HChar *
9765s390_irgen_CXTR(UChar r1, UChar r2)
9766{
9767   IRTemp op1 = newTemp(Ity_D128);
9768   IRTemp op2 = newTemp(Ity_D128);
9769   IRTemp cc_vex  = newTemp(Ity_I32);
9770   IRTemp cc_s390 = newTemp(Ity_I32);
9771
9772   assign(op1, get_dpr_pair(r1));
9773   assign(op2, get_dpr_pair(r2));
9774   assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9775
9776   assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9777   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9778
9779   return "cxtr";
9780}
9781
9782static const HChar *
9783s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9784                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9785{
9786   if (! s390_host_has_dfp) {
9787      emulation_failure(EmFail_S390X_DFP_insn);
9788   } else {
9789      if (! s390_host_has_fpext) {
9790         emulation_failure(EmFail_S390X_fpext);
9791      } else {
9792         IRTemp op2 = newTemp(Ity_I32);
9793
9794         assign(op2, get_gpr_w1(r2));
9795         put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9796      }
9797   }
9798   return "cdftr";
9799}
9800
9801static const HChar *
9802s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9803                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9804{
9805   if (! s390_host_has_dfp) {
9806      emulation_failure(EmFail_S390X_DFP_insn);
9807   } else {
9808      if (! s390_host_has_fpext) {
9809         emulation_failure(EmFail_S390X_fpext);
9810      } else {
9811         IRTemp op2 = newTemp(Ity_I32);
9812
9813         assign(op2, get_gpr_w1(r2));
9814         put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9815      }
9816   }
9817   return "cxftr";
9818}
9819
9820static const HChar *
9821s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9822                  UChar r1, UChar r2)
9823{
9824   if (! s390_host_has_dfp) {
9825      emulation_failure(EmFail_S390X_DFP_insn);
9826   } else {
9827      IRTemp op2 = newTemp(Ity_I64);
9828
9829      if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9830         emulation_warning(EmWarn_S390X_fpext_rounding);
9831         m3 = S390_DFP_ROUND_PER_FPC_0;
9832      }
9833
9834      assign(op2, get_gpr_dw0(r2));
9835      put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9836                            mkexpr(op2)));
9837   }
9838   return (m3 == 0) ? "cdgtr" : "cdgtra";
9839}
9840
9841static const HChar *
9842s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9843                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9844{
9845   if (! s390_host_has_dfp) {
9846      emulation_failure(EmFail_S390X_DFP_insn);
9847   } else {
9848      IRTemp op2 = newTemp(Ity_I64);
9849
9850      /* No emulation warning here about an non-zero m3 on hosts without
9851         floating point extension facility. No rounding is performed */
9852
9853      assign(op2, get_gpr_dw0(r2));
9854      put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9855   }
9856   return "cxgtr";
9857}
9858
9859static const HChar *
9860s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9861                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9862{
9863   if (! s390_host_has_dfp) {
9864      emulation_failure(EmFail_S390X_DFP_insn);
9865   } else {
9866      if (! s390_host_has_fpext) {
9867         emulation_failure(EmFail_S390X_fpext);
9868      } else {
9869         IRTemp op2 = newTemp(Ity_I32);
9870
9871         assign(op2, get_gpr_w1(r2));
9872         put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9873      }
9874   }
9875   return "cdlftr";
9876}
9877
9878static const HChar *
9879s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9880                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9881{
9882   if (! s390_host_has_dfp) {
9883      emulation_failure(EmFail_S390X_DFP_insn);
9884   } else {
9885      if (! s390_host_has_fpext) {
9886         emulation_failure(EmFail_S390X_fpext);
9887      } else {
9888         IRTemp op2 = newTemp(Ity_I32);
9889
9890         assign(op2, get_gpr_w1(r2));
9891         put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9892      }
9893   }
9894   return "cxlftr";
9895}
9896
9897static const HChar *
9898s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9899                  UChar r1, UChar r2)
9900{
9901   if (! s390_host_has_dfp) {
9902      emulation_failure(EmFail_S390X_DFP_insn);
9903   } else {
9904      if (! s390_host_has_fpext) {
9905         emulation_failure(EmFail_S390X_fpext);
9906      } else {
9907         IRTemp op2 = newTemp(Ity_I64);
9908
9909         assign(op2, get_gpr_dw0(r2));
9910         put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9911                               mkexpr(encode_dfp_rounding_mode(m3)),
9912                               mkexpr(op2)));
9913      }
9914   }
9915   return "cdlgtr";
9916}
9917
9918static const HChar *
9919s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9920                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9921{
9922   if (! s390_host_has_dfp) {
9923      emulation_failure(EmFail_S390X_DFP_insn);
9924   } else {
9925      if (! s390_host_has_fpext) {
9926         emulation_failure(EmFail_S390X_fpext);
9927      } else {
9928         IRTemp op2 = newTemp(Ity_I64);
9929
9930         assign(op2, get_gpr_dw0(r2));
9931         put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9932      }
9933   }
9934   return "cxlgtr";
9935}
9936
9937static const HChar *
9938s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9939                 UChar r1, UChar r2)
9940{
9941   if (! s390_host_has_dfp) {
9942      emulation_failure(EmFail_S390X_DFP_insn);
9943   } else {
9944      if (! s390_host_has_fpext) {
9945         emulation_failure(EmFail_S390X_fpext);
9946      } else {
9947         IRTemp op = newTemp(Ity_D64);
9948         IRTemp result = newTemp(Ity_I32);
9949         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9950
9951         assign(op, get_dpr_dw0(r2));
9952         assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9953                              mkexpr(op)));
9954         put_gpr_w1(r1, mkexpr(result));
9955         s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9956      }
9957   }
9958   return "cfdtr";
9959}
9960
9961static const HChar *
9962s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9963                 UChar r1, UChar r2)
9964{
9965   if (! s390_host_has_dfp) {
9966      emulation_failure(EmFail_S390X_DFP_insn);
9967   } else {
9968      if (! s390_host_has_fpext) {
9969         emulation_failure(EmFail_S390X_fpext);
9970      } else {
9971         IRTemp op = newTemp(Ity_D128);
9972         IRTemp result = newTemp(Ity_I32);
9973         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9974
9975         assign(op, get_dpr_pair(r2));
9976         assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9977                              mkexpr(op)));
9978         put_gpr_w1(r1, mkexpr(result));
9979         s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op,
9980                                 rounding_mode);
9981      }
9982   }
9983   return "cfxtr";
9984}
9985
9986static const HChar *
9987s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9988                 UChar r1, UChar r2)
9989{
9990   if (! s390_host_has_dfp) {
9991      emulation_failure(EmFail_S390X_DFP_insn);
9992   } else {
9993      IRTemp op = newTemp(Ity_D64);
9994      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9995
9996      /* If fpext is not installed and m3 is in 1:7,
9997         rounding mode performed is unpredictable */
9998      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9999         emulation_warning(EmWarn_S390X_fpext_rounding);
10000         m3 = S390_DFP_ROUND_PER_FPC_0;
10001      }
10002
10003      assign(op, get_dpr_dw0(r2));
10004      put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
10005      s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
10006   }
10007   return "cgdtr";
10008}
10009
10010static const HChar *
10011s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
10012                 UChar r1, UChar r2)
10013{
10014   if (! s390_host_has_dfp) {
10015      emulation_failure(EmFail_S390X_DFP_insn);
10016   } else {
10017      IRTemp op = newTemp(Ity_D128);
10018      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10019
10020      /* If fpext is not installed and m3 is in 1:7,
10021         rounding mode performed is unpredictable */
10022      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10023         emulation_warning(EmWarn_S390X_fpext_rounding);
10024         m3 = S390_DFP_ROUND_PER_FPC_0;
10025      }
10026      assign(op, get_dpr_pair(r2));
10027      put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
10028      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
10029   }
10030   return "cgxtr";
10031}
10032
10033static const HChar *
10034s390_irgen_CEDTR(UChar r1, UChar r2)
10035{
10036   if (! s390_host_has_dfp) {
10037      emulation_failure(EmFail_S390X_DFP_insn);
10038   } else {
10039      IRTemp op1 = newTemp(Ity_D64);
10040      IRTemp op2 = newTemp(Ity_D64);
10041      IRTemp cc_vex  = newTemp(Ity_I32);
10042      IRTemp cc_s390 = newTemp(Ity_I32);
10043
10044      assign(op1, get_dpr_dw0(r1));
10045      assign(op2, get_dpr_dw0(r2));
10046      assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
10047
10048      assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
10049      s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10050   }
10051   return "cedtr";
10052}
10053
10054static const HChar *
10055s390_irgen_CEXTR(UChar r1, UChar r2)
10056{
10057   if (! s390_host_has_dfp) {
10058      emulation_failure(EmFail_S390X_DFP_insn);
10059   } else {
10060      IRTemp op1 = newTemp(Ity_D128);
10061      IRTemp op2 = newTemp(Ity_D128);
10062      IRTemp cc_vex  = newTemp(Ity_I32);
10063      IRTemp cc_s390 = newTemp(Ity_I32);
10064
10065      assign(op1, get_dpr_pair(r1));
10066      assign(op2, get_dpr_pair(r2));
10067      assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
10068
10069      assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
10070      s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10071   }
10072   return "cextr";
10073}
10074
10075static const HChar *
10076s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
10077                  UChar r1, UChar r2)
10078{
10079   if (! s390_host_has_dfp) {
10080      emulation_failure(EmFail_S390X_DFP_insn);
10081   } else {
10082      if (! s390_host_has_fpext) {
10083         emulation_failure(EmFail_S390X_fpext);
10084      } else {
10085         IRTemp op = newTemp(Ity_D64);
10086         IRTemp result = newTemp(Ity_I32);
10087         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10088
10089         assign(op, get_dpr_dw0(r2));
10090         assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
10091                              mkexpr(op)));
10092         put_gpr_w1(r1, mkexpr(result));
10093         s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
10094      }
10095   }
10096   return "clfdtr";
10097}
10098
10099static const HChar *
10100s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
10101                  UChar r1, UChar r2)
10102{
10103   if (! s390_host_has_dfp) {
10104      emulation_failure(EmFail_S390X_DFP_insn);
10105   } else {
10106      if (! s390_host_has_fpext) {
10107         emulation_failure(EmFail_S390X_fpext);
10108      } else {
10109         IRTemp op = newTemp(Ity_D128);
10110         IRTemp result = newTemp(Ity_I32);
10111         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10112
10113         assign(op, get_dpr_pair(r2));
10114         assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
10115                              mkexpr(op)));
10116         put_gpr_w1(r1, mkexpr(result));
10117         s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op,
10118                                 rounding_mode);
10119      }
10120   }
10121   return "clfxtr";
10122}
10123
10124static const HChar *
10125s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
10126                  UChar r1, UChar r2)
10127{
10128   if (! s390_host_has_dfp) {
10129      emulation_failure(EmFail_S390X_DFP_insn);
10130   } else {
10131      if (! s390_host_has_fpext) {
10132         emulation_failure(EmFail_S390X_fpext);
10133      } else {
10134         IRTemp op = newTemp(Ity_D64);
10135         IRTemp result = newTemp(Ity_I64);
10136         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10137
10138         assign(op, get_dpr_dw0(r2));
10139         assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
10140                              mkexpr(op)));
10141         put_gpr_dw0(r1, mkexpr(result));
10142         s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
10143      }
10144   }
10145   return "clgdtr";
10146}
10147
10148static const HChar *
10149s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
10150                  UChar r1, UChar r2)
10151{
10152   if (! s390_host_has_dfp) {
10153      emulation_failure(EmFail_S390X_DFP_insn);
10154   } else {
10155      if (! s390_host_has_fpext) {
10156         emulation_failure(EmFail_S390X_fpext);
10157      } else {
10158         IRTemp op = newTemp(Ity_D128);
10159         IRTemp result = newTemp(Ity_I64);
10160         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10161
10162         assign(op, get_dpr_pair(r2));
10163         assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
10164                              mkexpr(op)));
10165         put_gpr_dw0(r1, mkexpr(result));
10166         s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
10167                                 rounding_mode);
10168      }
10169   }
10170   return "clgxtr";
10171}
10172
10173static const HChar *
10174s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10175{
10176   if (! s390_host_has_dfp) {
10177      emulation_failure(EmFail_S390X_DFP_insn);
10178   } else {
10179      IRTemp op1 = newTemp(Ity_D64);
10180      IRTemp op2 = newTemp(Ity_D64);
10181      IRTemp result = newTemp(Ity_D64);
10182      IRTemp rounding_mode;
10183
10184      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10185         emulation_warning(EmWarn_S390X_fpext_rounding);
10186         m4 = S390_DFP_ROUND_PER_FPC_0;
10187      }
10188
10189      rounding_mode = encode_dfp_rounding_mode(m4);
10190      assign(op1, get_dpr_dw0(r2));
10191      assign(op2, get_dpr_dw0(r3));
10192      assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
10193                           mkexpr(op2)));
10194      put_dpr_dw0(r1, mkexpr(result));
10195   }
10196   return (m4 == 0) ? "ddtr" : "ddtra";
10197}
10198
10199static const HChar *
10200s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10201{
10202   if (! s390_host_has_dfp) {
10203      emulation_failure(EmFail_S390X_DFP_insn);
10204   } else {
10205      IRTemp op1 = newTemp(Ity_D128);
10206      IRTemp op2 = newTemp(Ity_D128);
10207      IRTemp result = newTemp(Ity_D128);
10208      IRTemp rounding_mode;
10209
10210      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10211         emulation_warning(EmWarn_S390X_fpext_rounding);
10212         m4 = S390_DFP_ROUND_PER_FPC_0;
10213      }
10214
10215      rounding_mode = encode_dfp_rounding_mode(m4);
10216      assign(op1, get_dpr_pair(r2));
10217      assign(op2, get_dpr_pair(r3));
10218      assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
10219                           mkexpr(op2)));
10220      put_dpr_pair(r1, mkexpr(result));
10221   }
10222   return (m4 == 0) ? "dxtr" : "dxtra";
10223}
10224
10225static const HChar *
10226s390_irgen_EEDTR(UChar r1, UChar r2)
10227{
10228   if (! s390_host_has_dfp) {
10229      emulation_failure(EmFail_S390X_DFP_insn);
10230   } else {
10231      put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
10232   }
10233   return "eedtr";
10234}
10235
10236static const HChar *
10237s390_irgen_EEXTR(UChar r1, UChar r2)
10238{
10239   if (! s390_host_has_dfp) {
10240      emulation_failure(EmFail_S390X_DFP_insn);
10241   } else {
10242      put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
10243   }
10244   return "eextr";
10245}
10246
10247static const HChar *
10248s390_irgen_ESDTR(UChar r1, UChar r2)
10249{
10250   if (! s390_host_has_dfp) {
10251      emulation_failure(EmFail_S390X_DFP_insn);
10252   } else {
10253      put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
10254   }
10255   return "esdtr";
10256}
10257
10258static const HChar *
10259s390_irgen_ESXTR(UChar r1, UChar r2)
10260{
10261   if (! s390_host_has_dfp) {
10262      emulation_failure(EmFail_S390X_DFP_insn);
10263   } else {
10264      put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
10265   }
10266   return "esxtr";
10267}
10268
10269static const HChar *
10270s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
10271{
10272   if (! s390_host_has_dfp) {
10273      emulation_failure(EmFail_S390X_DFP_insn);
10274   } else {
10275      IRTemp op1 = newTemp(Ity_I64);
10276      IRTemp op2 = newTemp(Ity_D64);
10277      IRTemp result = newTemp(Ity_D64);
10278
10279      assign(op1, get_gpr_dw0(r2));
10280      assign(op2, get_dpr_dw0(r3));
10281      assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
10282      put_dpr_dw0(r1, mkexpr(result));
10283   }
10284   return "iedtr";
10285}
10286
10287static const HChar *
10288s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
10289{
10290   if (! s390_host_has_dfp) {
10291      emulation_failure(EmFail_S390X_DFP_insn);
10292   } else {
10293      IRTemp op1 = newTemp(Ity_I64);
10294      IRTemp op2 = newTemp(Ity_D128);
10295      IRTemp result = newTemp(Ity_D128);
10296
10297      assign(op1, get_gpr_dw0(r2));
10298      assign(op2, get_dpr_pair(r3));
10299      assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10300      put_dpr_pair(r1, mkexpr(result));
10301   }
10302   return "iextr";
10303}
10304
10305static const HChar *
10306s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10307{
10308   if (! s390_host_has_dfp) {
10309      emulation_failure(EmFail_S390X_DFP_insn);
10310   } else {
10311      IRTemp op = newTemp(Ity_D32);
10312
10313      assign(op, get_dpr_w0(r2));
10314      put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10315   }
10316   return "ldetr";
10317}
10318
10319static const HChar *
10320s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10321{
10322   IRTemp op = newTemp(Ity_D64);
10323
10324   assign(op, get_dpr_dw0(r2));
10325   put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10326
10327   return "lxdtr";
10328}
10329
10330static const HChar *
10331s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10332                 UChar r1, UChar r2)
10333{
10334   if (! s390_host_has_dfp) {
10335      emulation_failure(EmFail_S390X_DFP_insn);
10336   } else {
10337      /* If fpext is not installed and m3 is in 1:7,
10338         rounding mode performed is unpredictable */
10339      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10340         emulation_warning(EmWarn_S390X_fpext_rounding);
10341         m3 = S390_DFP_ROUND_PER_FPC_0;
10342      }
10343      IRTemp result = newTemp(Ity_D64);
10344
10345      assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10346                           get_dpr_pair(r2)));
10347      put_dpr_dw0(r1, mkexpr(result));
10348   }
10349   return "ldxtr";
10350}
10351
10352static const HChar *
10353s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10354                 UChar r1, UChar r2)
10355{
10356   if (! s390_host_has_dfp) {
10357      emulation_failure(EmFail_S390X_DFP_insn);
10358   } else {
10359      /* If fpext is not installed and m3 is in 1:7,
10360         rounding mode performed is unpredictable */
10361      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10362         emulation_warning(EmWarn_S390X_fpext_rounding);
10363         m3 = S390_DFP_ROUND_PER_FPC_0;
10364      }
10365      IRTemp op = newTemp(Ity_D64);
10366
10367      assign(op, get_dpr_dw0(r2));
10368      put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10369                           mkexpr(op)));
10370   }
10371   return "ledtr";
10372}
10373
10374static const HChar *
10375s390_irgen_LTDTR(UChar r1, UChar r2)
10376{
10377   IRTemp result = newTemp(Ity_D64);
10378
10379   assign(result, get_dpr_dw0(r2));
10380   put_dpr_dw0(r1, mkexpr(result));
10381   s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10382
10383   return "ltdtr";
10384}
10385
10386static const HChar *
10387s390_irgen_LTXTR(UChar r1, UChar r2)
10388{
10389   IRTemp result = newTemp(Ity_D128);
10390
10391   assign(result, get_dpr_pair(r2));
10392   put_dpr_pair(r1, mkexpr(result));
10393   s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10394
10395   return "ltxtr";
10396}
10397
10398static const HChar *
10399s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10400{
10401   if (! s390_host_has_dfp) {
10402      emulation_failure(EmFail_S390X_DFP_insn);
10403   } else {
10404      IRTemp op1 = newTemp(Ity_D64);
10405      IRTemp op2 = newTemp(Ity_D64);
10406      IRTemp result = newTemp(Ity_D64);
10407      IRTemp rounding_mode;
10408
10409      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10410         emulation_warning(EmWarn_S390X_fpext_rounding);
10411         m4 = S390_DFP_ROUND_PER_FPC_0;
10412      }
10413
10414      rounding_mode = encode_dfp_rounding_mode(m4);
10415      assign(op1, get_dpr_dw0(r2));
10416      assign(op2, get_dpr_dw0(r3));
10417      assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10418                           mkexpr(op2)));
10419      put_dpr_dw0(r1, mkexpr(result));
10420   }
10421   return (m4 == 0) ? "mdtr" : "mdtra";
10422}
10423
10424static const HChar *
10425s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10426{
10427   if (! s390_host_has_dfp) {
10428      emulation_failure(EmFail_S390X_DFP_insn);
10429   } else {
10430      IRTemp op1 = newTemp(Ity_D128);
10431      IRTemp op2 = newTemp(Ity_D128);
10432      IRTemp result = newTemp(Ity_D128);
10433      IRTemp rounding_mode;
10434
10435      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10436         emulation_warning(EmWarn_S390X_fpext_rounding);
10437         m4 = S390_DFP_ROUND_PER_FPC_0;
10438      }
10439
10440      rounding_mode = encode_dfp_rounding_mode(m4);
10441      assign(op1, get_dpr_pair(r2));
10442      assign(op2, get_dpr_pair(r3));
10443      assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10444                           mkexpr(op2)));
10445      put_dpr_pair(r1, mkexpr(result));
10446   }
10447   return (m4 == 0) ? "mxtr" : "mxtra";
10448}
10449
10450static const HChar *
10451s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10452{
10453   if (! s390_host_has_dfp) {
10454      emulation_failure(EmFail_S390X_DFP_insn);
10455   } else {
10456      IRTemp op1 = newTemp(Ity_D64);
10457      IRTemp op2 = newTemp(Ity_D64);
10458      IRTemp result = newTemp(Ity_D64);
10459      IRTemp rounding_mode;
10460
10461      /* If fpext is not installed and m4 is in 1:7,
10462         rounding mode performed is unpredictable */
10463      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10464         emulation_warning(EmWarn_S390X_fpext_rounding);
10465         m4 = S390_DFP_ROUND_PER_FPC_0;
10466      }
10467
10468      rounding_mode = encode_dfp_rounding_mode(m4);
10469      assign(op1, get_dpr_dw0(r2));
10470      assign(op2, get_dpr_dw0(r3));
10471      assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10472                           mkexpr(op2)));
10473      put_dpr_dw0(r1, mkexpr(result));
10474   }
10475   return "qadtr";
10476}
10477
10478static const HChar *
10479s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10480{
10481   if (! s390_host_has_dfp) {
10482      emulation_failure(EmFail_S390X_DFP_insn);
10483   } else {
10484      IRTemp op1 = newTemp(Ity_D128);
10485      IRTemp op2 = newTemp(Ity_D128);
10486      IRTemp result = newTemp(Ity_D128);
10487      IRTemp rounding_mode;
10488
10489      /* If fpext is not installed and m4 is in 1:7,
10490         rounding mode performed is unpredictable */
10491      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10492         emulation_warning(EmWarn_S390X_fpext_rounding);
10493         m4 = S390_DFP_ROUND_PER_FPC_0;
10494      }
10495
10496      rounding_mode = encode_dfp_rounding_mode(m4);
10497      assign(op1, get_dpr_pair(r2));
10498      assign(op2, get_dpr_pair(r3));
10499      assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10500                           mkexpr(op2)));
10501      put_dpr_pair(r1, mkexpr(result));
10502   }
10503   return "qaxtr";
10504}
10505
10506static const HChar *
10507s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10508{
10509   if (! s390_host_has_dfp) {
10510      emulation_failure(EmFail_S390X_DFP_insn);
10511   } else {
10512      IRTemp op1 = newTemp(Ity_I8);
10513      IRTemp op2 = newTemp(Ity_D64);
10514      IRTemp result = newTemp(Ity_D64);
10515      IRTemp rounding_mode;
10516
10517      /* If fpext is not installed and m4 is in 1:7,
10518         rounding mode performed is unpredictable */
10519      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10520         emulation_warning(EmWarn_S390X_fpext_rounding);
10521         m4 = S390_DFP_ROUND_PER_FPC_0;
10522      }
10523
10524      rounding_mode = encode_dfp_rounding_mode(m4);
10525      assign(op1, get_gpr_b7(r2));
10526      assign(op2, get_dpr_dw0(r3));
10527      assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10528                           mkexpr(op1), mkexpr(op2)));
10529      put_dpr_dw0(r1, mkexpr(result));
10530   }
10531   return "rrdtr";
10532}
10533
10534static const HChar *
10535s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10536{
10537   if (! s390_host_has_dfp) {
10538      emulation_failure(EmFail_S390X_DFP_insn);
10539   } else {
10540      IRTemp op1 = newTemp(Ity_I8);
10541      IRTemp op2 = newTemp(Ity_D128);
10542      IRTemp result = newTemp(Ity_D128);
10543      IRTemp rounding_mode;
10544
10545      /* If fpext is not installed and m4 is in 1:7,
10546         rounding mode performed is unpredictable */
10547      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10548         emulation_warning(EmWarn_S390X_fpext_rounding);
10549         m4 = S390_DFP_ROUND_PER_FPC_0;
10550      }
10551
10552      rounding_mode = encode_dfp_rounding_mode(m4);
10553      assign(op1, get_gpr_b7(r2));
10554      assign(op2, get_dpr_pair(r3));
10555      assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10556                           mkexpr(op1), mkexpr(op2)));
10557      put_dpr_pair(r1, mkexpr(result));
10558   }
10559   return "rrxtr";
10560}
10561
10562static const HChar *
10563s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10564{
10565   if (! s390_host_has_dfp) {
10566      emulation_failure(EmFail_S390X_DFP_insn);
10567   } else {
10568      IRTemp op1 = newTemp(Ity_D64);
10569      IRTemp op2 = newTemp(Ity_D64);
10570      IRTemp result = newTemp(Ity_D64);
10571      IRTemp rounding_mode;
10572
10573      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10574         emulation_warning(EmWarn_S390X_fpext_rounding);
10575         m4 = S390_DFP_ROUND_PER_FPC_0;
10576      }
10577
10578      rounding_mode = encode_dfp_rounding_mode(m4);
10579      assign(op1, get_dpr_dw0(r2));
10580      assign(op2, get_dpr_dw0(r3));
10581      assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10582                           mkexpr(op2)));
10583      s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10584      put_dpr_dw0(r1, mkexpr(result));
10585   }
10586   return (m4 == 0) ? "sdtr" : "sdtra";
10587}
10588
10589static const HChar *
10590s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10591{
10592   if (! s390_host_has_dfp) {
10593      emulation_failure(EmFail_S390X_DFP_insn);
10594   } else {
10595      IRTemp op1 = newTemp(Ity_D128);
10596      IRTemp op2 = newTemp(Ity_D128);
10597      IRTemp result = newTemp(Ity_D128);
10598      IRTemp rounding_mode;
10599
10600      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10601         emulation_warning(EmWarn_S390X_fpext_rounding);
10602         m4 = S390_DFP_ROUND_PER_FPC_0;
10603      }
10604
10605      rounding_mode = encode_dfp_rounding_mode(m4);
10606      assign(op1, get_dpr_pair(r2));
10607      assign(op2, get_dpr_pair(r3));
10608      assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10609                           mkexpr(op2)));
10610      put_dpr_pair(r1, mkexpr(result));
10611
10612      s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10613   }
10614   return (m4 == 0) ? "sxtr" : "sxtra";
10615}
10616
10617static const HChar *
10618s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10619{
10620   if (! s390_host_has_dfp) {
10621      emulation_failure(EmFail_S390X_DFP_insn);
10622   } else {
10623      IRTemp op = newTemp(Ity_D64);
10624
10625      assign(op, get_dpr_dw0(r3));
10626      put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op),
10627                            unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10628                                                  mkU64(63)))));
10629   }
10630   return "sldt";
10631}
10632
10633static const HChar *
10634s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10635{
10636   if (! s390_host_has_dfp) {
10637      emulation_failure(EmFail_S390X_DFP_insn);
10638   } else {
10639      IRTemp op = newTemp(Ity_D128);
10640
10641      assign(op, get_dpr_pair(r3));
10642      put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op),
10643                             unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10644                                                   mkU64(63)))));
10645   }
10646   return "slxt";
10647}
10648
10649static const HChar *
10650s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10651{
10652   if (! s390_host_has_dfp) {
10653      emulation_failure(EmFail_S390X_DFP_insn);
10654   } else {
10655      IRTemp op = newTemp(Ity_D64);
10656
10657      assign(op, get_dpr_dw0(r3));
10658      put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op),
10659                            unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10660                                                  mkU64(63)))));
10661   }
10662   return "srdt";
10663}
10664
10665static const HChar *
10666s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10667{
10668   if (! s390_host_has_dfp) {
10669      emulation_failure(EmFail_S390X_DFP_insn);
10670   } else {
10671      IRTemp op = newTemp(Ity_D128);
10672
10673      assign(op, get_dpr_pair(r3));
10674      put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op),
10675                             unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10676                                                   mkU64(63)))));
10677   }
10678   return "srxt";
10679}
10680
10681static const HChar *
10682s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10683{
10684   if (! s390_host_has_dfp) {
10685      emulation_failure(EmFail_S390X_DFP_insn);
10686   } else {
10687      IRTemp value = newTemp(Ity_D32);
10688
10689      assign(value, get_dpr_w0(r1));
10690
10691      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10692   }
10693   return "tdcet";
10694}
10695
10696static const HChar *
10697s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10698{
10699   if (! s390_host_has_dfp) {
10700      emulation_failure(EmFail_S390X_DFP_insn);
10701   } else {
10702      IRTemp value = newTemp(Ity_D64);
10703
10704      assign(value, get_dpr_dw0(r1));
10705
10706      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10707   }
10708   return "tdcdt";
10709}
10710
10711static const HChar *
10712s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10713{
10714   if (! s390_host_has_dfp) {
10715      emulation_failure(EmFail_S390X_DFP_insn);
10716   } else {
10717      IRTemp value = newTemp(Ity_D128);
10718
10719      assign(value, get_dpr_pair(r1));
10720
10721      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10722   }
10723   return "tdcxt";
10724}
10725
10726static const HChar *
10727s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10728{
10729   if (! s390_host_has_dfp) {
10730      emulation_failure(EmFail_S390X_DFP_insn);
10731   } else {
10732      IRTemp value = newTemp(Ity_D32);
10733
10734      assign(value, get_dpr_w0(r1));
10735
10736      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10737   }
10738   return "tdget";
10739}
10740
10741static const HChar *
10742s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10743{
10744   if (! s390_host_has_dfp) {
10745      emulation_failure(EmFail_S390X_DFP_insn);
10746   } else {
10747      IRTemp value = newTemp(Ity_D64);
10748
10749      assign(value, get_dpr_dw0(r1));
10750
10751      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10752   }
10753   return "tdgdt";
10754}
10755
10756static const HChar *
10757s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10758{
10759   if (! s390_host_has_dfp) {
10760      emulation_failure(EmFail_S390X_DFP_insn);
10761   } else {
10762      IRTemp value = newTemp(Ity_D128);
10763
10764      assign(value, get_dpr_pair(r1));
10765
10766      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10767   }
10768   return "tdgxt";
10769}
10770
10771static const HChar *
10772s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10773{
10774   IRTemp len = newTemp(Ity_I64);
10775
10776   assign(len, mkU64(length));
10777   s390_irgen_CLC_EX(len, start1, start2);
10778
10779   return "clc";
10780}
10781
10782static const HChar *
10783s390_irgen_CLCL(UChar r1, UChar r2)
10784{
10785   IRTemp addr1 = newTemp(Ity_I64);
10786   IRTemp addr2 = newTemp(Ity_I64);
10787   IRTemp addr1_load = newTemp(Ity_I64);
10788   IRTemp addr2_load = newTemp(Ity_I64);
10789   IRTemp len1 = newTemp(Ity_I32);
10790   IRTemp len2 = newTemp(Ity_I32);
10791   IRTemp r1p1 = newTemp(Ity_I32);   /* contents of r1 + 1 */
10792   IRTemp r2p1 = newTemp(Ity_I32);   /* contents of r2 + 1 */
10793   IRTemp single1 = newTemp(Ity_I8);
10794   IRTemp single2 = newTemp(Ity_I8);
10795   IRTemp pad = newTemp(Ity_I8);
10796
10797   assign(addr1, get_gpr_dw0(r1));
10798   assign(r1p1, get_gpr_w1(r1 + 1));
10799   assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10800   assign(addr2, get_gpr_dw0(r2));
10801   assign(r2p1, get_gpr_w1(r2 + 1));
10802   assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10803   assign(pad, get_gpr_b4(r2 + 1));
10804
10805   /* len1 == 0 and len2 == 0? Exit */
10806   s390_cc_set(0);
10807   next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10808                                         mkexpr(len2)), mkU32(0)));
10809
10810   /* Because mkite evaluates both the then-clause and the else-clause
10811      we cannot load directly from addr1 here. If len1 is 0, then adddr1
10812      may be NULL and loading from there would segfault. So we provide a
10813      valid dummy address in that case. Loading from there does no harm and
10814      the value will be discarded at runtime. */
10815   assign(addr1_load,
10816          mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10817                mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10818   assign(single1,
10819          mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10820                mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10821
10822   assign(addr2_load,
10823          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10824                mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10825   assign(single2,
10826          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10827                mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10828
10829   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10830   /* Fields differ ? */
10831   next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
10832
10833   /* Update len1 and addr1, unless len1 == 0. */
10834   put_gpr_dw0(r1,
10835               mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10836                     mkexpr(addr1),
10837                     binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10838
10839   /* When updating len1 we must not modify bits (r1+1)[0:39] */
10840   put_gpr_w1(r1 + 1,
10841              mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10842                    binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10843                    binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10844
10845   /* Update len2 and addr2, unless len2 == 0. */
10846   put_gpr_dw0(r2,
10847               mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10848                     mkexpr(addr2),
10849                     binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10850
10851   /* When updating len2 we must not modify bits (r2+1)[0:39] */
10852   put_gpr_w1(r2 + 1,
10853              mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10854                    binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10855                    binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10856
10857   iterate();
10858
10859   return "clcl";
10860}
10861
10862static const HChar *
10863s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10864{
10865   IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10866
10867   addr1 = newTemp(Ity_I64);
10868   addr3 = newTemp(Ity_I64);
10869   addr1_load = newTemp(Ity_I64);
10870   addr3_load = newTemp(Ity_I64);
10871   len1 = newTemp(Ity_I64);
10872   len3 = newTemp(Ity_I64);
10873   single1 = newTemp(Ity_I8);
10874   single3 = newTemp(Ity_I8);
10875
10876   assign(addr1, get_gpr_dw0(r1));
10877   assign(len1, get_gpr_dw0(r1 + 1));
10878   assign(addr3, get_gpr_dw0(r3));
10879   assign(len3, get_gpr_dw0(r3 + 1));
10880
10881   /* len1 == 0 and len3 == 0? Exit */
10882   s390_cc_set(0);
10883   next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10884                                        mkexpr(len3)), mkU64(0)));
10885
10886   /* A mux requires both ways to be possible. This is a way to prevent clcle
10887      from reading from addr1 if it should read from the pad. Since the pad
10888      has no address, just read from the instruction, we discard that anyway */
10889   assign(addr1_load,
10890          mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10891                mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10892
10893   /* same for addr3 */
10894   assign(addr3_load,
10895          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10896                mkU64(guest_IA_curr_instr), mkexpr(addr3)));
10897
10898   assign(single1,
10899          mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10900                unop(Iop_64to8, mkexpr(pad2)),
10901                load(Ity_I8, mkexpr(addr1_load))));
10902
10903   assign(single3,
10904          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10905                unop(Iop_64to8, mkexpr(pad2)),
10906                load(Ity_I8, mkexpr(addr3_load))));
10907
10908   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10909   /* Both fields differ ? */
10910   next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
10911
10912   /* If a length in 0 we must not change this length and the address */
10913   put_gpr_dw0(r1,
10914               mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10915                     mkexpr(addr1),
10916                     binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10917
10918   put_gpr_dw0(r1 + 1,
10919               mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10920                     mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
10921
10922   put_gpr_dw0(r3,
10923               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10924                     mkexpr(addr3),
10925                     binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
10926
10927   put_gpr_dw0(r3 + 1,
10928               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10929                     mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
10930
10931   iterate();
10932
10933   return "clcle";
10934}
10935
10936
10937static void
10938s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10939{
10940   s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10941}
10942
10943
10944static void
10945s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10946{
10947   s390_irgen_xonc(Iop_And8, length, start1, start2);
10948}
10949
10950
10951static void
10952s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10953{
10954   s390_irgen_xonc(Iop_Or8, length, start1, start2);
10955}
10956
10957
10958static void
10959s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10960{
10961   IRTemp current1 = newTemp(Ity_I8);
10962   IRTemp current2 = newTemp(Ity_I8);
10963   IRTemp counter = newTemp(Ity_I64);
10964
10965   assign(counter, get_counter_dw0());
10966   put_counter_dw0(mkU64(0));
10967
10968   assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10969                                       mkexpr(counter))));
10970   assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10971                                       mkexpr(counter))));
10972   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10973                      False);
10974
10975   /* Both fields differ ? */
10976   next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
10977
10978   /* Check for end of field */
10979   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10980   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
10981   put_counter_dw0(mkU64(0));
10982}
10983
10984static void
10985s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10986{
10987   IRTemp counter = newTemp(Ity_I64);
10988
10989   assign(counter, get_counter_dw0());
10990
10991   store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10992         load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10993
10994   /* Check for end of field */
10995   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10996   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
10997   put_counter_dw0(mkU64(0));
10998}
10999
11000static void
11001s390_irgen_MVCIN_EX(IRTemp length, IRTemp start1, IRTemp start2)
11002{
11003   IRTemp counter = newTemp(Ity_I64);
11004
11005   assign(counter, get_counter_dw0());
11006
11007   store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
11008         load(Ity_I8, binop(Iop_Sub64, mkexpr(start2), mkexpr(counter))));
11009
11010   /* Check for end of field */
11011   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11012   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
11013   put_counter_dw0(mkU64(0));
11014}
11015
11016static void
11017s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
11018{
11019   IRTemp op = newTemp(Ity_I8);
11020   IRTemp op1 = newTemp(Ity_I8);
11021   IRTemp result = newTemp(Ity_I64);
11022   IRTemp counter = newTemp(Ity_I64);
11023
11024   assign(counter, get_counter_dw0());
11025
11026   assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
11027
11028   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
11029
11030   assign(op1, load(Ity_I8, mkexpr(result)));
11031   store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
11032
11033   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11034   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
11035   put_counter_dw0(mkU64(0));
11036}
11037
11038
11039static void
11040s390_irgen_EX_SS(UChar r, IRTemp addr2,
11041                 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
11042                 UInt lensize)
11043{
11044   struct SS {
11045      unsigned int op :  8;
11046      unsigned int l  :  8;
11047      unsigned int b1 :  4;
11048      unsigned int d1 : 12;
11049      unsigned int b2 :  4;
11050      unsigned int d2 : 12;
11051   };
11052   union {
11053      struct SS dec;
11054      unsigned long bytes;
11055   } ss;
11056   IRTemp cond;
11057   IRDirty *d;
11058   IRTemp torun;
11059
11060   IRTemp start1 = newTemp(Ity_I64);
11061   IRTemp start2 = newTemp(Ity_I64);
11062   IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
11063   cond = newTemp(Ity_I1);
11064   torun = newTemp(Ity_I64);
11065
11066   assign(torun, load(Ity_I64, mkexpr(addr2)));
11067   /* Start with a check that the saved code is still correct */
11068   assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
11069   /* If not, save the new value */
11070   d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
11071                          mkIRExprVec_1(mkexpr(torun)));
11072   d->guard = mkexpr(cond);
11073   stmt(IRStmt_Dirty(d));
11074
11075   /* and restart */
11076   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
11077                   mkU64(guest_IA_curr_instr)));
11078   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
11079   restart_if(mkexpr(cond));
11080
11081   ss.bytes = last_execute_target;
11082   assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
11083          ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
11084   assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
11085          ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
11086   assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
11087          r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
11088   irgen(len, start1, start2);
11089
11090   last_execute_target = 0;
11091}
11092
11093static const HChar *
11094s390_irgen_EX(UChar r1, IRTemp addr2)
11095{
11096   switch(last_execute_target & 0xff00000000000000ULL) {
11097   case 0:
11098   {
11099      /* no code information yet */
11100      IRDirty *d;
11101
11102      /* so safe the code... */
11103      d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
11104                             mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
11105      stmt(IRStmt_Dirty(d));
11106      /* and restart */
11107      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
11108                      mkU64(guest_IA_curr_instr)));
11109      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
11110      restart_if(IRExpr_Const(IRConst_U1(True)));
11111
11112      /* we know that this will be invalidated */
11113      put_IA(mkaddr_expr(guest_IA_next_instr));
11114      dis_res->whatNext = Dis_StopHere;
11115      dis_res->jk_StopHere = Ijk_InvalICache;
11116      break;
11117   }
11118
11119   case 0xd200000000000000ULL:
11120      /* special case MVC */
11121      s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
11122      return "ex@mvc";
11123
11124   case 0xd500000000000000ULL:
11125      /* special case CLC */
11126      s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
11127      return "ex@clc";
11128
11129   case 0xd700000000000000ULL:
11130      /* special case XC */
11131      s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
11132      return "ex@xc";
11133
11134   case 0xd600000000000000ULL:
11135      /* special case OC */
11136      s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
11137      return "ex@oc";
11138
11139   case 0xd400000000000000ULL:
11140      /* special case NC */
11141      s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
11142      return "ex@nc";
11143
11144   case 0xdc00000000000000ULL:
11145      /* special case TR */
11146      s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
11147      return "ex@tr";
11148
11149   case 0xe800000000000000ULL:
11150      /* special case MVCIN */
11151      s390_irgen_EX_SS(r1, addr2, s390_irgen_MVCIN_EX, 64);
11152      return "ex@mvcin";
11153
11154   default:
11155   {
11156      /* everything else will get a self checking prefix that also checks the
11157         register content */
11158      IRDirty *d;
11159      UChar *bytes;
11160      IRTemp cond;
11161      IRTemp orperand;
11162      IRTemp torun;
11163
11164      cond = newTemp(Ity_I1);
11165      orperand = newTemp(Ity_I64);
11166      torun = newTemp(Ity_I64);
11167
11168      if (r1 == 0)
11169         assign(orperand, mkU64(0));
11170      else
11171         assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
11172      /* This code is going to be translated */
11173      assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
11174             binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
11175
11176      /* Start with a check that saved code is still correct */
11177      assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
11178             mkU64(last_execute_target)));
11179      /* If not, save the new value */
11180      d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
11181                             mkIRExprVec_1(mkexpr(torun)));
11182      d->guard = mkexpr(cond);
11183      stmt(IRStmt_Dirty(d));
11184
11185      /* and restart */
11186      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART), mkU64(guest_IA_curr_instr)));
11187      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
11188      restart_if(mkexpr(cond));
11189
11190      /* Now comes the actual translation */
11191      bytes = (UChar *) &last_execute_target;
11192      s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
11193                            dis_res);
11194      if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
11195         vex_printf("    which was executed by\n");
11196      /* dont make useless translations in the next execute */
11197      last_execute_target = 0;
11198   }
11199   }
11200   return "ex";
11201}
11202
11203static const HChar *
11204s390_irgen_EXRL(UChar r1, UInt offset)
11205{
11206   IRTemp addr = newTemp(Ity_I64);
11207   /* we might save one round trip because we know the target */
11208   if (!last_execute_target)
11209      last_execute_target = *(ULong *)(HWord)
11210                             (guest_IA_curr_instr + offset * 2UL);
11211   assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
11212   s390_irgen_EX(r1, addr);
11213   return "exrl";
11214}
11215
11216static const HChar *
11217s390_irgen_IPM(UChar r1)
11218{
11219   // As long as we dont support SPM, lets just assume 0 as program mask
11220   put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
11221                       binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
11222
11223   return "ipm";
11224}
11225
11226
11227static const HChar *
11228s390_irgen_SRST(UChar r1, UChar r2)
11229{
11230   IRTemp address = newTemp(Ity_I64);
11231   IRTemp next = newTemp(Ity_I64);
11232   IRTemp delim = newTemp(Ity_I8);
11233   IRTemp counter = newTemp(Ity_I64);
11234   IRTemp byte = newTemp(Ity_I8);
11235
11236   assign(address, get_gpr_dw0(r2));
11237   assign(next, get_gpr_dw0(r1));
11238
11239   assign(counter, get_counter_dw0());
11240   put_counter_dw0(mkU64(0));
11241
11242   // start = next?  CC=2 and out r1 and r2 unchanged
11243   s390_cc_set(2);
11244   put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
11245   next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
11246
11247   assign(byte, load(Ity_I8, mkexpr(address)));
11248   assign(delim, get_gpr_b7(0));
11249
11250   // byte = delim? CC=1, R1=address
11251   s390_cc_set(1);
11252   put_gpr_dw0(r1,  mkexpr(address));
11253   next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
11254
11255   // else: all equal, no end yet, loop
11256   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11257   put_gpr_dw0(r1, mkexpr(next));
11258   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
11259
11260   iterate();
11261
11262   return "srst";
11263}
11264
11265static const HChar *
11266s390_irgen_CLST(UChar r1, UChar r2)
11267{
11268   IRTemp address1 = newTemp(Ity_I64);
11269   IRTemp address2 = newTemp(Ity_I64);
11270   IRTemp end = newTemp(Ity_I8);
11271   IRTemp counter = newTemp(Ity_I64);
11272   IRTemp byte1 = newTemp(Ity_I8);
11273   IRTemp byte2 = newTemp(Ity_I8);
11274
11275   assign(address1, get_gpr_dw0(r1));
11276   assign(address2, get_gpr_dw0(r2));
11277   assign(end, get_gpr_b7(0));
11278   assign(counter, get_counter_dw0());
11279   put_counter_dw0(mkU64(0));
11280   assign(byte1, load(Ity_I8, mkexpr(address1)));
11281   assign(byte2, load(Ity_I8, mkexpr(address2)));
11282
11283   // end in both? all equal, reset r1 and r2 to start values
11284   s390_cc_set(0);
11285   put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
11286   put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
11287   next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
11288                      binop(Iop_Or8,
11289                            binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
11290                            binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
11291
11292   put_gpr_dw0(r1, mkexpr(address1));
11293   put_gpr_dw0(r2, mkexpr(address2));
11294
11295   // End found in string1
11296   s390_cc_set(1);
11297   next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
11298
11299   // End found in string2
11300   s390_cc_set(2);
11301   next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
11302
11303   // string1 < string2
11304   s390_cc_set(1);
11305   next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
11306                      unop(Iop_8Uto32, mkexpr(byte2))));
11307
11308   // string2 < string1
11309   s390_cc_set(2);
11310   next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
11311                      unop(Iop_8Uto32, mkexpr(byte1))));
11312
11313   // else: all equal, no end yet, loop
11314   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11315   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
11316   put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
11317
11318   iterate();
11319
11320   return "clst";
11321}
11322
11323static void
11324s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11325{
11326   UChar reg;
11327   IRTemp addr = newTemp(Ity_I64);
11328
11329   assign(addr, mkexpr(op2addr));
11330   reg = r1;
11331   do {
11332      IRTemp old = addr;
11333
11334      reg %= 16;
11335      put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
11336      addr = newTemp(Ity_I64);
11337      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11338      reg++;
11339   } while (reg != (r3 + 1));
11340}
11341
11342static const HChar *
11343s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
11344{
11345   s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11346
11347   return "lm";
11348}
11349
11350static const HChar *
11351s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11352{
11353   s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11354
11355   return "lmy";
11356}
11357
11358static const HChar *
11359s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11360{
11361   UChar reg;
11362   IRTemp addr = newTemp(Ity_I64);
11363
11364   assign(addr, mkexpr(op2addr));
11365   reg = r1;
11366   do {
11367      IRTemp old = addr;
11368
11369      reg %= 16;
11370      put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11371      addr = newTemp(Ity_I64);
11372      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11373      reg++;
11374   } while (reg != (r3 + 1));
11375
11376   return "lmh";
11377}
11378
11379static const HChar *
11380s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11381{
11382   UChar reg;
11383   IRTemp addr = newTemp(Ity_I64);
11384
11385   assign(addr, mkexpr(op2addr));
11386   reg = r1;
11387   do {
11388      IRTemp old = addr;
11389
11390      reg %= 16;
11391      put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11392      addr = newTemp(Ity_I64);
11393      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11394      reg++;
11395   } while (reg != (r3 + 1));
11396
11397   return "lmg";
11398}
11399
11400static void
11401s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11402{
11403   UChar reg;
11404   IRTemp addr = newTemp(Ity_I64);
11405
11406   assign(addr, mkexpr(op2addr));
11407   reg = r1;
11408   do {
11409      IRTemp old = addr;
11410
11411      reg %= 16;
11412      store(mkexpr(addr), get_gpr_w1(reg));
11413      addr = newTemp(Ity_I64);
11414      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11415      reg++;
11416   } while( reg != (r3 + 1));
11417}
11418
11419static const HChar *
11420s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11421{
11422   s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11423
11424   return "stm";
11425}
11426
11427static const HChar *
11428s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11429{
11430   s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11431
11432   return "stmy";
11433}
11434
11435static const HChar *
11436s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11437{
11438   UChar reg;
11439   IRTemp addr = newTemp(Ity_I64);
11440
11441   assign(addr, mkexpr(op2addr));
11442   reg = r1;
11443   do {
11444      IRTemp old = addr;
11445
11446      reg %= 16;
11447      store(mkexpr(addr), get_gpr_w0(reg));
11448      addr = newTemp(Ity_I64);
11449      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11450      reg++;
11451   } while( reg != (r3 + 1));
11452
11453   return "stmh";
11454}
11455
11456static const HChar *
11457s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11458{
11459   UChar reg;
11460   IRTemp addr = newTemp(Ity_I64);
11461
11462   assign(addr, mkexpr(op2addr));
11463   reg = r1;
11464   do {
11465      IRTemp old = addr;
11466
11467      reg %= 16;
11468      store(mkexpr(addr), get_gpr_dw0(reg));
11469      addr = newTemp(Ity_I64);
11470      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11471      reg++;
11472   } while( reg != (r3 + 1));
11473
11474   return "stmg";
11475}
11476
11477static void
11478s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
11479{
11480   IRTemp old1 = newTemp(Ity_I8);
11481   IRTemp old2 = newTemp(Ity_I8);
11482   IRTemp new1 = newTemp(Ity_I8);
11483   IRTemp counter = newTemp(Ity_I32);
11484   IRTemp addr1 = newTemp(Ity_I64);
11485
11486   assign(counter, get_counter_w0());
11487
11488   assign(addr1, binop(Iop_Add64, mkexpr(start1),
11489                       unop(Iop_32Uto64, mkexpr(counter))));
11490
11491   assign(old1, load(Ity_I8, mkexpr(addr1)));
11492   assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11493                                   unop(Iop_32Uto64,mkexpr(counter)))));
11494   assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11495
11496   /* Special case: xc is used to zero memory */
11497   if (op == Iop_Xor8) {
11498      store(mkexpr(addr1),
11499            mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11500                  mkU8(0), mkexpr(new1)));
11501   } else
11502      store(mkexpr(addr1), mkexpr(new1));
11503   put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11504                        get_counter_w1()));
11505
11506   /* Check for end of field */
11507   put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
11508   iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
11509   s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11510                      False);
11511   put_counter_dw0(mkU64(0));
11512}
11513
11514static const HChar *
11515s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11516{
11517   IRTemp len = newTemp(Ity_I32);
11518
11519   assign(len, mkU32(length));
11520   s390_irgen_xonc(Iop_Xor8, len, start1, start2);
11521
11522   return "xc";
11523}
11524
11525static void
11526s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11527{
11528   IRTemp counter = newTemp(Ity_I32);
11529   IRTemp start = newTemp(Ity_I64);
11530   IRTemp addr  = newTemp(Ity_I64);
11531
11532   assign(start,
11533          binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11534
11535   if (length < 8) {
11536      UInt i;
11537
11538      for (i = 0; i <= length; ++i) {
11539         store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11540      }
11541   } else {
11542     assign(counter, get_counter_w0());
11543
11544     assign(addr, binop(Iop_Add64, mkexpr(start),
11545                        unop(Iop_32Uto64, mkexpr(counter))));
11546
11547     store(mkexpr(addr), mkU8(0));
11548
11549     /* Check for end of field */
11550     put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
11551     iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
11552
11553     /* Reset counter */
11554     put_counter_dw0(mkU64(0));
11555   }
11556
11557   s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11558
11559   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
11560      s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11561}
11562
11563static const HChar *
11564s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11565{
11566   IRTemp len = newTemp(Ity_I32);
11567
11568   assign(len, mkU32(length));
11569   s390_irgen_xonc(Iop_And8, len, start1, start2);
11570
11571   return "nc";
11572}
11573
11574static const HChar *
11575s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11576{
11577   IRTemp len = newTemp(Ity_I32);
11578
11579   assign(len, mkU32(length));
11580   s390_irgen_xonc(Iop_Or8, len, start1, start2);
11581
11582   return "oc";
11583}
11584
11585
11586static const HChar *
11587s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11588{
11589   IRTemp len = newTemp(Ity_I64);
11590
11591   assign(len, mkU64(length));
11592   s390_irgen_MVC_EX(len, start1, start2);
11593
11594   return "mvc";
11595}
11596
11597static const HChar *
11598s390_irgen_MVCIN(UChar length, IRTemp start1, IRTemp start2)
11599{
11600   IRTemp len = newTemp(Ity_I64);
11601
11602   assign(len, mkU64(length));
11603   s390_irgen_MVCIN_EX(len, start1, start2);
11604
11605   return "mvcin";
11606}
11607
11608static const HChar *
11609s390_irgen_MVCL(UChar r1, UChar r2)
11610{
11611   IRTemp addr1 = newTemp(Ity_I64);
11612   IRTemp addr2 = newTemp(Ity_I64);
11613   IRTemp addr2_load = newTemp(Ity_I64);
11614   IRTemp r1p1 = newTemp(Ity_I32);   /* contents of r1 + 1 */
11615   IRTemp r2p1 = newTemp(Ity_I32);   /* contents of r2 + 1 */
11616   IRTemp len1 = newTemp(Ity_I32);
11617   IRTemp len2 = newTemp(Ity_I32);
11618   IRTemp pad = newTemp(Ity_I8);
11619   IRTemp single = newTemp(Ity_I8);
11620
11621   assign(addr1, get_gpr_dw0(r1));
11622   assign(r1p1, get_gpr_w1(r1 + 1));
11623   assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11624   assign(addr2, get_gpr_dw0(r2));
11625   assign(r2p1, get_gpr_w1(r2 + 1));
11626   assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11627   assign(pad, get_gpr_b4(r2 + 1));
11628
11629   /* len1 == 0 ? */
11630   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
11631   next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
11632
11633   /* Check for destructive overlap:
11634      addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11635   s390_cc_set(3);
11636   IRTemp cond1 = newTemp(Ity_I32);
11637   assign(cond1, unop(Iop_1Uto32,
11638                      binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11639   IRTemp cond2 = newTemp(Ity_I32);
11640   assign(cond2, unop(Iop_1Uto32,
11641                      binop(Iop_CmpLT64U, mkexpr(addr1),
11642                            binop(Iop_Add64, mkexpr(addr2),
11643                                  unop(Iop_32Uto64, mkexpr(len1))))));
11644   IRTemp cond3 = newTemp(Ity_I32);
11645   assign(cond3, unop(Iop_1Uto32,
11646                      binop(Iop_CmpLT64U,
11647                            mkexpr(addr1),
11648                            binop(Iop_Add64, mkexpr(addr2),
11649                                  unop(Iop_32Uto64, mkexpr(len2))))));
11650
11651   next_insn_if(binop(Iop_CmpEQ32,
11652                      binop(Iop_And32,
11653                            binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11654                            mkexpr(cond3)),
11655                      mkU32(1)));
11656
11657   /* See s390_irgen_CLCL for explanation why we cannot load directly
11658      and need two steps. */
11659   assign(addr2_load,
11660          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11661                mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11662   assign(single,
11663          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11664                mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11665
11666   store(mkexpr(addr1), mkexpr(single));
11667
11668   /* Update addr1 and len1 */
11669   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11670   put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11671
11672   /* Update addr2 and len2 */
11673   put_gpr_dw0(r2,
11674               mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11675                     mkexpr(addr2),
11676                     binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11677
11678   /* When updating len2 we must not modify bits (r2+1)[0:39] */
11679   put_gpr_w1(r2 + 1,
11680              mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11681                    binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11682                    binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11683
11684   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
11685   iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
11686
11687   return "mvcl";
11688}
11689
11690
11691static const HChar *
11692s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11693{
11694   IRTemp addr1, addr3, addr3_load, len1, len3, single;
11695
11696   addr1 = newTemp(Ity_I64);
11697   addr3 = newTemp(Ity_I64);
11698   addr3_load = newTemp(Ity_I64);
11699   len1 = newTemp(Ity_I64);
11700   len3 = newTemp(Ity_I64);
11701   single = newTemp(Ity_I8);
11702
11703   assign(addr1, get_gpr_dw0(r1));
11704   assign(len1, get_gpr_dw0(r1 + 1));
11705   assign(addr3, get_gpr_dw0(r3));
11706   assign(len3, get_gpr_dw0(r3 + 1));
11707
11708   // len1 == 0 ?
11709   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
11710   next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
11711
11712   /* This is a hack to prevent mvcle from reading from addr3 if it
11713      should read from the pad. Since the pad has no address, just
11714      read from the instruction, we discard that anyway */
11715   assign(addr3_load,
11716          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11717                mkU64(guest_IA_curr_instr), mkexpr(addr3)));
11718
11719   assign(single,
11720          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11721                unop(Iop_64to8, mkexpr(pad2)),
11722                load(Ity_I8, mkexpr(addr3_load))));
11723   store(mkexpr(addr1), mkexpr(single));
11724
11725   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11726
11727   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11728
11729   put_gpr_dw0(r3,
11730               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11731                     mkexpr(addr3),
11732                     binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
11733
11734   put_gpr_dw0(r3 + 1,
11735               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11736                     mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
11737
11738   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
11739   iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
11740
11741   return "mvcle";
11742}
11743
11744static const HChar *
11745s390_irgen_MVST(UChar r1, UChar r2)
11746{
11747   IRTemp addr1 = newTemp(Ity_I64);
11748   IRTemp addr2 = newTemp(Ity_I64);
11749   IRTemp end = newTemp(Ity_I8);
11750   IRTemp byte = newTemp(Ity_I8);
11751   IRTemp counter = newTemp(Ity_I64);
11752
11753   assign(addr1, get_gpr_dw0(r1));
11754   assign(addr2, get_gpr_dw0(r2));
11755   assign(counter, get_counter_dw0());
11756   assign(end, get_gpr_b7(0));
11757   assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11758   store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11759
11760   // We use unlimited as cpu-determined number
11761   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11762   iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
11763
11764   // and always set cc=1 at the end + update r1
11765   s390_cc_set(1);
11766   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11767   put_counter_dw0(mkU64(0));
11768
11769   return "mvst";
11770}
11771
11772static void
11773s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11774{
11775   IRTemp op1 = newTemp(Ity_I64);
11776   IRTemp result = newTemp(Ity_I64);
11777
11778   assign(op1, binop(Iop_32HLto64,
11779                     get_gpr_w1(r1),         // high 32 bits
11780                     get_gpr_w1(r1 + 1)));   // low  32 bits
11781   assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11782   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));   // remainder
11783   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11784}
11785
11786static void
11787s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11788{
11789   IRTemp op1 = newTemp(Ity_I128);
11790   IRTemp result = newTemp(Ity_I128);
11791
11792   assign(op1, binop(Iop_64HLto128,
11793                     get_gpr_dw0(r1),         // high 64 bits
11794                     get_gpr_dw0(r1 + 1)));   // low  64 bits
11795   assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11796   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));   // remainder
11797   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11798}
11799
11800static void
11801s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11802{
11803   IRTemp op1 = newTemp(Ity_I64);
11804   IRTemp result = newTemp(Ity_I128);
11805
11806   assign(op1, get_gpr_dw0(r1 + 1));
11807   assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11808   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));   // remainder
11809   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11810}
11811
11812static const HChar *
11813s390_irgen_DR(UChar r1, UChar r2)
11814{
11815   IRTemp op2 = newTemp(Ity_I32);
11816
11817   assign(op2, get_gpr_w1(r2));
11818
11819   s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11820
11821   return "dr";
11822}
11823
11824static const HChar *
11825s390_irgen_D(UChar r1, IRTemp op2addr)
11826{
11827   IRTemp op2 = newTemp(Ity_I32);
11828
11829   assign(op2, load(Ity_I32, mkexpr(op2addr)));
11830
11831   s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11832
11833   return "d";
11834}
11835
11836static const HChar *
11837s390_irgen_DLR(UChar r1, UChar r2)
11838{
11839   IRTemp op2 = newTemp(Ity_I32);
11840
11841   assign(op2, get_gpr_w1(r2));
11842
11843   s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11844
11845   return "dlr";
11846}
11847
11848static const HChar *
11849s390_irgen_DL(UChar r1, IRTemp op2addr)
11850{
11851   IRTemp op2 = newTemp(Ity_I32);
11852
11853   assign(op2, load(Ity_I32, mkexpr(op2addr)));
11854
11855   s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11856
11857   return "dl";
11858}
11859
11860static const HChar *
11861s390_irgen_DLG(UChar r1, IRTemp op2addr)
11862{
11863   IRTemp op2 = newTemp(Ity_I64);
11864
11865   assign(op2, load(Ity_I64, mkexpr(op2addr)));
11866
11867   s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11868
11869   return "dlg";
11870}
11871
11872static const HChar *
11873s390_irgen_DLGR(UChar r1, UChar r2)
11874{
11875   IRTemp op2 = newTemp(Ity_I64);
11876
11877   assign(op2, get_gpr_dw0(r2));
11878
11879   s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11880
11881   return "dlgr";
11882}
11883
11884static const HChar *
11885s390_irgen_DSGR(UChar r1, UChar r2)
11886{
11887   IRTemp op2 = newTemp(Ity_I64);
11888
11889   assign(op2, get_gpr_dw0(r2));
11890
11891   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11892
11893   return "dsgr";
11894}
11895
11896static const HChar *
11897s390_irgen_DSG(UChar r1, IRTemp op2addr)
11898{
11899   IRTemp op2 = newTemp(Ity_I64);
11900
11901   assign(op2, load(Ity_I64, mkexpr(op2addr)));
11902
11903   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11904
11905   return "dsg";
11906}
11907
11908static const HChar *
11909s390_irgen_DSGFR(UChar r1, UChar r2)
11910{
11911   IRTemp op2 = newTemp(Ity_I64);
11912
11913   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11914
11915   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11916
11917   return "dsgfr";
11918}
11919
11920static const HChar *
11921s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11922{
11923   IRTemp op2 = newTemp(Ity_I64);
11924
11925   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11926
11927   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11928
11929   return "dsgf";
11930}
11931
11932static void
11933s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11934{
11935   UChar reg;
11936   IRTemp addr = newTemp(Ity_I64);
11937
11938   assign(addr, mkexpr(op2addr));
11939   reg = r1;
11940   do {
11941      IRTemp old = addr;
11942
11943      reg %= 16;
11944      put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11945      addr = newTemp(Ity_I64);
11946      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11947      reg++;
11948   } while (reg != (r3 + 1));
11949}
11950
11951static const HChar *
11952s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11953{
11954   s390_irgen_load_ar_multiple(r1, r3, op2addr);
11955
11956   return "lam";
11957}
11958
11959static const HChar *
11960s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11961{
11962   s390_irgen_load_ar_multiple(r1, r3, op2addr);
11963
11964   return "lamy";
11965}
11966
11967static void
11968s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11969{
11970   UChar reg;
11971   IRTemp addr = newTemp(Ity_I64);
11972
11973   assign(addr, mkexpr(op2addr));
11974   reg = r1;
11975   do {
11976      IRTemp old = addr;
11977
11978      reg %= 16;
11979      store(mkexpr(addr), get_ar_w0(reg));
11980      addr = newTemp(Ity_I64);
11981      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11982      reg++;
11983   } while (reg != (r3 + 1));
11984}
11985
11986static const HChar *
11987s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11988{
11989   s390_irgen_store_ar_multiple(r1, r3, op2addr);
11990
11991   return "stam";
11992}
11993
11994static const HChar *
11995s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11996{
11997   s390_irgen_store_ar_multiple(r1, r3, op2addr);
11998
11999   return "stamy";
12000}
12001
12002
12003/* Implementation for 32-bit compare-and-swap */
12004static void
12005s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
12006{
12007   IRCAS *cas;
12008   IRTemp op1 = newTemp(Ity_I32);
12009   IRTemp old_mem = newTemp(Ity_I32);
12010   IRTemp op3 = newTemp(Ity_I32);
12011   IRTemp result = newTemp(Ity_I32);
12012   IRTemp nequal = newTemp(Ity_I1);
12013
12014   assign(op1, get_gpr_w1(r1));
12015   assign(op3, get_gpr_w1(r3));
12016
12017   /* The first and second operands are compared. If they are equal,
12018      the third operand is stored at the second- operand location. */
12019   cas = mkIRCAS(IRTemp_INVALID, old_mem,
12020                 Iend_BE, mkexpr(op2addr),
12021                 NULL, mkexpr(op1), /* expected value */
12022                 NULL, mkexpr(op3)  /* new value */);
12023   stmt(IRStmt_CAS(cas));
12024
12025   /* Set CC. Operands compared equal -> 0, else 1. */
12026   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
12027   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12028
12029   /* If operands were equal (cc == 0) just store the old value op1 in r1.
12030      Otherwise, store the old_value from memory in r1 and yield. */
12031   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12032   put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
12033   yield_if(mkexpr(nequal));
12034}
12035
12036static const HChar *
12037s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
12038{
12039   s390_irgen_cas_32(r1, r3, op2addr);
12040
12041   return "cs";
12042}
12043
12044static const HChar *
12045s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
12046{
12047   s390_irgen_cas_32(r1, r3, op2addr);
12048
12049   return "csy";
12050}
12051
12052static const HChar *
12053s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
12054{
12055   IRCAS *cas;
12056   IRTemp op1 = newTemp(Ity_I64);
12057   IRTemp old_mem = newTemp(Ity_I64);
12058   IRTemp op3 = newTemp(Ity_I64);
12059   IRTemp result = newTemp(Ity_I64);
12060   IRTemp nequal = newTemp(Ity_I1);
12061
12062   assign(op1, get_gpr_dw0(r1));
12063   assign(op3, get_gpr_dw0(r3));
12064
12065   /* The first and second operands are compared. If they are equal,
12066      the third operand is stored at the second- operand location. */
12067   cas = mkIRCAS(IRTemp_INVALID, old_mem,
12068                 Iend_BE, mkexpr(op2addr),
12069                 NULL, mkexpr(op1), /* expected value */
12070                 NULL, mkexpr(op3)  /* new value */);
12071   stmt(IRStmt_CAS(cas));
12072
12073   /* Set CC. Operands compared equal -> 0, else 1. */
12074   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
12075   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12076
12077   /* If operands were equal (cc == 0) just store the old value op1 in r1.
12078      Otherwise, store the old_value from memory in r1 and yield. */
12079   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12080   put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
12081   yield_if(mkexpr(nequal));
12082
12083   return "csg";
12084}
12085
12086/* Implementation for 32-bit compare-double-and-swap */
12087static void
12088s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
12089{
12090   IRCAS *cas;
12091   IRTemp op1_high = newTemp(Ity_I32);
12092   IRTemp op1_low  = newTemp(Ity_I32);
12093   IRTemp old_mem_high = newTemp(Ity_I32);
12094   IRTemp old_mem_low  = newTemp(Ity_I32);
12095   IRTemp op3_high = newTemp(Ity_I32);
12096   IRTemp op3_low  = newTemp(Ity_I32);
12097   IRTemp result = newTemp(Ity_I32);
12098   IRTemp nequal = newTemp(Ity_I1);
12099
12100   assign(op1_high, get_gpr_w1(r1));
12101   assign(op1_low,  get_gpr_w1(r1+1));
12102   assign(op3_high, get_gpr_w1(r3));
12103   assign(op3_low,  get_gpr_w1(r3+1));
12104
12105   /* The first and second operands are compared. If they are equal,
12106      the third operand is stored at the second-operand location. */
12107   cas = mkIRCAS(old_mem_high, old_mem_low,
12108                 Iend_BE, mkexpr(op2addr),
12109                 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
12110                 mkexpr(op3_high), mkexpr(op3_low)  /* new value */);
12111   stmt(IRStmt_CAS(cas));
12112
12113   /* Set CC. Operands compared equal -> 0, else 1. */
12114   assign(result, unop(Iop_1Uto32,
12115          binop(Iop_CmpNE32,
12116                binop(Iop_Or32,
12117                      binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
12118                      binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
12119                mkU32(0))));
12120
12121   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12122
12123   /* If operands were equal (cc == 0) just store the old value op1 in r1.
12124      Otherwise, store the old_value from memory in r1 and yield. */
12125   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12126   put_gpr_w1(r1,   mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
12127   put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low),  mkexpr(op1_low)));
12128   yield_if(mkexpr(nequal));
12129}
12130
12131static const HChar *
12132s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
12133{
12134   s390_irgen_cdas_32(r1, r3, op2addr);
12135
12136   return "cds";
12137}
12138
12139static const HChar *
12140s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
12141{
12142   s390_irgen_cdas_32(r1, r3, op2addr);
12143
12144   return "cdsy";
12145}
12146
12147static const HChar *
12148s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
12149{
12150   IRCAS *cas;
12151   IRTemp op1_high = newTemp(Ity_I64);
12152   IRTemp op1_low  = newTemp(Ity_I64);
12153   IRTemp old_mem_high = newTemp(Ity_I64);
12154   IRTemp old_mem_low  = newTemp(Ity_I64);
12155   IRTemp op3_high = newTemp(Ity_I64);
12156   IRTemp op3_low  = newTemp(Ity_I64);
12157   IRTemp result = newTemp(Ity_I64);
12158   IRTemp nequal = newTemp(Ity_I1);
12159
12160   assign(op1_high, get_gpr_dw0(r1));
12161   assign(op1_low,  get_gpr_dw0(r1+1));
12162   assign(op3_high, get_gpr_dw0(r3));
12163   assign(op3_low,  get_gpr_dw0(r3+1));
12164
12165   /* The first and second operands are compared. If they are equal,
12166      the third operand is stored at the second-operand location. */
12167   cas = mkIRCAS(old_mem_high, old_mem_low,
12168                 Iend_BE, mkexpr(op2addr),
12169                 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
12170                 mkexpr(op3_high), mkexpr(op3_low)  /* new value */);
12171   stmt(IRStmt_CAS(cas));
12172
12173   /* Set CC. Operands compared equal -> 0, else 1. */
12174   assign(result, unop(Iop_1Uto64,
12175          binop(Iop_CmpNE64,
12176                binop(Iop_Or64,
12177                      binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
12178                      binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
12179                mkU64(0))));
12180
12181   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12182
12183   /* If operands were equal (cc == 0) just store the old value op1 in r1.
12184      Otherwise, store the old_value from memory in r1 and yield. */
12185   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12186   put_gpr_dw0(r1,   mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
12187   put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low),  mkexpr(op1_low)));
12188   yield_if(mkexpr(nequal));
12189
12190   return "cdsg";
12191}
12192
12193
12194/* Binary floating point */
12195
12196static const HChar *
12197s390_irgen_AXBR(UChar r1, UChar r2)
12198{
12199   IRTemp op1 = newTemp(Ity_F128);
12200   IRTemp op2 = newTemp(Ity_F128);
12201   IRTemp result = newTemp(Ity_F128);
12202   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12203
12204   assign(op1, get_fpr_pair(r1));
12205   assign(op2, get_fpr_pair(r2));
12206   assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
12207                        mkexpr(op2)));
12208   put_fpr_pair(r1, mkexpr(result));
12209
12210   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12211
12212   return "axbr";
12213}
12214
12215static const HChar *
12216s390_irgen_CEBR(UChar r1, UChar r2)
12217{
12218   IRTemp op1 = newTemp(Ity_F32);
12219   IRTemp op2 = newTemp(Ity_F32);
12220   IRTemp cc_vex  = newTemp(Ity_I32);
12221   IRTemp cc_s390 = newTemp(Ity_I32);
12222
12223   assign(op1, get_fpr_w0(r1));
12224   assign(op2, get_fpr_w0(r2));
12225   assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12226
12227   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12228   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12229
12230   return "cebr";
12231}
12232
12233static const HChar *
12234s390_irgen_CDBR(UChar r1, UChar r2)
12235{
12236   IRTemp op1 = newTemp(Ity_F64);
12237   IRTemp op2 = newTemp(Ity_F64);
12238   IRTemp cc_vex  = newTemp(Ity_I32);
12239   IRTemp cc_s390 = newTemp(Ity_I32);
12240
12241   assign(op1, get_fpr_dw0(r1));
12242   assign(op2, get_fpr_dw0(r2));
12243   assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12244
12245   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12246   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12247
12248   return "cdbr";
12249}
12250
12251static const HChar *
12252s390_irgen_CXBR(UChar r1, UChar r2)
12253{
12254   IRTemp op1 = newTemp(Ity_F128);
12255   IRTemp op2 = newTemp(Ity_F128);
12256   IRTemp cc_vex  = newTemp(Ity_I32);
12257   IRTemp cc_s390 = newTemp(Ity_I32);
12258
12259   assign(op1, get_fpr_pair(r1));
12260   assign(op2, get_fpr_pair(r2));
12261   assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
12262
12263   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12264   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12265
12266   return "cxbr";
12267}
12268
12269static const HChar *
12270s390_irgen_CEB(UChar r1, IRTemp op2addr)
12271{
12272   IRTemp op1 = newTemp(Ity_F32);
12273   IRTemp op2 = newTemp(Ity_F32);
12274   IRTemp cc_vex  = newTemp(Ity_I32);
12275   IRTemp cc_s390 = newTemp(Ity_I32);
12276
12277   assign(op1, get_fpr_w0(r1));
12278   assign(op2, load(Ity_F32, mkexpr(op2addr)));
12279   assign(cc_vex,  binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12280
12281   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12282   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12283
12284   return "ceb";
12285}
12286
12287static const HChar *
12288s390_irgen_CDB(UChar r1, IRTemp op2addr)
12289{
12290   IRTemp op1 = newTemp(Ity_F64);
12291   IRTemp op2 = newTemp(Ity_F64);
12292   IRTemp cc_vex  = newTemp(Ity_I32);
12293   IRTemp cc_s390 = newTemp(Ity_I32);
12294
12295   assign(op1, get_fpr_dw0(r1));
12296   assign(op2, load(Ity_F64, mkexpr(op2addr)));
12297   assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12298
12299   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12300   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12301
12302   return "cdb";
12303}
12304
12305static const HChar *
12306s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
12307                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12308{
12309   IRTemp op2 = newTemp(Ity_I32);
12310
12311   assign(op2, get_gpr_w1(r2));
12312   put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
12313
12314   return "cxfbr";
12315}
12316
12317static const HChar *
12318s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
12319                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12320{
12321   if (! s390_host_has_fpext) {
12322      emulation_failure(EmFail_S390X_fpext);
12323   } else {
12324      IRTemp op2 = newTemp(Ity_I32);
12325
12326      assign(op2, get_gpr_w1(r2));
12327      put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
12328   }
12329   return "cxlfbr";
12330}
12331
12332
12333static const HChar *
12334s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
12335                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12336{
12337   IRTemp op2 = newTemp(Ity_I64);
12338
12339   assign(op2, get_gpr_dw0(r2));
12340   put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
12341
12342   return "cxgbr";
12343}
12344
12345static const HChar *
12346s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
12347                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12348{
12349   if (! s390_host_has_fpext) {
12350      emulation_failure(EmFail_S390X_fpext);
12351   } else {
12352      IRTemp op2 = newTemp(Ity_I64);
12353
12354      assign(op2, get_gpr_dw0(r2));
12355      put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
12356   }
12357   return "cxlgbr";
12358}
12359
12360static const HChar *
12361s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
12362                 UChar r1, UChar r2)
12363{
12364   IRTemp op = newTemp(Ity_F128);
12365   IRTemp result = newTemp(Ity_I32);
12366   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12367
12368   assign(op, get_fpr_pair(r2));
12369   assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
12370                        mkexpr(op)));
12371   put_gpr_w1(r1, mkexpr(result));
12372   s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
12373
12374   return "cfxbr";
12375}
12376
12377static const HChar *
12378s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12379                  UChar r1, UChar r2)
12380{
12381   if (! s390_host_has_fpext) {
12382      emulation_failure(EmFail_S390X_fpext);
12383   } else {
12384      IRTemp op = newTemp(Ity_F128);
12385      IRTemp result = newTemp(Ity_I32);
12386      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12387
12388      assign(op, get_fpr_pair(r2));
12389      assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
12390                           mkexpr(op)));
12391      put_gpr_w1(r1, mkexpr(result));
12392      s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
12393   }
12394   return "clfxbr";
12395}
12396
12397
12398static const HChar *
12399s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12400                 UChar r1, UChar r2)
12401{
12402   IRTemp op = newTemp(Ity_F128);
12403   IRTemp result = newTemp(Ity_I64);
12404   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12405
12406   assign(op, get_fpr_pair(r2));
12407   assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
12408                        mkexpr(op)));
12409   put_gpr_dw0(r1, mkexpr(result));
12410   s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
12411
12412   return "cgxbr";
12413}
12414
12415static const HChar *
12416s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12417                  UChar r1, UChar r2)
12418{
12419   if (! s390_host_has_fpext) {
12420      emulation_failure(EmFail_S390X_fpext);
12421   } else {
12422      IRTemp op = newTemp(Ity_F128);
12423      IRTemp result = newTemp(Ity_I64);
12424      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12425
12426      assign(op, get_fpr_pair(r2));
12427      assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
12428                           mkexpr(op)));
12429      put_gpr_dw0(r1, mkexpr(result));
12430      s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12431                              rounding_mode);
12432   }
12433   return "clgxbr";
12434}
12435
12436static const HChar *
12437s390_irgen_DXBR(UChar r1, UChar r2)
12438{
12439   IRTemp op1 = newTemp(Ity_F128);
12440   IRTemp op2 = newTemp(Ity_F128);
12441   IRTemp result = newTemp(Ity_F128);
12442   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12443
12444   assign(op1, get_fpr_pair(r1));
12445   assign(op2, get_fpr_pair(r2));
12446   assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
12447                        mkexpr(op2)));
12448   put_fpr_pair(r1, mkexpr(result));
12449
12450   return "dxbr";
12451}
12452
12453static const HChar *
12454s390_irgen_LTXBR(UChar r1, UChar r2)
12455{
12456   IRTemp result = newTemp(Ity_F128);
12457
12458   assign(result, get_fpr_pair(r2));
12459   put_fpr_pair(r1, mkexpr(result));
12460   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12461
12462   return "ltxbr";
12463}
12464
12465static const HChar *
12466s390_irgen_LCXBR(UChar r1, UChar r2)
12467{
12468   IRTemp result = newTemp(Ity_F128);
12469
12470   assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
12471   put_fpr_pair(r1, mkexpr(result));
12472   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12473
12474   return "lcxbr";
12475}
12476
12477static const HChar *
12478s390_irgen_LXDBR(UChar r1, UChar r2)
12479{
12480   IRTemp op = newTemp(Ity_F64);
12481
12482   assign(op, get_fpr_dw0(r2));
12483   put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12484
12485   return "lxdbr";
12486}
12487
12488static const HChar *
12489s390_irgen_LXEBR(UChar r1, UChar r2)
12490{
12491   IRTemp op = newTemp(Ity_F32);
12492
12493   assign(op, get_fpr_w0(r2));
12494   put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12495
12496   return "lxebr";
12497}
12498
12499static const HChar *
12500s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12501{
12502   IRTemp op = newTemp(Ity_F64);
12503
12504   assign(op, load(Ity_F64, mkexpr(op2addr)));
12505   put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12506
12507   return "lxdb";
12508}
12509
12510static const HChar *
12511s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12512{
12513   IRTemp op = newTemp(Ity_F32);
12514
12515   assign(op, load(Ity_F32, mkexpr(op2addr)));
12516   put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12517
12518   return "lxeb";
12519}
12520
12521static const HChar *
12522s390_irgen_FIEBRA(UChar m3, UChar m4 __attribute__((unused)),
12523                  UChar r1, UChar r2)
12524{
12525   IRTemp result = newTemp(Ity_F32);
12526
12527   assign(result, binop(Iop_RoundF32toInt, mkexpr(encode_bfp_rounding_mode(m3)),
12528                        get_fpr_w0(r2)));
12529   put_fpr_w0(r1, mkexpr(result));
12530
12531   return "fiebra";
12532}
12533
12534static const HChar *
12535s390_irgen_FIDBRA(UChar m3, UChar m4 __attribute__((unused)),
12536                  UChar r1, UChar r2)
12537{
12538   IRTemp result = newTemp(Ity_F64);
12539
12540   assign(result, binop(Iop_RoundF64toInt, mkexpr(encode_bfp_rounding_mode(m3)),
12541                        get_fpr_dw0(r2)));
12542   put_fpr_dw0(r1, mkexpr(result));
12543
12544   return "fidbra";
12545}
12546
12547static const HChar *
12548s390_irgen_FIXBRA(UChar m3, UChar m4 __attribute__((unused)),
12549                  UChar r1, UChar r2)
12550{
12551   IRTemp result = newTemp(Ity_F128);
12552
12553   assign(result, binop(Iop_RoundF128toInt, mkexpr(encode_bfp_rounding_mode(m3)),
12554                        get_fpr_pair(r2)));
12555   put_fpr_pair(r1, mkexpr(result));
12556
12557   return "fixbra";
12558}
12559
12560static const HChar *
12561s390_irgen_LNEBR(UChar r1, UChar r2)
12562{
12563   IRTemp result = newTemp(Ity_F32);
12564
12565   assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12566   put_fpr_w0(r1, mkexpr(result));
12567   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12568
12569   return "lnebr";
12570}
12571
12572static const HChar *
12573s390_irgen_LNDBR(UChar r1, UChar r2)
12574{
12575   IRTemp result = newTemp(Ity_F64);
12576
12577   assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12578   put_fpr_dw0(r1, mkexpr(result));
12579   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12580
12581   return "lndbr";
12582}
12583
12584static const HChar *
12585s390_irgen_LNXBR(UChar r1, UChar r2)
12586{
12587   IRTemp result = newTemp(Ity_F128);
12588
12589   assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12590   put_fpr_pair(r1, mkexpr(result));
12591   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12592
12593   return "lnxbr";
12594}
12595
12596static const HChar *
12597s390_irgen_LPEBR(UChar r1, UChar r2)
12598{
12599   IRTemp result = newTemp(Ity_F32);
12600
12601   assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12602   put_fpr_w0(r1, mkexpr(result));
12603   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12604
12605   return "lpebr";
12606}
12607
12608static const HChar *
12609s390_irgen_LPDBR(UChar r1, UChar r2)
12610{
12611   IRTemp result = newTemp(Ity_F64);
12612
12613   assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12614   put_fpr_dw0(r1, mkexpr(result));
12615   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12616
12617   return "lpdbr";
12618}
12619
12620static const HChar *
12621s390_irgen_LPXBR(UChar r1, UChar r2)
12622{
12623   IRTemp result = newTemp(Ity_F128);
12624
12625   assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12626   put_fpr_pair(r1, mkexpr(result));
12627   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12628
12629   return "lpxbr";
12630}
12631
12632static const HChar *
12633s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12634                 UChar r1, UChar r2)
12635{
12636   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
12637      emulation_warning(EmWarn_S390X_fpext_rounding);
12638      m3 = S390_BFP_ROUND_PER_FPC;
12639   }
12640   IRTemp result = newTemp(Ity_F64);
12641
12642   assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
12643                        get_fpr_pair(r2)));
12644   put_fpr_dw0(r1, mkexpr(result));
12645
12646   return "ldxbr";
12647}
12648
12649static const HChar *
12650s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12651                 UChar r1, UChar r2)
12652{
12653   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
12654      emulation_warning(EmWarn_S390X_fpext_rounding);
12655      m3 = S390_BFP_ROUND_PER_FPC;
12656   }
12657   IRTemp result = newTemp(Ity_F32);
12658
12659   assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
12660                        get_fpr_pair(r2)));
12661   put_fpr_w0(r1, mkexpr(result));
12662
12663   return "lexbr";
12664}
12665
12666static const HChar *
12667s390_irgen_MXBR(UChar r1, UChar r2)
12668{
12669   IRTemp op1 = newTemp(Ity_F128);
12670   IRTemp op2 = newTemp(Ity_F128);
12671   IRTemp result = newTemp(Ity_F128);
12672   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12673
12674   assign(op1, get_fpr_pair(r1));
12675   assign(op2, get_fpr_pair(r2));
12676   assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
12677                        mkexpr(op2)));
12678   put_fpr_pair(r1, mkexpr(result));
12679
12680   return "mxbr";
12681}
12682
12683static const HChar *
12684s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12685{
12686   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12687
12688   put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
12689                      get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
12690
12691   return "maebr";
12692}
12693
12694static const HChar *
12695s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12696{
12697   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12698
12699   put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
12700                       get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
12701
12702   return "madbr";
12703}
12704
12705static const HChar *
12706s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12707{
12708   IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
12709   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12710
12711   put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
12712                      get_fpr_w0(r3), op2, get_fpr_w0(r1)));
12713
12714   return "maeb";
12715}
12716
12717static const HChar *
12718s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12719{
12720   IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
12721   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12722
12723   put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
12724                       get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
12725
12726   return "madb";
12727}
12728
12729static const HChar *
12730s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12731{
12732   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12733
12734   put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
12735                      get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
12736
12737   return "msebr";
12738}
12739
12740static const HChar *
12741s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12742{
12743   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12744
12745   put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
12746                       get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
12747
12748   return "msdbr";
12749}
12750
12751static const HChar *
12752s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12753{
12754   IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
12755   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12756
12757   put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
12758                      get_fpr_w0(r3), op2, get_fpr_w0(r1)));
12759
12760   return "mseb";
12761}
12762
12763static const HChar *
12764s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12765{
12766   IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
12767   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12768
12769   put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
12770                       get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
12771
12772   return "msdb";
12773}
12774
12775static const HChar *
12776s390_irgen_SQEBR(UChar r1, UChar r2)
12777{
12778   IRTemp result = newTemp(Ity_F32);
12779   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12780
12781   assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
12782   put_fpr_w0(r1, mkexpr(result));
12783
12784   return "sqebr";
12785}
12786
12787static const HChar *
12788s390_irgen_SQDBR(UChar r1, UChar r2)
12789{
12790   IRTemp result = newTemp(Ity_F64);
12791   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12792
12793   assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
12794   put_fpr_dw0(r1, mkexpr(result));
12795
12796   return "sqdbr";
12797}
12798
12799static const HChar *
12800s390_irgen_SQXBR(UChar r1, UChar r2)
12801{
12802   IRTemp result = newTemp(Ity_F128);
12803   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12804
12805   assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12806                        get_fpr_pair(r2)));
12807   put_fpr_pair(r1, mkexpr(result));
12808
12809   return "sqxbr";
12810}
12811
12812static const HChar *
12813s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12814{
12815   IRTemp op = newTemp(Ity_F32);
12816   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12817
12818   assign(op, load(Ity_F32, mkexpr(op2addr)));
12819   put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
12820
12821   return "sqeb";
12822}
12823
12824static const HChar *
12825s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12826{
12827   IRTemp op = newTemp(Ity_F64);
12828   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12829
12830   assign(op, load(Ity_F64, mkexpr(op2addr)));
12831   put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
12832
12833   return "sqdb";
12834}
12835
12836static const HChar *
12837s390_irgen_SXBR(UChar r1, UChar r2)
12838{
12839   IRTemp op1 = newTemp(Ity_F128);
12840   IRTemp op2 = newTemp(Ity_F128);
12841   IRTemp result = newTemp(Ity_F128);
12842   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12843
12844   assign(op1, get_fpr_pair(r1));
12845   assign(op2, get_fpr_pair(r2));
12846   assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
12847                        mkexpr(op2)));
12848   put_fpr_pair(r1, mkexpr(result));
12849   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12850
12851   return "sxbr";
12852}
12853
12854static const HChar *
12855s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12856{
12857   IRTemp value = newTemp(Ity_F32);
12858
12859   assign(value, get_fpr_w0(r1));
12860
12861   s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12862
12863   return "tceb";
12864}
12865
12866static const HChar *
12867s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12868{
12869   IRTemp value = newTemp(Ity_F64);
12870
12871   assign(value, get_fpr_dw0(r1));
12872
12873   s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12874
12875   return "tcdb";
12876}
12877
12878static const HChar *
12879s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12880{
12881   IRTemp value = newTemp(Ity_F128);
12882
12883   assign(value, get_fpr_pair(r1));
12884
12885   s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12886
12887   return "tcxb";
12888}
12889
12890static const HChar *
12891s390_irgen_LCDFR(UChar r1, UChar r2)
12892{
12893   IRTemp result = newTemp(Ity_F64);
12894
12895   assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12896   put_fpr_dw0(r1, mkexpr(result));
12897
12898   return "lcdfr";
12899}
12900
12901static const HChar *
12902s390_irgen_LNDFR(UChar r1, UChar r2)
12903{
12904   IRTemp result = newTemp(Ity_F64);
12905
12906   assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12907   put_fpr_dw0(r1, mkexpr(result));
12908
12909   return "lndfr";
12910}
12911
12912static const HChar *
12913s390_irgen_LPDFR(UChar r1, UChar r2)
12914{
12915   IRTemp result = newTemp(Ity_F64);
12916
12917   assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12918   put_fpr_dw0(r1, mkexpr(result));
12919
12920   return "lpdfr";
12921}
12922
12923static const HChar *
12924s390_irgen_LDGR(UChar r1, UChar r2)
12925{
12926   put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12927
12928   return "ldgr";
12929}
12930
12931static const HChar *
12932s390_irgen_LGDR(UChar r1, UChar r2)
12933{
12934   put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12935
12936   return "lgdr";
12937}
12938
12939
12940static const HChar *
12941s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12942{
12943   IRTemp sign  = newTemp(Ity_I64);
12944   IRTemp value = newTemp(Ity_I64);
12945
12946   assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12947                      mkU64(1ULL << 63)));
12948   assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12949                       mkU64((1ULL << 63) - 1)));
12950   put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12951                                                    mkexpr(sign))));
12952
12953   return "cpsdr";
12954}
12955
12956
12957static IRExpr *
12958s390_call_cvb(IRExpr *in)
12959{
12960   IRExpr **args, *call;
12961
12962   args = mkIRExprVec_1(in);
12963   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12964                        "s390_do_cvb", &s390_do_cvb, args);
12965
12966   /* Nothing is excluded from definedness checking. */
12967   call->Iex.CCall.cee->mcx_mask = 0;
12968
12969   return call;
12970}
12971
12972static const HChar *
12973s390_irgen_CVB(UChar r1, IRTemp op2addr)
12974{
12975   put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12976
12977   return "cvb";
12978}
12979
12980static const HChar *
12981s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12982{
12983   put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12984
12985   return "cvby";
12986}
12987
12988
12989static IRExpr *
12990s390_call_cvd(IRExpr *in)
12991{
12992   IRExpr **args, *call;
12993
12994   args = mkIRExprVec_1(in);
12995   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12996                        "s390_do_cvd", &s390_do_cvd, args);
12997
12998   /* Nothing is excluded from definedness checking. */
12999   call->Iex.CCall.cee->mcx_mask = 0;
13000
13001   return call;
13002}
13003
13004static const HChar *
13005s390_irgen_CVD(UChar r1, IRTemp op2addr)
13006{
13007   store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
13008
13009   return "cvd";
13010}
13011
13012static const HChar *
13013s390_irgen_CVDY(UChar r1, IRTemp op2addr)
13014{
13015   store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
13016
13017   return "cvdy";
13018}
13019
13020static const HChar *
13021s390_irgen_FLOGR(UChar r1, UChar r2)
13022{
13023   IRTemp input    = newTemp(Ity_I64);
13024   IRTemp not_zero = newTemp(Ity_I64);
13025   IRTemp tmpnum   = newTemp(Ity_I64);
13026   IRTemp num      = newTemp(Ity_I64);
13027   IRTemp shift_amount = newTemp(Ity_I8);
13028
13029   /* We use the "count leading zeroes" operator because the number of
13030      leading zeroes is identical with the bit position of the first '1' bit.
13031      However, that operator does not work when the input value is zero.
13032      Therefore, we set the LSB of the input value to 1 and use Clz64 on
13033      the modified value. If input == 0, then the result is 64. Otherwise,
13034      the result of Clz64 is what we want. */
13035
13036   assign(input, get_gpr_dw0(r2));
13037   assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
13038   assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
13039
13040   /* num = (input == 0) ? 64 : tmpnum */
13041   assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
13042                     /* == 0 */ mkU64(64),
13043                     /* != 0 */ mkexpr(tmpnum)));
13044
13045   put_gpr_dw0(r1, mkexpr(num));
13046
13047   /* Set the leftmost '1' bit of the input value to zero. The general scheme
13048      is to first shift the input value by NUM + 1 bits to the left which
13049      causes the leftmost '1' bit to disappear. Then we shift logically to
13050      the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
13051      Iop_Shr64 are undefined if the shift-amount is greater than or equal to
13052      the width of the value-to-be-shifted, we need to special case
13053      NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
13054      For both such INPUT values the result will be 0. */
13055
13056   assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
13057                          mkU64(1))));
13058
13059   put_gpr_dw0(r1 + 1,
13060               mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
13061                     /* == 0 || == 1*/ mkU64(0),
13062                     /* otherwise */
13063                     binop(Iop_Shr64,
13064                           binop(Iop_Shl64, mkexpr(input),
13065                                 mkexpr(shift_amount)),
13066                           mkexpr(shift_amount))));
13067
13068   /* Compare the original value as an unsigned integer with 0. */
13069   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
13070                      mktemp(Ity_I64, mkU64(0)), False);
13071
13072   return "flogr";
13073}
13074
13075static const HChar *
13076s390_irgen_POPCNT(UChar r1, UChar r2)
13077{
13078   Int i;
13079   IRTemp val = newTemp(Ity_I64);
13080   IRTemp mask[3];
13081
13082   assign(val, get_gpr_dw0(r2));
13083   for (i = 0; i < 3; i++) {
13084      mask[i] = newTemp(Ity_I64);
13085   }
13086   assign(mask[0], mkU64(0x5555555555555555ULL));
13087   assign(mask[1], mkU64(0x3333333333333333ULL));
13088   assign(mask[2], mkU64(0x0F0F0F0F0F0F0F0FULL));
13089   for (i = 0; i < 3; i++) {
13090      IRTemp tmp = newTemp(Ity_I64);
13091
13092      assign(tmp,
13093             binop(Iop_Add64,
13094                   binop(Iop_And64,
13095                         mkexpr(val),
13096                         mkexpr(mask[i])),
13097                   binop(Iop_And64,
13098                         binop(Iop_Shr64, mkexpr(val), mkU8(1 << i)),
13099                         mkexpr(mask[i]))));
13100      val = tmp;
13101   }
13102   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, val);
13103   put_gpr_dw0(r1, mkexpr(val));
13104   return "popcnt";
13105}
13106
13107static const HChar *
13108s390_irgen_STCK(IRTemp op2addr)
13109{
13110   IRDirty *d;
13111   IRTemp cc = newTemp(Ity_I64);
13112
13113   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
13114                         &s390x_dirtyhelper_STCK,
13115                         mkIRExprVec_1(mkexpr(op2addr)));
13116   d->mFx   = Ifx_Write;
13117   d->mAddr = mkexpr(op2addr);
13118   d->mSize = 8;
13119   stmt(IRStmt_Dirty(d));
13120   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
13121                      mkexpr(cc), mkU64(0), mkU64(0));
13122   return "stck";
13123}
13124
13125static const HChar *
13126s390_irgen_STCKF(IRTemp op2addr)
13127{
13128   if (! s390_host_has_stckf) {
13129      emulation_failure(EmFail_S390X_stckf);
13130   } else {
13131      IRTemp cc = newTemp(Ity_I64);
13132
13133      IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
13134                                     &s390x_dirtyhelper_STCKF,
13135                                     mkIRExprVec_1(mkexpr(op2addr)));
13136      d->mFx   = Ifx_Write;
13137      d->mAddr = mkexpr(op2addr);
13138      d->mSize = 8;
13139      stmt(IRStmt_Dirty(d));
13140      s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
13141                         mkexpr(cc), mkU64(0), mkU64(0));
13142   }
13143   return "stckf";
13144}
13145
13146static const HChar *
13147s390_irgen_STCKE(IRTemp op2addr)
13148{
13149   IRDirty *d;
13150   IRTemp cc = newTemp(Ity_I64);
13151
13152   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
13153                         &s390x_dirtyhelper_STCKE,
13154                         mkIRExprVec_1(mkexpr(op2addr)));
13155   d->mFx   = Ifx_Write;
13156   d->mAddr = mkexpr(op2addr);
13157   d->mSize = 16;
13158   stmt(IRStmt_Dirty(d));
13159   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
13160                      mkexpr(cc), mkU64(0), mkU64(0));
13161   return "stcke";
13162}
13163
13164static const HChar *
13165s390_irgen_STFLE(IRTemp op2addr)
13166{
13167   if (! s390_host_has_stfle) {
13168      emulation_failure(EmFail_S390X_stfle);
13169      return "stfle";
13170   }
13171
13172   IRDirty *d;
13173   IRTemp cc = newTemp(Ity_I64);
13174
13175   /* IRExpr_GSPTR() => Need to pass pointer to guest state to helper */
13176   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
13177                         &s390x_dirtyhelper_STFLE,
13178                         mkIRExprVec_2(IRExpr_GSPTR(), mkexpr(op2addr)));
13179
13180   d->nFxState = 1;
13181   vex_bzero(&d->fxState, sizeof(d->fxState));
13182
13183   d->fxState[0].fx     = Ifx_Modify;  /* read then write */
13184   d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
13185   d->fxState[0].size   = sizeof(ULong);
13186
13187   d->mAddr = mkexpr(op2addr);
13188   /* Pretend all double words are written */
13189   d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
13190   d->mFx   = Ifx_Write;
13191
13192   stmt(IRStmt_Dirty(d));
13193
13194   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
13195
13196   return "stfle";
13197}
13198
13199static const HChar *
13200s390_irgen_CKSM(UChar r1,UChar r2)
13201{
13202   IRTemp addr = newTemp(Ity_I64);
13203   IRTemp op = newTemp(Ity_I32);
13204   IRTemp len = newTemp(Ity_I64);
13205   IRTemp oldval = newTemp(Ity_I32);
13206   IRTemp mask = newTemp(Ity_I32);
13207   IRTemp newop = newTemp(Ity_I32);
13208   IRTemp result = newTemp(Ity_I32);
13209   IRTemp result1 = newTemp(Ity_I32);
13210   IRTemp inc = newTemp(Ity_I64);
13211
13212   assign(oldval, get_gpr_w1(r1));
13213   assign(addr, get_gpr_dw0(r2));
13214   assign(len, get_gpr_dw0(r2+1));
13215
13216   /* Condition code is always zero. */
13217   s390_cc_set(0);
13218
13219   /* If length is zero, there is no need to calculate the checksum */
13220   next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
13221
13222   /* Assiging the increment variable to adjust address and length
13223      later on. */
13224   assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
13225                           mkexpr(len), mkU64(4)));
13226
13227   /* If length < 4 the final 4-byte 2nd operand value is computed by
13228      appending the remaining bytes to the right with 0. This is done
13229      by AND'ing the 4 bytes loaded from memory with an appropriate
13230      mask. If length >= 4, that mask is simply 0xffffffff. */
13231
13232   assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
13233                      /* Mask computation when len < 4:
13234                         0xffffffff << (32 - (len % 4)*8) */
13235                      binop(Iop_Shl32, mkU32(0xffffffff),
13236                            unop(Iop_32to8,
13237                                 binop(Iop_Sub32, mkU32(32),
13238                                       binop(Iop_Shl32,
13239                                             unop(Iop_64to32,
13240                                                  binop(Iop_And64,
13241                                                        mkexpr(len), mkU64(3))),
13242                                             mkU8(3))))),
13243                      mkU32(0xffffffff)));
13244
13245   assign(op, load(Ity_I32, mkexpr(addr)));
13246   assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
13247   assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
13248
13249   /* Checking for carry */
13250   assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
13251                         binop(Iop_Add32, mkexpr(result), mkU32(1)),
13252                         mkexpr(result)));
13253
13254   put_gpr_w1(r1, mkexpr(result1));
13255   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
13256   put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
13257
13258   iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
13259
13260   return "cksm";
13261}
13262
13263static const HChar *
13264s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
13265{
13266   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13267   src_addr = newTemp(Ity_I64);
13268   des_addr = newTemp(Ity_I64);
13269   tab_addr = newTemp(Ity_I64);
13270   test_byte = newTemp(Ity_I8);
13271   src_len = newTemp(Ity_I64);
13272
13273   assign(src_addr, get_gpr_dw0(r2));
13274   assign(des_addr, get_gpr_dw0(r1));
13275   assign(tab_addr, get_gpr_dw0(1));
13276   assign(src_len, get_gpr_dw0(r1+1));
13277   assign(test_byte, get_gpr_b7(0));
13278
13279   IRTemp op = newTemp(Ity_I8);
13280   IRTemp op1 = newTemp(Ity_I8);
13281   IRTemp result = newTemp(Ity_I64);
13282
13283   /* End of source string? We're done; proceed to next insn */
13284   s390_cc_set(0);
13285   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13286
13287   /* Load character from source string, index translation table and
13288      store translated character in op1. */
13289   assign(op, load(Ity_I8, mkexpr(src_addr)));
13290
13291   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13292                        mkexpr(tab_addr)));
13293   assign(op1, load(Ity_I8, mkexpr(result)));
13294
13295   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13296      s390_cc_set(1);
13297      next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
13298   }
13299   store(get_gpr_dw0(r1), mkexpr(op1));
13300
13301   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13302   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13303   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13304
13305   iterate();
13306
13307   return "troo";
13308}
13309
13310static const HChar *
13311s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
13312{
13313   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13314   src_addr = newTemp(Ity_I64);
13315   des_addr = newTemp(Ity_I64);
13316   tab_addr = newTemp(Ity_I64);
13317   test_byte = newTemp(Ity_I8);
13318   src_len = newTemp(Ity_I64);
13319
13320   assign(src_addr, get_gpr_dw0(r2));
13321   assign(des_addr, get_gpr_dw0(r1));
13322   assign(tab_addr, get_gpr_dw0(1));
13323   assign(src_len, get_gpr_dw0(r1+1));
13324   assign(test_byte, get_gpr_b7(0));
13325
13326   IRTemp op = newTemp(Ity_I16);
13327   IRTemp op1 = newTemp(Ity_I8);
13328   IRTemp result = newTemp(Ity_I64);
13329
13330   /* End of source string? We're done; proceed to next insn */
13331   s390_cc_set(0);
13332   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13333
13334   /* Load character from source string, index translation table and
13335      store translated character in op1. */
13336   assign(op, load(Ity_I16, mkexpr(src_addr)));
13337
13338   assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13339                        mkexpr(tab_addr)));
13340
13341   assign(op1, load(Ity_I8, mkexpr(result)));
13342
13343   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13344      s390_cc_set(1);
13345      next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
13346   }
13347   store(get_gpr_dw0(r1), mkexpr(op1));
13348
13349   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13350   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13351   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13352
13353   iterate();
13354
13355   return "trto";
13356}
13357
13358static const HChar *
13359s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
13360{
13361   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13362   src_addr = newTemp(Ity_I64);
13363   des_addr = newTemp(Ity_I64);
13364   tab_addr = newTemp(Ity_I64);
13365   test_byte = newTemp(Ity_I16);
13366   src_len = newTemp(Ity_I64);
13367
13368   assign(src_addr, get_gpr_dw0(r2));
13369   assign(des_addr, get_gpr_dw0(r1));
13370   assign(tab_addr, get_gpr_dw0(1));
13371   assign(src_len, get_gpr_dw0(r1+1));
13372   assign(test_byte, get_gpr_hw3(0));
13373
13374   IRTemp op = newTemp(Ity_I8);
13375   IRTemp op1 = newTemp(Ity_I16);
13376   IRTemp result = newTemp(Ity_I64);
13377
13378   /* End of source string? We're done; proceed to next insn */
13379   s390_cc_set(0);
13380   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13381
13382   /* Load character from source string, index translation table and
13383      store translated character in op1. */
13384   assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
13385
13386   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13387                        mkexpr(tab_addr)));
13388   assign(op1, load(Ity_I16, mkexpr(result)));
13389
13390   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13391      s390_cc_set(1);
13392      next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
13393   }
13394   store(get_gpr_dw0(r1), mkexpr(op1));
13395
13396   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13397   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13398   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13399
13400   iterate();
13401
13402   return "trot";
13403}
13404
13405static const HChar *
13406s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
13407{
13408   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13409   src_addr = newTemp(Ity_I64);
13410   des_addr = newTemp(Ity_I64);
13411   tab_addr = newTemp(Ity_I64);
13412   test_byte = newTemp(Ity_I16);
13413   src_len = newTemp(Ity_I64);
13414
13415   assign(src_addr, get_gpr_dw0(r2));
13416   assign(des_addr, get_gpr_dw0(r1));
13417   assign(tab_addr, get_gpr_dw0(1));
13418   assign(src_len, get_gpr_dw0(r1+1));
13419   assign(test_byte, get_gpr_hw3(0));
13420
13421   IRTemp op = newTemp(Ity_I16);
13422   IRTemp op1 = newTemp(Ity_I16);
13423   IRTemp result = newTemp(Ity_I64);
13424
13425   /* End of source string? We're done; proceed to next insn */
13426   s390_cc_set(0);
13427   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13428
13429   /* Load character from source string, index translation table and
13430      store translated character in op1. */
13431   assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
13432
13433   assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13434                        mkexpr(tab_addr)));
13435   assign(op1, load(Ity_I16, mkexpr(result)));
13436
13437   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13438      s390_cc_set(1);
13439      next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
13440   }
13441
13442   store(get_gpr_dw0(r1), mkexpr(op1));
13443
13444   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13445   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13446   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13447
13448   iterate();
13449
13450   return "trtt";
13451}
13452
13453static const HChar *
13454s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13455{
13456   IRTemp len = newTemp(Ity_I64);
13457
13458   assign(len, mkU64(length));
13459   s390_irgen_TR_EX(len, start1, start2);
13460
13461   return "tr";
13462}
13463
13464static const HChar *
13465s390_irgen_TRE(UChar r1,UChar r2)
13466{
13467   IRTemp src_addr, tab_addr, src_len, test_byte;
13468   src_addr = newTemp(Ity_I64);
13469   tab_addr = newTemp(Ity_I64);
13470   src_len = newTemp(Ity_I64);
13471   test_byte = newTemp(Ity_I8);
13472
13473   assign(src_addr, get_gpr_dw0(r1));
13474   assign(src_len, get_gpr_dw0(r1+1));
13475   assign(tab_addr, get_gpr_dw0(r2));
13476   assign(test_byte, get_gpr_b7(0));
13477
13478   IRTemp op = newTemp(Ity_I8);
13479   IRTemp op1 = newTemp(Ity_I8);
13480   IRTemp result = newTemp(Ity_I64);
13481
13482   /* End of source string? We're done; proceed to next insn */
13483   s390_cc_set(0);
13484   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13485
13486   /* Load character from source string and compare with test byte */
13487   assign(op, load(Ity_I8, mkexpr(src_addr)));
13488
13489   s390_cc_set(1);
13490   next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
13491
13492   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13493			mkexpr(tab_addr)));
13494
13495   assign(op1, load(Ity_I8, mkexpr(result)));
13496
13497   store(get_gpr_dw0(r1), mkexpr(op1));
13498   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13499   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13500
13501   iterate();
13502
13503   return "tre";
13504}
13505
13506static IRExpr *
13507s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13508{
13509   IRExpr **args, *call;
13510   args = mkIRExprVec_2(srcval, low_surrogate);
13511   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13512                       "s390_do_cu21", &s390_do_cu21, args);
13513
13514   /* Nothing is excluded from definedness checking. */
13515   call->Iex.CCall.cee->mcx_mask = 0;
13516
13517   return call;
13518}
13519
13520static const HChar *
13521s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13522{
13523   IRTemp addr1 = newTemp(Ity_I64);
13524   IRTemp addr2 = newTemp(Ity_I64);
13525   IRTemp len1 = newTemp(Ity_I64);
13526   IRTemp len2 = newTemp(Ity_I64);
13527
13528   assign(addr1, get_gpr_dw0(r1));
13529   assign(addr2, get_gpr_dw0(r2));
13530   assign(len1, get_gpr_dw0(r1 + 1));
13531   assign(len2, get_gpr_dw0(r2 + 1));
13532
13533   /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13534      there are less than 2 bytes left, then the 2nd operand is exhausted
13535      and we're done here. cc = 0 */
13536   s390_cc_set(0);
13537   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
13538
13539   /* There are at least two bytes there. Read them. */
13540   IRTemp srcval = newTemp(Ity_I32);
13541   assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13542
13543   /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13544      inside the interval [0xd800 - 0xdbff] */
13545   IRTemp  is_high_surrogate = newTemp(Ity_I32);
13546   IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13547                         mkU32(1), mkU32(0));
13548   IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13549                         mkU32(1), mkU32(0));
13550   assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13551
13552   /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13553      then the 2nd operand is exhausted and we're done here. cc = 0 */
13554   IRExpr *not_enough_bytes =
13555      mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13556
13557   next_insn_if(binop(Iop_CmpEQ32,
13558                      binop(Iop_And32, mkexpr(is_high_surrogate),
13559                            not_enough_bytes), mkU32(1)));
13560
13561   /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13562      surrogate, read the next two bytes (low surrogate). */
13563   IRTemp  low_surrogate = newTemp(Ity_I32);
13564   IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13565
13566   assign(low_surrogate,
13567          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13568                unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13569                mkU32(0)));  // any value is fine; it will not be used
13570
13571   /* Call the helper */
13572   IRTemp retval = newTemp(Ity_I64);
13573   assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13574                                 unop(Iop_32Uto64, mkexpr(low_surrogate))));
13575
13576   /* Before we can test whether the 1st operand is exhausted we need to
13577      test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13578   if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13579      IRExpr *invalid_low_surrogate =
13580         binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13581
13582      s390_cc_set(2);
13583      next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
13584   }
13585
13586   /* Now test whether the 1st operand is exhausted */
13587   IRTemp num_bytes = newTemp(Ity_I64);
13588   assign(num_bytes, binop(Iop_And64,
13589                           binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13590                           mkU64(0xff)));
13591   s390_cc_set(1);
13592   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13593
13594   /* Extract the bytes to be stored at addr1 */
13595   IRTemp data = newTemp(Ity_I64);
13596   assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13597
13598   /* To store the bytes construct 4 dirty helper calls. The helper calls
13599      are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13600      one of them will be called at runtime. */
13601   UInt i;
13602   for (i = 1; i <= 4; ++i) {
13603      IRDirty *d;
13604
13605      d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13606                            &s390x_dirtyhelper_CUxy,
13607                            mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13608                                          mkexpr(num_bytes)));
13609      d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13610      d->mFx   = Ifx_Write;
13611      d->mAddr = mkexpr(addr1);
13612      d->mSize = i;
13613      stmt(IRStmt_Dirty(d));
13614   }
13615
13616   /* Update source address and length */
13617   IRTemp num_src_bytes = newTemp(Ity_I64);
13618   assign(num_src_bytes,
13619          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13620                mkU64(4), mkU64(2)));
13621   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13622   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
13623
13624   /* Update destination address and length */
13625   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13626   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13627
13628   iterate();
13629
13630   return "cu21";
13631}
13632
13633static IRExpr *
13634s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13635{
13636   IRExpr **args, *call;
13637   args = mkIRExprVec_2(srcval, low_surrogate);
13638   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13639                       "s390_do_cu24", &s390_do_cu24, args);
13640
13641   /* Nothing is excluded from definedness checking. */
13642   call->Iex.CCall.cee->mcx_mask = 0;
13643
13644   return call;
13645}
13646
13647static const HChar *
13648s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13649{
13650   IRTemp addr1 = newTemp(Ity_I64);
13651   IRTemp addr2 = newTemp(Ity_I64);
13652   IRTemp len1 = newTemp(Ity_I64);
13653   IRTemp len2 = newTemp(Ity_I64);
13654
13655   assign(addr1, get_gpr_dw0(r1));
13656   assign(addr2, get_gpr_dw0(r2));
13657   assign(len1, get_gpr_dw0(r1 + 1));
13658   assign(len2, get_gpr_dw0(r2 + 1));
13659
13660   /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13661      there are less than 2 bytes left, then the 2nd operand is exhausted
13662      and we're done here. cc = 0 */
13663   s390_cc_set(0);
13664   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
13665
13666   /* There are at least two bytes there. Read them. */
13667   IRTemp srcval = newTemp(Ity_I32);
13668   assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13669
13670   /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13671      inside the interval [0xd800 - 0xdbff] */
13672   IRTemp  is_high_surrogate = newTemp(Ity_I32);
13673   IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13674                         mkU32(1), mkU32(0));
13675   IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13676                         mkU32(1), mkU32(0));
13677   assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13678
13679   /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13680      then the 2nd operand is exhausted and we're done here. cc = 0 */
13681   IRExpr *not_enough_bytes =
13682      mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13683
13684   next_insn_if(binop(Iop_CmpEQ32,
13685                      binop(Iop_And32, mkexpr(is_high_surrogate),
13686                            not_enough_bytes),
13687                      mkU32(1)));
13688
13689   /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13690      surrogate, read the next two bytes (low surrogate). */
13691   IRTemp  low_surrogate = newTemp(Ity_I32);
13692   IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13693
13694   assign(low_surrogate,
13695          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13696                unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13697                mkU32(0)));  // any value is fine; it will not be used
13698
13699   /* Call the helper */
13700   IRTemp retval = newTemp(Ity_I64);
13701   assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13702                                 unop(Iop_32Uto64, mkexpr(low_surrogate))));
13703
13704   /* Before we can test whether the 1st operand is exhausted we need to
13705      test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13706   if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13707      IRExpr *invalid_low_surrogate =
13708         binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13709
13710      s390_cc_set(2);
13711      next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
13712   }
13713
13714   /* Now test whether the 1st operand is exhausted */
13715   s390_cc_set(1);
13716   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
13717
13718   /* Extract the bytes to be stored at addr1 */
13719   IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13720
13721   store(mkexpr(addr1), data);
13722
13723   /* Update source address and length */
13724   IRTemp num_src_bytes = newTemp(Ity_I64);
13725   assign(num_src_bytes,
13726          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13727                mkU64(4), mkU64(2)));
13728   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13729   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
13730
13731   /* Update destination address and length */
13732   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13733   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkU64(4)));
13734
13735   iterate();
13736
13737   return "cu24";
13738}
13739
13740static IRExpr *
13741s390_call_cu42(IRExpr *srcval)
13742{
13743   IRExpr **args, *call;
13744   args = mkIRExprVec_1(srcval);
13745   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13746                       "s390_do_cu42", &s390_do_cu42, args);
13747
13748   /* Nothing is excluded from definedness checking. */
13749   call->Iex.CCall.cee->mcx_mask = 0;
13750
13751   return call;
13752}
13753
13754static const HChar *
13755s390_irgen_CU42(UChar r1, UChar r2)
13756{
13757   IRTemp addr1 = newTemp(Ity_I64);
13758   IRTemp addr2 = newTemp(Ity_I64);
13759   IRTemp len1 = newTemp(Ity_I64);
13760   IRTemp len2 = newTemp(Ity_I64);
13761
13762   assign(addr1, get_gpr_dw0(r1));
13763   assign(addr2, get_gpr_dw0(r2));
13764   assign(len1, get_gpr_dw0(r1 + 1));
13765   assign(len2, get_gpr_dw0(r2 + 1));
13766
13767   /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13768      there are less than 4 bytes left, then the 2nd operand is exhausted
13769      and we're done here. cc = 0 */
13770   s390_cc_set(0);
13771   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13772
13773   /* Read the 2nd operand. */
13774   IRTemp srcval = newTemp(Ity_I32);
13775   assign(srcval, load(Ity_I32, mkexpr(addr2)));
13776
13777   /* Call the helper */
13778   IRTemp retval = newTemp(Ity_I64);
13779   assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
13780
13781   /* If the UTF-32 character was invalid, set cc=2 and we're done.
13782      cc=2 outranks cc=1 (1st operand exhausted) */
13783   IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13784
13785   s390_cc_set(2);
13786   next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13787
13788   /* Now test whether the 1st operand is exhausted */
13789   IRTemp num_bytes = newTemp(Ity_I64);
13790   assign(num_bytes, binop(Iop_And64,
13791                           binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13792                           mkU64(0xff)));
13793   s390_cc_set(1);
13794   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13795
13796   /* Extract the bytes to be stored at addr1 */
13797   IRTemp data = newTemp(Ity_I64);
13798   assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13799
13800   /* To store the bytes construct 2 dirty helper calls. The helper calls
13801      are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13802      that only one of them will be called at runtime. */
13803
13804   Int i;
13805   for (i = 2; i <= 4; ++i) {
13806      IRDirty *d;
13807
13808      if (i == 3) continue;  // skip this one
13809
13810      d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13811                            &s390x_dirtyhelper_CUxy,
13812                            mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13813                                          mkexpr(num_bytes)));
13814      d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13815      d->mFx   = Ifx_Write;
13816      d->mAddr = mkexpr(addr1);
13817      d->mSize = i;
13818      stmt(IRStmt_Dirty(d));
13819   }
13820
13821   /* Update source address and length */
13822   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13823   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkU64(4)));
13824
13825   /* Update destination address and length */
13826   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13827   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13828
13829   iterate();
13830
13831   return "cu42";
13832}
13833
13834static IRExpr *
13835s390_call_cu41(IRExpr *srcval)
13836{
13837   IRExpr **args, *call;
13838   args = mkIRExprVec_1(srcval);
13839   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13840                       "s390_do_cu41", &s390_do_cu41, args);
13841
13842   /* Nothing is excluded from definedness checking. */
13843   call->Iex.CCall.cee->mcx_mask = 0;
13844
13845   return call;
13846}
13847
13848static const HChar *
13849s390_irgen_CU41(UChar r1, UChar r2)
13850{
13851   IRTemp addr1 = newTemp(Ity_I64);
13852   IRTemp addr2 = newTemp(Ity_I64);
13853   IRTemp len1 = newTemp(Ity_I64);
13854   IRTemp len2 = newTemp(Ity_I64);
13855
13856   assign(addr1, get_gpr_dw0(r1));
13857   assign(addr2, get_gpr_dw0(r2));
13858   assign(len1, get_gpr_dw0(r1 + 1));
13859   assign(len2, get_gpr_dw0(r2 + 1));
13860
13861   /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13862      there are less than 4 bytes left, then the 2nd operand is exhausted
13863      and we're done here. cc = 0 */
13864   s390_cc_set(0);
13865   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13866
13867   /* Read the 2nd operand. */
13868   IRTemp srcval = newTemp(Ity_I32);
13869   assign(srcval, load(Ity_I32, mkexpr(addr2)));
13870
13871   /* Call the helper */
13872   IRTemp retval = newTemp(Ity_I64);
13873   assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
13874
13875   /* If the UTF-32 character was invalid, set cc=2 and we're done.
13876      cc=2 outranks cc=1 (1st operand exhausted) */
13877   IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13878
13879   s390_cc_set(2);
13880   next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13881
13882   /* Now test whether the 1st operand is exhausted */
13883   IRTemp num_bytes = newTemp(Ity_I64);
13884   assign(num_bytes, binop(Iop_And64,
13885                           binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13886                           mkU64(0xff)));
13887   s390_cc_set(1);
13888   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13889
13890   /* Extract the bytes to be stored at addr1 */
13891   IRTemp data = newTemp(Ity_I64);
13892   assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13893
13894   /* To store the bytes construct 4 dirty helper calls. The helper calls
13895      are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13896      one of them will be called at runtime. */
13897   UInt i;
13898   for (i = 1; i <= 4; ++i) {
13899      IRDirty *d;
13900
13901      d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13902                            &s390x_dirtyhelper_CUxy,
13903                            mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13904                                          mkexpr(num_bytes)));
13905      d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13906      d->mFx   = Ifx_Write;
13907      d->mAddr = mkexpr(addr1);
13908      d->mSize = i;
13909      stmt(IRStmt_Dirty(d));
13910   }
13911
13912   /* Update source address and length */
13913   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13914   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkU64(4)));
13915
13916   /* Update destination address and length */
13917   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13918   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13919
13920   iterate();
13921
13922   return "cu41";
13923}
13924
13925static IRExpr *
13926s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
13927{
13928   IRExpr **args, *call;
13929   args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
13930   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13931                        &s390_do_cu12_cu14_helper1, args);
13932
13933   /* Nothing is excluded from definedness checking. */
13934   call->Iex.CCall.cee->mcx_mask = 0;
13935
13936   return call;
13937}
13938
13939static IRExpr *
13940s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13941                       IRExpr *byte4, IRExpr *stuff)
13942{
13943   IRExpr **args, *call;
13944   args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13945   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13946                        "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13947
13948   /* Nothing is excluded from definedness checking. */
13949   call->Iex.CCall.cee->mcx_mask = 0;
13950
13951   return call;
13952}
13953
13954static IRExpr *
13955s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13956                       IRExpr *byte4, IRExpr *stuff)
13957{
13958   IRExpr **args, *call;
13959   args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13960   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13961                        "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13962
13963   /* Nothing is excluded from definedness checking. */
13964   call->Iex.CCall.cee->mcx_mask = 0;
13965
13966   return call;
13967}
13968
13969static void
13970s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
13971{
13972   IRTemp addr1 = newTemp(Ity_I64);
13973   IRTemp addr2 = newTemp(Ity_I64);
13974   IRTemp len1 = newTemp(Ity_I64);
13975   IRTemp len2 = newTemp(Ity_I64);
13976
13977   assign(addr1, get_gpr_dw0(r1));
13978   assign(addr2, get_gpr_dw0(r2));
13979   assign(len1, get_gpr_dw0(r1 + 1));
13980   assign(len2, get_gpr_dw0(r2 + 1));
13981
13982   UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13983
13984   /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13985      there is less than 1 byte left, then the 2nd operand is exhausted
13986      and we're done here. cc = 0 */
13987   s390_cc_set(0);
13988   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13989
13990   /* There is at least one byte there. Read it. */
13991   IRTemp byte1 = newTemp(Ity_I64);
13992   assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
13993
13994   /* Call the helper to get number of bytes and invalid byte indicator */
13995   IRTemp retval1 = newTemp(Ity_I64);
13996   assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
13997                                               mkU64(extended_checking)));
13998
13999   /* Check for invalid 1st byte */
14000   IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
14001   s390_cc_set(2);
14002   next_insn_if(is_invalid);
14003
14004   /* How many bytes do we have to read? */
14005   IRTemp num_src_bytes = newTemp(Ity_I64);
14006   assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
14007
14008   /* Now test whether the 2nd operand is exhausted */
14009   s390_cc_set(0);
14010   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
14011
14012   /* Read the remaining bytes */
14013   IRExpr *cond, *addr, *byte2, *byte3, *byte4;
14014
14015   cond  = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
14016   addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
14017   byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
14018   cond  = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
14019   addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
14020   byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
14021   cond  = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
14022   addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
14023   byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
14024
14025   /* Call the helper to get the converted value and invalid byte indicator.
14026      We can pass at most 5 arguments; therefore some encoding is needed
14027      here */
14028   IRExpr *stuff = binop(Iop_Or64,
14029                         binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
14030                         mkU64(extended_checking));
14031   IRTemp retval2 = newTemp(Ity_I64);
14032
14033   if (is_cu12) {
14034      assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
14035                                             byte4, stuff));
14036   } else {
14037      assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
14038                                             byte4, stuff));
14039   }
14040
14041   /* Check for invalid character */
14042   s390_cc_set(2);
14043   is_invalid = unop(Iop_64to1, mkexpr(retval2));
14044   next_insn_if(is_invalid);
14045
14046   /* Now test whether the 1st operand is exhausted */
14047   IRTemp num_bytes = newTemp(Ity_I64);
14048   assign(num_bytes, binop(Iop_And64,
14049                           binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
14050                           mkU64(0xff)));
14051   s390_cc_set(1);
14052   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
14053
14054   /* Extract the bytes to be stored at addr1 */
14055   IRTemp data = newTemp(Ity_I64);
14056   assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
14057
14058   if (is_cu12) {
14059      /* To store the bytes construct 2 dirty helper calls. The helper calls
14060         are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
14061         that only one of them will be called at runtime. */
14062
14063      Int i;
14064      for (i = 2; i <= 4; ++i) {
14065         IRDirty *d;
14066
14067         if (i == 3) continue;  // skip this one
14068
14069         d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
14070                               &s390x_dirtyhelper_CUxy,
14071                               mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
14072                                             mkexpr(num_bytes)));
14073         d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
14074         d->mFx   = Ifx_Write;
14075         d->mAddr = mkexpr(addr1);
14076         d->mSize = i;
14077         stmt(IRStmt_Dirty(d));
14078      }
14079   } else {
14080      // cu14
14081      store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
14082   }
14083
14084   /* Update source address and length */
14085   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
14086   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
14087
14088   /* Update destination address and length */
14089   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
14090   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
14091
14092   iterate();
14093}
14094
14095static const HChar *
14096s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
14097{
14098   s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
14099
14100   return "cu12";
14101}
14102
14103static const HChar *
14104s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
14105{
14106   s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
14107
14108   return "cu14";
14109}
14110
14111static IRExpr *
14112s390_call_ecag(IRExpr *op2addr)
14113{
14114   IRExpr **args, *call;
14115
14116   args = mkIRExprVec_1(op2addr);
14117   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
14118                        "s390_do_ecag", &s390_do_ecag, args);
14119
14120   /* Nothing is excluded from definedness checking. */
14121   call->Iex.CCall.cee->mcx_mask = 0;
14122
14123   return call;
14124}
14125
14126static const HChar *
14127s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
14128{
14129   if (! s390_host_has_gie) {
14130      emulation_failure(EmFail_S390X_ecag);
14131   } else {
14132      put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
14133   }
14134
14135   return "ecag";
14136}
14137
14138
14139/* New insns are added here.
14140   If an insn is contingent on a facility being installed also
14141   check whether the list of supported facilities in function
14142   s390x_dirtyhelper_STFLE needs updating */
14143
14144/*------------------------------------------------------------*/
14145/*--- Build IR for special instructions                    ---*/
14146/*------------------------------------------------------------*/
14147
14148static void
14149s390_irgen_client_request(void)
14150{
14151   if (0)
14152      vex_printf("%%R3 = client_request ( %%R2 )\n");
14153
14154   Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
14155                                     + S390_SPECIAL_OP_SIZE;
14156
14157   dis_res->jk_StopHere = Ijk_ClientReq;
14158   dis_res->whatNext = Dis_StopHere;
14159
14160   put_IA(mkaddr_expr(next));
14161}
14162
14163static void
14164s390_irgen_guest_NRADDR(void)
14165{
14166   if (0)
14167      vex_printf("%%R3 = guest_NRADDR\n");
14168
14169   put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
14170}
14171
14172static void
14173s390_irgen_call_noredir(void)
14174{
14175   Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
14176                                     + S390_SPECIAL_OP_SIZE;
14177
14178   /* Continue after special op */
14179   put_gpr_dw0(14, mkaddr_expr(next));
14180
14181   /* The address is in REG1, all parameters are in the right (guest) places */
14182   put_IA(get_gpr_dw0(1));
14183
14184   dis_res->whatNext = Dis_StopHere;
14185   dis_res->jk_StopHere = Ijk_NoRedir;
14186}
14187
14188/* Force proper alignment for the structures below. */
14189#pragma pack(1)
14190
14191
14192static s390_decode_t
14193s390_decode_2byte_and_irgen(const UChar *bytes)
14194{
14195   typedef union {
14196      struct {
14197         unsigned int op : 16;
14198      } E;
14199      struct {
14200         unsigned int op :  8;
14201         unsigned int i  :  8;
14202      } I;
14203      struct {
14204         unsigned int op :  8;
14205         unsigned int r1 :  4;
14206         unsigned int r2 :  4;
14207      } RR;
14208   } formats;
14209   union {
14210      formats fmt;
14211      UShort value;
14212   } ovl;
14213
14214   vassert(sizeof(formats) == 2);
14215
14216   ((UChar *)(&ovl.value))[0] = bytes[0];
14217   ((UChar *)(&ovl.value))[1] = bytes[1];
14218
14219   switch (ovl.value & 0xffff) {
14220   case 0x0101: /* PR */ goto unimplemented;
14221   case 0x0102: /* UPT */ goto unimplemented;
14222   case 0x0104: /* PTFF */ goto unimplemented;
14223   case 0x0107: /* SCKPF */ goto unimplemented;
14224   case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
14225   case 0x010b: /* TAM */ goto unimplemented;
14226   case 0x010c: /* SAM24 */ goto unimplemented;
14227   case 0x010d: /* SAM31 */ goto unimplemented;
14228   case 0x010e: /* SAM64 */ goto unimplemented;
14229   case 0x01ff: /* TRAP2 */ goto unimplemented;
14230   }
14231
14232   switch ((ovl.value & 0xff00) >> 8) {
14233   case 0x04: /* SPM */ goto unimplemented;
14234   case 0x05: /* BALR */ goto unimplemented;
14235   case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14236                                goto ok;
14237   case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14238                             goto ok;
14239   case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i);  goto ok;
14240   case 0x0b: /* BSM */ goto unimplemented;
14241   case 0x0c: /* BASSM */ goto unimplemented;
14242   case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14243                                goto ok;
14244   case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14245                             goto ok;
14246   case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14247                             goto ok;
14248   case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14249                                goto ok;
14250   case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14251                                goto ok;
14252   case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14253                                goto ok;
14254   case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14255                                goto ok;
14256   case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14257                                goto ok;
14258   case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14259                                goto ok;
14260   case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14261                                goto ok;
14262   case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14263                                goto ok;
14264   case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14265                                goto ok;
14266   case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14267                                goto ok;
14268   case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14269                                goto ok;
14270   case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14271                                goto ok;
14272   case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14273                                goto ok;
14274   case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14275                                goto ok;
14276   case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14277                                goto ok;
14278   case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14279                                goto ok;
14280   case 0x20: /* LPDR */ goto unimplemented;
14281   case 0x21: /* LNDR */ goto unimplemented;
14282   case 0x22: /* LTDR */ goto unimplemented;
14283   case 0x23: /* LCDR */ goto unimplemented;
14284   case 0x24: /* HDR */ goto unimplemented;
14285   case 0x25: /* LDXR */ goto unimplemented;
14286   case 0x26: /* MXR */ goto unimplemented;
14287   case 0x27: /* MXDR */ goto unimplemented;
14288   case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14289                                goto ok;
14290   case 0x29: /* CDR */ goto unimplemented;
14291   case 0x2a: /* ADR */ goto unimplemented;
14292   case 0x2b: /* SDR */ goto unimplemented;
14293   case 0x2c: /* MDR */ goto unimplemented;
14294   case 0x2d: /* DDR */ goto unimplemented;
14295   case 0x2e: /* AWR */ goto unimplemented;
14296   case 0x2f: /* SWR */ goto unimplemented;
14297   case 0x30: /* LPER */ goto unimplemented;
14298   case 0x31: /* LNER */ goto unimplemented;
14299   case 0x32: /* LTER */ goto unimplemented;
14300   case 0x33: /* LCER */ goto unimplemented;
14301   case 0x34: /* HER */ goto unimplemented;
14302   case 0x35: /* LEDR */ goto unimplemented;
14303   case 0x36: /* AXR */ goto unimplemented;
14304   case 0x37: /* SXR */ goto unimplemented;
14305   case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14306                                goto ok;
14307   case 0x39: /* CER */ goto unimplemented;
14308   case 0x3a: /* AER */ goto unimplemented;
14309   case 0x3b: /* SER */ goto unimplemented;
14310   case 0x3c: /* MDER */ goto unimplemented;
14311   case 0x3d: /* DER */ goto unimplemented;
14312   case 0x3e: /* AUR */ goto unimplemented;
14313   case 0x3f: /* SUR */ goto unimplemented;
14314   }
14315
14316   return S390_DECODE_UNKNOWN_INSN;
14317
14318ok:
14319   return S390_DECODE_OK;
14320
14321unimplemented:
14322   return S390_DECODE_UNIMPLEMENTED_INSN;
14323}
14324
14325static s390_decode_t
14326s390_decode_4byte_and_irgen(const UChar *bytes)
14327{
14328   typedef union {
14329      struct {
14330         unsigned int op1 :  8;
14331         unsigned int r1  :  4;
14332         unsigned int op2 :  4;
14333         unsigned int i2  : 16;
14334      } RI;
14335      struct {
14336         unsigned int op : 16;
14337         unsigned int    :  8;
14338         unsigned int r1 :  4;
14339         unsigned int r2 :  4;
14340      } RRE;
14341      struct {
14342         unsigned int op : 16;
14343         unsigned int r1 :  4;
14344         unsigned int    :  4;
14345         unsigned int r3 :  4;
14346         unsigned int r2 :  4;
14347      } RRF;
14348      struct {
14349         unsigned int op : 16;
14350         unsigned int m3 :  4;
14351         unsigned int m4 :  4;
14352         unsigned int r1 :  4;
14353         unsigned int r2 :  4;
14354      } RRF2;
14355      struct {
14356         unsigned int op : 16;
14357         unsigned int r3 :  4;
14358         unsigned int    :  4;
14359         unsigned int r1 :  4;
14360         unsigned int r2 :  4;
14361      } RRF3;
14362      struct {
14363         unsigned int op : 16;
14364         unsigned int r3 :  4;
14365         unsigned int    :  4;
14366         unsigned int r1 :  4;
14367         unsigned int r2 :  4;
14368      } RRR;
14369      struct {
14370         unsigned int op : 16;
14371         unsigned int r3 :  4;
14372         unsigned int m4 :  4;
14373         unsigned int r1 :  4;
14374         unsigned int r2 :  4;
14375      } RRF4;
14376      struct {
14377         unsigned int op : 16;
14378         unsigned int    :  4;
14379         unsigned int m4 :  4;
14380         unsigned int r1 :  4;
14381         unsigned int r2 :  4;
14382      } RRF5;
14383      struct {
14384         unsigned int op :  8;
14385         unsigned int r1 :  4;
14386         unsigned int r3 :  4;
14387         unsigned int b2 :  4;
14388         unsigned int d2 : 12;
14389      } RS;
14390      struct {
14391         unsigned int op :  8;
14392         unsigned int r1 :  4;
14393         unsigned int r3 :  4;
14394         unsigned int i2 : 16;
14395      } RSI;
14396      struct {
14397         unsigned int op :  8;
14398         unsigned int r1 :  4;
14399         unsigned int x2 :  4;
14400         unsigned int b2 :  4;
14401         unsigned int d2 : 12;
14402      } RX;
14403      struct {
14404         unsigned int op : 16;
14405         unsigned int b2 :  4;
14406         unsigned int d2 : 12;
14407      } S;
14408      struct {
14409         unsigned int op :  8;
14410         unsigned int i2 :  8;
14411         unsigned int b1 :  4;
14412         unsigned int d1 : 12;
14413      } SI;
14414   } formats;
14415   union {
14416      formats fmt;
14417      UInt value;
14418   } ovl;
14419
14420   vassert(sizeof(formats) == 4);
14421
14422   ((UChar *)(&ovl.value))[0] = bytes[0];
14423   ((UChar *)(&ovl.value))[1] = bytes[1];
14424   ((UChar *)(&ovl.value))[2] = bytes[2];
14425   ((UChar *)(&ovl.value))[3] = bytes[3];
14426
14427   switch ((ovl.value & 0xff0f0000) >> 16) {
14428   case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
14429                                  ovl.fmt.RI.i2);  goto ok;
14430   case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
14431                                  ovl.fmt.RI.i2);  goto ok;
14432   case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14433                                  ovl.fmt.RI.i2);  goto ok;
14434   case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14435                                  ovl.fmt.RI.i2);  goto ok;
14436   case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14437                                  ovl.fmt.RI.i2);  goto ok;
14438   case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14439                                  ovl.fmt.RI.i2);  goto ok;
14440   case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14441                                  ovl.fmt.RI.i2);  goto ok;
14442   case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14443                                  ovl.fmt.RI.i2);  goto ok;
14444   case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14445                                  ovl.fmt.RI.i2);  goto ok;
14446   case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14447                                  ovl.fmt.RI.i2);  goto ok;
14448   case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14449                                  ovl.fmt.RI.i2);  goto ok;
14450   case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14451                                  ovl.fmt.RI.i2);  goto ok;
14452   case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14453                                  ovl.fmt.RI.i2);  goto ok;
14454   case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14455                                  ovl.fmt.RI.i2);  goto ok;
14456   case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14457                                  ovl.fmt.RI.i2);  goto ok;
14458   case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14459                                  ovl.fmt.RI.i2);  goto ok;
14460   case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14461                                  ovl.fmt.RI.i2);  goto ok;
14462   case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14463                                  ovl.fmt.RI.i2);  goto ok;
14464   case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14465                                  ovl.fmt.RI.i2);  goto ok;
14466   case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14467                                  ovl.fmt.RI.i2);  goto ok;
14468   case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14469                               goto ok;
14470   case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14471                                  ovl.fmt.RI.i2);  goto ok;
14472   case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14473                                  ovl.fmt.RI.i2);  goto ok;
14474   case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14475                                  ovl.fmt.RI.i2);  goto ok;
14476   case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14477                                  goto ok;
14478   case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14479                                  ovl.fmt.RI.i2);  goto ok;
14480   case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14481                                  goto ok;
14482   case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14483                                  ovl.fmt.RI.i2);  goto ok;
14484   case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14485                                  goto ok;
14486   case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14487                                  ovl.fmt.RI.i2);  goto ok;
14488   case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14489                                  goto ok;
14490   case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14491                                  ovl.fmt.RI.i2);  goto ok;
14492   }
14493
14494   switch ((ovl.value & 0xffff0000) >> 16) {
14495   case 0x8000: /* SSM */ goto unimplemented;
14496   case 0x8200: /* LPSW */ goto unimplemented;
14497   case 0x9300: /* TS */ goto unimplemented;
14498   case 0xb202: /* STIDP */ goto unimplemented;
14499   case 0xb204: /* SCK */ goto unimplemented;
14500   case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14501                goto ok;
14502   case 0xb206: /* SCKC */ goto unimplemented;
14503   case 0xb207: /* STCKC */ goto unimplemented;
14504   case 0xb208: /* SPT */ goto unimplemented;
14505   case 0xb209: /* STPT */ goto unimplemented;
14506   case 0xb20a: /* SPKA */ goto unimplemented;
14507   case 0xb20b: /* IPK */ goto unimplemented;
14508   case 0xb20d: /* PTLB */ goto unimplemented;
14509   case 0xb210: /* SPX */ goto unimplemented;
14510   case 0xb211: /* STPX */ goto unimplemented;
14511   case 0xb212: /* STAP */ goto unimplemented;
14512   case 0xb214: /* SIE */ goto unimplemented;
14513   case 0xb218: /* PC */ goto unimplemented;
14514   case 0xb219: /* SAC */ goto unimplemented;
14515   case 0xb21a: /* CFC */ goto unimplemented;
14516   case 0xb221: /* IPTE */ goto unimplemented;
14517   case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1);  goto ok;
14518   case 0xb223: /* IVSK */ goto unimplemented;
14519   case 0xb224: /* IAC */ goto unimplemented;
14520   case 0xb225: /* SSAR */ goto unimplemented;
14521   case 0xb226: /* EPAR */ goto unimplemented;
14522   case 0xb227: /* ESAR */ goto unimplemented;
14523   case 0xb228: /* PT */ goto unimplemented;
14524   case 0xb229: /* ISKE */ goto unimplemented;
14525   case 0xb22a: /* RRBE */ goto unimplemented;
14526   case 0xb22b: /* SSKE */ goto unimplemented;
14527   case 0xb22c: /* TB */ goto unimplemented;
14528   case 0xb22d: /* DXR */ goto unimplemented;
14529   case 0xb22e: /* PGIN */ goto unimplemented;
14530   case 0xb22f: /* PGOUT */ goto unimplemented;
14531   case 0xb230: /* CSCH */ goto unimplemented;
14532   case 0xb231: /* HSCH */ goto unimplemented;
14533   case 0xb232: /* MSCH */ goto unimplemented;
14534   case 0xb233: /* SSCH */ goto unimplemented;
14535   case 0xb234: /* STSCH */ goto unimplemented;
14536   case 0xb235: /* TSCH */ goto unimplemented;
14537   case 0xb236: /* TPI */ goto unimplemented;
14538   case 0xb237: /* SAL */ goto unimplemented;
14539   case 0xb238: /* RSCH */ goto unimplemented;
14540   case 0xb239: /* STCRW */ goto unimplemented;
14541   case 0xb23a: /* STCPS */ goto unimplemented;
14542   case 0xb23b: /* RCHP */ goto unimplemented;
14543   case 0xb23c: /* SCHM */ goto unimplemented;
14544   case 0xb240: /* BAKR */ goto unimplemented;
14545   case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14546                                ovl.fmt.RRE.r2);  goto ok;
14547   case 0xb244: /* SQDR */ goto unimplemented;
14548   case 0xb245: /* SQER */ goto unimplemented;
14549   case 0xb246: /* STURA */ goto unimplemented;
14550   case 0xb247: /* MSTA */ goto unimplemented;
14551   case 0xb248: /* PALB */ goto unimplemented;
14552   case 0xb249: /* EREG */ goto unimplemented;
14553   case 0xb24a: /* ESTA */ goto unimplemented;
14554   case 0xb24b: /* LURA */ goto unimplemented;
14555   case 0xb24c: /* TAR */ goto unimplemented;
14556   case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14557                                ovl.fmt.RRE.r2);  goto ok;
14558   case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14559                                goto ok;
14560   case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14561                                goto ok;
14562   case 0xb250: /* CSP */ goto unimplemented;
14563   case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14564                                   ovl.fmt.RRE.r2);  goto ok;
14565   case 0xb254: /* MVPG */ goto unimplemented;
14566   case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14567                                   ovl.fmt.RRE.r2);  goto ok;
14568   case 0xb257: /* CUSE */ goto unimplemented;
14569   case 0xb258: /* BSG */ goto unimplemented;
14570   case 0xb25a: /* BSA */ goto unimplemented;
14571   case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14572                                   ovl.fmt.RRE.r2);  goto ok;
14573   case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14574                                   ovl.fmt.RRE.r2);  goto ok;
14575   case 0xb263: /* CMPSC */ goto unimplemented;
14576   case 0xb274: /* SIGA */ goto unimplemented;
14577   case 0xb276: /* XSCH */ goto unimplemented;
14578   case 0xb277: /* RP */ goto unimplemented;
14579   case 0xb278: s390_format_S_RD(s390_irgen_STCKE, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
14580   case 0xb279: /* SACF */ goto unimplemented;
14581   case 0xb27c: s390_format_S_RD(s390_irgen_STCKF, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
14582   case 0xb27d: /* STSI */ goto unimplemented;
14583   case 0xb280: /* LPP */ goto unimplemented;
14584   case 0xb284: /* LCCTL */ goto unimplemented;
14585   case 0xb285: /* LPCTL */ goto unimplemented;
14586   case 0xb286: /* QSI */ goto unimplemented;
14587   case 0xb287: /* LSCTL */ goto unimplemented;
14588   case 0xb28e: /* QCTRI */ goto unimplemented;
14589   case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14590                                 goto ok;
14591   case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14592                                 goto ok;
14593   case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14594                                 goto ok;
14595   case 0xb2a5: s390_format_RRE_FF(s390_irgen_TRE, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);  goto ok;
14596   case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14597                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14598      goto ok;
14599   case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14600                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14601      goto ok;
14602   case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14603                                 goto ok;
14604   case 0xb2b1: /* STFL */ goto unimplemented;
14605   case 0xb2b2: /* LPSWE */ goto unimplemented;
14606   case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14607      goto ok;
14608   case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14609      goto ok;
14610   case 0xb2bd: /* LFAS */ goto unimplemented;
14611   case 0xb2e0: /* SCCTR */ goto unimplemented;
14612   case 0xb2e1: /* SPCTR */ goto unimplemented;
14613   case 0xb2e4: /* ECCTR */ goto unimplemented;
14614   case 0xb2e5: /* EPCTR */ goto unimplemented;
14615   case 0xb2e8: /* PPA */ goto unimplemented;
14616   case 0xb2ec: /* ETND */ goto unimplemented;
14617   case 0xb2ed: /* ECPGA */ goto unimplemented;
14618   case 0xb2f8: /* TEND */ goto unimplemented;
14619   case 0xb2fa: /* NIAI */ goto unimplemented;
14620   case 0xb2fc: /* TABORT */ goto unimplemented;
14621   case 0xb2ff: /* TRAP4 */ goto unimplemented;
14622   case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14623                                   ovl.fmt.RRE.r2);  goto ok;
14624   case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14625                                   ovl.fmt.RRE.r2);  goto ok;
14626   case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14627                                   ovl.fmt.RRE.r2);  goto ok;
14628   case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14629                                   ovl.fmt.RRE.r2);  goto ok;
14630   case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14631                                   ovl.fmt.RRE.r2);  goto ok;
14632   case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14633                                   ovl.fmt.RRE.r2);  goto ok;
14634   case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14635                                   ovl.fmt.RRE.r2);  goto ok;
14636   case 0xb307: /* MXDBR */ goto unimplemented;
14637   case 0xb308: /* KEBR */ goto unimplemented;
14638   case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14639                                   ovl.fmt.RRE.r2);  goto ok;
14640   case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14641                                   ovl.fmt.RRE.r2);  goto ok;
14642   case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14643                                   ovl.fmt.RRE.r2);  goto ok;
14644   case 0xb30c: /* MDEBR */ goto unimplemented;
14645   case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14646                                   ovl.fmt.RRE.r2);  goto ok;
14647   case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14648                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14649   case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14650                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14651   case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14652                                   ovl.fmt.RRE.r2);  goto ok;
14653   case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14654                                   ovl.fmt.RRE.r2);  goto ok;
14655   case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14656                                   ovl.fmt.RRE.r2);  goto ok;
14657   case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14658                                   ovl.fmt.RRE.r2);  goto ok;
14659   case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14660                                   ovl.fmt.RRE.r2);  goto ok;
14661   case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14662                                   ovl.fmt.RRE.r2);  goto ok;
14663   case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14664                                   ovl.fmt.RRE.r2);  goto ok;
14665   case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14666                                   ovl.fmt.RRE.r2);  goto ok;
14667   case 0xb318: /* KDBR */ goto unimplemented;
14668   case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14669                                   ovl.fmt.RRE.r2);  goto ok;
14670   case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14671                                   ovl.fmt.RRE.r2);  goto ok;
14672   case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14673                                   ovl.fmt.RRE.r2);  goto ok;
14674   case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14675                                   ovl.fmt.RRE.r2);  goto ok;
14676   case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14677                                   ovl.fmt.RRE.r2);  goto ok;
14678   case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14679                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14680   case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14681                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14682   case 0xb324: s390_format_RRE_FF(s390_irgen_LDER, ovl.fmt.RRE.r1,
14683                                   ovl.fmt.RRE.r2); goto ok;
14684   case 0xb325: /* LXDR */ goto unimplemented;
14685   case 0xb326: /* LXER */ goto unimplemented;
14686   case 0xb32e: /* MAER */ goto unimplemented;
14687   case 0xb32f: /* MSER */ goto unimplemented;
14688   case 0xb336: /* SQXR */ goto unimplemented;
14689   case 0xb337: /* MEER */ goto unimplemented;
14690   case 0xb338: /* MAYLR */ goto unimplemented;
14691   case 0xb339: /* MYLR */ goto unimplemented;
14692   case 0xb33a: /* MAYR */ goto unimplemented;
14693   case 0xb33b: /* MYR */ goto unimplemented;
14694   case 0xb33c: /* MAYHR */ goto unimplemented;
14695   case 0xb33d: /* MYHR */ goto unimplemented;
14696   case 0xb33e: /* MADR */ goto unimplemented;
14697   case 0xb33f: /* MSDR */ goto unimplemented;
14698   case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14699                                   ovl.fmt.RRE.r2);  goto ok;
14700   case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14701                                   ovl.fmt.RRE.r2);  goto ok;
14702   case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14703                                   ovl.fmt.RRE.r2);  goto ok;
14704   case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14705                                   ovl.fmt.RRE.r2);  goto ok;
14706   case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14707                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14708                                     ovl.fmt.RRF2.r2);  goto ok;
14709   case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14710                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14711                                     ovl.fmt.RRF2.r2);  goto ok;
14712   case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14713                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14714                                     ovl.fmt.RRF2.r2);  goto ok;
14715   case 0xb347: s390_format_RRF_UUFF(s390_irgen_FIXBRA, ovl.fmt.RRF2.m3,
14716                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14717                                     ovl.fmt.RRF2.r2);  goto ok;
14718   case 0xb348: /* KXBR */ goto unimplemented;
14719   case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14720                                   ovl.fmt.RRE.r2);  goto ok;
14721   case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14722                                   ovl.fmt.RRE.r2);  goto ok;
14723   case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14724                                   ovl.fmt.RRE.r2);  goto ok;
14725   case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14726                                   ovl.fmt.RRE.r2);  goto ok;
14727   case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14728                                   ovl.fmt.RRE.r2);  goto ok;
14729   case 0xb350: /* TBEDR */ goto unimplemented;
14730   case 0xb351: /* TBDR */ goto unimplemented;
14731   case 0xb353: /* DIEBR */ goto unimplemented;
14732   case 0xb357: s390_format_RRF_UUFF(s390_irgen_FIEBRA, ovl.fmt.RRF2.m3,
14733                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14734                                     ovl.fmt.RRF2.r2);  goto ok;
14735   case 0xb358: /* THDER */ goto unimplemented;
14736   case 0xb359: /* THDR */ goto unimplemented;
14737   case 0xb35b: /* DIDBR */ goto unimplemented;
14738   case 0xb35f: s390_format_RRF_UUFF(s390_irgen_FIDBRA, ovl.fmt.RRF2.m3,
14739                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14740                                     ovl.fmt.RRF2.r2);  goto ok;
14741   case 0xb360: /* LPXR */ goto unimplemented;
14742   case 0xb361: /* LNXR */ goto unimplemented;
14743   case 0xb362: /* LTXR */ goto unimplemented;
14744   case 0xb363: /* LCXR */ goto unimplemented;
14745   case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14746                                   ovl.fmt.RRE.r2);  goto ok;
14747   case 0xb366: /* LEXR */ goto unimplemented;
14748   case 0xb367: /* FIXR */ goto unimplemented;
14749   case 0xb369: /* CXR */ goto unimplemented;
14750   case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14751                                   ovl.fmt.RRE.r2);  goto ok;
14752   case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14753                                   ovl.fmt.RRE.r2);  goto ok;
14754   case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14755                                      ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14756                                      goto ok;
14757   case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14758                                   ovl.fmt.RRE.r2);  goto ok;
14759   case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1);  goto ok;
14760   case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1);  goto ok;
14761   case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1);  goto ok;
14762   case 0xb377: /* FIER */ goto unimplemented;
14763   case 0xb37f: /* FIDR */ goto unimplemented;
14764   case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1);  goto ok;
14765   case 0xb385: /* SFASR */ goto unimplemented;
14766   case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1);  goto ok;
14767   case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14768                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14769                                     ovl.fmt.RRF2.r2);  goto ok;
14770   case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14771                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14772                                     ovl.fmt.RRF2.r2);  goto ok;
14773   case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14774                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14775                                     ovl.fmt.RRF2.r2);  goto ok;
14776   case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14777                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14778                                     ovl.fmt.RRF2.r2);  goto ok;
14779   case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14780                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14781                                     ovl.fmt.RRF2.r2);  goto ok;
14782   case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14783                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14784                                     ovl.fmt.RRF2.r2);  goto ok;
14785   case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14786                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14787                                     ovl.fmt.RRF2.r2);  goto ok;
14788   case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14789                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14790                                     ovl.fmt.RRF2.r2);  goto ok;
14791   case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14792                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14793                                     ovl.fmt.RRF2.r2);  goto ok;
14794   case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14795                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14796                                     ovl.fmt.RRF2.r2);  goto ok;
14797   case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14798                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14799                                     ovl.fmt.RRF2.r2);  goto ok;
14800   case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14801                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14802                                     ovl.fmt.RRF2.r2);  goto ok;
14803   case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14804                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14805                                     ovl.fmt.RRF2.r2);  goto ok;
14806   case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14807                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14808                                     ovl.fmt.RRF2.r2);  goto ok;
14809   case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14810                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14811                                     ovl.fmt.RRF2.r2);  goto ok;
14812   case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14813                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14814                                     ovl.fmt.RRF2.r2);  goto ok;
14815   case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14816                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14817                                     ovl.fmt.RRF2.r2);  goto ok;
14818   case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14819                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14820                                     ovl.fmt.RRF2.r2);  goto ok;
14821   case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14822                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14823                                     ovl.fmt.RRF2.r2);  goto ok;
14824   case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14825                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14826                                     ovl.fmt.RRF2.r2);  goto ok;
14827   case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14828                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14829                                     ovl.fmt.RRF2.r2);  goto ok;
14830   case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14831                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14832                                     ovl.fmt.RRF2.r2);  goto ok;
14833   case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14834                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14835                                     ovl.fmt.RRF2.r2);  goto ok;
14836   case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14837                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14838                                     ovl.fmt.RRF2.r2);  goto ok;
14839   case 0xb3b4: /* CEFR */ goto unimplemented;
14840   case 0xb3b5: /* CDFR */ goto unimplemented;
14841   case 0xb3b6: /* CXFR */ goto unimplemented;
14842   case 0xb3b8: /* CFER */ goto unimplemented;
14843   case 0xb3b9: /* CFDR */ goto unimplemented;
14844   case 0xb3ba: /* CFXR */ goto unimplemented;
14845   case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14846                                   ovl.fmt.RRE.r2);  goto ok;
14847   case 0xb3c4: /* CEGR */ goto unimplemented;
14848   case 0xb3c5: /* CDGR */ goto unimplemented;
14849   case 0xb3c6: /* CXGR */ goto unimplemented;
14850   case 0xb3c8: /* CGER */ goto unimplemented;
14851   case 0xb3c9: /* CGDR */ goto unimplemented;
14852   case 0xb3ca: /* CGXR */ goto unimplemented;
14853   case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14854                                   ovl.fmt.RRE.r2);  goto ok;
14855   case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14856                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14857                                      ovl.fmt.RRF4.r2); goto ok;
14858   case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14859                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14860                                      ovl.fmt.RRF4.r2); goto ok;
14861   case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14862                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14863                                      ovl.fmt.RRF4.r2); goto ok;
14864   case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14865                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14866                                      ovl.fmt.RRF4.r2); goto ok;
14867   case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14868                                     ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14869   case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14870                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14871                                     ovl.fmt.RRF2.r2);  goto ok;
14872   case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14873                                   ovl.fmt.RRE.r2);  goto ok;
14874   case 0xb3d7: /* FIDTR */ goto unimplemented;
14875   case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14876                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14877                                     ovl.fmt.RRF4.r2); goto ok;
14878   case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14879                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14880                                     ovl.fmt.RRF4.r2); goto ok;
14881   case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14882                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14883                                     ovl.fmt.RRF4.r2); goto ok;
14884   case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14885                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14886                                     ovl.fmt.RRF4.r2); goto ok;
14887   case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14888                                     ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14889   case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14890                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14891                                     ovl.fmt.RRF2.r2);  goto ok;
14892   case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14893                                   ovl.fmt.RRE.r2);  goto ok;
14894   case 0xb3df: /* FIXTR */ goto unimplemented;
14895   case 0xb3e0: /* KDTR */ goto unimplemented;
14896   case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14897                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14898                                     ovl.fmt.RRF2.r2);  goto ok;
14899   case 0xb3e2: /* CUDTR */ goto unimplemented;
14900   case 0xb3e3: /* CSDTR */ goto unimplemented;
14901   case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14902                                   ovl.fmt.RRE.r2);  goto ok;
14903   case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14904                                   ovl.fmt.RRE.r2);  goto ok;
14905   case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14906                                   ovl.fmt.RRE.r2);  goto ok;
14907   case 0xb3e8: /* KXTR */ goto unimplemented;
14908   case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14909                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14910                                     ovl.fmt.RRF2.r2);  goto ok;
14911   case 0xb3ea: /* CUXTR */ goto unimplemented;
14912   case 0xb3eb: /* CSXTR */ goto unimplemented;
14913   case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14914                                   ovl.fmt.RRE.r2);  goto ok;
14915   case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14916                                   ovl.fmt.RRE.r2);  goto ok;
14917   case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14918                                   ovl.fmt.RRE.r2);  goto ok;
14919   case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14920                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14921                                     ovl.fmt.RRF2.r2);  goto ok;
14922   case 0xb3f2: /* CDUTR */ goto unimplemented;
14923   case 0xb3f3: /* CDSTR */ goto unimplemented;
14924   case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14925                                   ovl.fmt.RRE.r2);  goto ok;
14926   case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14927                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14928                                     ovl.fmt.RRF4.r2); goto ok;
14929   case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14930                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14931   case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14932                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14933                                     ovl.fmt.RRF4.r2); goto ok;
14934   case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14935                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14936                                     ovl.fmt.RRF2.r2);  goto ok;
14937   case 0xb3fa: /* CXUTR */ goto unimplemented;
14938   case 0xb3fb: /* CXSTR */ goto unimplemented;
14939   case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14940                                   ovl.fmt.RRE.r2);  goto ok;
14941   case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14942                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14943                                     ovl.fmt.RRF4.r2); goto ok;
14944   case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14945                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14946   case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14947                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14948                                     ovl.fmt.RRF4.r2); goto ok;
14949   case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14950                                   ovl.fmt.RRE.r2);  goto ok;
14951   case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14952                                   ovl.fmt.RRE.r2);  goto ok;
14953   case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14954                                   ovl.fmt.RRE.r2);  goto ok;
14955   case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14956                                   ovl.fmt.RRE.r2);  goto ok;
14957   case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14958                                   ovl.fmt.RRE.r2);  goto ok;
14959   case 0xb905: /* LURAG */ goto unimplemented;
14960   case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14961                                   ovl.fmt.RRE.r2);  goto ok;
14962   case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14963                                   ovl.fmt.RRE.r2);  goto ok;
14964   case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14965                                   ovl.fmt.RRE.r2);  goto ok;
14966   case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14967                                   ovl.fmt.RRE.r2);  goto ok;
14968   case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14969                                   ovl.fmt.RRE.r2);  goto ok;
14970   case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14971                                   ovl.fmt.RRE.r2);  goto ok;
14972   case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14973                                   ovl.fmt.RRE.r2);  goto ok;
14974   case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14975                                   ovl.fmt.RRE.r2);  goto ok;
14976   case 0xb90e: /* EREGG */ goto unimplemented;
14977   case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14978                                   ovl.fmt.RRE.r2);  goto ok;
14979   case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14980                                   ovl.fmt.RRE.r2);  goto ok;
14981   case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14982                                   ovl.fmt.RRE.r2);  goto ok;
14983   case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14984                                   ovl.fmt.RRE.r2);  goto ok;
14985   case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14986                                   ovl.fmt.RRE.r2);  goto ok;
14987   case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14988                                   ovl.fmt.RRE.r2);  goto ok;
14989   case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14990                                   ovl.fmt.RRE.r2);  goto ok;
14991   case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14992                                   ovl.fmt.RRE.r2);  goto ok;
14993   case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14994                                   ovl.fmt.RRE.r2);  goto ok;
14995   case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14996                                   ovl.fmt.RRE.r2);  goto ok;
14997   case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14998                                   ovl.fmt.RRE.r2);  goto ok;
14999   case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
15000                                   ovl.fmt.RRE.r2);  goto ok;
15001   case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
15002                                   ovl.fmt.RRE.r2);  goto ok;
15003   case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
15004                                   ovl.fmt.RRE.r2);  goto ok;
15005   case 0xb91e: /* KMAC */ goto unimplemented;
15006   case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
15007                                   ovl.fmt.RRE.r2);  goto ok;
15008   case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
15009                                   ovl.fmt.RRE.r2);  goto ok;
15010   case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
15011                                   ovl.fmt.RRE.r2);  goto ok;
15012   case 0xb925: /* STURG */ goto unimplemented;
15013   case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
15014                                   ovl.fmt.RRE.r2);  goto ok;
15015   case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
15016                                   ovl.fmt.RRE.r2);  goto ok;
15017   case 0xb928: /* PCKMO */ goto unimplemented;
15018   case 0xb92a: /* KMF */ goto unimplemented;
15019   case 0xb92b: /* KMO */ goto unimplemented;
15020   case 0xb92c: /* PCC */ goto unimplemented;
15021   case 0xb92d: /* KMCTR */ goto unimplemented;
15022   case 0xb92e: /* KM */ goto unimplemented;
15023   case 0xb92f: /* KMC */ goto unimplemented;
15024   case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
15025                                   ovl.fmt.RRE.r2);  goto ok;
15026   case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
15027                                   ovl.fmt.RRE.r2);  goto ok;
15028   case 0xb93e: /* KIMD */ goto unimplemented;
15029   case 0xb93f: /* KLMD */ goto unimplemented;
15030   case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
15031                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15032                                     ovl.fmt.RRF2.r2);  goto ok;
15033   case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
15034                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15035                                     ovl.fmt.RRF2.r2);  goto ok;
15036   case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
15037                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15038                                     ovl.fmt.RRF2.r2);  goto ok;
15039   case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
15040                                   ovl.fmt.RRE.r2);  goto ok;
15041   case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
15042                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15043                                     ovl.fmt.RRF2.r2);  goto ok;
15044   case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
15045                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15046                                     ovl.fmt.RRF2.r2);  goto ok;
15047   case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
15048                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15049                                     ovl.fmt.RRF2.r2);  goto ok;
15050   case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
15051                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15052                                     ovl.fmt.RRF2.r2);  goto ok;
15053   case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
15054                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15055                                     ovl.fmt.RRF2.r2);  goto ok;
15056   case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
15057                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15058                                     ovl.fmt.RRF2.r2);  goto ok;
15059   case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
15060                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15061                                     ovl.fmt.RRF2.r2);  goto ok;
15062   case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
15063                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15064                                     ovl.fmt.RRF2.r2);  goto ok;
15065   case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
15066                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15067                                     ovl.fmt.RRF2.r2);  goto ok;
15068   case 0xb960: /* CGRT */ goto unimplemented;
15069   case 0xb961: /* CLGRT */ goto unimplemented;
15070   case 0xb972: /* CRT */ goto unimplemented;
15071   case 0xb973: /* CLRT */ goto unimplemented;
15072   case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
15073                                   ovl.fmt.RRE.r2);  goto ok;
15074   case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
15075                                   ovl.fmt.RRE.r2);  goto ok;
15076   case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
15077                                   ovl.fmt.RRE.r2);  goto ok;
15078   case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
15079                                   ovl.fmt.RRE.r2);  goto ok;
15080   case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
15081                                   ovl.fmt.RRE.r2);  goto ok;
15082   case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
15083                                   ovl.fmt.RRE.r2);  goto ok;
15084   case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
15085                                   ovl.fmt.RRE.r2);  goto ok;
15086   case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
15087                                   ovl.fmt.RRE.r2);  goto ok;
15088   case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
15089                                   ovl.fmt.RRE.r2);  goto ok;
15090   case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
15091                                   ovl.fmt.RRE.r2);  goto ok;
15092   case 0xb98a: /* CSPG */ goto unimplemented;
15093   case 0xb98d: /* EPSW */ goto unimplemented;
15094   case 0xb98e: /* IDTE */ goto unimplemented;
15095   case 0xb98f: /* CRDTE */ goto unimplemented;
15096   case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
15097                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
15098   case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
15099                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
15100   case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
15101                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
15102   case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
15103                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
15104   case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
15105                                   ovl.fmt.RRE.r2);  goto ok;
15106   case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
15107                                   ovl.fmt.RRE.r2);  goto ok;
15108   case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
15109                                   ovl.fmt.RRE.r2);  goto ok;
15110   case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
15111                                   ovl.fmt.RRE.r2);  goto ok;
15112   case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
15113                                   ovl.fmt.RRE.r2);  goto ok;
15114   case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
15115                                   ovl.fmt.RRE.r2);  goto ok;
15116   case 0xb99a: /* EPAIR */ goto unimplemented;
15117   case 0xb99b: /* ESAIR */ goto unimplemented;
15118   case 0xb99d: /* ESEA */ goto unimplemented;
15119   case 0xb99e: /* PTI */ goto unimplemented;
15120   case 0xb99f: /* SSAIR */ goto unimplemented;
15121   case 0xb9a2: /* PTF */ goto unimplemented;
15122   case 0xb9aa: /* LPTEA */ goto unimplemented;
15123   case 0xb9ae: /* RRBM */ goto unimplemented;
15124   case 0xb9af: /* PFMF */ goto unimplemented;
15125   case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
15126                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
15127      goto ok;
15128   case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
15129                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
15130      goto ok;
15131   case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
15132                                   ovl.fmt.RRE.r2);  goto ok;
15133   case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
15134                                   ovl.fmt.RRE.r2);  goto ok;
15135   case 0xb9bd: /* TRTRE */ goto unimplemented;
15136   case 0xb9be: /* SRSTU */ goto unimplemented;
15137   case 0xb9bf: /* TRTE */ goto unimplemented;
15138   case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
15139                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15140                                      goto ok;
15141   case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
15142                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15143                                      goto ok;
15144   case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
15145                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15146                                      goto ok;
15147   case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
15148                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15149                                      goto ok;
15150   case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
15151                                   ovl.fmt.RRE.r2);  goto ok;
15152   case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
15153                                   ovl.fmt.RRE.r2);  goto ok;
15154   case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
15155                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15156                                      goto ok;
15157   case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
15158                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15159                                      goto ok;
15160   case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
15161                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15162                                      goto ok;
15163   case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
15164                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15165                                      goto ok;
15166   case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
15167                                   ovl.fmt.RRE.r2);  goto ok;
15168   case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
15169                                   ovl.fmt.RRE.r2);  goto ok;
15170   case 0xb9e1: s390_format_RRE_RR(s390_irgen_POPCNT, ovl.fmt.RRE.r1,
15171                                   ovl.fmt.RRE.r2);  goto ok;
15172   case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
15173                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
15174                                     S390_XMNM_LOCGR);  goto ok;
15175   case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
15176                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15177                                      goto ok;
15178   case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
15179                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15180                                      goto ok;
15181   case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
15182                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15183                                      goto ok;
15184   case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
15185                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15186                                      goto ok;
15187   case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
15188                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15189                                      goto ok;
15190   case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
15191                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15192                                      goto ok;
15193   case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
15194                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15195                                      goto ok;
15196   case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
15197                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
15198                                     S390_XMNM_LOCR);  goto ok;
15199   case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
15200                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15201                                      goto ok;
15202   case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
15203                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15204                                      goto ok;
15205   case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
15206                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15207                                      goto ok;
15208   case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
15209                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15210                                      goto ok;
15211   case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
15212                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15213                                      goto ok;
15214   case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
15215                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15216                                      goto ok;
15217   case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
15218                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15219                                      goto ok;
15220   }
15221
15222   switch ((ovl.value & 0xff000000) >> 24) {
15223   case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15224                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15225   case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15226                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15227   case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15228                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15229   case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15230                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15231   case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15232                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15233   case 0x45: /* BAL */ goto unimplemented;
15234   case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15235                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15236   case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15237                             ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15238   case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15239                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15240   case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15241                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15242   case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15243                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15244   case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15245                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15246   case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15247                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15248   case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15249                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15250   case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15251                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15252   case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15253                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15254   case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15255                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15256   case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15257                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15258   case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15259                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15260   case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15261                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15262   case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15263                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15264   case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15265                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15266   case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15267                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15268   case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15269                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15270   case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15271                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15272   case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15273                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15274   case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15275                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15276   case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15277                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15278   case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15279                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15280   case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15281                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15282   case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15283                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15284   case 0x67: /* MXD */ goto unimplemented;
15285   case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15286                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15287   case 0x69: /* CD */ goto unimplemented;
15288   case 0x6a: /* AD */ goto unimplemented;
15289   case 0x6b: /* SD */ goto unimplemented;
15290   case 0x6c: /* MD */ goto unimplemented;
15291   case 0x6d: /* DD */ goto unimplemented;
15292   case 0x6e: /* AW */ goto unimplemented;
15293   case 0x6f: /* SW */ goto unimplemented;
15294   case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15295                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15296   case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15297                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15298   case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15299                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15300   case 0x79: /* CE */ goto unimplemented;
15301   case 0x7a: /* AE */ goto unimplemented;
15302   case 0x7b: /* SE */ goto unimplemented;
15303   case 0x7c: /* MDE */ goto unimplemented;
15304   case 0x7d: /* DE */ goto unimplemented;
15305   case 0x7e: /* AU */ goto unimplemented;
15306   case 0x7f: /* SU */ goto unimplemented;
15307   case 0x83: /* DIAG */ goto unimplemented;
15308   case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
15309                                  ovl.fmt.RSI.r3, ovl.fmt.RSI.i2);  goto ok;
15310   case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
15311                                  ovl.fmt.RSI.r3, ovl.fmt.RSI.i2);  goto ok;
15312   case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15313                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15314   case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15315                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15316   case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15317                                  ovl.fmt.RS.d2);  goto ok;
15318   case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15319                                  ovl.fmt.RS.d2);  goto ok;
15320   case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15321                                  ovl.fmt.RS.d2);  goto ok;
15322   case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15323                                  ovl.fmt.RS.d2);  goto ok;
15324   case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15325                                  ovl.fmt.RS.d2);  goto ok;
15326   case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15327                                  ovl.fmt.RS.d2);  goto ok;
15328   case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15329                                  ovl.fmt.RS.d2);  goto ok;
15330   case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15331                                  ovl.fmt.RS.d2);  goto ok;
15332   case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15333                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15334   case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15335                                 ovl.fmt.SI.d1);  goto ok;
15336   case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15337                                 ovl.fmt.SI.d1);  goto ok;
15338   case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15339                                 ovl.fmt.SI.d1);  goto ok;
15340   case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15341                                 ovl.fmt.SI.d1);  goto ok;
15342   case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15343                                 ovl.fmt.SI.d1);  goto ok;
15344   case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15345                                 ovl.fmt.SI.d1);  goto ok;
15346   case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15347                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15348   case 0x99: /* TRACE */ goto unimplemented;
15349   case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15350                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15351   case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15352                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15353   case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
15354                                  ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15355                                  goto ok;
15356   case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
15357                                  ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15358                                  goto ok;
15359   case 0xac: /* STNSM */ goto unimplemented;
15360   case 0xad: /* STOSM */ goto unimplemented;
15361   case 0xae: /* SIGP */ goto unimplemented;
15362   case 0xaf: /* MC */ goto unimplemented;
15363   case 0xb1: /* LRA */ goto unimplemented;
15364   case 0xb6: /* STCTL */ goto unimplemented;
15365   case 0xb7: /* LCTL */ goto unimplemented;
15366   case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15367                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15368   case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15369                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15370   case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15371                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15372   case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15373                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15374   case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15375                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15376   }
15377
15378   return S390_DECODE_UNKNOWN_INSN;
15379
15380ok:
15381   return S390_DECODE_OK;
15382
15383unimplemented:
15384   return S390_DECODE_UNIMPLEMENTED_INSN;
15385}
15386
15387static s390_decode_t
15388s390_decode_6byte_and_irgen(const UChar *bytes)
15389{
15390   typedef union {
15391      struct {
15392         unsigned int op1 :  8;
15393         unsigned int r1  :  4;
15394         unsigned int r3  :  4;
15395         unsigned int i2  : 16;
15396         unsigned int     :  8;
15397         unsigned int op2 :  8;
15398      } RIE;
15399      struct {
15400         unsigned int op1 :  8;
15401         unsigned int r1  :  4;
15402         unsigned int r2  :  4;
15403         unsigned int i3  :  8;
15404         unsigned int i4  :  8;
15405         unsigned int i5  :  8;
15406         unsigned int op2 :  8;
15407      } RIE_RRUUU;
15408      struct {
15409         unsigned int op1 :  8;
15410         unsigned int r1  :  4;
15411         unsigned int     :  4;
15412         unsigned int i2  : 16;
15413         unsigned int m3  :  4;
15414         unsigned int     :  4;
15415         unsigned int op2 :  8;
15416      } RIEv1;
15417      struct {
15418         unsigned int op1 :  8;
15419         unsigned int r1  :  4;
15420         unsigned int r2  :  4;
15421         unsigned int i4  : 16;
15422         unsigned int m3  :  4;
15423         unsigned int     :  4;
15424         unsigned int op2 :  8;
15425      } RIE_RRPU;
15426      struct {
15427         unsigned int op1 :  8;
15428         unsigned int r1  :  4;
15429         unsigned int m3  :  4;
15430         unsigned int i4  : 16;
15431         unsigned int i2  :  8;
15432         unsigned int op2 :  8;
15433      } RIEv3;
15434      struct {
15435         unsigned int op1 :  8;
15436         unsigned int r1  :  4;
15437         unsigned int op2 :  4;
15438         unsigned int i2  : 32;
15439      } RIL;
15440      struct {
15441         unsigned int op1 :  8;
15442         unsigned int r1  :  4;
15443         unsigned int m3  :  4;
15444         unsigned int b4  :  4;
15445         unsigned int d4  : 12;
15446         unsigned int i2  :  8;
15447         unsigned int op2 :  8;
15448      } RIS;
15449      struct {
15450         unsigned int op1 :  8;
15451         unsigned int r1  :  4;
15452         unsigned int r2  :  4;
15453         unsigned int b4  :  4;
15454         unsigned int d4  : 12;
15455         unsigned int m3  :  4;
15456         unsigned int     :  4;
15457         unsigned int op2 :  8;
15458      } RRS;
15459      struct {
15460         unsigned int op1 :  8;
15461         unsigned int l1  :  4;
15462         unsigned int     :  4;
15463         unsigned int b1  :  4;
15464         unsigned int d1  : 12;
15465         unsigned int     :  8;
15466         unsigned int op2 :  8;
15467      } RSL;
15468      struct {
15469         unsigned int op1 :  8;
15470         unsigned int r1  :  4;
15471         unsigned int r3  :  4;
15472         unsigned int b2  :  4;
15473         unsigned int dl2 : 12;
15474         unsigned int dh2 :  8;
15475         unsigned int op2 :  8;
15476      } RSY;
15477      struct {
15478         unsigned int op1 :  8;
15479         unsigned int r1  :  4;
15480         unsigned int x2  :  4;
15481         unsigned int b2  :  4;
15482         unsigned int d2  : 12;
15483         unsigned int     :  8;
15484         unsigned int op2 :  8;
15485      } RXE;
15486      struct {
15487         unsigned int op1 :  8;
15488         unsigned int r3  :  4;
15489         unsigned int x2  :  4;
15490         unsigned int b2  :  4;
15491         unsigned int d2  : 12;
15492         unsigned int r1  :  4;
15493         unsigned int     :  4;
15494         unsigned int op2 :  8;
15495      } RXF;
15496      struct {
15497         unsigned int op1 :  8;
15498         unsigned int r1  :  4;
15499         unsigned int x2  :  4;
15500         unsigned int b2  :  4;
15501         unsigned int dl2 : 12;
15502         unsigned int dh2 :  8;
15503         unsigned int op2 :  8;
15504      } RXY;
15505      struct {
15506         unsigned int op1 :  8;
15507         unsigned int i2  :  8;
15508         unsigned int b1  :  4;
15509         unsigned int dl1 : 12;
15510         unsigned int dh1 :  8;
15511         unsigned int op2 :  8;
15512      } SIY;
15513      struct {
15514         unsigned int op :  8;
15515         unsigned int l  :  8;
15516         unsigned int b1 :  4;
15517         unsigned int d1 : 12;
15518         unsigned int b2 :  4;
15519         unsigned int d2 : 12;
15520      } SS;
15521      struct {
15522         unsigned int op :  8;
15523         unsigned int l1 :  4;
15524         unsigned int l2 :  4;
15525         unsigned int b1 :  4;
15526         unsigned int d1 : 12;
15527         unsigned int b2 :  4;
15528         unsigned int d2 : 12;
15529      } SS_LLRDRD;
15530      struct {
15531         unsigned int op :  8;
15532         unsigned int r1 :  4;
15533         unsigned int r3 :  4;
15534         unsigned int b2 :  4;
15535         unsigned int d2 : 12;
15536         unsigned int b4 :  4;
15537         unsigned int d4 : 12;
15538      } SS_RRRDRD2;
15539      struct {
15540         unsigned int op : 16;
15541         unsigned int b1 :  4;
15542         unsigned int d1 : 12;
15543         unsigned int b2 :  4;
15544         unsigned int d2 : 12;
15545      } SSE;
15546      struct {
15547         unsigned int op1 :  8;
15548         unsigned int r3  :  4;
15549         unsigned int op2 :  4;
15550         unsigned int b1  :  4;
15551         unsigned int d1  : 12;
15552         unsigned int b2  :  4;
15553         unsigned int d2  : 12;
15554      } SSF;
15555      struct {
15556         unsigned int op : 16;
15557         unsigned int b1 :  4;
15558         unsigned int d1 : 12;
15559         unsigned int i2 : 16;
15560      } SIL;
15561   } formats;
15562   union {
15563      formats fmt;
15564      ULong value;
15565   } ovl;
15566
15567   vassert(sizeof(formats) == 6);
15568
15569   ((UChar *)(&ovl.value))[0] = bytes[0];
15570   ((UChar *)(&ovl.value))[1] = bytes[1];
15571   ((UChar *)(&ovl.value))[2] = bytes[2];
15572   ((UChar *)(&ovl.value))[3] = bytes[3];
15573   ((UChar *)(&ovl.value))[4] = bytes[4];
15574   ((UChar *)(&ovl.value))[5] = bytes[5];
15575   ((UChar *)(&ovl.value))[6] = 0x0;
15576   ((UChar *)(&ovl.value))[7] = 0x0;
15577
15578   switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15579   case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15580                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15581                                                ovl.fmt.RXY.dl2,
15582                                                ovl.fmt.RXY.dh2);  goto ok;
15583   case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15584   case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15585                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15586                                                ovl.fmt.RXY.dl2,
15587                                                ovl.fmt.RXY.dh2);  goto ok;
15588   case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15589                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15590                                                ovl.fmt.RXY.dl2,
15591                                                ovl.fmt.RXY.dh2);  goto ok;
15592   case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15593                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15594                                                ovl.fmt.RXY.dl2,
15595                                                ovl.fmt.RXY.dh2);  goto ok;
15596   case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15597                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15598                                                ovl.fmt.RXY.dl2,
15599                                                ovl.fmt.RXY.dh2);  goto ok;
15600   case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15601                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15602                                                ovl.fmt.RXY.dl2,
15603                                                ovl.fmt.RXY.dh2);  goto ok;
15604   case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15605                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15606                                                ovl.fmt.RXY.dl2,
15607                                                ovl.fmt.RXY.dh2);  goto ok;
15608   case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15609                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15610                                                ovl.fmt.RXY.dl2,
15611                                                ovl.fmt.RXY.dh2);  goto ok;
15612   case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15613                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15614                                                ovl.fmt.RXY.dl2,
15615                                                ovl.fmt.RXY.dh2);  goto ok;
15616   case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15617   case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
15618                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15619                                                ovl.fmt.RXY.dl2,
15620                                                ovl.fmt.RXY.dh2);  goto ok;
15621   case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
15622                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15623                                                ovl.fmt.RXY.dl2,
15624                                                ovl.fmt.RXY.dh2);  goto ok;
15625   case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15626   case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15627                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15628                                                ovl.fmt.RXY.dl2,
15629                                                ovl.fmt.RXY.dh2);  goto ok;
15630   case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15631                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15632                                                ovl.fmt.RXY.dl2,
15633                                                ovl.fmt.RXY.dh2);  goto ok;
15634   case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15635                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15636                                                ovl.fmt.RXY.dl2,
15637                                                ovl.fmt.RXY.dh2);  goto ok;
15638   case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15639                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15640                                                ovl.fmt.RXY.dl2,
15641                                                ovl.fmt.RXY.dh2);  goto ok;
15642   case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15643                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15644                                                ovl.fmt.RXY.dl2,
15645                                                ovl.fmt.RXY.dh2);  goto ok;
15646   case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15647                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15648                                                ovl.fmt.RXY.dl2,
15649                                                ovl.fmt.RXY.dh2);  goto ok;
15650   case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15651                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15652                                                ovl.fmt.RXY.dl2,
15653                                                ovl.fmt.RXY.dh2);  goto ok;
15654   case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15655                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15656                                                ovl.fmt.RXY.dl2,
15657                                                ovl.fmt.RXY.dh2);  goto ok;
15658   case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15659                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15660                                                ovl.fmt.RXY.dl2,
15661                                                ovl.fmt.RXY.dh2);  goto ok;
15662   case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15663                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15664                                                ovl.fmt.RXY.dl2,
15665                                                ovl.fmt.RXY.dh2);  goto ok;
15666   case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15667                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15668                                                ovl.fmt.RXY.dl2,
15669                                                ovl.fmt.RXY.dh2);  goto ok;
15670   case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15671                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15672                                                ovl.fmt.RXY.dl2,
15673                                                ovl.fmt.RXY.dh2);  goto ok;
15674   case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15675                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15676                                                ovl.fmt.RXY.dl2,
15677                                                ovl.fmt.RXY.dh2);  goto ok;
15678   case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15679                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15680                                                ovl.fmt.RXY.dl2,
15681                                                ovl.fmt.RXY.dh2);  goto ok;
15682   case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15683                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15684                                                ovl.fmt.RXY.dl2,
15685                                                ovl.fmt.RXY.dh2);  goto ok;
15686   case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
15687   case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15688                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15689                                                ovl.fmt.RXY.dl2,
15690                                                ovl.fmt.RXY.dh2);  goto ok;
15691   case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15692   case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15693                                                ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15694                                                ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15695                                                ovl.fmt.RXY.dh2);  goto ok;
15696   case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15697                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15698                                                ovl.fmt.RXY.dl2,
15699                                                ovl.fmt.RXY.dh2);  goto ok;
15700   case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15701                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15702                                                ovl.fmt.RXY.dl2,
15703                                                ovl.fmt.RXY.dh2);  goto ok;
15704   case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15705                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15706                                                ovl.fmt.RXY.dl2,
15707                                                ovl.fmt.RXY.dh2);  goto ok;
15708   case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15709                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15710                                                ovl.fmt.RXY.dl2,
15711                                                ovl.fmt.RXY.dh2);  goto ok;
15712   case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15713                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15714                                                ovl.fmt.RXY.dl2,
15715                                                ovl.fmt.RXY.dh2);  goto ok;
15716   case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15717                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15718                                                ovl.fmt.RXY.dl2,
15719                                                ovl.fmt.RXY.dh2);  goto ok;
15720   case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15721                                                ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15722                                                ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15723                                                ovl.fmt.RXY.dh2);  goto ok;
15724   case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15725                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15726                                                ovl.fmt.RXY.dl2,
15727                                                ovl.fmt.RXY.dh2);  goto ok;
15728   case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15729                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15730                                                ovl.fmt.RXY.dl2,
15731                                                ovl.fmt.RXY.dh2);  goto ok;
15732   case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15733                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15734                                                ovl.fmt.RXY.dl2,
15735                                                ovl.fmt.RXY.dh2);  goto ok;
15736   case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15737                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15738                                                ovl.fmt.RXY.dl2,
15739                                                ovl.fmt.RXY.dh2);  goto ok;
15740   case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15741                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15742                                                ovl.fmt.RXY.dl2,
15743                                                ovl.fmt.RXY.dh2);  goto ok;
15744   case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15745                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15746                                                ovl.fmt.RXY.dl2,
15747                                                ovl.fmt.RXY.dh2);  goto ok;
15748   case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15749                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15750                                                ovl.fmt.RXY.dl2,
15751                                                ovl.fmt.RXY.dh2);  goto ok;
15752   case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15753                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15754                                                ovl.fmt.RXY.dl2,
15755                                                ovl.fmt.RXY.dh2);  goto ok;
15756   case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15757                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15758                                                ovl.fmt.RXY.dl2,
15759                                                ovl.fmt.RXY.dh2);  goto ok;
15760   case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15761                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15762                                                ovl.fmt.RXY.dl2,
15763                                                ovl.fmt.RXY.dh2);  goto ok;
15764   case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15765                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15766                                                ovl.fmt.RXY.dl2,
15767                                                ovl.fmt.RXY.dh2);  goto ok;
15768   case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15769                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15770                                                ovl.fmt.RXY.dl2,
15771                                                ovl.fmt.RXY.dh2);  goto ok;
15772   case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15773                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15774                                                ovl.fmt.RXY.dl2,
15775                                                ovl.fmt.RXY.dh2);  goto ok;
15776   case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15777                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15778                                                ovl.fmt.RXY.dl2,
15779                                                ovl.fmt.RXY.dh2);  goto ok;
15780   case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15781                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15782                                                ovl.fmt.RXY.dl2,
15783                                                ovl.fmt.RXY.dh2);  goto ok;
15784   case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15785                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15786                                                ovl.fmt.RXY.dl2,
15787                                                ovl.fmt.RXY.dh2);  goto ok;
15788   case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15789                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15790                                                ovl.fmt.RXY.dl2,
15791                                                ovl.fmt.RXY.dh2);  goto ok;
15792   case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15793                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15794                                                ovl.fmt.RXY.dl2,
15795                                                ovl.fmt.RXY.dh2);  goto ok;
15796   case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15797                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15798                                                ovl.fmt.RXY.dl2,
15799                                                ovl.fmt.RXY.dh2);  goto ok;
15800   case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15801                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15802                                                ovl.fmt.RXY.dl2,
15803                                                ovl.fmt.RXY.dh2);  goto ok;
15804   case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15805                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15806                                                ovl.fmt.RXY.dl2,
15807                                                ovl.fmt.RXY.dh2);  goto ok;
15808   case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15809                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15810                                                ovl.fmt.RXY.dl2,
15811                                                ovl.fmt.RXY.dh2);  goto ok;
15812   case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15813                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15814                                                ovl.fmt.RXY.dl2,
15815                                                ovl.fmt.RXY.dh2);  goto ok;
15816   case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15817                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15818                                                ovl.fmt.RXY.dl2,
15819                                                ovl.fmt.RXY.dh2);  goto ok;
15820   case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15821                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15822                                                ovl.fmt.RXY.dl2,
15823                                                ovl.fmt.RXY.dh2);  goto ok;
15824   case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15825                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15826                                                ovl.fmt.RXY.dl2,
15827                                                ovl.fmt.RXY.dh2);  goto ok;
15828   case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15829                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15830                                                ovl.fmt.RXY.dl2,
15831                                                ovl.fmt.RXY.dh2);  goto ok;
15832   case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15833                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15834                                                ovl.fmt.RXY.dl2,
15835                                                ovl.fmt.RXY.dh2);  goto ok;
15836   case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15837                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15838                                                ovl.fmt.RXY.dl2,
15839                                                ovl.fmt.RXY.dh2);  goto ok;
15840   case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
15841   case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15842                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15843                                                ovl.fmt.RXY.dl2,
15844                                                ovl.fmt.RXY.dh2);  goto ok;
15845   case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15846                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15847                                                ovl.fmt.RXY.dl2,
15848                                                ovl.fmt.RXY.dh2);  goto ok;
15849   case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15850                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15851                                                ovl.fmt.RXY.dl2,
15852                                                ovl.fmt.RXY.dh2);  goto ok;
15853   case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15854                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15855                                                ovl.fmt.RXY.dl2,
15856                                                ovl.fmt.RXY.dh2);  goto ok;
15857   case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15858                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15859                                                ovl.fmt.RXY.dl2,
15860                                                ovl.fmt.RXY.dh2);  goto ok;
15861   case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15862                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15863                                                ovl.fmt.RXY.dl2,
15864                                                ovl.fmt.RXY.dh2);  goto ok;
15865   case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15866                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15867                                                ovl.fmt.RXY.dl2,
15868                                                ovl.fmt.RXY.dh2);  goto ok;
15869   case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15870                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15871                                                ovl.fmt.RXY.dl2,
15872                                                ovl.fmt.RXY.dh2);  goto ok;
15873   case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15874                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15875                                                ovl.fmt.RXY.dl2,
15876                                                ovl.fmt.RXY.dh2);  goto ok;
15877   case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15878                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15879                                                ovl.fmt.RXY.dl2,
15880                                                ovl.fmt.RXY.dh2);  goto ok;
15881   case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15882                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15883                                                ovl.fmt.RXY.dl2,
15884                                                ovl.fmt.RXY.dh2);  goto ok;
15885   case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15886                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15887                                                ovl.fmt.RXY.dl2,
15888                                                ovl.fmt.RXY.dh2);  goto ok;
15889   case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15890                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15891                                                ovl.fmt.RXY.dl2,
15892                                                ovl.fmt.RXY.dh2);  goto ok;
15893   case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15894                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15895                                                ovl.fmt.RXY.dl2,
15896                                                ovl.fmt.RXY.dh2);  goto ok;
15897   case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15898   case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15899   case 0xe3000000009fULL: /* LAT */ goto unimplemented;
15900   case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15901                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15902                                                ovl.fmt.RXY.dl2,
15903                                                ovl.fmt.RXY.dh2);  goto ok;
15904   case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15905                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15906                                                ovl.fmt.RXY.dl2,
15907                                                ovl.fmt.RXY.dh2);  goto ok;
15908   case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15909                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15910                                                ovl.fmt.RXY.dl2,
15911                                                ovl.fmt.RXY.dh2);  goto ok;
15912   case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15913                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15914                                                ovl.fmt.RXY.dl2,
15915                                                ovl.fmt.RXY.dh2);  goto ok;
15916   case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15917                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15918                                                ovl.fmt.RXY.dl2,
15919                                                ovl.fmt.RXY.dh2);  goto ok;
15920   case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15921                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15922                                                ovl.fmt.RXY.dl2,
15923                                                ovl.fmt.RXY.dh2);  goto ok;
15924   case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
15925   case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15926                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15927                                                ovl.fmt.RXY.dl2,
15928                                                ovl.fmt.RXY.dh2);  goto ok;
15929   case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15930                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15931                                                ovl.fmt.RXY.dl2,
15932                                                ovl.fmt.RXY.dh2);  goto ok;
15933   case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15934                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15935                                                ovl.fmt.RXY.dl2,
15936                                                ovl.fmt.RXY.dh2);  goto ok;
15937   case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15938                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15939                                                ovl.fmt.RXY.dl2,
15940                                                ovl.fmt.RXY.dh2);  goto ok;
15941   case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15942                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15943                                                ovl.fmt.RSY.dl2,
15944                                                ovl.fmt.RSY.dh2);  goto ok;
15945   case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15946                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15947                                                ovl.fmt.RSY.dl2,
15948                                                ovl.fmt.RSY.dh2);  goto ok;
15949   case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15950                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15951                                                ovl.fmt.RSY.dl2,
15952                                                ovl.fmt.RSY.dh2);  goto ok;
15953   case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15954                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15955                                                ovl.fmt.RSY.dl2,
15956                                                ovl.fmt.RSY.dh2);  goto ok;
15957   case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15958                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15959                                                ovl.fmt.RSY.dl2,
15960                                                ovl.fmt.RSY.dh2);  goto ok;
15961   case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15962   case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15963                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15964                                                ovl.fmt.RSY.dl2,
15965                                                ovl.fmt.RSY.dh2);  goto ok;
15966   case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15967                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15968                                                ovl.fmt.RSY.dl2,
15969                                                ovl.fmt.RSY.dh2);  goto ok;
15970   case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15971                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15972                                                ovl.fmt.RSY.dl2,
15973                                                ovl.fmt.RSY.dh2);  goto ok;
15974   case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15975                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15976                                                ovl.fmt.RSY.dl2,
15977                                                ovl.fmt.RSY.dh2);  goto ok;
15978   case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15979                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15980                                                ovl.fmt.RSY.dl2,
15981                                                ovl.fmt.RSY.dh2);  goto ok;
15982   case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
15983   case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15984                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15985                                                ovl.fmt.RSY.dl2,
15986                                                ovl.fmt.RSY.dh2);  goto ok;
15987   case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15988   case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15989                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15990                                                ovl.fmt.RSY.dl2,
15991                                                ovl.fmt.RSY.dh2);  goto ok;
15992   case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
15993   case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15994                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15995                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15996                                                ovl.fmt.RSY.dh2);  goto ok;
15997   case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15998                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15999                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16000                                                ovl.fmt.RSY.dh2);  goto ok;
16001   case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
16002   case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
16003                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16004                                                ovl.fmt.RSY.dl2,
16005                                                ovl.fmt.RSY.dh2);  goto ok;
16006   case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
16007                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16008                                                ovl.fmt.RSY.dl2,
16009                                                ovl.fmt.RSY.dh2);  goto ok;
16010   case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
16011                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16012                                                ovl.fmt.RSY.dl2,
16013                                                ovl.fmt.RSY.dh2);  goto ok;
16014   case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
16015                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16016                                                ovl.fmt.RSY.dl2,
16017                                                ovl.fmt.RSY.dh2);  goto ok;
16018   case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
16019                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
16020                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16021                                                ovl.fmt.RSY.dh2);  goto ok;
16022   case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
16023                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16024                                                ovl.fmt.RSY.dl2,
16025                                                ovl.fmt.RSY.dh2);  goto ok;
16026   case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
16027                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16028                                               ovl.fmt.SIY.dh1);  goto ok;
16029   case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
16030                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16031                                               ovl.fmt.SIY.dh1);  goto ok;
16032   case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
16033                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16034                                               ovl.fmt.SIY.dh1);  goto ok;
16035   case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
16036                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16037                                               ovl.fmt.SIY.dh1);  goto ok;
16038   case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
16039                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16040                                               ovl.fmt.SIY.dh1);  goto ok;
16041   case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
16042                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16043                                               ovl.fmt.SIY.dh1);  goto ok;
16044   case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
16045                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16046                                               ovl.fmt.SIY.dh1);  goto ok;
16047   case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
16048                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16049                                               ovl.fmt.SIY.dh1);  goto ok;
16050   case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
16051                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16052                                               ovl.fmt.SIY.dh1);  goto ok;
16053   case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
16054                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16055                                               ovl.fmt.SIY.dh1);  goto ok;
16056   case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
16057                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16058                                                ovl.fmt.RSY.dl2,
16059                                                ovl.fmt.RSY.dh2);  goto ok;
16060   case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
16061                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16062                                                ovl.fmt.RSY.dl2,
16063                                                ovl.fmt.RSY.dh2);  goto ok;
16064   case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
16065   case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
16066   case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
16067                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16068                                                ovl.fmt.RSY.dl2,
16069                                                ovl.fmt.RSY.dh2);  goto ok;
16070   case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
16071                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16072                                                ovl.fmt.RSY.dl2,
16073                                                ovl.fmt.RSY.dh2);  goto ok;
16074   case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
16075                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16076                                                ovl.fmt.RSY.dl2,
16077                                                ovl.fmt.RSY.dh2);  goto ok;
16078   case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
16079                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16080                                                ovl.fmt.RSY.dl2,
16081                                                ovl.fmt.RSY.dh2);  goto ok;
16082   case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
16083                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
16084                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16085                                                ovl.fmt.RSY.dh2);  goto ok;
16086   case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
16087   case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
16088                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16089                                                ovl.fmt.RSY.dl2,
16090                                                ovl.fmt.RSY.dh2);  goto ok;
16091   case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
16092                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16093                                                ovl.fmt.RSY.dl2,
16094                                                ovl.fmt.RSY.dh2);  goto ok;
16095   case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
16096                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16097                                                ovl.fmt.RSY.dl2,
16098                                                ovl.fmt.RSY.dh2);  goto ok;
16099   case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
16100                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16101                                                ovl.fmt.RSY.dl2,
16102                                                ovl.fmt.RSY.dh2);  goto ok;
16103   case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
16104                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16105                                                ovl.fmt.RSY.dl2,
16106                                                ovl.fmt.RSY.dh2,
16107                                                S390_XMNM_LOCG);  goto ok;
16108   case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
16109                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
16110                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16111                                                ovl.fmt.RSY.dh2,
16112                                                S390_XMNM_STOCG);  goto ok;
16113   case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
16114                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16115                                                ovl.fmt.RSY.dl2,
16116                                                ovl.fmt.RSY.dh2);  goto ok;
16117   case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
16118                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16119                                                ovl.fmt.RSY.dl2,
16120                                                ovl.fmt.RSY.dh2);  goto ok;
16121   case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
16122                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16123                                                ovl.fmt.RSY.dl2,
16124                                                ovl.fmt.RSY.dh2);  goto ok;
16125   case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
16126                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16127                                                ovl.fmt.RSY.dl2,
16128                                                ovl.fmt.RSY.dh2);  goto ok;
16129   case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
16130                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
16131                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16132                                                ovl.fmt.RSY.dh2);  goto ok;
16133   case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
16134                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16135                                                ovl.fmt.RSY.dl2,
16136                                                ovl.fmt.RSY.dh2, S390_XMNM_LOC);
16137                                                goto ok;
16138   case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
16139                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16140                                                ovl.fmt.RSY.dl2,
16141                                                ovl.fmt.RSY.dh2,
16142                                                S390_XMNM_STOC);  goto ok;
16143   case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
16144                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16145                                                ovl.fmt.RSY.dl2,
16146                                                ovl.fmt.RSY.dh2);  goto ok;
16147   case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
16148                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16149                                                ovl.fmt.RSY.dl2,
16150                                                ovl.fmt.RSY.dh2);  goto ok;
16151   case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
16152                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16153                                                ovl.fmt.RSY.dl2,
16154                                                ovl.fmt.RSY.dh2);  goto ok;
16155   case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
16156                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16157                                                ovl.fmt.RSY.dl2,
16158                                                ovl.fmt.RSY.dh2);  goto ok;
16159   case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
16160                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16161                                                ovl.fmt.RSY.dl2,
16162                                                ovl.fmt.RSY.dh2);  goto ok;
16163   case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
16164                                               ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
16165                                               goto ok;
16166   case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
16167                                               ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
16168                                               goto ok;
16169   case 0xec0000000051ULL: s390_format_RIE_RRUUU(s390_irgen_RISBLG,
16170                                                 ovl.fmt.RIE_RRUUU.r1,
16171                                                 ovl.fmt.RIE_RRUUU.r2,
16172                                                 ovl.fmt.RIE_RRUUU.i3,
16173                                                 ovl.fmt.RIE_RRUUU.i4,
16174                                                 ovl.fmt.RIE_RRUUU.i5);
16175                                                 goto ok;
16176   case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
16177                                                 ovl.fmt.RIE_RRUUU.r1,
16178                                                 ovl.fmt.RIE_RRUUU.r2,
16179                                                 ovl.fmt.RIE_RRUUU.i3,
16180                                                 ovl.fmt.RIE_RRUUU.i4,
16181                                                 ovl.fmt.RIE_RRUUU.i5);
16182                                                 goto ok;
16183   case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
16184                                                 ovl.fmt.RIE_RRUUU.r1,
16185                                                 ovl.fmt.RIE_RRUUU.r2,
16186                                                 ovl.fmt.RIE_RRUUU.i3,
16187                                                 ovl.fmt.RIE_RRUUU.i4,
16188                                                 ovl.fmt.RIE_RRUUU.i5);
16189                                                 goto ok;
16190   case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
16191                                                 ovl.fmt.RIE_RRUUU.r1,
16192                                                 ovl.fmt.RIE_RRUUU.r2,
16193                                                 ovl.fmt.RIE_RRUUU.i3,
16194                                                 ovl.fmt.RIE_RRUUU.i4,
16195                                                 ovl.fmt.RIE_RRUUU.i5);
16196                                                 goto ok;
16197   case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
16198                                                 ovl.fmt.RIE_RRUUU.r1,
16199                                                 ovl.fmt.RIE_RRUUU.r2,
16200                                                 ovl.fmt.RIE_RRUUU.i3,
16201                                                 ovl.fmt.RIE_RRUUU.i4,
16202                                                 ovl.fmt.RIE_RRUUU.i5);
16203                                                 goto ok;
16204   case 0xec0000000059ULL: s390_format_RIE_RRUUU(s390_irgen_RISBGN,
16205                                                 ovl.fmt.RIE_RRUUU.r1,
16206                                                 ovl.fmt.RIE_RRUUU.r2,
16207                                                 ovl.fmt.RIE_RRUUU.i3,
16208                                                 ovl.fmt.RIE_RRUUU.i4,
16209                                                 ovl.fmt.RIE_RRUUU.i5);
16210                                                 goto ok;
16211   case 0xec000000005dULL: s390_format_RIE_RRUUU(s390_irgen_RISBHG,
16212                                                 ovl.fmt.RIE_RRUUU.r1,
16213                                                 ovl.fmt.RIE_RRUUU.r2,
16214                                                 ovl.fmt.RIE_RRUUU.i3,
16215                                                 ovl.fmt.RIE_RRUUU.i4,
16216                                                 ovl.fmt.RIE_RRUUU.i5);
16217                                                 goto ok;
16218   case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
16219                                                ovl.fmt.RIE_RRPU.r1,
16220                                                ovl.fmt.RIE_RRPU.r2,
16221                                                ovl.fmt.RIE_RRPU.i4,
16222                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
16223   case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
16224                                                ovl.fmt.RIE_RRPU.r1,
16225                                                ovl.fmt.RIE_RRPU.r2,
16226                                                ovl.fmt.RIE_RRPU.i4,
16227                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
16228   case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
16229   case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
16230   case 0xec0000000072ULL: /* CIT */ goto unimplemented;
16231   case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
16232   case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
16233                                                ovl.fmt.RIE_RRPU.r1,
16234                                                ovl.fmt.RIE_RRPU.r2,
16235                                                ovl.fmt.RIE_RRPU.i4,
16236                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
16237   case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
16238                                                ovl.fmt.RIE_RRPU.r1,
16239                                                ovl.fmt.RIE_RRPU.r2,
16240                                                ovl.fmt.RIE_RRPU.i4,
16241                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
16242   case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
16243                                                ovl.fmt.RIEv3.r1,
16244                                                ovl.fmt.RIEv3.m3,
16245                                                ovl.fmt.RIEv3.i4,
16246                                                ovl.fmt.RIEv3.i2);  goto ok;
16247   case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
16248                                                ovl.fmt.RIEv3.r1,
16249                                                ovl.fmt.RIEv3.m3,
16250                                                ovl.fmt.RIEv3.i4,
16251                                                ovl.fmt.RIEv3.i2);  goto ok;
16252   case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
16253                                                ovl.fmt.RIEv3.r1,
16254                                                ovl.fmt.RIEv3.m3,
16255                                                ovl.fmt.RIEv3.i4,
16256                                                ovl.fmt.RIEv3.i2);  goto ok;
16257   case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
16258                                                ovl.fmt.RIEv3.r1,
16259                                                ovl.fmt.RIEv3.m3,
16260                                                ovl.fmt.RIEv3.i4,
16261                                                ovl.fmt.RIEv3.i2);  goto ok;
16262   case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
16263                                                ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
16264                                                goto ok;
16265   case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
16266                                                ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16267                                                ovl.fmt.RIE.i2);  goto ok;
16268   case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
16269                                                ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16270                                                ovl.fmt.RIE.i2);  goto ok;
16271   case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
16272                                                ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16273                                                ovl.fmt.RIE.i2);  goto ok;
16274   case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
16275                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16276                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16277                                           goto ok;
16278   case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
16279                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16280                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16281                                           goto ok;
16282   case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
16283                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16284                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16285                                           goto ok;
16286   case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
16287                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16288                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16289                                           goto ok;
16290   case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
16291                                                 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16292                                                 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16293                                                 ovl.fmt.RIS.i2);  goto ok;
16294   case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
16295                                                 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16296                                                 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16297                                                 ovl.fmt.RIS.i2);  goto ok;
16298   case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
16299                                                 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
16300                                                 ovl.fmt.RIS.d4,
16301                                                 ovl.fmt.RIS.i2);  goto ok;
16302   case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
16303                                                 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16304                                                 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16305                                                 ovl.fmt.RIS.i2);  goto ok;
16306   case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
16307                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16308                                                ovl.fmt.RXE.d2);  goto ok;
16309   case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
16310                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16311                                                ovl.fmt.RXE.d2);  goto ok;
16312   case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
16313                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16314                                                ovl.fmt.RXE.d2);  goto ok;
16315   case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
16316   case 0xed0000000008ULL: /* KEB */ goto unimplemented;
16317   case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
16318                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16319                                                ovl.fmt.RXE.d2);  goto ok;
16320   case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
16321                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16322                                                ovl.fmt.RXE.d2);  goto ok;
16323   case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
16324                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16325                                                ovl.fmt.RXE.d2);  goto ok;
16326   case 0xed000000000cULL: /* MDEB */ goto unimplemented;
16327   case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
16328                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16329                                                ovl.fmt.RXE.d2);  goto ok;
16330   case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
16331                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16332                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16333                                                 ovl.fmt.RXF.r1);  goto ok;
16334   case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
16335                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16336                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16337                                                 ovl.fmt.RXF.r1);  goto ok;
16338   case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
16339                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16340                                                ovl.fmt.RXE.d2);  goto ok;
16341   case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
16342                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16343                                                ovl.fmt.RXE.d2);  goto ok;
16344   case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
16345                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16346                                                ovl.fmt.RXE.d2);  goto ok;
16347   case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
16348                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16349                                                ovl.fmt.RXE.d2);  goto ok;
16350   case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
16351                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16352                                                ovl.fmt.RXE.d2);  goto ok;
16353   case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
16354                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16355                                                ovl.fmt.RXE.d2);  goto ok;
16356   case 0xed0000000018ULL: /* KDB */ goto unimplemented;
16357   case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
16358                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16359                                                ovl.fmt.RXE.d2);  goto ok;
16360   case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
16361                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16362                                                ovl.fmt.RXE.d2);  goto ok;
16363   case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
16364                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16365                                                ovl.fmt.RXE.d2);  goto ok;
16366   case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
16367                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16368                                                ovl.fmt.RXE.d2);  goto ok;
16369   case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
16370                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16371                                                ovl.fmt.RXE.d2);  goto ok;
16372   case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
16373                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16374                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16375                                                 ovl.fmt.RXF.r1);  goto ok;
16376   case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
16377                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16378                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16379                                                 ovl.fmt.RXF.r1);  goto ok;
16380   case 0xed0000000024ULL: s390_format_RXE_FRRD(s390_irgen_LDE,
16381                                                ovl.fmt.RXE.r1, ovl.fmt.RXE.x2,
16382                                                ovl.fmt.RXE.b2,
16383                                                ovl.fmt.RXE.d2); goto ok;
16384   case 0xed0000000025ULL: /* LXD */ goto unimplemented;
16385   case 0xed0000000026ULL: /* LXE */ goto unimplemented;
16386   case 0xed000000002eULL: /* MAE */ goto unimplemented;
16387   case 0xed000000002fULL: /* MSE */ goto unimplemented;
16388   case 0xed0000000034ULL: /* SQE */ goto unimplemented;
16389   case 0xed0000000035ULL: /* SQD */ goto unimplemented;
16390   case 0xed0000000037ULL: /* MEE */ goto unimplemented;
16391   case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
16392   case 0xed0000000039ULL: /* MYL */ goto unimplemented;
16393   case 0xed000000003aULL: /* MAY */ goto unimplemented;
16394   case 0xed000000003bULL: /* MY */ goto unimplemented;
16395   case 0xed000000003cULL: /* MAYH */ goto unimplemented;
16396   case 0xed000000003dULL: /* MYH */ goto unimplemented;
16397   case 0xed000000003eULL: /* MAD */ goto unimplemented;
16398   case 0xed000000003fULL: /* MSD */ goto unimplemented;
16399   case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
16400                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16401                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16402                                                 ovl.fmt.RXF.r1);  goto ok;
16403   case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
16404                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16405                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16406                                                 ovl.fmt.RXF.r1);  goto ok;
16407   case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
16408                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16409                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16410                                                 ovl.fmt.RXF.r1);  goto ok;
16411   case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
16412                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16413                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16414                                                 ovl.fmt.RXF.r1);  goto ok;
16415   case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
16416                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16417                                                ovl.fmt.RXE.d2);  goto ok;
16418   case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
16419                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16420                                                ovl.fmt.RXE.d2);  goto ok;
16421   case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
16422                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16423                                                ovl.fmt.RXE.d2);  goto ok;
16424   case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
16425                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16426                                                ovl.fmt.RXE.d2);  goto ok;
16427   case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
16428                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16429                                                ovl.fmt.RXE.d2);  goto ok;
16430   case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
16431                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16432                                                ovl.fmt.RXE.d2);  goto ok;
16433   case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
16434                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16435                                                ovl.fmt.RXY.dl2,
16436                                                ovl.fmt.RXY.dh2);  goto ok;
16437   case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
16438                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16439                                                ovl.fmt.RXY.dl2,
16440                                                ovl.fmt.RXY.dh2);  goto ok;
16441   case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
16442                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16443                                                ovl.fmt.RXY.dl2,
16444                                                ovl.fmt.RXY.dh2);  goto ok;
16445   case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
16446                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16447                                                ovl.fmt.RXY.dl2,
16448                                                ovl.fmt.RXY.dh2);  goto ok;
16449   case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
16450   case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
16451   case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
16452   case 0xed00000000abULL: /* CXZT */ goto unimplemented;
16453   }
16454
16455   switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
16456   case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
16457                                      ovl.fmt.RIL.i2);  goto ok;
16458   case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
16459                                      ovl.fmt.RIL.i2);  goto ok;
16460   case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
16461                                   ovl.fmt.RIL.i2);  goto ok;
16462   case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16463                                      ovl.fmt.RIL.i2);  goto ok;
16464   case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16465                                      ovl.fmt.RIL.i2);  goto ok;
16466   case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16467                                      ovl.fmt.RIL.i2);  goto ok;
16468   case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16469                                      ovl.fmt.RIL.i2);  goto ok;
16470   case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16471                                      ovl.fmt.RIL.i2);  goto ok;
16472   case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16473                                      ovl.fmt.RIL.i2);  goto ok;
16474   case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16475                                      ovl.fmt.RIL.i2);  goto ok;
16476   case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16477                                      ovl.fmt.RIL.i2);  goto ok;
16478   case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16479                                      ovl.fmt.RIL.i2);  goto ok;
16480   case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16481                                      ovl.fmt.RIL.i2);  goto ok;
16482   case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16483                                      ovl.fmt.RIL.i2);  goto ok;
16484   case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16485                                      ovl.fmt.RIL.i2);  goto ok;
16486   case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16487                                      ovl.fmt.RIL.i2);  goto ok;
16488   case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16489                                      ovl.fmt.RIL.i2);  goto ok;
16490   case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16491                                      ovl.fmt.RIL.i2);  goto ok;
16492   case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16493                                      ovl.fmt.RIL.i2);  goto ok;
16494   case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16495                                      ovl.fmt.RIL.i2);  goto ok;
16496   case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16497                                      ovl.fmt.RIL.i2);  goto ok;
16498   case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16499                                      ovl.fmt.RIL.i2);  goto ok;
16500   case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16501                                      ovl.fmt.RIL.i2);  goto ok;
16502   case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16503                                      ovl.fmt.RIL.i2);  goto ok;
16504   case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16505                                      ovl.fmt.RIL.i2);  goto ok;
16506   case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16507                                      ovl.fmt.RIL.i2);  goto ok;
16508   case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16509                                      ovl.fmt.RIL.i2);  goto ok;
16510   case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16511                                      ovl.fmt.RIL.i2);  goto ok;
16512   case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16513                                      ovl.fmt.RIL.i2);  goto ok;
16514   case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16515                                      ovl.fmt.RIL.i2);  goto ok;
16516   case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16517                                      ovl.fmt.RIL.i2);  goto ok;
16518   case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16519                                      ovl.fmt.RIL.i2);  goto ok;
16520   case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16521                                      ovl.fmt.RIL.i2);  goto ok;
16522   case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16523                                      ovl.fmt.RIL.i2);  goto ok;
16524   case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16525                                      ovl.fmt.RIL.i2);  goto ok;
16526   case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16527                                      ovl.fmt.RIL.i2);  goto ok;
16528   case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16529                                      ovl.fmt.RIL.i2);  goto ok;
16530   case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16531                                      ovl.fmt.RIL.i2);  goto ok;
16532   case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16533                                      ovl.fmt.RIL.i2);  goto ok;
16534   case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16535                                      ovl.fmt.RIL.i2);  goto ok;
16536   case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16537                                      ovl.fmt.RIL.i2);  goto ok;
16538   case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16539                                      ovl.fmt.RIL.i2);  goto ok;
16540   case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16541                                      ovl.fmt.RIL.i2);  goto ok;
16542   case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16543                                      ovl.fmt.RIL.i2);  goto ok;
16544   case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16545                                      ovl.fmt.RIL.i2);  goto ok;
16546   case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16547                                      ovl.fmt.RIL.i2);  goto ok;
16548   case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16549                                      ovl.fmt.RIL.i2);  goto ok;
16550   case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16551                                      ovl.fmt.RIL.i2);  goto ok;
16552   case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16553                                      ovl.fmt.RIL.i2);  goto ok;
16554   case 0xc800ULL: /* MVCOS */ goto unimplemented;
16555   case 0xc801ULL: /* ECTG */ goto unimplemented;
16556   case 0xc802ULL: /* CSST */ goto unimplemented;
16557   case 0xc804ULL: /* LPD */ goto unimplemented;
16558   case 0xc805ULL: /* LPDG */ goto unimplemented;
16559   case 0xcc06ULL:  s390_format_RIL_RP(s390_irgen_BRCTH, ovl.fmt.RIL.r1,
16560                                       ovl.fmt.RIL.i2);  goto ok;
16561   case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16562                                      ovl.fmt.RIL.i2);  goto ok;
16563   case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16564                                      ovl.fmt.RIL.i2);  goto ok;
16565   case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16566                                      ovl.fmt.RIL.i2);  goto ok;
16567   case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16568                                      ovl.fmt.RIL.i2);  goto ok;
16569   case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16570                                      ovl.fmt.RIL.i2);  goto ok;
16571   }
16572
16573   switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
16574   case 0xc5ULL: /* BPRP */ goto unimplemented;
16575   case 0xc7ULL: /* BPP */ goto unimplemented;
16576   case 0xd0ULL: /* TRTR */ goto unimplemented;
16577   case 0xd1ULL: /* MVN */ goto unimplemented;
16578   case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16579                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16580                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16581   case 0xd3ULL: /* MVZ */ goto unimplemented;
16582   case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16583                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16584                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16585   case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16586                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16587                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16588   case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16589                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16590                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16591   case 0xd7ULL:
16592      if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16593         s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16594      else
16595        s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16596                              ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16597                              ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16598      goto ok;
16599   case 0xd9ULL: /* MVCK */ goto unimplemented;
16600   case 0xdaULL: /* MVCP */ goto unimplemented;
16601   case 0xdbULL: /* MVCS */ goto unimplemented;
16602   case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16603                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16604                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16605   case 0xddULL: /* TRT */ goto unimplemented;
16606   case 0xdeULL: /* ED */ goto unimplemented;
16607   case 0xdfULL: /* EDMK */ goto unimplemented;
16608   case 0xe1ULL: /* PKU */ goto unimplemented;
16609   case 0xe2ULL: /* UNPKU */ goto unimplemented;
16610   case 0xe8ULL: s390_format_SS_L0RDRD(s390_irgen_MVCIN, ovl.fmt.SS.l,
16611                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16612                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16613   case 0xe9ULL: /* PKA */ goto unimplemented;
16614   case 0xeaULL: /* UNPKA */ goto unimplemented;
16615   case 0xeeULL: /* PLO */ goto unimplemented;
16616   case 0xefULL: /* LMD */ goto unimplemented;
16617   case 0xf0ULL: /* SRP */ goto unimplemented;
16618   case 0xf1ULL: /* MVO */ goto unimplemented;
16619   case 0xf2ULL: /* PACK */ goto unimplemented;
16620   case 0xf3ULL: /* UNPK */ goto unimplemented;
16621   case 0xf8ULL: /* ZAP */ goto unimplemented;
16622   case 0xf9ULL: /* CP */ goto unimplemented;
16623   case 0xfaULL: /* AP */ goto unimplemented;
16624   case 0xfbULL: /* SP */ goto unimplemented;
16625   case 0xfcULL: /* MP */ goto unimplemented;
16626   case 0xfdULL: /* DP */ goto unimplemented;
16627   }
16628
16629   switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16630   case 0xe500ULL: /* LASP */ goto unimplemented;
16631   case 0xe501ULL: /* TPROT */ goto unimplemented;
16632   case 0xe502ULL: /* STRAG */ goto unimplemented;
16633   case 0xe50eULL: /* MVCSK */ goto unimplemented;
16634   case 0xe50fULL: /* MVCDK */ goto unimplemented;
16635   case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16636                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16637                                       goto ok;
16638   case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16639                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16640                                       goto ok;
16641   case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16642                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16643                                       goto ok;
16644   case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16645                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16646                                       goto ok;
16647   case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16648                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16649                                       goto ok;
16650   case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16651                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16652                                       goto ok;
16653   case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16654                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16655                                       goto ok;
16656   case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16657                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16658                                       goto ok;
16659   case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16660                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16661                                       goto ok;
16662   case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16663   case 0xe561ULL: /* TBEGINC */ goto unimplemented;
16664   }
16665
16666   return S390_DECODE_UNKNOWN_INSN;
16667
16668ok:
16669   return S390_DECODE_OK;
16670
16671unimplemented:
16672   return S390_DECODE_UNIMPLEMENTED_INSN;
16673}
16674
16675/* Handle "special" instructions. */
16676static s390_decode_t
16677s390_decode_special_and_irgen(const UChar *bytes)
16678{
16679   s390_decode_t status = S390_DECODE_OK;
16680
16681   /* Got a "Special" instruction preamble.  Which one is it? */
16682   if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16683      s390_irgen_client_request();
16684   } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16685      s390_irgen_guest_NRADDR();
16686   } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16687      s390_irgen_call_noredir();
16688   } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16689      vex_inject_ir(irsb, Iend_BE);
16690
16691      /* Invalidate the current insn. The reason is that the IRop we're
16692         injecting here can change. In which case the translation has to
16693         be redone. For ease of handling, we simply invalidate all the
16694         time. */
16695      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
16696                      mkU64(guest_IA_curr_instr)));
16697      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN),
16698                      mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16699      vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16700              S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16701
16702      put_IA(mkaddr_expr(guest_IA_next_instr));
16703      dis_res->whatNext    = Dis_StopHere;
16704      dis_res->jk_StopHere = Ijk_InvalICache;
16705   } else {
16706      /* We don't know what it is. */
16707      return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16708   }
16709
16710   dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16711
16712   return status;
16713}
16714
16715
16716/* Function returns # bytes that were decoded or 0 in case of failure */
16717static UInt
16718s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres)
16719{
16720   s390_decode_t status;
16721
16722   dis_res = dres;
16723
16724   /* Spot the 8-byte preamble:   18ff lr r15,r15
16725                                  1811 lr r1,r1
16726                                  1822 lr r2,r2
16727                                  1833 lr r3,r3 */
16728   if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16729       bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16730       bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16731
16732      /* Handle special instruction that follows that preamble. */
16733      if (0) vex_printf("special function handling...\n");
16734
16735      insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16736      guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16737
16738      status =
16739         s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
16740   } else {
16741      /* Handle normal instructions. */
16742      switch (insn_length) {
16743      case 2:
16744         status = s390_decode_2byte_and_irgen(bytes);
16745         break;
16746
16747      case 4:
16748         status = s390_decode_4byte_and_irgen(bytes);
16749         break;
16750
16751      case 6:
16752         status = s390_decode_6byte_and_irgen(bytes);
16753         break;
16754
16755      default:
16756        status = S390_DECODE_ERROR;
16757        break;
16758      }
16759   }
16760   /* If next instruction is execute, stop here */
16761   if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16762      put_IA(mkaddr_expr(guest_IA_next_instr));
16763      dis_res->whatNext = Dis_StopHere;
16764      dis_res->jk_StopHere = Ijk_Boring;
16765   }
16766
16767   if (status == S390_DECODE_OK) return insn_length;  /* OK */
16768
16769   /* Decoding failed somehow */
16770   if (sigill_diag) {
16771      vex_printf("vex s390->IR: ");
16772      switch (status) {
16773      case S390_DECODE_UNKNOWN_INSN:
16774         vex_printf("unknown insn: ");
16775         break;
16776
16777      case S390_DECODE_UNIMPLEMENTED_INSN:
16778         vex_printf("unimplemented insn: ");
16779         break;
16780
16781      case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16782         vex_printf("unimplemented special insn: ");
16783         break;
16784
16785      case S390_DECODE_ERROR:
16786         vex_printf("decoding error: ");
16787         break;
16788
16789      default:
16790         vpanic("s390_decode_and_irgen");
16791      }
16792
16793      vex_printf("%02x%02x", bytes[0], bytes[1]);
16794      if (insn_length > 2) {
16795         vex_printf(" %02x%02x", bytes[2], bytes[3]);
16796      }
16797      if (insn_length > 4) {
16798         vex_printf(" %02x%02x", bytes[4], bytes[5]);
16799      }
16800      vex_printf("\n");
16801   }
16802
16803   return 0;  /* Failed */
16804}
16805
16806
16807/* Disassemble a single instruction INSN into IR. */
16808static DisResult
16809disInstr_S390_WRK(const UChar *insn)
16810{
16811   UChar byte;
16812   UInt  insn_length;
16813   DisResult dres;
16814
16815   /* ---------------------------------------------------- */
16816   /* --- Compute instruction length                    -- */
16817   /* ---------------------------------------------------- */
16818
16819   /* Get the first byte of the insn. */
16820   byte = insn[0];
16821
16822   /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16823      00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16824   insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16825
16826   guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16827
16828   /* ---------------------------------------------------- */
16829   /* --- Initialise the DisResult data                 -- */
16830   /* ---------------------------------------------------- */
16831   dres.whatNext   = Dis_Continue;
16832   dres.len        = insn_length;
16833   dres.continueAt = 0;
16834   dres.jk_StopHere = Ijk_INVALID;
16835   dres.hint        = Dis_HintNone;
16836
16837   /* fixs390: consider chasing of conditional jumps */
16838
16839   /* Normal and special instruction handling starts here. */
16840   if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16841      /* All decode failures end up here. The decoder has already issued an
16842         error message.
16843         Tell the dispatcher that this insn cannot be decoded, and so has
16844         not been executed, and (is currently) the next to be executed.
16845         The insn address in the guest state needs to be set to
16846         guest_IA_curr_instr, otherwise the complaint will report an
16847         incorrect address. */
16848      put_IA(mkaddr_expr(guest_IA_curr_instr));
16849
16850      dres.len         = 0;
16851      dres.whatNext    = Dis_StopHere;
16852      dres.jk_StopHere = Ijk_NoDecode;
16853      dres.continueAt  = 0;
16854   } else {
16855      /* Decode success */
16856      switch (dres.whatNext) {
16857      case Dis_Continue:
16858         put_IA(mkaddr_expr(guest_IA_next_instr));
16859         break;
16860      case Dis_ResteerU:
16861      case Dis_ResteerC:
16862         put_IA(mkaddr_expr(dres.continueAt));
16863         break;
16864      case Dis_StopHere:
16865         if (dres.jk_StopHere == Ijk_EmWarn ||
16866             dres.jk_StopHere == Ijk_EmFail) {
16867            /* We assume here, that emulation warnings are not given for
16868               insns that transfer control. There is no good way to
16869               do that. */
16870            put_IA(mkaddr_expr(guest_IA_next_instr));
16871         }
16872         break;
16873      default:
16874         vpanic("disInstr_S390_WRK");
16875      }
16876   }
16877
16878   return dres;
16879}
16880
16881
16882/*------------------------------------------------------------*/
16883/*--- Top-level fn                                         ---*/
16884/*------------------------------------------------------------*/
16885
16886/* Disassemble a single instruction into IR.  The instruction
16887   is located in host memory at &guest_code[delta]. */
16888
16889DisResult
16890disInstr_S390(IRSB        *irsb_IN,
16891              Bool       (*resteerOkFn)(void *, Addr),
16892              Bool         resteerCisOk,
16893              void        *callback_opaque,
16894              const UChar *guest_code,
16895              Long         delta,
16896              Addr         guest_IP,
16897              VexArch      guest_arch,
16898              const VexArchInfo *archinfo,
16899              const VexAbiInfo  *abiinfo,
16900              VexEndness   host_endness,
16901              Bool         sigill_diag_IN)
16902{
16903   vassert(guest_arch == VexArchS390X);
16904
16905   /* The instruction decoder requires a big-endian machine. */
16906   vassert(host_endness == VexEndnessBE);
16907
16908   /* Set globals (see top of this file) */
16909   guest_IA_curr_instr = guest_IP;
16910   irsb = irsb_IN;
16911   resteer_fn = resteerOkFn;
16912   resteer_data = callback_opaque;
16913   sigill_diag = sigill_diag_IN;
16914
16915   return disInstr_S390_WRK(guest_code + delta);
16916}
16917
16918/*---------------------------------------------------------------*/
16919/*--- end                                   guest_s390_toIR.c ---*/
16920/*---------------------------------------------------------------*/
16921