guest_s390_toIR.c revision c36ed7a14ec92dee029d0fa5918afc71a475432b
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-2013
12
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License as
15   published by the Free Software Foundation; either version 2 of the
16   License, or (at your option) any later version.
17
18   This program is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21   General Public License for more details.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26   02110-1301, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
37#include "libvex_emnote.h"
38#include "libvex_s390x_common.h"
39#include "main_util.h"               /* vassert */
40#include "main_globals.h"            /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h"  /* DisResult */
42#include "guest_s390_defs.h"         /* prototypes for this file's functions */
43#include "s390_disasm.h"
44#include "s390_defs.h"               /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h"          /* s390_host_has_xyzzy */
46
47
48/*------------------------------------------------------------*/
49/*--- Forward declarations                                 ---*/
50/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(const UChar *, UInt, DisResult *);
52static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
53static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
54
55
56/*------------------------------------------------------------*/
57/*--- Globals                                              ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64   translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
73/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr);
75static void *resteer_data;
76
77/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
80/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85   S390_DECODE_OK,
86   S390_DECODE_UNKNOWN_INSN,
87   S390_DECODE_UNIMPLEMENTED_INSN,
88   S390_DECODE_UNKNOWN_SPECIAL_INSN,
89   S390_DECODE_ERROR
90} s390_decode_t;
91
92
93/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR.                         ---*/
95/*------------------------------------------------------------*/
96
97/* Add a statement to the current irsb. */
98static __inline__ void
99stmt(IRStmt *st)
100{
101   addStmtToIRSB(irsb, st);
102}
103
104/* Allocate a new temporary of the given type. */
105static __inline__ IRTemp
106newTemp(IRType type)
107{
108   vassert(isPlausibleIRType(type));
109
110   return newIRTemp(irsb->tyenv, type);
111}
112
113/* Create an expression node for a temporary */
114static __inline__ IRExpr *
115mkexpr(IRTemp tmp)
116{
117   return IRExpr_RdTmp(tmp);
118}
119
120/* Generate an expression node for an address. */
121static __inline__ IRExpr *
122mkaddr_expr(Addr64 addr)
123{
124   return IRExpr_Const(IRConst_U64(addr));
125}
126
127/* Add a statement that assigns to a temporary */
128static __inline__ void
129assign(IRTemp dst, IRExpr *expr)
130{
131   stmt(IRStmt_WrTmp(dst, expr));
132}
133
134/* Write an address into the guest_IA */
135static __inline__ void
136put_IA(IRExpr *address)
137{
138   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
139}
140
141/* Create a temporary of the given type and assign the expression to it */
142static __inline__ IRTemp
143mktemp(IRType type, IRExpr *expr)
144{
145   IRTemp temp = newTemp(type);
146
147   assign(temp, expr);
148
149   return temp;
150}
151
152/* Create a unary expression */
153static __inline__ IRExpr *
154unop(IROp kind, IRExpr *op)
155{
156   return IRExpr_Unop(kind, op);
157}
158
159/* Create a binary expression */
160static __inline__ IRExpr *
161binop(IROp kind, IRExpr *op1, IRExpr *op2)
162{
163   return IRExpr_Binop(kind, op1, op2);
164}
165
166/* Create a ternary expression */
167static __inline__ IRExpr *
168triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
169{
170   return IRExpr_Triop(kind, op1, op2, op3);
171}
172
173/* Create a quaternary expression */
174static __inline__  IRExpr *
175qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
176{
177   return IRExpr_Qop(kind, op1, op2, op3, op4);
178}
179
180/* Create an expression node for an 8-bit integer constant */
181static __inline__ IRExpr *
182mkU8(UInt value)
183{
184   vassert(value < 256);
185
186   return IRExpr_Const(IRConst_U8((UChar)value));
187}
188
189/* Create an expression node for a 16-bit integer constant */
190static __inline__ IRExpr *
191mkU16(UInt value)
192{
193   vassert(value < 65536);
194
195   return IRExpr_Const(IRConst_U16((UShort)value));
196}
197
198/* Create an expression node for a 32-bit integer constant */
199static __inline__ IRExpr *
200mkU32(UInt value)
201{
202   return IRExpr_Const(IRConst_U32(value));
203}
204
205/* Create an expression node for a 64-bit integer constant */
206static __inline__ IRExpr *
207mkU64(ULong value)
208{
209   return IRExpr_Const(IRConst_U64(value));
210}
211
212/* Create an expression node for a 32-bit floating point constant
213   whose value is given by a bit pattern. */
214static __inline__ IRExpr *
215mkF32i(UInt value)
216{
217   return IRExpr_Const(IRConst_F32i(value));
218}
219
220/* Create an expression node for a 32-bit floating point constant
221   whose value is given by a bit pattern. */
222static __inline__ IRExpr *
223mkF64i(ULong value)
224{
225   return IRExpr_Const(IRConst_F64i(value));
226}
227
228/* Little helper function for my sanity. ITE = if-then-else */
229static IRExpr *
230mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
231{
232   vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
233
234   return IRExpr_ITE(condition, iftrue, iffalse);
235}
236
237/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
238static __inline__ void
239store(IRExpr *addr, IRExpr *data)
240{
241   stmt(IRStmt_Store(Iend_BE, addr, data));
242}
243
244/* Create an expression that loads a TYPE sized value from ADDR.
245   This is a big-endian machine. */
246static __inline__ IRExpr *
247load(IRType type, IRExpr *addr)
248{
249   return IRExpr_Load(Iend_BE, type, addr);
250}
251
252/* Function call */
253static void
254call_function(IRExpr *callee_address)
255{
256   put_IA(callee_address);
257
258   dis_res->whatNext    = Dis_StopHere;
259   dis_res->jk_StopHere = Ijk_Call;
260}
261
262/* Function call with known target. */
263static void
264call_function_and_chase(Addr64 callee_address)
265{
266   if (resteer_fn(resteer_data, callee_address)) {
267      dis_res->whatNext   = Dis_ResteerU;
268      dis_res->continueAt = callee_address;
269   } else {
270      put_IA(mkaddr_expr(callee_address));
271
272      dis_res->whatNext = Dis_StopHere;
273      dis_res->jk_StopHere = Ijk_Call;
274   }
275}
276
277/* Function return sequence */
278static void
279return_from_function(IRExpr *return_address)
280{
281   put_IA(return_address);
282
283   dis_res->whatNext    = Dis_StopHere;
284   dis_res->jk_StopHere = Ijk_Ret;
285}
286
287/* A conditional branch whose target is not known at instrumentation time.
288
289   if (condition) goto computed_target;
290
291   Needs to be represented as:
292
293   if (! condition) goto next_instruction;
294   goto computed_target;
295*/
296static void
297if_condition_goto_computed(IRExpr *condition, IRExpr *target)
298{
299   vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
300
301   condition = unop(Iop_Not1, condition);
302
303   stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
304                    S390X_GUEST_OFFSET(guest_IA)));
305
306   put_IA(target);
307
308   dis_res->whatNext    = Dis_StopHere;
309   dis_res->jk_StopHere = Ijk_Boring;
310}
311
312/* A conditional branch whose target is known at instrumentation time. */
313static void
314if_condition_goto(IRExpr *condition, Addr64 target)
315{
316   vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
317
318   stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
319                    S390X_GUEST_OFFSET(guest_IA)));
320
321   put_IA(mkaddr_expr(guest_IA_next_instr));
322
323   dis_res->whatNext    = Dis_StopHere;
324   dis_res->jk_StopHere = Ijk_Boring;
325}
326
327/* An unconditional branch. Target may or may not be known at instrumentation
328   time. */
329static void
330always_goto(IRExpr *target)
331{
332   put_IA(target);
333
334   dis_res->whatNext    = Dis_StopHere;
335   dis_res->jk_StopHere = Ijk_Boring;
336}
337
338
339/* An unconditional branch to a known target. */
340static void
341always_goto_and_chase(Addr64 target)
342{
343   if (resteer_fn(resteer_data, target)) {
344      /* Follow into the target */
345      dis_res->whatNext   = Dis_ResteerU;
346      dis_res->continueAt = target;
347   } else {
348      put_IA(mkaddr_expr(target));
349
350      dis_res->whatNext    = Dis_StopHere;
351      dis_res->jk_StopHere = Ijk_Boring;
352   }
353}
354
355/* A system call */
356static void
357system_call(IRExpr *sysno)
358{
359   /* Store the system call number in the pseudo register. */
360   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
361
362   /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
363   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
364                   mkU64(guest_IA_curr_instr)));
365
366   put_IA(mkaddr_expr(guest_IA_next_instr));
367
368   /* It's important that all ArchRegs carry their up-to-date value
369      at this point.  So we declare an end-of-block here, which
370      forces any TempRegs caching ArchRegs to be flushed. */
371   dis_res->whatNext    = Dis_StopHere;
372   dis_res->jk_StopHere = Ijk_Sys_syscall;
373}
374
375/* A side exit that branches back to the current insn if CONDITION is
376   true. Does not set DisResult. */
377static void
378iterate_if(IRExpr *condition)
379{
380   vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
381
382   stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
383                    S390X_GUEST_OFFSET(guest_IA)));
384}
385
386/* A side exit that branches back to the current insn.
387   Does not set DisResult. */
388static __inline__ void
389iterate(void)
390{
391   iterate_if(IRExpr_Const(IRConst_U1(True)));
392}
393
394/* A side exit that branches back to the insn immediately following the
395   current insn if CONDITION is true. Does not set DisResult. */
396static void
397next_insn_if(IRExpr *condition)
398{
399   vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
400
401   stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
402                    S390X_GUEST_OFFSET(guest_IA)));
403}
404
405/* Convenience function to restart the current insn */
406static void
407restart_if(IRExpr *condition)
408{
409   vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
410
411   stmt(IRStmt_Exit(condition, Ijk_InvalICache,
412                    IRConst_U64(guest_IA_curr_instr),
413                    S390X_GUEST_OFFSET(guest_IA)));
414}
415
416/* Convenience function to yield to thread scheduler */
417static void
418yield_if(IRExpr *condition)
419{
420   stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
421                    S390X_GUEST_OFFSET(guest_IA)));
422}
423
424static __inline__ IRExpr *get_fpr_dw0(UInt);
425static __inline__ void    put_fpr_dw0(UInt, IRExpr *);
426static __inline__ IRExpr *get_dpr_dw0(UInt);
427static __inline__ void    put_dpr_dw0(UInt, IRExpr *);
428
429/* Read a floating point register pair and combine their contents into a
430   128-bit value */
431static IRExpr *
432get_fpr_pair(UInt archreg)
433{
434   IRExpr *high = get_fpr_dw0(archreg);
435   IRExpr *low  = get_fpr_dw0(archreg + 2);
436
437   return binop(Iop_F64HLtoF128, high, low);
438}
439
440/* Write a 128-bit floating point value into a register pair. */
441static void
442put_fpr_pair(UInt archreg, IRExpr *expr)
443{
444   IRExpr *high = unop(Iop_F128HItoF64, expr);
445   IRExpr *low  = unop(Iop_F128LOtoF64, expr);
446
447   put_fpr_dw0(archreg,     high);
448   put_fpr_dw0(archreg + 2, low);
449}
450
451/* Read a floating point register pair cointaining DFP value
452   and combine their contents into a 128-bit value */
453
454static IRExpr *
455get_dpr_pair(UInt archreg)
456{
457   IRExpr *high = get_dpr_dw0(archreg);
458   IRExpr *low  = get_dpr_dw0(archreg + 2);
459
460   return binop(Iop_D64HLtoD128, high, low);
461}
462
463/* Write a 128-bit decimal floating point value into a register pair. */
464static void
465put_dpr_pair(UInt archreg, IRExpr *expr)
466{
467   IRExpr *high = unop(Iop_D128HItoD64, expr);
468   IRExpr *low  = unop(Iop_D128LOtoD64, expr);
469
470   put_dpr_dw0(archreg,     high);
471   put_dpr_dw0(archreg + 2, low);
472}
473
474/* Terminate the current IRSB with an emulation failure. */
475static void
476emulation_failure_with_expr(IRExpr *emfailure)
477{
478   vassert(typeOfIRExpr(irsb->tyenv, emfailure) == Ity_I32);
479
480   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emfailure));
481   dis_res->whatNext = Dis_StopHere;
482   dis_res->jk_StopHere = Ijk_EmFail;
483}
484
485static void
486emulation_failure(VexEmNote fail_kind)
487{
488   emulation_failure_with_expr(mkU32(fail_kind));
489}
490
491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_warning_with_expr(IRExpr *emwarning)
494{
495   vassert(typeOfIRExpr(irsb->tyenv, emwarning) == Ity_I32);
496
497   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emwarning));
498   dis_res->whatNext = Dis_StopHere;
499   dis_res->jk_StopHere = Ijk_EmWarn;
500}
501
502static void
503emulation_warning(VexEmNote warn_kind)
504{
505   emulation_warning_with_expr(mkU32(warn_kind));
506}
507
508/*------------------------------------------------------------*/
509/*--- IR Debugging aids.                                   ---*/
510/*------------------------------------------------------------*/
511#if 0
512
513static ULong
514s390_do_print(HChar *text, ULong value)
515{
516   vex_printf("%s %llu\n", text, value);
517   return 0;
518}
519
520static void
521s390_print(HChar *text, IRExpr *value)
522{
523   IRDirty *d;
524
525   d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
526                         mkIRExprVec_2(mkU64((ULong)text), value));
527   stmt(IRStmt_Dirty(d));
528}
529#endif
530
531
532/*------------------------------------------------------------*/
533/*--- Build the flags thunk.                               ---*/
534/*------------------------------------------------------------*/
535
536/* Completely fill the flags thunk. We're always filling all fields.
537   Apparently, that is better for redundant PUT elimination. */
538static void
539s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
540{
541   UInt op_off, dep1_off, dep2_off, ndep_off;
542
543   op_off   = S390X_GUEST_OFFSET(guest_CC_OP);
544   dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
545   dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
546   ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
547
548   stmt(IRStmt_Put(op_off,   op));
549   stmt(IRStmt_Put(dep1_off, dep1));
550   stmt(IRStmt_Put(dep2_off, dep2));
551   stmt(IRStmt_Put(ndep_off, ndep));
552}
553
554
555/* Create an expression for V and widen the result to 64 bit. */
556static IRExpr *
557s390_cc_widen(IRTemp v, Bool sign_extend)
558{
559   IRExpr *expr;
560
561   expr = mkexpr(v);
562
563   switch (typeOfIRTemp(irsb->tyenv, v)) {
564   case Ity_I64:
565      break;
566   case Ity_I32:
567      expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
568      break;
569   case Ity_I16:
570      expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
571      break;
572   case Ity_I8:
573      expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
574      break;
575   default:
576      vpanic("s390_cc_widen");
577   }
578
579   return expr;
580}
581
582static void
583s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
584{
585   IRExpr *op, *dep1, *dep2, *ndep;
586
587   op   = mkU64(opc);
588   dep1 = s390_cc_widen(d1, sign_extend);
589   dep2 = mkU64(0);
590   ndep = mkU64(0);
591
592   s390_cc_thunk_fill(op, dep1, dep2, ndep);
593}
594
595
596static void
597s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
598{
599   IRExpr *op, *dep1, *dep2, *ndep;
600
601   op   = mkU64(opc);
602   dep1 = s390_cc_widen(d1, sign_extend);
603   dep2 = s390_cc_widen(d2, sign_extend);
604   ndep = mkU64(0);
605
606   s390_cc_thunk_fill(op, dep1, dep2, ndep);
607}
608
609
610/* memcheck believes that the NDEP field in the flags thunk is always
611   defined. But for some flag computations (e.g. add with carry) that is
612   just not true. We therefore need to convey to memcheck that the value
613   of the ndep field does matter and therefore we make the DEP2 field
614   depend on it:
615
616   DEP2 = original_DEP2 ^ NDEP
617
618   In s390_calculate_cc we exploit that  (a^b)^b == a
619   I.e. we xor the DEP2 value with the NDEP value to recover the
620   original_DEP2 value. */
621static void
622s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
623{
624   IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
625
626   op   = mkU64(opc);
627   dep1 = s390_cc_widen(d1, sign_extend);
628   dep2 = s390_cc_widen(d2, sign_extend);
629   ndep = s390_cc_widen(nd, sign_extend);
630
631   dep2x = binop(Iop_Xor64, dep2, ndep);
632
633   s390_cc_thunk_fill(op, dep1, dep2x, ndep);
634}
635
636
637/* Write one floating point value into the flags thunk */
638static void
639s390_cc_thunk_put1f(UInt opc, IRTemp d1)
640{
641   IRExpr *op, *dep1, *dep2, *ndep;
642
643   /* Make the CC_DEP1 slot appear completely defined.
644      Otherwise, assigning a 32-bit value will cause memcheck
645      to trigger an undefinedness error.
646   */
647   if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
648      UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
649      stmt(IRStmt_Put(dep1_off, mkU64(0)));
650   }
651   op   = mkU64(opc);
652   dep1 = mkexpr(d1);
653   dep2 = mkU64(0);
654   ndep = mkU64(0);
655
656   s390_cc_thunk_fill(op, dep1, dep2, ndep);
657}
658
659
660/* Write a floating point value and an integer into the flags thunk. The
661   integer value is zero-extended first. */
662static void
663s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
664{
665   IRExpr *op, *dep1, *dep2, *ndep;
666
667   /* Make the CC_DEP1 slot appear completely defined.
668      Otherwise, assigning a 32-bit value will cause memcheck
669      to trigger an undefinedness error.
670   */
671   if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
672      UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
673      stmt(IRStmt_Put(dep1_off, mkU64(0)));
674   }
675   op   = mkU64(opc);
676   dep1 = mkexpr(d1);
677   dep2 = s390_cc_widen(d2, False);
678   ndep = mkU64(0);
679
680   s390_cc_thunk_fill(op, dep1, dep2, ndep);
681}
682
683
684/* Write a 128-bit floating point value into the flags thunk. This is
685   done by splitting the value into two 64-bits values. */
686static void
687s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
688{
689   IRExpr *op, *hi, *lo, *ndep;
690
691   op   = mkU64(opc);
692   hi   = unop(Iop_F128HItoF64, mkexpr(d1));
693   lo   = unop(Iop_F128LOtoF64, mkexpr(d1));
694   ndep = mkU64(0);
695
696   s390_cc_thunk_fill(op, hi, lo, ndep);
697}
698
699
700/* Write a 128-bit floating point value and an integer into the flags thunk.
701   The integer value is zero-extended first. */
702static void
703s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
704{
705   IRExpr *op, *hi, *lo, *lox, *ndep;
706
707   op   = mkU64(opc);
708   hi   = unop(Iop_F128HItoF64, mkexpr(d1));
709   lo   = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
710   ndep = s390_cc_widen(nd, False);
711
712   lox = binop(Iop_Xor64, lo, ndep);  /* convey dependency */
713
714   s390_cc_thunk_fill(op, hi, lox, ndep);
715}
716
717
718/* Write a 128-bit decimal floating point value into the flags thunk.
719   This is done by splitting the value into two 64-bits values. */
720static void
721s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
722{
723   IRExpr *op, *hi, *lo, *ndep;
724
725   op   = mkU64(opc);
726   hi   = unop(Iop_D128HItoD64, mkexpr(d1));
727   lo   = unop(Iop_D128LOtoD64, mkexpr(d1));
728   ndep = mkU64(0);
729
730   s390_cc_thunk_fill(op, hi, lo, ndep);
731}
732
733
734/* Write a 128-bit decimal floating point value and an integer into the flags
735   thunk. The integer value is zero-extended first. */
736static void
737s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
738{
739   IRExpr *op, *hi, *lo, *lox, *ndep;
740
741   op   = mkU64(opc);
742   hi   = unop(Iop_D128HItoD64, mkexpr(d1));
743   lo   = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
744   ndep = s390_cc_widen(nd, False);
745
746   lox = binop(Iop_Xor64, lo, ndep);  /* convey dependency */
747
748   s390_cc_thunk_fill(op, hi, lox, ndep);
749}
750
751
752static void
753s390_cc_set(UInt val)
754{
755   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
756                      mkU64(val), mkU64(0), mkU64(0));
757}
758
759/* Build IR to calculate the condition code from flags thunk.
760   Returns an expression of type Ity_I32 */
761static IRExpr *
762s390_call_calculate_cc(void)
763{
764   IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
765
766   op   = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP),   Ity_I64);
767   dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
768   dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
769   ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
770
771   args = mkIRExprVec_4(op, dep1, dep2, ndep);
772   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
773                        "s390_calculate_cc", &s390_calculate_cc, args);
774
775   /* Exclude OP and NDEP from definedness checking.  We're only
776      interested in DEP1 and DEP2. */
777   call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
778
779   return call;
780}
781
782/* Build IR to calculate the internal condition code for a "compare and branch"
783   insn. Returns an expression of type Ity_I32 */
784static IRExpr *
785s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
786{
787   IRExpr **args, *call, *op, *dep1, *dep2, *mask;
788
789   switch (opc) {
790   case S390_CC_OP_SIGNED_COMPARE:
791      dep1 = s390_cc_widen(op1, True);
792      dep2 = s390_cc_widen(op2, True);
793      break;
794
795   case S390_CC_OP_UNSIGNED_COMPARE:
796      dep1 = s390_cc_widen(op1, False);
797      dep2 = s390_cc_widen(op2, False);
798      break;
799
800   default:
801      vpanic("s390_call_calculate_icc");
802   }
803
804   mask = mkU64(m);
805   op   = mkU64(opc);
806
807   args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
808   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
809                        "s390_calculate_cond", &s390_calculate_cond, args);
810
811   /* Exclude the requested condition, OP and NDEP from definedness
812      checking.  We're only interested in DEP1 and DEP2. */
813   call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
814
815   return call;
816}
817
818/* Build IR to calculate the condition code from flags thunk.
819   Returns an expression of type Ity_I32 */
820static IRExpr *
821s390_call_calculate_cond(UInt m)
822{
823   IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
824
825   mask = mkU64(m);
826   op   = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP),   Ity_I64);
827   dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
828   dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
829   ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
830
831   args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
832   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
833                        "s390_calculate_cond", &s390_calculate_cond, args);
834
835   /* Exclude the requested condition, OP and NDEP from definedness
836      checking.  We're only interested in DEP1 and DEP2. */
837   call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
838
839   return call;
840}
841
842#define s390_cc_thunk_putZ(op,dep1)  s390_cc_thunk_put1(op,dep1,False)
843#define s390_cc_thunk_putS(op,dep1)  s390_cc_thunk_put1(op,dep1,True)
844#define s390_cc_thunk_putF(op,dep1)  s390_cc_thunk_put1f(op,dep1)
845#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
846#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
847#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
848#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
849        s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
850#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
851        s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
852
853
854
855
856/*------------------------------------------------------------*/
857/*--- Guest register access                                ---*/
858/*------------------------------------------------------------*/
859
860
861/*------------------------------------------------------------*/
862/*--- ar registers                                         ---*/
863/*------------------------------------------------------------*/
864
865/* Return the guest state offset of a ar register. */
866static UInt
867ar_offset(UInt archreg)
868{
869   static const UInt offset[16] = {
870      S390X_GUEST_OFFSET(guest_a0),
871      S390X_GUEST_OFFSET(guest_a1),
872      S390X_GUEST_OFFSET(guest_a2),
873      S390X_GUEST_OFFSET(guest_a3),
874      S390X_GUEST_OFFSET(guest_a4),
875      S390X_GUEST_OFFSET(guest_a5),
876      S390X_GUEST_OFFSET(guest_a6),
877      S390X_GUEST_OFFSET(guest_a7),
878      S390X_GUEST_OFFSET(guest_a8),
879      S390X_GUEST_OFFSET(guest_a9),
880      S390X_GUEST_OFFSET(guest_a10),
881      S390X_GUEST_OFFSET(guest_a11),
882      S390X_GUEST_OFFSET(guest_a12),
883      S390X_GUEST_OFFSET(guest_a13),
884      S390X_GUEST_OFFSET(guest_a14),
885      S390X_GUEST_OFFSET(guest_a15),
886   };
887
888   vassert(archreg < 16);
889
890   return offset[archreg];
891}
892
893
894/* Return the guest state offset of word #0 of a ar register. */
895static __inline__ UInt
896ar_w0_offset(UInt archreg)
897{
898   return ar_offset(archreg) + 0;
899}
900
901/* Write word #0 of a ar to the guest state. */
902static __inline__ void
903put_ar_w0(UInt archreg, IRExpr *expr)
904{
905   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
906
907   stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
908}
909
910/* Read word #0 of a ar register. */
911static __inline__ IRExpr *
912get_ar_w0(UInt archreg)
913{
914   return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
915}
916
917
918/*------------------------------------------------------------*/
919/*--- fpr registers                                        ---*/
920/*------------------------------------------------------------*/
921
922/* Return the guest state offset of a fpr register. */
923static UInt
924fpr_offset(UInt archreg)
925{
926   static const UInt offset[16] = {
927      S390X_GUEST_OFFSET(guest_f0),
928      S390X_GUEST_OFFSET(guest_f1),
929      S390X_GUEST_OFFSET(guest_f2),
930      S390X_GUEST_OFFSET(guest_f3),
931      S390X_GUEST_OFFSET(guest_f4),
932      S390X_GUEST_OFFSET(guest_f5),
933      S390X_GUEST_OFFSET(guest_f6),
934      S390X_GUEST_OFFSET(guest_f7),
935      S390X_GUEST_OFFSET(guest_f8),
936      S390X_GUEST_OFFSET(guest_f9),
937      S390X_GUEST_OFFSET(guest_f10),
938      S390X_GUEST_OFFSET(guest_f11),
939      S390X_GUEST_OFFSET(guest_f12),
940      S390X_GUEST_OFFSET(guest_f13),
941      S390X_GUEST_OFFSET(guest_f14),
942      S390X_GUEST_OFFSET(guest_f15),
943   };
944
945   vassert(archreg < 16);
946
947   return offset[archreg];
948}
949
950
951/* Return the guest state offset of word #0 of a fpr register. */
952static __inline__ UInt
953fpr_w0_offset(UInt archreg)
954{
955   return fpr_offset(archreg) + 0;
956}
957
958/* Write word #0 of a fpr to the guest state. */
959static __inline__ void
960put_fpr_w0(UInt archreg, IRExpr *expr)
961{
962   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
963
964   stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
965}
966
967/* Read word #0 of a fpr register. */
968static __inline__ IRExpr *
969get_fpr_w0(UInt archreg)
970{
971   return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
972}
973
974/* Return the guest state offset of double word #0 of a fpr register. */
975static __inline__ UInt
976fpr_dw0_offset(UInt archreg)
977{
978   return fpr_offset(archreg) + 0;
979}
980
981/* Write double word #0 of a fpr to the guest state. */
982static __inline__ void
983put_fpr_dw0(UInt archreg, IRExpr *expr)
984{
985   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
986
987   stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
988}
989
990/* Read double word #0 of a fpr register. */
991static __inline__ IRExpr *
992get_fpr_dw0(UInt archreg)
993{
994   return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
995}
996
997/* Write word #0 of a dpr to the guest state. */
998static __inline__ void
999put_dpr_w0(UInt archreg, IRExpr *expr)
1000{
1001   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
1002
1003   stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
1004}
1005
1006/* Read word #0 of a dpr register. */
1007static __inline__ IRExpr *
1008get_dpr_w0(UInt archreg)
1009{
1010   return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
1011}
1012
1013/* Write double word #0 of a fpr containg DFP value to the guest state. */
1014static __inline__ void
1015put_dpr_dw0(UInt archreg, IRExpr *expr)
1016{
1017   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
1018
1019   stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1020}
1021
1022/* Read double word #0 of a fpr register containing DFP value. */
1023static __inline__ IRExpr *
1024get_dpr_dw0(UInt archreg)
1025{
1026   return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1027}
1028
1029/*------------------------------------------------------------*/
1030/*--- gpr registers                                        ---*/
1031/*------------------------------------------------------------*/
1032
1033/* Return the guest state offset of a gpr register. */
1034static UInt
1035gpr_offset(UInt archreg)
1036{
1037   static const UInt offset[16] = {
1038      S390X_GUEST_OFFSET(guest_r0),
1039      S390X_GUEST_OFFSET(guest_r1),
1040      S390X_GUEST_OFFSET(guest_r2),
1041      S390X_GUEST_OFFSET(guest_r3),
1042      S390X_GUEST_OFFSET(guest_r4),
1043      S390X_GUEST_OFFSET(guest_r5),
1044      S390X_GUEST_OFFSET(guest_r6),
1045      S390X_GUEST_OFFSET(guest_r7),
1046      S390X_GUEST_OFFSET(guest_r8),
1047      S390X_GUEST_OFFSET(guest_r9),
1048      S390X_GUEST_OFFSET(guest_r10),
1049      S390X_GUEST_OFFSET(guest_r11),
1050      S390X_GUEST_OFFSET(guest_r12),
1051      S390X_GUEST_OFFSET(guest_r13),
1052      S390X_GUEST_OFFSET(guest_r14),
1053      S390X_GUEST_OFFSET(guest_r15),
1054   };
1055
1056   vassert(archreg < 16);
1057
1058   return offset[archreg];
1059}
1060
1061
1062/* Return the guest state offset of word #0 of a gpr register. */
1063static __inline__ UInt
1064gpr_w0_offset(UInt archreg)
1065{
1066   return gpr_offset(archreg) + 0;
1067}
1068
1069/* Write word #0 of a gpr to the guest state. */
1070static __inline__ void
1071put_gpr_w0(UInt archreg, IRExpr *expr)
1072{
1073   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1074
1075   stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1076}
1077
1078/* Read word #0 of a gpr register. */
1079static __inline__ IRExpr *
1080get_gpr_w0(UInt archreg)
1081{
1082   return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1083}
1084
1085/* Return the guest state offset of double word #0 of a gpr register. */
1086static __inline__ UInt
1087gpr_dw0_offset(UInt archreg)
1088{
1089   return gpr_offset(archreg) + 0;
1090}
1091
1092/* Write double word #0 of a gpr to the guest state. */
1093static __inline__ void
1094put_gpr_dw0(UInt archreg, IRExpr *expr)
1095{
1096   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1097
1098   stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1099}
1100
1101/* Read double word #0 of a gpr register. */
1102static __inline__ IRExpr *
1103get_gpr_dw0(UInt archreg)
1104{
1105   return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1106}
1107
1108/* Return the guest state offset of half word #1 of a gpr register. */
1109static __inline__ UInt
1110gpr_hw1_offset(UInt archreg)
1111{
1112   return gpr_offset(archreg) + 2;
1113}
1114
1115/* Write half word #1 of a gpr to the guest state. */
1116static __inline__ void
1117put_gpr_hw1(UInt archreg, IRExpr *expr)
1118{
1119   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1120
1121   stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1122}
1123
1124/* Read half word #1 of a gpr register. */
1125static __inline__ IRExpr *
1126get_gpr_hw1(UInt archreg)
1127{
1128   return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1129}
1130
1131/* Return the guest state offset of byte #6 of a gpr register. */
1132static __inline__ UInt
1133gpr_b6_offset(UInt archreg)
1134{
1135   return gpr_offset(archreg) + 6;
1136}
1137
1138/* Write byte #6 of a gpr to the guest state. */
1139static __inline__ void
1140put_gpr_b6(UInt archreg, IRExpr *expr)
1141{
1142   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1143
1144   stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1145}
1146
1147/* Read byte #6 of a gpr register. */
1148static __inline__ IRExpr *
1149get_gpr_b6(UInt archreg)
1150{
1151   return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1152}
1153
1154/* Return the guest state offset of byte #3 of a gpr register. */
1155static __inline__ UInt
1156gpr_b3_offset(UInt archreg)
1157{
1158   return gpr_offset(archreg) + 3;
1159}
1160
1161/* Write byte #3 of a gpr to the guest state. */
1162static __inline__ void
1163put_gpr_b3(UInt archreg, IRExpr *expr)
1164{
1165   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1166
1167   stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1168}
1169
1170/* Read byte #3 of a gpr register. */
1171static __inline__ IRExpr *
1172get_gpr_b3(UInt archreg)
1173{
1174   return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1175}
1176
1177/* Return the guest state offset of byte #0 of a gpr register. */
1178static __inline__ UInt
1179gpr_b0_offset(UInt archreg)
1180{
1181   return gpr_offset(archreg) + 0;
1182}
1183
1184/* Write byte #0 of a gpr to the guest state. */
1185static __inline__ void
1186put_gpr_b0(UInt archreg, IRExpr *expr)
1187{
1188   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1189
1190   stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1191}
1192
1193/* Read byte #0 of a gpr register. */
1194static __inline__ IRExpr *
1195get_gpr_b0(UInt archreg)
1196{
1197   return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1198}
1199
1200/* Return the guest state offset of word #1 of a gpr register. */
1201static __inline__ UInt
1202gpr_w1_offset(UInt archreg)
1203{
1204   return gpr_offset(archreg) + 4;
1205}
1206
1207/* Write word #1 of a gpr to the guest state. */
1208static __inline__ void
1209put_gpr_w1(UInt archreg, IRExpr *expr)
1210{
1211   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1212
1213   stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1214}
1215
1216/* Read word #1 of a gpr register. */
1217static __inline__ IRExpr *
1218get_gpr_w1(UInt archreg)
1219{
1220   return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1221}
1222
1223/* Return the guest state offset of half word #3 of a gpr register. */
1224static __inline__ UInt
1225gpr_hw3_offset(UInt archreg)
1226{
1227   return gpr_offset(archreg) + 6;
1228}
1229
1230/* Write half word #3 of a gpr to the guest state. */
1231static __inline__ void
1232put_gpr_hw3(UInt archreg, IRExpr *expr)
1233{
1234   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1235
1236   stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1237}
1238
1239/* Read half word #3 of a gpr register. */
1240static __inline__ IRExpr *
1241get_gpr_hw3(UInt archreg)
1242{
1243   return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1244}
1245
1246/* Return the guest state offset of byte #7 of a gpr register. */
1247static __inline__ UInt
1248gpr_b7_offset(UInt archreg)
1249{
1250   return gpr_offset(archreg) + 7;
1251}
1252
1253/* Write byte #7 of a gpr to the guest state. */
1254static __inline__ void
1255put_gpr_b7(UInt archreg, IRExpr *expr)
1256{
1257   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1258
1259   stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1260}
1261
1262/* Read byte #7 of a gpr register. */
1263static __inline__ IRExpr *
1264get_gpr_b7(UInt archreg)
1265{
1266   return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1267}
1268
1269/* Return the guest state offset of half word #0 of a gpr register. */
1270static __inline__ UInt
1271gpr_hw0_offset(UInt archreg)
1272{
1273   return gpr_offset(archreg) + 0;
1274}
1275
1276/* Write half word #0 of a gpr to the guest state. */
1277static __inline__ void
1278put_gpr_hw0(UInt archreg, IRExpr *expr)
1279{
1280   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1281
1282   stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1283}
1284
1285/* Read half word #0 of a gpr register. */
1286static __inline__ IRExpr *
1287get_gpr_hw0(UInt archreg)
1288{
1289   return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1290}
1291
1292/* Return the guest state offset of byte #4 of a gpr register. */
1293static __inline__ UInt
1294gpr_b4_offset(UInt archreg)
1295{
1296   return gpr_offset(archreg) + 4;
1297}
1298
1299/* Write byte #4 of a gpr to the guest state. */
1300static __inline__ void
1301put_gpr_b4(UInt archreg, IRExpr *expr)
1302{
1303   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1304
1305   stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1306}
1307
1308/* Read byte #4 of a gpr register. */
1309static __inline__ IRExpr *
1310get_gpr_b4(UInt archreg)
1311{
1312   return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1313}
1314
1315/* Return the guest state offset of byte #1 of a gpr register. */
1316static __inline__ UInt
1317gpr_b1_offset(UInt archreg)
1318{
1319   return gpr_offset(archreg) + 1;
1320}
1321
1322/* Write byte #1 of a gpr to the guest state. */
1323static __inline__ void
1324put_gpr_b1(UInt archreg, IRExpr *expr)
1325{
1326   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1327
1328   stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1329}
1330
1331/* Read byte #1 of a gpr register. */
1332static __inline__ IRExpr *
1333get_gpr_b1(UInt archreg)
1334{
1335   return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1336}
1337
1338/* Return the guest state offset of half word #2 of a gpr register. */
1339static __inline__ UInt
1340gpr_hw2_offset(UInt archreg)
1341{
1342   return gpr_offset(archreg) + 4;
1343}
1344
1345/* Write half word #2 of a gpr to the guest state. */
1346static __inline__ void
1347put_gpr_hw2(UInt archreg, IRExpr *expr)
1348{
1349   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1350
1351   stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1352}
1353
1354/* Read half word #2 of a gpr register. */
1355static __inline__ IRExpr *
1356get_gpr_hw2(UInt archreg)
1357{
1358   return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1359}
1360
1361/* Return the guest state offset of byte #5 of a gpr register. */
1362static __inline__ UInt
1363gpr_b5_offset(UInt archreg)
1364{
1365   return gpr_offset(archreg) + 5;
1366}
1367
1368/* Write byte #5 of a gpr to the guest state. */
1369static __inline__ void
1370put_gpr_b5(UInt archreg, IRExpr *expr)
1371{
1372   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1373
1374   stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1375}
1376
1377/* Read byte #5 of a gpr register. */
1378static __inline__ IRExpr *
1379get_gpr_b5(UInt archreg)
1380{
1381   return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1382}
1383
1384/* Return the guest state offset of byte #2 of a gpr register. */
1385static __inline__ UInt
1386gpr_b2_offset(UInt archreg)
1387{
1388   return gpr_offset(archreg) + 2;
1389}
1390
1391/* Write byte #2 of a gpr to the guest state. */
1392static __inline__ void
1393put_gpr_b2(UInt archreg, IRExpr *expr)
1394{
1395   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1396
1397   stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1398}
1399
1400/* Read byte #2 of a gpr register. */
1401static __inline__ IRExpr *
1402get_gpr_b2(UInt archreg)
1403{
1404   return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1405}
1406
1407/* Return the guest state offset of the counter register. */
1408static UInt
1409counter_offset(void)
1410{
1411   return S390X_GUEST_OFFSET(guest_counter);
1412}
1413
1414/* Return the guest state offset of double word #0 of the counter register. */
1415static __inline__ UInt
1416counter_dw0_offset(void)
1417{
1418   return counter_offset() + 0;
1419}
1420
1421/* Write double word #0 of the counter to the guest state. */
1422static __inline__ void
1423put_counter_dw0(IRExpr *expr)
1424{
1425   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1426
1427   stmt(IRStmt_Put(counter_dw0_offset(), expr));
1428}
1429
1430/* Read double word #0 of the counter register. */
1431static __inline__ IRExpr *
1432get_counter_dw0(void)
1433{
1434   return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1435}
1436
1437/* Return the guest state offset of word #0 of the counter register. */
1438static __inline__ UInt
1439counter_w0_offset(void)
1440{
1441   return counter_offset() + 0;
1442}
1443
1444/* Return the guest state offset of word #1 of the counter register. */
1445static __inline__ UInt
1446counter_w1_offset(void)
1447{
1448   return counter_offset() + 4;
1449}
1450
1451/* Write word #0 of the counter to the guest state. */
1452static __inline__ void
1453put_counter_w0(IRExpr *expr)
1454{
1455   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1456
1457   stmt(IRStmt_Put(counter_w0_offset(), expr));
1458}
1459
1460/* Read word #0 of the counter register. */
1461static __inline__ IRExpr *
1462get_counter_w0(void)
1463{
1464   return IRExpr_Get(counter_w0_offset(), Ity_I32);
1465}
1466
1467/* Write word #1 of the counter to the guest state. */
1468static __inline__ void
1469put_counter_w1(IRExpr *expr)
1470{
1471   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1472
1473   stmt(IRStmt_Put(counter_w1_offset(), expr));
1474}
1475
1476/* Read word #1 of the counter register. */
1477static __inline__ IRExpr *
1478get_counter_w1(void)
1479{
1480   return IRExpr_Get(counter_w1_offset(), Ity_I32);
1481}
1482
1483/* Return the guest state offset of the fpc register. */
1484static UInt
1485fpc_offset(void)
1486{
1487   return S390X_GUEST_OFFSET(guest_fpc);
1488}
1489
1490/* Return the guest state offset of word #0 of the fpc register. */
1491static __inline__ UInt
1492fpc_w0_offset(void)
1493{
1494   return fpc_offset() + 0;
1495}
1496
1497/* Write word #0 of the fpc to the guest state. */
1498static __inline__ void
1499put_fpc_w0(IRExpr *expr)
1500{
1501   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1502
1503   stmt(IRStmt_Put(fpc_w0_offset(), expr));
1504}
1505
1506/* Read word #0 of the fpc register. */
1507static __inline__ IRExpr *
1508get_fpc_w0(void)
1509{
1510   return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1511}
1512
1513
1514/*------------------------------------------------------------*/
1515/*--- Rounding modes                                       ---*/
1516/*------------------------------------------------------------*/
1517
1518/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
1519   IRRoundingMode:
1520
1521   rounding mode | s390 | IR
1522   -------------------------
1523   to nearest    |  00  | 00
1524   to zero       |  01  | 11
1525   to +infinity  |  10  | 10
1526   to -infinity  |  11  | 01
1527
1528   So:  IR = (4 - s390) & 3
1529*/
1530static IRExpr *
1531get_bfp_rounding_mode_from_fpc(void)
1532{
1533   IRTemp fpc_bits = newTemp(Ity_I32);
1534
1535   /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1536      Prior to that bits [30:31] contained the bfp rounding mode with
1537      bit 29 being unused and having a value of 0. So we can always
1538      extract the least significant 3 bits. */
1539   assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1540
1541   /* fixs390:
1542
1543
1544      if (! s390_host_has_fpext && rounding_mode > 3) {
1545         emulation warning @ runtime and
1546         set fpc to round nearest
1547      }
1548   */
1549
1550   /* For now silently adjust an unsupported rounding mode to "nearest" */
1551   IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1552                           mkexpr(fpc_bits),
1553                           mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
1554
1555   // rm_IR = (4 - rm_s390) & 3;
1556   return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1557}
1558
1559/* Encode the s390 rounding mode as it appears in the m3 field of certain
1560   instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1561   represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1562   Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1563   considers the default rounding mode (4.3.3). */
1564static IRTemp
1565encode_bfp_rounding_mode(UChar mode)
1566{
1567   IRExpr *rm;
1568
1569   switch (mode) {
1570   case S390_BFP_ROUND_PER_FPC:
1571      rm = get_bfp_rounding_mode_from_fpc();
1572      break;
1573   case S390_BFP_ROUND_NEAREST_AWAY:  /* not supported */
1574   case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1575   case S390_BFP_ROUND_NEAREST_EVEN:  rm = mkU32(Irrm_NEAREST); break;
1576   case S390_BFP_ROUND_ZERO:          rm = mkU32(Irrm_ZERO);    break;
1577   case S390_BFP_ROUND_POSINF:        rm = mkU32(Irrm_PosINF);  break;
1578   case S390_BFP_ROUND_NEGINF:        rm = mkU32(Irrm_NegINF);  break;
1579   default:
1580      vpanic("encode_bfp_rounding_mode");
1581   }
1582
1583   return mktemp(Ity_I32, rm);
1584}
1585
1586/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1587   IRRoundingMode:
1588
1589   rounding mode                     | s390  | IR
1590   ------------------------------------------------
1591   to nearest, ties to even          |  000  | 000
1592   to zero                           |  001  | 011
1593   to +infinity                      |  010  | 010
1594   to -infinity                      |  011  | 001
1595   to nearest, ties away from 0      |  100  | 100
1596   to nearest, ties toward 0         |  101  | 111
1597   to away from 0                    |  110  | 110
1598   to prepare for shorter precision  |  111  | 101
1599
1600   So:  IR = (s390 ^ ((s390 << 1) & 2))
1601*/
1602static IRExpr *
1603get_dfp_rounding_mode_from_fpc(void)
1604{
1605   IRTemp fpc_bits = newTemp(Ity_I32);
1606
1607   /* The dfp rounding mode is stored in bits [25:27].
1608      extract the bits at 25:27 and right shift 4 times. */
1609   assign(fpc_bits, binop(Iop_Shr32,
1610                          binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1611                          mkU8(4)));
1612
1613   IRExpr *rm_s390 = mkexpr(fpc_bits);
1614   // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1615
1616   return binop(Iop_Xor32, rm_s390,
1617                binop( Iop_And32,
1618                       binop(Iop_Shl32, rm_s390, mkU8(1)),
1619                       mkU32(2)));
1620}
1621
1622/* Encode the s390 rounding mode as it appears in the m3 field of certain
1623   instructions to VEX's IRRoundingMode. */
1624static IRTemp
1625encode_dfp_rounding_mode(UChar mode)
1626{
1627   IRExpr *rm;
1628
1629   switch (mode) {
1630   case S390_DFP_ROUND_PER_FPC_0:
1631   case S390_DFP_ROUND_PER_FPC_2:
1632      rm = get_dfp_rounding_mode_from_fpc(); break;
1633   case S390_DFP_ROUND_NEAREST_EVEN_4:
1634   case S390_DFP_ROUND_NEAREST_EVEN_8:
1635      rm = mkU32(Irrm_NEAREST); break;
1636   case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1637   case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1638      rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
1639   case S390_DFP_ROUND_PREPARE_SHORT_3:
1640   case S390_DFP_ROUND_PREPARE_SHORT_15:
1641      rm = mkU32(Irrm_PREPARE_SHORTER); break;
1642   case S390_DFP_ROUND_ZERO_5:
1643   case S390_DFP_ROUND_ZERO_9:
1644      rm = mkU32(Irrm_ZERO ); break;
1645   case S390_DFP_ROUND_POSINF_6:
1646   case S390_DFP_ROUND_POSINF_10:
1647      rm = mkU32(Irrm_PosINF); break;
1648   case S390_DFP_ROUND_NEGINF_7:
1649   case S390_DFP_ROUND_NEGINF_11:
1650      rm = mkU32(Irrm_NegINF); break;
1651   case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1652      rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
1653   case S390_DFP_ROUND_AWAY_0:
1654      rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
1655   default:
1656      vpanic("encode_dfp_rounding_mode");
1657   }
1658
1659   return mktemp(Ity_I32, rm);
1660}
1661
1662
1663/*------------------------------------------------------------*/
1664/*--- Condition code helpers                               ---*/
1665/*------------------------------------------------------------*/
1666
1667/* The result of a Iop_CmpFxx operation is a condition code. It is
1668   encoded using the values defined in type IRCmpFxxResult.
1669   Before we can store the condition code into the guest state (or do
1670   anything else with it for that matter) we need to convert it to
1671   the encoding that s390 uses. This is what this function does.
1672
1673   s390     VEX                b6 b2 b0   cc.1  cc.0
1674   0      0x40 EQ             1  0  0     0     0
1675   1      0x01 LT             0  0  1     0     1
1676   2      0x00 GT             0  0  0     1     0
1677   3      0x45 Unordered      1  1  1     1     1
1678
1679   The following bits from the VEX encoding are interesting:
1680   b0, b2, b6  with b0 being the LSB. We observe:
1681
1682   cc.0 = b0;
1683   cc.1 = b2 | (~b0 & ~b6)
1684
1685   with cc being the s390 condition code.
1686*/
1687static IRExpr *
1688convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1689{
1690   IRTemp cc0  = newTemp(Ity_I32);
1691   IRTemp cc1  = newTemp(Ity_I32);
1692   IRTemp b0   = newTemp(Ity_I32);
1693   IRTemp b2   = newTemp(Ity_I32);
1694   IRTemp b6   = newTemp(Ity_I32);
1695
1696   assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1697   assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1698                    mkU32(1)));
1699   assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1700                    mkU32(1)));
1701
1702   assign(cc0, mkexpr(b0));
1703   assign(cc1, binop(Iop_Or32, mkexpr(b2),
1704                     binop(Iop_And32,
1705                           binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1706                           binop(Iop_Sub32, mkU32(1), mkexpr(b6))  /* ~b6 */
1707                           )));
1708
1709   return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1710}
1711
1712
1713/* The result of a Iop_CmpDxx operation is a condition code. It is
1714   encoded using the values defined in type IRCmpDxxResult.
1715   Before we can store the condition code into the guest state (or do
1716   anything else with it for that matter) we need to convert it to
1717   the encoding that s390 uses. This is what this function does. */
1718static IRExpr *
1719convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1720{
1721   /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1722      same. currently. */
1723   return convert_vex_bfpcc_to_s390(vex_cc);
1724}
1725
1726
1727/*------------------------------------------------------------*/
1728/*--- Build IR for formats                                 ---*/
1729/*------------------------------------------------------------*/
1730static void
1731s390_format_I(const HChar *(*irgen)(UChar i),
1732              UChar i)
1733{
1734   const HChar *mnm = irgen(i);
1735
1736   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1737      s390_disasm(ENC2(MNM, UINT), mnm, i);
1738}
1739
1740static void
1741s390_format_E(const HChar *(*irgen)(void))
1742{
1743   const HChar *mnm = irgen();
1744
1745   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1746      s390_disasm(ENC1(MNM), mnm);
1747}
1748
1749static void
1750s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
1751               UChar r1, UShort i2)
1752{
1753   irgen(r1, i2);
1754}
1755
1756static void
1757s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
1758                  UChar r1, UShort i2)
1759{
1760   const HChar *mnm = irgen(r1, i2);
1761
1762   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1763      s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1764}
1765
1766static void
1767s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
1768                  UChar r1, UShort i2)
1769{
1770   const HChar *mnm = irgen(r1, i2);
1771
1772   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1773      s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1774}
1775
1776static void
1777s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
1778                  UChar r1, UShort i2)
1779{
1780   const HChar *mnm = irgen(r1, i2);
1781
1782   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1783      s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1784}
1785
1786static void
1787s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1788                    UChar r1, UChar r3, UShort i2)
1789{
1790   const HChar *mnm = irgen(r1, r3, i2);
1791
1792   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1793      s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1794}
1795
1796static void
1797s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1798                     UChar r1, UChar r3, UShort i2)
1799{
1800   const HChar *mnm = irgen(r1, r3, i2);
1801
1802   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1803      s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1804}
1805
1806static void
1807s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1808                                            UChar i4, UChar i5),
1809                      UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1810{
1811   const HChar *mnm = irgen(r1, r2, i3, i4, i5);
1812
1813   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1814      s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1815                  i5);
1816}
1817
1818static void
1819s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1820                                           UChar m3),
1821                     UChar r1, UChar r2, UShort i4, UChar m3)
1822{
1823   const HChar *mnm = irgen(r1, r2, i4, m3);
1824
1825   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1826      s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1827                  r2, m3, (Int)(Short)i4);
1828}
1829
1830static void
1831s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1832                                           UChar i2),
1833                     UChar r1, UChar m3, UShort i4, UChar i2)
1834{
1835   const HChar *mnm = irgen(r1, m3, i4, i2);
1836
1837   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1838      s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1839                  r1, i2, m3, (Int)(Short)i4);
1840}
1841
1842static void
1843s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1844                                           UChar i2),
1845                     UChar r1, UChar m3, UShort i4, UChar i2)
1846{
1847   const HChar *mnm = irgen(r1, m3, i4, i2);
1848
1849   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1850      s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1851                  (Int)(Char)i2, m3, (Int)(Short)i4);
1852}
1853
1854static void
1855s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
1856                UChar r1, UInt i2)
1857{
1858   irgen(r1, i2);
1859}
1860
1861static void
1862s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
1863                   UChar r1, UInt i2)
1864{
1865   const HChar *mnm = irgen(r1, i2);
1866
1867   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1868      s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1869}
1870
1871static void
1872s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
1873                   UChar r1, UInt i2)
1874{
1875   const HChar *mnm = irgen(r1, i2);
1876
1877   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1878      s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1879}
1880
1881static void
1882s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
1883                   UChar r1, UInt i2)
1884{
1885   const HChar *mnm = irgen(r1, i2);
1886
1887   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1888      s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1889}
1890
1891static void
1892s390_format_RIL_UP(const HChar *(*irgen)(void),
1893                   UChar r1, UInt i2)
1894{
1895   const HChar *mnm = irgen();
1896
1897   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1898      s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1899}
1900
1901static void
1902s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1903                      IRTemp op4addr),
1904                      UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1905{
1906   const HChar *mnm;
1907   IRTemp op4addr = newTemp(Ity_I64);
1908
1909   assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1910          mkU64(0)));
1911
1912   mnm = irgen(r1, m3, i2, op4addr);
1913
1914   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1915      s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1916                  (Int)(Char)i2, m3, d4, 0, b4);
1917}
1918
1919static void
1920s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1921                      IRTemp op4addr),
1922                      UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1923{
1924   const HChar *mnm;
1925   IRTemp op4addr = newTemp(Ity_I64);
1926
1927   assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1928          mkU64(0)));
1929
1930   mnm = irgen(r1, m3, i2, op4addr);
1931
1932   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1933      s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1934                  i2, m3, d4, 0, b4);
1935}
1936
1937static void
1938s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
1939               UChar r1, UChar r2)
1940{
1941   irgen(r1, r2);
1942}
1943
1944static void
1945s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
1946                  UChar r1, UChar r2)
1947{
1948   const HChar *mnm = irgen(r1, r2);
1949
1950   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1951      s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1952}
1953
1954static void
1955s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
1956                  UChar r1, UChar r2)
1957{
1958   const HChar *mnm = irgen(r1, r2);
1959
1960   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1961      s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1962}
1963
1964static void
1965s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
1966                UChar r1, UChar r2)
1967{
1968   irgen(r1, r2);
1969}
1970
1971static void
1972s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
1973                   UChar r1, UChar r2)
1974{
1975   const HChar *mnm = irgen(r1, r2);
1976
1977   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1978      s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1979}
1980
1981static void
1982s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
1983                   UChar r1, UChar r2)
1984{
1985   const HChar *mnm = irgen(r1, r2);
1986
1987   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1988      s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1989}
1990
1991static void
1992s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
1993                   UChar r1, UChar r2)
1994{
1995   const HChar *mnm = irgen(r1, r2);
1996
1997   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1998      s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1999}
2000
2001static void
2002s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
2003                   UChar r1, UChar r2)
2004{
2005   const HChar *mnm = irgen(r1, r2);
2006
2007   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2008      s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
2009}
2010
2011static void
2012s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
2013                   UChar r1)
2014{
2015   const HChar *mnm = irgen(r1);
2016
2017   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2018      s390_disasm(ENC2(MNM, GPR), mnm, r1);
2019}
2020
2021static void
2022s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
2023                   UChar r1)
2024{
2025   const HChar *mnm = irgen(r1);
2026
2027   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2028      s390_disasm(ENC2(MNM, FPR), mnm, r1);
2029}
2030
2031static void
2032s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
2033                       UChar m3, UChar r1, UChar r2)
2034{
2035   const HChar *mnm = irgen(m3, r1, r2);
2036
2037   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2038      s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
2039}
2040
2041static void
2042s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
2043                     UChar r1, UChar r3, UChar r2)
2044{
2045   const HChar *mnm = irgen(r1, r3, r2);
2046
2047   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2048      s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2049}
2050
2051static void
2052s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2053                     UChar r3, UChar r1, UChar r2)
2054{
2055   const HChar *mnm = irgen(r3, r1, r2);
2056
2057   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2058      s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2059}
2060
2061static void
2062s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2063                                           UChar r2),
2064                     UChar m3, UChar m4, UChar r1, UChar r2)
2065{
2066   const HChar *mnm = irgen(m3, m4, r1, r2);
2067
2068   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2069      s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2070}
2071
2072static void
2073s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2074                     UChar m4, UChar r1, UChar r2)
2075{
2076   const HChar *mnm = irgen(m4, r1, r2);
2077
2078   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2079      s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2080}
2081
2082static void
2083s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2084                                           UChar r2),
2085                     UChar m3, UChar m4, UChar r1, UChar r2)
2086{
2087   const HChar *mnm = irgen(m3, m4, r1, r2);
2088
2089   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2090      s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2091}
2092
2093static void
2094s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2095                                           UChar r2),
2096                     UChar m3, UChar m4, UChar r1, UChar r2)
2097{
2098   const HChar *mnm = irgen(m3, m4, r1, r2);
2099
2100   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2101      s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2102}
2103
2104
2105static void
2106s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
2107                     UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2108{
2109   irgen(m3, r1, r2);
2110
2111   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2112      s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2113}
2114
2115static void
2116s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
2117                      UChar r3, UChar r1, UChar r2)
2118{
2119   const HChar *mnm = irgen(r3, r1, r2);
2120
2121   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2122      s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2123}
2124
2125static void
2126s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2127                     UChar r3, UChar m4, UChar r1, UChar r2)
2128{
2129   const HChar *mnm = irgen(r3, m4, r1, r2);
2130
2131   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2132      s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2133}
2134
2135static void
2136s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2137                     UChar r3, UChar m4, UChar r1, UChar r2)
2138{
2139   const HChar *mnm = irgen(r3, m4, r1, r2);
2140
2141   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2142      s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2143}
2144
2145static void
2146s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2147                      UChar r3, UChar m4, UChar r1, UChar r2)
2148{
2149   const HChar *mnm = irgen(r3, m4, r1, r2);
2150
2151   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2152      s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2153}
2154
2155static void
2156s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
2157                      UChar r3, UChar r1, UChar r2)
2158{
2159   const HChar *mnm = irgen(r3, r1, r2);
2160
2161   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2162      s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2163}
2164
2165static void
2166s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2167                                      IRTemp op4addr),
2168                UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2169{
2170   const HChar *mnm;
2171   IRTemp op4addr = newTemp(Ity_I64);
2172
2173   assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2174          mkU64(0)));
2175
2176   mnm = irgen(r1, r2, m3, op4addr);
2177
2178   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2179      s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2180                  r2, m3, d4, 0, b4);
2181}
2182
2183static void
2184s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2185                    UChar r1, UChar b2, UShort d2)
2186{
2187   const HChar *mnm;
2188   IRTemp op2addr = newTemp(Ity_I64);
2189
2190   assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2191          mkU64(0)));
2192
2193   mnm = irgen(r1, op2addr);
2194
2195   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2196      s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2197}
2198
2199static void
2200s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2201                    UChar r1, UChar r3, UChar b2, UShort d2)
2202{
2203   const HChar *mnm;
2204   IRTemp op2addr = newTemp(Ity_I64);
2205
2206   assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2207          mkU64(0)));
2208
2209   mnm = irgen(r1, r3, op2addr);
2210
2211   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2212      s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2213}
2214
2215static void
2216s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2217                    UChar r1, UChar r3, UChar b2, UShort d2)
2218{
2219   const HChar *mnm;
2220   IRTemp op2addr = newTemp(Ity_I64);
2221
2222   assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2223          mkU64(0)));
2224
2225   mnm = irgen(r1, r3, op2addr);
2226
2227   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2228      s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2229}
2230
2231static void
2232s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
2233                    UChar r1, UChar r3, UChar b2, UShort d2)
2234{
2235   const HChar *mnm;
2236   IRTemp op2addr = newTemp(Ity_I64);
2237
2238   assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2239          mkU64(0)));
2240
2241   mnm = irgen(r1, r3, op2addr);
2242
2243   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2244      s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2245}
2246
2247static void
2248s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
2249                    UChar r1, UChar r3, UShort i2)
2250{
2251   const HChar *mnm = irgen(r1, r3, i2);
2252
2253   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2254      s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2255}
2256
2257static void
2258s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2259                     UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2260{
2261   const HChar *mnm;
2262   IRTemp op2addr = newTemp(Ity_I64);
2263   IRTemp d2 = newTemp(Ity_I64);
2264
2265   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2266   assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2267          mkU64(0)));
2268
2269   mnm = irgen(r1, r3, op2addr);
2270
2271   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2272      s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2273}
2274
2275static void
2276s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
2277                     UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2278{
2279   const HChar *mnm;
2280   IRTemp op2addr = newTemp(Ity_I64);
2281   IRTemp d2 = newTemp(Ity_I64);
2282
2283   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2284   assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2285          mkU64(0)));
2286
2287   mnm = irgen(r1, r3, op2addr);
2288
2289   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2290      s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2291}
2292
2293static void
2294s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2295                     UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2296{
2297   const HChar *mnm;
2298   IRTemp op2addr = newTemp(Ity_I64);
2299   IRTemp d2 = newTemp(Ity_I64);
2300
2301   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2302   assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2303          mkU64(0)));
2304
2305   mnm = irgen(r1, r3, op2addr);
2306
2307   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2308      s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2309}
2310
2311static void
2312s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2313                     UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2314                     Int xmnm_kind)
2315{
2316   IRTemp op2addr = newTemp(Ity_I64);
2317   IRTemp d2 = newTemp(Ity_I64);
2318
2319   next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2320
2321   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2322   assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2323          mkU64(0)));
2324
2325   irgen(r1, op2addr);
2326
2327   vassert(dis_res->whatNext == Dis_Continue);
2328
2329   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2330      s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2331}
2332
2333static void
2334s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
2335               IRTemp op2addr),
2336               UChar r1, UChar x2, UChar b2, UShort d2)
2337{
2338   IRTemp op2addr = newTemp(Ity_I64);
2339
2340   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2341          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2342          mkU64(0)));
2343
2344   irgen(r1, x2, b2, d2, op2addr);
2345}
2346
2347static void
2348s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2349                    UChar r1, UChar x2, UChar b2, UShort d2)
2350{
2351   const HChar *mnm;
2352   IRTemp op2addr = newTemp(Ity_I64);
2353
2354   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2355          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2356          mkU64(0)));
2357
2358   mnm = irgen(r1, op2addr);
2359
2360   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2361      s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2362}
2363
2364static void
2365s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2366                    UChar r1, UChar x2, UChar b2, UShort d2)
2367{
2368   const HChar *mnm;
2369   IRTemp op2addr = newTemp(Ity_I64);
2370
2371   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2372          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2373          mkU64(0)));
2374
2375   mnm = irgen(r1, op2addr);
2376
2377   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2378      s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2379}
2380
2381static void
2382s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2383                     UChar r1, UChar x2, UChar b2, UShort d2)
2384{
2385   const HChar *mnm;
2386   IRTemp op2addr = newTemp(Ity_I64);
2387
2388   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2389          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2390          mkU64(0)));
2391
2392   mnm = irgen(r1, op2addr);
2393
2394   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2395      s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2396}
2397
2398static void
2399s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
2400                      UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2401{
2402   const HChar *mnm;
2403   IRTemp op2addr = newTemp(Ity_I64);
2404
2405   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2406          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2407          mkU64(0)));
2408
2409   mnm = irgen(r3, op2addr, r1);
2410
2411   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2412      s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2413}
2414
2415static void
2416s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2417                     UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2418{
2419   const HChar *mnm;
2420   IRTemp op2addr = newTemp(Ity_I64);
2421   IRTemp d2 = newTemp(Ity_I64);
2422
2423   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2424   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2425          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2426          mkU64(0)));
2427
2428   mnm = irgen(r1, op2addr);
2429
2430   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2431      s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2432}
2433
2434static void
2435s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
2436                     UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2437{
2438   const HChar *mnm;
2439   IRTemp op2addr = newTemp(Ity_I64);
2440   IRTemp d2 = newTemp(Ity_I64);
2441
2442   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2443   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2444          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2445          mkU64(0)));
2446
2447   mnm = irgen(r1, op2addr);
2448
2449   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2450      s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2451}
2452
2453static void
2454s390_format_RXY_URRD(const HChar *(*irgen)(void),
2455                     UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2456{
2457   const HChar *mnm;
2458   IRTemp op2addr = newTemp(Ity_I64);
2459   IRTemp d2 = newTemp(Ity_I64);
2460
2461   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2462   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2463          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2464          mkU64(0)));
2465
2466   mnm = irgen();
2467
2468   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2469      s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2470}
2471
2472static void
2473s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
2474                 UChar b2, UShort d2)
2475{
2476   const HChar *mnm;
2477   IRTemp op2addr = newTemp(Ity_I64);
2478
2479   assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2480          mkU64(0)));
2481
2482   mnm = irgen(op2addr);
2483
2484   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2485      s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2486}
2487
2488static void
2489s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
2490                   UChar i2, UChar b1, UShort d1)
2491{
2492   const HChar *mnm;
2493   IRTemp op1addr = newTemp(Ity_I64);
2494
2495   assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2496          mkU64(0)));
2497
2498   mnm = irgen(i2, op1addr);
2499
2500   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2501      s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2502}
2503
2504static void
2505s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
2506                    UChar i2, UChar b1, UShort dl1, UChar dh1)
2507{
2508   const HChar *mnm;
2509   IRTemp op1addr = newTemp(Ity_I64);
2510   IRTemp d1 = newTemp(Ity_I64);
2511
2512   assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2513   assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2514          mkU64(0)));
2515
2516   mnm = irgen(i2, op1addr);
2517
2518   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2519      s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2520}
2521
2522static void
2523s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
2524                    UChar i2, UChar b1, UShort dl1, UChar dh1)
2525{
2526   const HChar *mnm;
2527   IRTemp op1addr = newTemp(Ity_I64);
2528   IRTemp d1 = newTemp(Ity_I64);
2529
2530   assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2531   assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2532          mkU64(0)));
2533
2534   mnm = irgen(i2, op1addr);
2535
2536   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2537      s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2538}
2539
2540static void
2541s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
2542                      UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2543{
2544   const HChar *mnm;
2545   IRTemp op1addr = newTemp(Ity_I64);
2546   IRTemp op2addr = newTemp(Ity_I64);
2547
2548   assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2549          mkU64(0)));
2550   assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2551          mkU64(0)));
2552
2553   mnm = irgen(l, op1addr, op2addr);
2554
2555   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2556      s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2557}
2558
2559static void
2560s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
2561                    UChar b1, UShort d1, UShort i2)
2562{
2563   const HChar *mnm;
2564   IRTemp op1addr = newTemp(Ity_I64);
2565
2566   assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2567          mkU64(0)));
2568
2569   mnm = irgen(i2, op1addr);
2570
2571   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2572      s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2573}
2574
2575static void
2576s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
2577                    UChar b1, UShort d1, UShort i2)
2578{
2579   const HChar *mnm;
2580   IRTemp op1addr = newTemp(Ity_I64);
2581
2582   assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2583          mkU64(0)));
2584
2585   mnm = irgen(i2, op1addr);
2586
2587   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2588      s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2589}
2590
2591
2592
2593/*------------------------------------------------------------*/
2594/*--- Build IR for opcodes                                 ---*/
2595/*------------------------------------------------------------*/
2596
2597static const HChar *
2598s390_irgen_AR(UChar r1, UChar r2)
2599{
2600   IRTemp op1 = newTemp(Ity_I32);
2601   IRTemp op2 = newTemp(Ity_I32);
2602   IRTemp result = newTemp(Ity_I32);
2603
2604   assign(op1, get_gpr_w1(r1));
2605   assign(op2, get_gpr_w1(r2));
2606   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2607   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2608   put_gpr_w1(r1, mkexpr(result));
2609
2610   return "ar";
2611}
2612
2613static const HChar *
2614s390_irgen_AGR(UChar r1, UChar r2)
2615{
2616   IRTemp op1 = newTemp(Ity_I64);
2617   IRTemp op2 = newTemp(Ity_I64);
2618   IRTemp result = newTemp(Ity_I64);
2619
2620   assign(op1, get_gpr_dw0(r1));
2621   assign(op2, get_gpr_dw0(r2));
2622   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2623   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2624   put_gpr_dw0(r1, mkexpr(result));
2625
2626   return "agr";
2627}
2628
2629static const HChar *
2630s390_irgen_AGFR(UChar r1, UChar r2)
2631{
2632   IRTemp op1 = newTemp(Ity_I64);
2633   IRTemp op2 = newTemp(Ity_I64);
2634   IRTemp result = newTemp(Ity_I64);
2635
2636   assign(op1, get_gpr_dw0(r1));
2637   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2638   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2639   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2640   put_gpr_dw0(r1, mkexpr(result));
2641
2642   return "agfr";
2643}
2644
2645static const HChar *
2646s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2647{
2648   IRTemp op2 = newTemp(Ity_I32);
2649   IRTemp op3 = newTemp(Ity_I32);
2650   IRTemp result = newTemp(Ity_I32);
2651
2652   assign(op2, get_gpr_w1(r2));
2653   assign(op3, get_gpr_w1(r3));
2654   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2655   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2656   put_gpr_w1(r1, mkexpr(result));
2657
2658   return "ark";
2659}
2660
2661static const HChar *
2662s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2663{
2664   IRTemp op2 = newTemp(Ity_I64);
2665   IRTemp op3 = newTemp(Ity_I64);
2666   IRTemp result = newTemp(Ity_I64);
2667
2668   assign(op2, get_gpr_dw0(r2));
2669   assign(op3, get_gpr_dw0(r3));
2670   assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2671   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2672   put_gpr_dw0(r1, mkexpr(result));
2673
2674   return "agrk";
2675}
2676
2677static const HChar *
2678s390_irgen_A(UChar r1, IRTemp op2addr)
2679{
2680   IRTemp op1 = newTemp(Ity_I32);
2681   IRTemp op2 = newTemp(Ity_I32);
2682   IRTemp result = newTemp(Ity_I32);
2683
2684   assign(op1, get_gpr_w1(r1));
2685   assign(op2, load(Ity_I32, mkexpr(op2addr)));
2686   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2687   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2688   put_gpr_w1(r1, mkexpr(result));
2689
2690   return "a";
2691}
2692
2693static const HChar *
2694s390_irgen_AY(UChar r1, IRTemp op2addr)
2695{
2696   IRTemp op1 = newTemp(Ity_I32);
2697   IRTemp op2 = newTemp(Ity_I32);
2698   IRTemp result = newTemp(Ity_I32);
2699
2700   assign(op1, get_gpr_w1(r1));
2701   assign(op2, load(Ity_I32, mkexpr(op2addr)));
2702   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2703   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2704   put_gpr_w1(r1, mkexpr(result));
2705
2706   return "ay";
2707}
2708
2709static const HChar *
2710s390_irgen_AG(UChar r1, IRTemp op2addr)
2711{
2712   IRTemp op1 = newTemp(Ity_I64);
2713   IRTemp op2 = newTemp(Ity_I64);
2714   IRTemp result = newTemp(Ity_I64);
2715
2716   assign(op1, get_gpr_dw0(r1));
2717   assign(op2, load(Ity_I64, mkexpr(op2addr)));
2718   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2719   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2720   put_gpr_dw0(r1, mkexpr(result));
2721
2722   return "ag";
2723}
2724
2725static const HChar *
2726s390_irgen_AGF(UChar r1, IRTemp op2addr)
2727{
2728   IRTemp op1 = newTemp(Ity_I64);
2729   IRTemp op2 = newTemp(Ity_I64);
2730   IRTemp result = newTemp(Ity_I64);
2731
2732   assign(op1, get_gpr_dw0(r1));
2733   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2734   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2735   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2736   put_gpr_dw0(r1, mkexpr(result));
2737
2738   return "agf";
2739}
2740
2741static const HChar *
2742s390_irgen_AFI(UChar r1, UInt i2)
2743{
2744   IRTemp op1 = newTemp(Ity_I32);
2745   Int op2;
2746   IRTemp result = newTemp(Ity_I32);
2747
2748   assign(op1, get_gpr_w1(r1));
2749   op2 = (Int)i2;
2750   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2751   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2752                       mkU32((UInt)op2)));
2753   put_gpr_w1(r1, mkexpr(result));
2754
2755   return "afi";
2756}
2757
2758static const HChar *
2759s390_irgen_AGFI(UChar r1, UInt i2)
2760{
2761   IRTemp op1 = newTemp(Ity_I64);
2762   Long op2;
2763   IRTemp result = newTemp(Ity_I64);
2764
2765   assign(op1, get_gpr_dw0(r1));
2766   op2 = (Long)(Int)i2;
2767   assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2768   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2769                       mkU64((ULong)op2)));
2770   put_gpr_dw0(r1, mkexpr(result));
2771
2772   return "agfi";
2773}
2774
2775static const HChar *
2776s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2777{
2778   Int op2;
2779   IRTemp op3 = newTemp(Ity_I32);
2780   IRTemp result = newTemp(Ity_I32);
2781
2782   op2 = (Int)(Short)i2;
2783   assign(op3, get_gpr_w1(r3));
2784   assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2785   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2786                       op2)), op3);
2787   put_gpr_w1(r1, mkexpr(result));
2788
2789   return "ahik";
2790}
2791
2792static const HChar *
2793s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2794{
2795   Long op2;
2796   IRTemp op3 = newTemp(Ity_I64);
2797   IRTemp result = newTemp(Ity_I64);
2798
2799   op2 = (Long)(Short)i2;
2800   assign(op3, get_gpr_dw0(r3));
2801   assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2802   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2803                       op2)), op3);
2804   put_gpr_dw0(r1, mkexpr(result));
2805
2806   return "aghik";
2807}
2808
2809static const HChar *
2810s390_irgen_ASI(UChar i2, IRTemp op1addr)
2811{
2812   IRTemp op1 = newTemp(Ity_I32);
2813   Int op2;
2814   IRTemp result = newTemp(Ity_I32);
2815
2816   assign(op1, load(Ity_I32, mkexpr(op1addr)));
2817   op2 = (Int)(Char)i2;
2818   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2819   store(mkexpr(op1addr), mkexpr(result));
2820   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2821                       mkU32((UInt)op2)));
2822
2823   return "asi";
2824}
2825
2826static const HChar *
2827s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2828{
2829   IRTemp op1 = newTemp(Ity_I64);
2830   Long op2;
2831   IRTemp result = newTemp(Ity_I64);
2832
2833   assign(op1, load(Ity_I64, mkexpr(op1addr)));
2834   op2 = (Long)(Char)i2;
2835   assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2836   store(mkexpr(op1addr), mkexpr(result));
2837   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2838                       mkU64((ULong)op2)));
2839
2840   return "agsi";
2841}
2842
2843static const HChar *
2844s390_irgen_AH(UChar r1, IRTemp op2addr)
2845{
2846   IRTemp op1 = newTemp(Ity_I32);
2847   IRTemp op2 = newTemp(Ity_I32);
2848   IRTemp result = newTemp(Ity_I32);
2849
2850   assign(op1, get_gpr_w1(r1));
2851   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2852   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2853   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2854   put_gpr_w1(r1, mkexpr(result));
2855
2856   return "ah";
2857}
2858
2859static const HChar *
2860s390_irgen_AHY(UChar r1, IRTemp op2addr)
2861{
2862   IRTemp op1 = newTemp(Ity_I32);
2863   IRTemp op2 = newTemp(Ity_I32);
2864   IRTemp result = newTemp(Ity_I32);
2865
2866   assign(op1, get_gpr_w1(r1));
2867   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2868   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2869   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2870   put_gpr_w1(r1, mkexpr(result));
2871
2872   return "ahy";
2873}
2874
2875static const HChar *
2876s390_irgen_AHI(UChar r1, UShort i2)
2877{
2878   IRTemp op1 = newTemp(Ity_I32);
2879   Int op2;
2880   IRTemp result = newTemp(Ity_I32);
2881
2882   assign(op1, get_gpr_w1(r1));
2883   op2 = (Int)(Short)i2;
2884   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2885   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2886                       mkU32((UInt)op2)));
2887   put_gpr_w1(r1, mkexpr(result));
2888
2889   return "ahi";
2890}
2891
2892static const HChar *
2893s390_irgen_AGHI(UChar r1, UShort i2)
2894{
2895   IRTemp op1 = newTemp(Ity_I64);
2896   Long op2;
2897   IRTemp result = newTemp(Ity_I64);
2898
2899   assign(op1, get_gpr_dw0(r1));
2900   op2 = (Long)(Short)i2;
2901   assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2902   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2903                       mkU64((ULong)op2)));
2904   put_gpr_dw0(r1, mkexpr(result));
2905
2906   return "aghi";
2907}
2908
2909static const HChar *
2910s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2911{
2912   IRTemp op2 = newTemp(Ity_I32);
2913   IRTemp op3 = newTemp(Ity_I32);
2914   IRTemp result = newTemp(Ity_I32);
2915
2916   assign(op2, get_gpr_w0(r2));
2917   assign(op3, get_gpr_w0(r3));
2918   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2919   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2920   put_gpr_w0(r1, mkexpr(result));
2921
2922   return "ahhhr";
2923}
2924
2925static const HChar *
2926s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2927{
2928   IRTemp op2 = newTemp(Ity_I32);
2929   IRTemp op3 = newTemp(Ity_I32);
2930   IRTemp result = newTemp(Ity_I32);
2931
2932   assign(op2, get_gpr_w0(r2));
2933   assign(op3, get_gpr_w1(r3));
2934   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2935   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2936   put_gpr_w0(r1, mkexpr(result));
2937
2938   return "ahhlr";
2939}
2940
2941static const HChar *
2942s390_irgen_AIH(UChar r1, UInt i2)
2943{
2944   IRTemp op1 = newTemp(Ity_I32);
2945   Int op2;
2946   IRTemp result = newTemp(Ity_I32);
2947
2948   assign(op1, get_gpr_w0(r1));
2949   op2 = (Int)i2;
2950   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2951   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2952                       mkU32((UInt)op2)));
2953   put_gpr_w0(r1, mkexpr(result));
2954
2955   return "aih";
2956}
2957
2958static const HChar *
2959s390_irgen_ALR(UChar r1, UChar r2)
2960{
2961   IRTemp op1 = newTemp(Ity_I32);
2962   IRTemp op2 = newTemp(Ity_I32);
2963   IRTemp result = newTemp(Ity_I32);
2964
2965   assign(op1, get_gpr_w1(r1));
2966   assign(op2, get_gpr_w1(r2));
2967   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2968   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2969   put_gpr_w1(r1, mkexpr(result));
2970
2971   return "alr";
2972}
2973
2974static const HChar *
2975s390_irgen_ALGR(UChar r1, UChar r2)
2976{
2977   IRTemp op1 = newTemp(Ity_I64);
2978   IRTemp op2 = newTemp(Ity_I64);
2979   IRTemp result = newTemp(Ity_I64);
2980
2981   assign(op1, get_gpr_dw0(r1));
2982   assign(op2, get_gpr_dw0(r2));
2983   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2984   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2985   put_gpr_dw0(r1, mkexpr(result));
2986
2987   return "algr";
2988}
2989
2990static const HChar *
2991s390_irgen_ALGFR(UChar r1, UChar r2)
2992{
2993   IRTemp op1 = newTemp(Ity_I64);
2994   IRTemp op2 = newTemp(Ity_I64);
2995   IRTemp result = newTemp(Ity_I64);
2996
2997   assign(op1, get_gpr_dw0(r1));
2998   assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2999   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3000   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3001   put_gpr_dw0(r1, mkexpr(result));
3002
3003   return "algfr";
3004}
3005
3006static const HChar *
3007s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
3008{
3009   IRTemp op2 = newTemp(Ity_I32);
3010   IRTemp op3 = newTemp(Ity_I32);
3011   IRTemp result = newTemp(Ity_I32);
3012
3013   assign(op2, get_gpr_w1(r2));
3014   assign(op3, get_gpr_w1(r3));
3015   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3016   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3017   put_gpr_w1(r1, mkexpr(result));
3018
3019   return "alrk";
3020}
3021
3022static const HChar *
3023s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
3024{
3025   IRTemp op2 = newTemp(Ity_I64);
3026   IRTemp op3 = newTemp(Ity_I64);
3027   IRTemp result = newTemp(Ity_I64);
3028
3029   assign(op2, get_gpr_dw0(r2));
3030   assign(op3, get_gpr_dw0(r3));
3031   assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
3032   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
3033   put_gpr_dw0(r1, mkexpr(result));
3034
3035   return "algrk";
3036}
3037
3038static const HChar *
3039s390_irgen_AL(UChar r1, IRTemp op2addr)
3040{
3041   IRTemp op1 = newTemp(Ity_I32);
3042   IRTemp op2 = newTemp(Ity_I32);
3043   IRTemp result = newTemp(Ity_I32);
3044
3045   assign(op1, get_gpr_w1(r1));
3046   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3047   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3048   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3049   put_gpr_w1(r1, mkexpr(result));
3050
3051   return "al";
3052}
3053
3054static const HChar *
3055s390_irgen_ALY(UChar r1, IRTemp op2addr)
3056{
3057   IRTemp op1 = newTemp(Ity_I32);
3058   IRTemp op2 = newTemp(Ity_I32);
3059   IRTemp result = newTemp(Ity_I32);
3060
3061   assign(op1, get_gpr_w1(r1));
3062   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3063   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3064   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3065   put_gpr_w1(r1, mkexpr(result));
3066
3067   return "aly";
3068}
3069
3070static const HChar *
3071s390_irgen_ALG(UChar r1, IRTemp op2addr)
3072{
3073   IRTemp op1 = newTemp(Ity_I64);
3074   IRTemp op2 = newTemp(Ity_I64);
3075   IRTemp result = newTemp(Ity_I64);
3076
3077   assign(op1, get_gpr_dw0(r1));
3078   assign(op2, load(Ity_I64, mkexpr(op2addr)));
3079   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3080   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3081   put_gpr_dw0(r1, mkexpr(result));
3082
3083   return "alg";
3084}
3085
3086static const HChar *
3087s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3088{
3089   IRTemp op1 = newTemp(Ity_I64);
3090   IRTemp op2 = newTemp(Ity_I64);
3091   IRTemp result = newTemp(Ity_I64);
3092
3093   assign(op1, get_gpr_dw0(r1));
3094   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3095   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3096   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3097   put_gpr_dw0(r1, mkexpr(result));
3098
3099   return "algf";
3100}
3101
3102static const HChar *
3103s390_irgen_ALFI(UChar r1, UInt i2)
3104{
3105   IRTemp op1 = newTemp(Ity_I32);
3106   UInt op2;
3107   IRTemp result = newTemp(Ity_I32);
3108
3109   assign(op1, get_gpr_w1(r1));
3110   op2 = i2;
3111   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3112   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3113                       mkU32(op2)));
3114   put_gpr_w1(r1, mkexpr(result));
3115
3116   return "alfi";
3117}
3118
3119static const HChar *
3120s390_irgen_ALGFI(UChar r1, UInt i2)
3121{
3122   IRTemp op1 = newTemp(Ity_I64);
3123   ULong op2;
3124   IRTemp result = newTemp(Ity_I64);
3125
3126   assign(op1, get_gpr_dw0(r1));
3127   op2 = (ULong)i2;
3128   assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3129   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3130                       mkU64(op2)));
3131   put_gpr_dw0(r1, mkexpr(result));
3132
3133   return "algfi";
3134}
3135
3136static const HChar *
3137s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3138{
3139   IRTemp op2 = newTemp(Ity_I32);
3140   IRTemp op3 = newTemp(Ity_I32);
3141   IRTemp result = newTemp(Ity_I32);
3142
3143   assign(op2, get_gpr_w0(r2));
3144   assign(op3, get_gpr_w0(r3));
3145   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3146   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3147   put_gpr_w0(r1, mkexpr(result));
3148
3149   return "alhhhr";
3150}
3151
3152static const HChar *
3153s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3154{
3155   IRTemp op2 = newTemp(Ity_I32);
3156   IRTemp op3 = newTemp(Ity_I32);
3157   IRTemp result = newTemp(Ity_I32);
3158
3159   assign(op2, get_gpr_w0(r2));
3160   assign(op3, get_gpr_w1(r3));
3161   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3162   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3163   put_gpr_w0(r1, mkexpr(result));
3164
3165   return "alhhlr";
3166}
3167
3168static const HChar *
3169s390_irgen_ALCR(UChar r1, UChar r2)
3170{
3171   IRTemp op1 = newTemp(Ity_I32);
3172   IRTemp op2 = newTemp(Ity_I32);
3173   IRTemp result = newTemp(Ity_I32);
3174   IRTemp carry_in = newTemp(Ity_I32);
3175
3176   assign(op1, get_gpr_w1(r1));
3177   assign(op2, get_gpr_w1(r2));
3178   assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3179   assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3180          mkexpr(carry_in)));
3181   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3182   put_gpr_w1(r1, mkexpr(result));
3183
3184   return "alcr";
3185}
3186
3187static const HChar *
3188s390_irgen_ALCGR(UChar r1, UChar r2)
3189{
3190   IRTemp op1 = newTemp(Ity_I64);
3191   IRTemp op2 = newTemp(Ity_I64);
3192   IRTemp result = newTemp(Ity_I64);
3193   IRTemp carry_in = newTemp(Ity_I64);
3194
3195   assign(op1, get_gpr_dw0(r1));
3196   assign(op2, get_gpr_dw0(r2));
3197   assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3198          mkU8(1))));
3199   assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3200          mkexpr(carry_in)));
3201   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3202   put_gpr_dw0(r1, mkexpr(result));
3203
3204   return "alcgr";
3205}
3206
3207static const HChar *
3208s390_irgen_ALC(UChar r1, IRTemp op2addr)
3209{
3210   IRTemp op1 = newTemp(Ity_I32);
3211   IRTemp op2 = newTemp(Ity_I32);
3212   IRTemp result = newTemp(Ity_I32);
3213   IRTemp carry_in = newTemp(Ity_I32);
3214
3215   assign(op1, get_gpr_w1(r1));
3216   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3217   assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3218   assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3219          mkexpr(carry_in)));
3220   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3221   put_gpr_w1(r1, mkexpr(result));
3222
3223   return "alc";
3224}
3225
3226static const HChar *
3227s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3228{
3229   IRTemp op1 = newTemp(Ity_I64);
3230   IRTemp op2 = newTemp(Ity_I64);
3231   IRTemp result = newTemp(Ity_I64);
3232   IRTemp carry_in = newTemp(Ity_I64);
3233
3234   assign(op1, get_gpr_dw0(r1));
3235   assign(op2, load(Ity_I64, mkexpr(op2addr)));
3236   assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3237          mkU8(1))));
3238   assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3239          mkexpr(carry_in)));
3240   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3241   put_gpr_dw0(r1, mkexpr(result));
3242
3243   return "alcg";
3244}
3245
3246static const HChar *
3247s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3248{
3249   IRTemp op1 = newTemp(Ity_I32);
3250   UInt op2;
3251   IRTemp result = newTemp(Ity_I32);
3252
3253   assign(op1, load(Ity_I32, mkexpr(op1addr)));
3254   op2 = (UInt)(Int)(Char)i2;
3255   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3256   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3257                       mkU32(op2)));
3258   store(mkexpr(op1addr), mkexpr(result));
3259
3260   return "alsi";
3261}
3262
3263static const HChar *
3264s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3265{
3266   IRTemp op1 = newTemp(Ity_I64);
3267   ULong op2;
3268   IRTemp result = newTemp(Ity_I64);
3269
3270   assign(op1, load(Ity_I64, mkexpr(op1addr)));
3271   op2 = (ULong)(Long)(Char)i2;
3272   assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3273   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3274                       mkU64(op2)));
3275   store(mkexpr(op1addr), mkexpr(result));
3276
3277   return "algsi";
3278}
3279
3280static const HChar *
3281s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3282{
3283   UInt op2;
3284   IRTemp op3 = newTemp(Ity_I32);
3285   IRTemp result = newTemp(Ity_I32);
3286
3287   op2 = (UInt)(Int)(Short)i2;
3288   assign(op3, get_gpr_w1(r3));
3289   assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3290   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3291                       op3);
3292   put_gpr_w1(r1, mkexpr(result));
3293
3294   return "alhsik";
3295}
3296
3297static const HChar *
3298s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3299{
3300   ULong op2;
3301   IRTemp op3 = newTemp(Ity_I64);
3302   IRTemp result = newTemp(Ity_I64);
3303
3304   op2 = (ULong)(Long)(Short)i2;
3305   assign(op3, get_gpr_dw0(r3));
3306   assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3307   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3308                       op3);
3309   put_gpr_dw0(r1, mkexpr(result));
3310
3311   return "alghsik";
3312}
3313
3314static const HChar *
3315s390_irgen_ALSIH(UChar r1, UInt i2)
3316{
3317   IRTemp op1 = newTemp(Ity_I32);
3318   UInt op2;
3319   IRTemp result = newTemp(Ity_I32);
3320
3321   assign(op1, get_gpr_w0(r1));
3322   op2 = i2;
3323   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3324   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3325                       mkU32(op2)));
3326   put_gpr_w0(r1, mkexpr(result));
3327
3328   return "alsih";
3329}
3330
3331static const HChar *
3332s390_irgen_ALSIHN(UChar r1, UInt i2)
3333{
3334   IRTemp op1 = newTemp(Ity_I32);
3335   UInt op2;
3336   IRTemp result = newTemp(Ity_I32);
3337
3338   assign(op1, get_gpr_w0(r1));
3339   op2 = i2;
3340   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3341   put_gpr_w0(r1, mkexpr(result));
3342
3343   return "alsihn";
3344}
3345
3346static const HChar *
3347s390_irgen_NR(UChar r1, UChar r2)
3348{
3349   IRTemp op1 = newTemp(Ity_I32);
3350   IRTemp op2 = newTemp(Ity_I32);
3351   IRTemp result = newTemp(Ity_I32);
3352
3353   assign(op1, get_gpr_w1(r1));
3354   assign(op2, get_gpr_w1(r2));
3355   assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3356   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3357   put_gpr_w1(r1, mkexpr(result));
3358
3359   return "nr";
3360}
3361
3362static const HChar *
3363s390_irgen_NGR(UChar r1, UChar r2)
3364{
3365   IRTemp op1 = newTemp(Ity_I64);
3366   IRTemp op2 = newTemp(Ity_I64);
3367   IRTemp result = newTemp(Ity_I64);
3368
3369   assign(op1, get_gpr_dw0(r1));
3370   assign(op2, get_gpr_dw0(r2));
3371   assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3372   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3373   put_gpr_dw0(r1, mkexpr(result));
3374
3375   return "ngr";
3376}
3377
3378static const HChar *
3379s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3380{
3381   IRTemp op2 = newTemp(Ity_I32);
3382   IRTemp op3 = newTemp(Ity_I32);
3383   IRTemp result = newTemp(Ity_I32);
3384
3385   assign(op2, get_gpr_w1(r2));
3386   assign(op3, get_gpr_w1(r3));
3387   assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3388   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3389   put_gpr_w1(r1, mkexpr(result));
3390
3391   return "nrk";
3392}
3393
3394static const HChar *
3395s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3396{
3397   IRTemp op2 = newTemp(Ity_I64);
3398   IRTemp op3 = newTemp(Ity_I64);
3399   IRTemp result = newTemp(Ity_I64);
3400
3401   assign(op2, get_gpr_dw0(r2));
3402   assign(op3, get_gpr_dw0(r3));
3403   assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3404   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3405   put_gpr_dw0(r1, mkexpr(result));
3406
3407   return "ngrk";
3408}
3409
3410static const HChar *
3411s390_irgen_N(UChar r1, IRTemp op2addr)
3412{
3413   IRTemp op1 = newTemp(Ity_I32);
3414   IRTemp op2 = newTemp(Ity_I32);
3415   IRTemp result = newTemp(Ity_I32);
3416
3417   assign(op1, get_gpr_w1(r1));
3418   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3419   assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3420   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3421   put_gpr_w1(r1, mkexpr(result));
3422
3423   return "n";
3424}
3425
3426static const HChar *
3427s390_irgen_NY(UChar r1, IRTemp op2addr)
3428{
3429   IRTemp op1 = newTemp(Ity_I32);
3430   IRTemp op2 = newTemp(Ity_I32);
3431   IRTemp result = newTemp(Ity_I32);
3432
3433   assign(op1, get_gpr_w1(r1));
3434   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3435   assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3436   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3437   put_gpr_w1(r1, mkexpr(result));
3438
3439   return "ny";
3440}
3441
3442static const HChar *
3443s390_irgen_NG(UChar r1, IRTemp op2addr)
3444{
3445   IRTemp op1 = newTemp(Ity_I64);
3446   IRTemp op2 = newTemp(Ity_I64);
3447   IRTemp result = newTemp(Ity_I64);
3448
3449   assign(op1, get_gpr_dw0(r1));
3450   assign(op2, load(Ity_I64, mkexpr(op2addr)));
3451   assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3452   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3453   put_gpr_dw0(r1, mkexpr(result));
3454
3455   return "ng";
3456}
3457
3458static const HChar *
3459s390_irgen_NI(UChar i2, IRTemp op1addr)
3460{
3461   IRTemp op1 = newTemp(Ity_I8);
3462   UChar op2;
3463   IRTemp result = newTemp(Ity_I8);
3464
3465   assign(op1, load(Ity_I8, mkexpr(op1addr)));
3466   op2 = i2;
3467   assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3468   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3469   store(mkexpr(op1addr), mkexpr(result));
3470
3471   return "ni";
3472}
3473
3474static const HChar *
3475s390_irgen_NIY(UChar i2, IRTemp op1addr)
3476{
3477   IRTemp op1 = newTemp(Ity_I8);
3478   UChar op2;
3479   IRTemp result = newTemp(Ity_I8);
3480
3481   assign(op1, load(Ity_I8, mkexpr(op1addr)));
3482   op2 = i2;
3483   assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3484   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3485   store(mkexpr(op1addr), mkexpr(result));
3486
3487   return "niy";
3488}
3489
3490static const HChar *
3491s390_irgen_NIHF(UChar r1, UInt i2)
3492{
3493   IRTemp op1 = newTemp(Ity_I32);
3494   UInt op2;
3495   IRTemp result = newTemp(Ity_I32);
3496
3497   assign(op1, get_gpr_w0(r1));
3498   op2 = i2;
3499   assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3500   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3501   put_gpr_w0(r1, mkexpr(result));
3502
3503   return "nihf";
3504}
3505
3506static const HChar *
3507s390_irgen_NIHH(UChar r1, UShort i2)
3508{
3509   IRTemp op1 = newTemp(Ity_I16);
3510   UShort op2;
3511   IRTemp result = newTemp(Ity_I16);
3512
3513   assign(op1, get_gpr_hw0(r1));
3514   op2 = i2;
3515   assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3516   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3517   put_gpr_hw0(r1, mkexpr(result));
3518
3519   return "nihh";
3520}
3521
3522static const HChar *
3523s390_irgen_NIHL(UChar r1, UShort i2)
3524{
3525   IRTemp op1 = newTemp(Ity_I16);
3526   UShort op2;
3527   IRTemp result = newTemp(Ity_I16);
3528
3529   assign(op1, get_gpr_hw1(r1));
3530   op2 = i2;
3531   assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3532   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3533   put_gpr_hw1(r1, mkexpr(result));
3534
3535   return "nihl";
3536}
3537
3538static const HChar *
3539s390_irgen_NILF(UChar r1, UInt i2)
3540{
3541   IRTemp op1 = newTemp(Ity_I32);
3542   UInt op2;
3543   IRTemp result = newTemp(Ity_I32);
3544
3545   assign(op1, get_gpr_w1(r1));
3546   op2 = i2;
3547   assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3548   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3549   put_gpr_w1(r1, mkexpr(result));
3550
3551   return "nilf";
3552}
3553
3554static const HChar *
3555s390_irgen_NILH(UChar r1, UShort i2)
3556{
3557   IRTemp op1 = newTemp(Ity_I16);
3558   UShort op2;
3559   IRTemp result = newTemp(Ity_I16);
3560
3561   assign(op1, get_gpr_hw2(r1));
3562   op2 = i2;
3563   assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3564   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3565   put_gpr_hw2(r1, mkexpr(result));
3566
3567   return "nilh";
3568}
3569
3570static const HChar *
3571s390_irgen_NILL(UChar r1, UShort i2)
3572{
3573   IRTemp op1 = newTemp(Ity_I16);
3574   UShort op2;
3575   IRTemp result = newTemp(Ity_I16);
3576
3577   assign(op1, get_gpr_hw3(r1));
3578   op2 = i2;
3579   assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3580   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3581   put_gpr_hw3(r1, mkexpr(result));
3582
3583   return "nill";
3584}
3585
3586static const HChar *
3587s390_irgen_BASR(UChar r1, UChar r2)
3588{
3589   IRTemp target = newTemp(Ity_I64);
3590
3591   if (r2 == 0) {
3592      put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3593   } else {
3594      if (r1 != r2) {
3595         put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3596         call_function(get_gpr_dw0(r2));
3597      } else {
3598         assign(target, get_gpr_dw0(r2));
3599         put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3600         call_function(mkexpr(target));
3601      }
3602   }
3603
3604   return "basr";
3605}
3606
3607static const HChar *
3608s390_irgen_BAS(UChar r1, IRTemp op2addr)
3609{
3610   IRTemp target = newTemp(Ity_I64);
3611
3612   put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3613   assign(target, mkexpr(op2addr));
3614   call_function(mkexpr(target));
3615
3616   return "bas";
3617}
3618
3619static const HChar *
3620s390_irgen_BCR(UChar r1, UChar r2)
3621{
3622   IRTemp cond = newTemp(Ity_I32);
3623
3624   if (r2 == 0 && (r1 >= 14)) {    /* serialization */
3625      stmt(IRStmt_MBE(Imbe_Fence));
3626   }
3627
3628   if ((r2 == 0) || (r1 == 0)) {
3629   } else {
3630      if (r1 == 15) {
3631         return_from_function(get_gpr_dw0(r2));
3632      } else {
3633         assign(cond, s390_call_calculate_cond(r1));
3634         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3635                                    get_gpr_dw0(r2));
3636      }
3637   }
3638   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3639      s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3640
3641   return "bcr";
3642}
3643
3644static const HChar *
3645s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3646{
3647   IRTemp cond = newTemp(Ity_I32);
3648
3649   if (r1 == 0) {
3650   } else {
3651      if (r1 == 15) {
3652         always_goto(mkexpr(op2addr));
3653      } else {
3654         assign(cond, s390_call_calculate_cond(r1));
3655         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3656                                    mkexpr(op2addr));
3657      }
3658   }
3659   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3660      s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3661
3662   return "bc";
3663}
3664
3665static const HChar *
3666s390_irgen_BCTR(UChar r1, UChar r2)
3667{
3668   put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3669   if (r2 != 0) {
3670      if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3671                                 get_gpr_dw0(r2));
3672   }
3673
3674   return "bctr";
3675}
3676
3677static const HChar *
3678s390_irgen_BCTGR(UChar r1, UChar r2)
3679{
3680   put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3681   if (r2 != 0) {
3682      if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3683                                 get_gpr_dw0(r2));
3684   }
3685
3686   return "bctgr";
3687}
3688
3689static const HChar *
3690s390_irgen_BCT(UChar r1, IRTemp op2addr)
3691{
3692   put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3693   if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3694                              mkexpr(op2addr));
3695
3696   return "bct";
3697}
3698
3699static const HChar *
3700s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3701{
3702   put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3703   if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3704                              mkexpr(op2addr));
3705
3706   return "bctg";
3707}
3708
3709static const HChar *
3710s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3711{
3712   IRTemp value = newTemp(Ity_I32);
3713
3714   assign(value, get_gpr_w1(r3 | 1));
3715   put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3716   if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3717                                    get_gpr_w1(r1)), mkexpr(op2addr));
3718
3719   return "bxh";
3720}
3721
3722static const HChar *
3723s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3724{
3725   IRTemp value = newTemp(Ity_I64);
3726
3727   assign(value, get_gpr_dw0(r3 | 1));
3728   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3729   if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3730                                    get_gpr_dw0(r1)), mkexpr(op2addr));
3731
3732   return "bxhg";
3733}
3734
3735static const HChar *
3736s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3737{
3738   IRTemp value = newTemp(Ity_I32);
3739
3740   assign(value, get_gpr_w1(r3 | 1));
3741   put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3742   if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3743                                    mkexpr(value)), mkexpr(op2addr));
3744
3745   return "bxle";
3746}
3747
3748static const HChar *
3749s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3750{
3751   IRTemp value = newTemp(Ity_I64);
3752
3753   assign(value, get_gpr_dw0(r3 | 1));
3754   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3755   if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3756                                    mkexpr(value)), mkexpr(op2addr));
3757
3758   return "bxleg";
3759}
3760
3761static const HChar *
3762s390_irgen_BRAS(UChar r1, UShort i2)
3763{
3764   put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3765   call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3766
3767   return "bras";
3768}
3769
3770static const HChar *
3771s390_irgen_BRASL(UChar r1, UInt i2)
3772{
3773   put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
3774   call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3775
3776   return "brasl";
3777}
3778
3779static const HChar *
3780s390_irgen_BRC(UChar r1, UShort i2)
3781{
3782   IRTemp cond = newTemp(Ity_I32);
3783
3784   if (r1 == 0) {
3785   } else {
3786      if (r1 == 15) {
3787         always_goto_and_chase(
3788               guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3789      } else {
3790         assign(cond, s390_call_calculate_cond(r1));
3791         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3792                           guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3793
3794      }
3795   }
3796   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3797      s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3798
3799   return "brc";
3800}
3801
3802static const HChar *
3803s390_irgen_BRCL(UChar r1, UInt i2)
3804{
3805   IRTemp cond = newTemp(Ity_I32);
3806
3807   if (r1 == 0) {
3808   } else {
3809      if (r1 == 15) {
3810         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3811      } else {
3812         assign(cond, s390_call_calculate_cond(r1));
3813         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3814                           guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3815      }
3816   }
3817   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3818      s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3819
3820   return "brcl";
3821}
3822
3823static const HChar *
3824s390_irgen_BRCT(UChar r1, UShort i2)
3825{
3826   put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3827   if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3828                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3829
3830   return "brct";
3831}
3832
3833static const HChar *
3834s390_irgen_BRCTG(UChar r1, UShort i2)
3835{
3836   put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3837   if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3838                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3839
3840   return "brctg";
3841}
3842
3843static const HChar *
3844s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3845{
3846   IRTemp value = newTemp(Ity_I32);
3847
3848   assign(value, get_gpr_w1(r3 | 1));
3849   put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3850   if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3851                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3852
3853   return "brxh";
3854}
3855
3856static const HChar *
3857s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3858{
3859   IRTemp value = newTemp(Ity_I64);
3860
3861   assign(value, get_gpr_dw0(r3 | 1));
3862   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3863   if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3864                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3865
3866   return "brxhg";
3867}
3868
3869static const HChar *
3870s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3871{
3872   IRTemp value = newTemp(Ity_I32);
3873
3874   assign(value, get_gpr_w1(r3 | 1));
3875   put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3876   if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3877                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3878
3879   return "brxle";
3880}
3881
3882static const HChar *
3883s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3884{
3885   IRTemp value = newTemp(Ity_I64);
3886
3887   assign(value, get_gpr_dw0(r3 | 1));
3888   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3889   if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3890                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3891
3892   return "brxlg";
3893}
3894
3895static const HChar *
3896s390_irgen_CR(UChar r1, UChar r2)
3897{
3898   IRTemp op1 = newTemp(Ity_I32);
3899   IRTemp op2 = newTemp(Ity_I32);
3900
3901   assign(op1, get_gpr_w1(r1));
3902   assign(op2, get_gpr_w1(r2));
3903   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3904
3905   return "cr";
3906}
3907
3908static const HChar *
3909s390_irgen_CGR(UChar r1, UChar r2)
3910{
3911   IRTemp op1 = newTemp(Ity_I64);
3912   IRTemp op2 = newTemp(Ity_I64);
3913
3914   assign(op1, get_gpr_dw0(r1));
3915   assign(op2, get_gpr_dw0(r2));
3916   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3917
3918   return "cgr";
3919}
3920
3921static const HChar *
3922s390_irgen_CGFR(UChar r1, UChar r2)
3923{
3924   IRTemp op1 = newTemp(Ity_I64);
3925   IRTemp op2 = newTemp(Ity_I64);
3926
3927   assign(op1, get_gpr_dw0(r1));
3928   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3929   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3930
3931   return "cgfr";
3932}
3933
3934static const HChar *
3935s390_irgen_C(UChar r1, IRTemp op2addr)
3936{
3937   IRTemp op1 = newTemp(Ity_I32);
3938   IRTemp op2 = newTemp(Ity_I32);
3939
3940   assign(op1, get_gpr_w1(r1));
3941   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3942   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3943
3944   return "c";
3945}
3946
3947static const HChar *
3948s390_irgen_CY(UChar r1, IRTemp op2addr)
3949{
3950   IRTemp op1 = newTemp(Ity_I32);
3951   IRTemp op2 = newTemp(Ity_I32);
3952
3953   assign(op1, get_gpr_w1(r1));
3954   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3955   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3956
3957   return "cy";
3958}
3959
3960static const HChar *
3961s390_irgen_CG(UChar r1, IRTemp op2addr)
3962{
3963   IRTemp op1 = newTemp(Ity_I64);
3964   IRTemp op2 = newTemp(Ity_I64);
3965
3966   assign(op1, get_gpr_dw0(r1));
3967   assign(op2, load(Ity_I64, mkexpr(op2addr)));
3968   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3969
3970   return "cg";
3971}
3972
3973static const HChar *
3974s390_irgen_CGF(UChar r1, IRTemp op2addr)
3975{
3976   IRTemp op1 = newTemp(Ity_I64);
3977   IRTemp op2 = newTemp(Ity_I64);
3978
3979   assign(op1, get_gpr_dw0(r1));
3980   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3981   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3982
3983   return "cgf";
3984}
3985
3986static const HChar *
3987s390_irgen_CFI(UChar r1, UInt i2)
3988{
3989   IRTemp op1 = newTemp(Ity_I32);
3990   Int op2;
3991
3992   assign(op1, get_gpr_w1(r1));
3993   op2 = (Int)i2;
3994   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3995                       mkU32((UInt)op2)));
3996
3997   return "cfi";
3998}
3999
4000static const HChar *
4001s390_irgen_CGFI(UChar r1, UInt i2)
4002{
4003   IRTemp op1 = newTemp(Ity_I64);
4004   Long op2;
4005
4006   assign(op1, get_gpr_dw0(r1));
4007   op2 = (Long)(Int)i2;
4008   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4009                       mkU64((ULong)op2)));
4010
4011   return "cgfi";
4012}
4013
4014static const HChar *
4015s390_irgen_CRL(UChar r1, UInt i2)
4016{
4017   IRTemp op1 = newTemp(Ity_I32);
4018   IRTemp op2 = newTemp(Ity_I32);
4019
4020   assign(op1, get_gpr_w1(r1));
4021   assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4022          i2 << 1))));
4023   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4024
4025   return "crl";
4026}
4027
4028static const HChar *
4029s390_irgen_CGRL(UChar r1, UInt i2)
4030{
4031   IRTemp op1 = newTemp(Ity_I64);
4032   IRTemp op2 = newTemp(Ity_I64);
4033
4034   assign(op1, get_gpr_dw0(r1));
4035   assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4036          i2 << 1))));
4037   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4038
4039   return "cgrl";
4040}
4041
4042static const HChar *
4043s390_irgen_CGFRL(UChar r1, UInt i2)
4044{
4045   IRTemp op1 = newTemp(Ity_I64);
4046   IRTemp op2 = newTemp(Ity_I64);
4047
4048   assign(op1, get_gpr_dw0(r1));
4049   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4050          ((ULong)(Long)(Int)i2 << 1)))));
4051   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4052
4053   return "cgfrl";
4054}
4055
4056static const HChar *
4057s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4058{
4059   IRTemp op1 = newTemp(Ity_I32);
4060   IRTemp op2 = newTemp(Ity_I32);
4061   IRTemp cond = newTemp(Ity_I32);
4062
4063   if (m3 == 0) {
4064   } else {
4065      if (m3 == 14) {
4066         always_goto(mkexpr(op4addr));
4067      } else {
4068         assign(op1, get_gpr_w1(r1));
4069         assign(op2, get_gpr_w1(r2));
4070         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4071                                              op1, op2));
4072         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4073                                          mkU32(0)), mkexpr(op4addr));
4074      }
4075   }
4076
4077   return "crb";
4078}
4079
4080static const HChar *
4081s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4082{
4083   IRTemp op1 = newTemp(Ity_I64);
4084   IRTemp op2 = newTemp(Ity_I64);
4085   IRTemp cond = newTemp(Ity_I32);
4086
4087   if (m3 == 0) {
4088   } else {
4089      if (m3 == 14) {
4090         always_goto(mkexpr(op4addr));
4091      } else {
4092         assign(op1, get_gpr_dw0(r1));
4093         assign(op2, get_gpr_dw0(r2));
4094         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4095                                              op1, op2));
4096         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4097                                          mkU32(0)), mkexpr(op4addr));
4098      }
4099   }
4100
4101   return "cgrb";
4102}
4103
4104static const HChar *
4105s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4106{
4107   IRTemp op1 = newTemp(Ity_I32);
4108   IRTemp op2 = newTemp(Ity_I32);
4109   IRTemp cond = newTemp(Ity_I32);
4110
4111   if (m3 == 0) {
4112   } else {
4113      if (m3 == 14) {
4114         always_goto_and_chase(
4115                guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4116      } else {
4117         assign(op1, get_gpr_w1(r1));
4118         assign(op2, get_gpr_w1(r2));
4119         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4120                                              op1, op2));
4121         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4122                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4123
4124      }
4125   }
4126
4127   return "crj";
4128}
4129
4130static const HChar *
4131s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4132{
4133   IRTemp op1 = newTemp(Ity_I64);
4134   IRTemp op2 = newTemp(Ity_I64);
4135   IRTemp cond = newTemp(Ity_I32);
4136
4137   if (m3 == 0) {
4138   } else {
4139      if (m3 == 14) {
4140         always_goto_and_chase(
4141                guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4142      } else {
4143         assign(op1, get_gpr_dw0(r1));
4144         assign(op2, get_gpr_dw0(r2));
4145         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4146                                              op1, op2));
4147         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4148                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4149
4150      }
4151   }
4152
4153   return "cgrj";
4154}
4155
4156static const HChar *
4157s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4158{
4159   IRTemp op1 = newTemp(Ity_I32);
4160   Int op2;
4161   IRTemp cond = newTemp(Ity_I32);
4162
4163   if (m3 == 0) {
4164   } else {
4165      if (m3 == 14) {
4166         always_goto(mkexpr(op4addr));
4167      } else {
4168         assign(op1, get_gpr_w1(r1));
4169         op2 = (Int)(Char)i2;
4170         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4171                                              mktemp(Ity_I32, mkU32((UInt)op2))));
4172         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4173                                    mkexpr(op4addr));
4174      }
4175   }
4176
4177   return "cib";
4178}
4179
4180static const HChar *
4181s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4182{
4183   IRTemp op1 = newTemp(Ity_I64);
4184   Long op2;
4185   IRTemp cond = newTemp(Ity_I32);
4186
4187   if (m3 == 0) {
4188   } else {
4189      if (m3 == 14) {
4190         always_goto(mkexpr(op4addr));
4191      } else {
4192         assign(op1, get_gpr_dw0(r1));
4193         op2 = (Long)(Char)i2;
4194         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4195                                              mktemp(Ity_I64, mkU64((ULong)op2))));
4196         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4197                                    mkexpr(op4addr));
4198      }
4199   }
4200
4201   return "cgib";
4202}
4203
4204static const HChar *
4205s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4206{
4207   IRTemp op1 = newTemp(Ity_I32);
4208   Int op2;
4209   IRTemp cond = newTemp(Ity_I32);
4210
4211   if (m3 == 0) {
4212   } else {
4213      if (m3 == 14) {
4214         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4215      } else {
4216         assign(op1, get_gpr_w1(r1));
4217         op2 = (Int)(Char)i2;
4218         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4219                                              mktemp(Ity_I32, mkU32((UInt)op2))));
4220         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4221                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4222
4223      }
4224   }
4225
4226   return "cij";
4227}
4228
4229static const HChar *
4230s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4231{
4232   IRTemp op1 = newTemp(Ity_I64);
4233   Long op2;
4234   IRTemp cond = newTemp(Ity_I32);
4235
4236   if (m3 == 0) {
4237   } else {
4238      if (m3 == 14) {
4239         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4240      } else {
4241         assign(op1, get_gpr_dw0(r1));
4242         op2 = (Long)(Char)i2;
4243         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4244                                              mktemp(Ity_I64, mkU64((ULong)op2))));
4245         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4246                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4247
4248      }
4249   }
4250
4251   return "cgij";
4252}
4253
4254static const HChar *
4255s390_irgen_CH(UChar r1, IRTemp op2addr)
4256{
4257   IRTemp op1 = newTemp(Ity_I32);
4258   IRTemp op2 = newTemp(Ity_I32);
4259
4260   assign(op1, get_gpr_w1(r1));
4261   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4262   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4263
4264   return "ch";
4265}
4266
4267static const HChar *
4268s390_irgen_CHY(UChar r1, IRTemp op2addr)
4269{
4270   IRTemp op1 = newTemp(Ity_I32);
4271   IRTemp op2 = newTemp(Ity_I32);
4272
4273   assign(op1, get_gpr_w1(r1));
4274   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4275   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4276
4277   return "chy";
4278}
4279
4280static const HChar *
4281s390_irgen_CGH(UChar r1, IRTemp op2addr)
4282{
4283   IRTemp op1 = newTemp(Ity_I64);
4284   IRTemp op2 = newTemp(Ity_I64);
4285
4286   assign(op1, get_gpr_dw0(r1));
4287   assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4288   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4289
4290   return "cgh";
4291}
4292
4293static const HChar *
4294s390_irgen_CHI(UChar r1, UShort i2)
4295{
4296   IRTemp op1 = newTemp(Ity_I32);
4297   Int op2;
4298
4299   assign(op1, get_gpr_w1(r1));
4300   op2 = (Int)(Short)i2;
4301   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4302                       mkU32((UInt)op2)));
4303
4304   return "chi";
4305}
4306
4307static const HChar *
4308s390_irgen_CGHI(UChar r1, UShort i2)
4309{
4310   IRTemp op1 = newTemp(Ity_I64);
4311   Long op2;
4312
4313   assign(op1, get_gpr_dw0(r1));
4314   op2 = (Long)(Short)i2;
4315   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4316                       mkU64((ULong)op2)));
4317
4318   return "cghi";
4319}
4320
4321static const HChar *
4322s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4323{
4324   IRTemp op1 = newTemp(Ity_I16);
4325   Short op2;
4326
4327   assign(op1, load(Ity_I16, mkexpr(op1addr)));
4328   op2 = (Short)i2;
4329   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4330                       mkU16((UShort)op2)));
4331
4332   return "chhsi";
4333}
4334
4335static const HChar *
4336s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4337{
4338   IRTemp op1 = newTemp(Ity_I32);
4339   Int op2;
4340
4341   assign(op1, load(Ity_I32, mkexpr(op1addr)));
4342   op2 = (Int)(Short)i2;
4343   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4344                       mkU32((UInt)op2)));
4345
4346   return "chsi";
4347}
4348
4349static const HChar *
4350s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4351{
4352   IRTemp op1 = newTemp(Ity_I64);
4353   Long op2;
4354
4355   assign(op1, load(Ity_I64, mkexpr(op1addr)));
4356   op2 = (Long)(Short)i2;
4357   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4358                       mkU64((ULong)op2)));
4359
4360   return "cghsi";
4361}
4362
4363static const HChar *
4364s390_irgen_CHRL(UChar r1, UInt i2)
4365{
4366   IRTemp op1 = newTemp(Ity_I32);
4367   IRTemp op2 = newTemp(Ity_I32);
4368
4369   assign(op1, get_gpr_w1(r1));
4370   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4371          ((ULong)(Long)(Int)i2 << 1)))));
4372   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4373
4374   return "chrl";
4375}
4376
4377static const HChar *
4378s390_irgen_CGHRL(UChar r1, UInt i2)
4379{
4380   IRTemp op1 = newTemp(Ity_I64);
4381   IRTemp op2 = newTemp(Ity_I64);
4382
4383   assign(op1, get_gpr_dw0(r1));
4384   assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4385          ((ULong)(Long)(Int)i2 << 1)))));
4386   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4387
4388   return "cghrl";
4389}
4390
4391static const HChar *
4392s390_irgen_CHHR(UChar r1, UChar r2)
4393{
4394   IRTemp op1 = newTemp(Ity_I32);
4395   IRTemp op2 = newTemp(Ity_I32);
4396
4397   assign(op1, get_gpr_w0(r1));
4398   assign(op2, get_gpr_w0(r2));
4399   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4400
4401   return "chhr";
4402}
4403
4404static const HChar *
4405s390_irgen_CHLR(UChar r1, UChar r2)
4406{
4407   IRTemp op1 = newTemp(Ity_I32);
4408   IRTemp op2 = newTemp(Ity_I32);
4409
4410   assign(op1, get_gpr_w0(r1));
4411   assign(op2, get_gpr_w1(r2));
4412   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4413
4414   return "chlr";
4415}
4416
4417static const HChar *
4418s390_irgen_CHF(UChar r1, IRTemp op2addr)
4419{
4420   IRTemp op1 = newTemp(Ity_I32);
4421   IRTemp op2 = newTemp(Ity_I32);
4422
4423   assign(op1, get_gpr_w0(r1));
4424   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4425   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4426
4427   return "chf";
4428}
4429
4430static const HChar *
4431s390_irgen_CIH(UChar r1, UInt i2)
4432{
4433   IRTemp op1 = newTemp(Ity_I32);
4434   Int op2;
4435
4436   assign(op1, get_gpr_w0(r1));
4437   op2 = (Int)i2;
4438   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4439                       mkU32((UInt)op2)));
4440
4441   return "cih";
4442}
4443
4444static const HChar *
4445s390_irgen_CLR(UChar r1, UChar r2)
4446{
4447   IRTemp op1 = newTemp(Ity_I32);
4448   IRTemp op2 = newTemp(Ity_I32);
4449
4450   assign(op1, get_gpr_w1(r1));
4451   assign(op2, get_gpr_w1(r2));
4452   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4453
4454   return "clr";
4455}
4456
4457static const HChar *
4458s390_irgen_CLGR(UChar r1, UChar r2)
4459{
4460   IRTemp op1 = newTemp(Ity_I64);
4461   IRTemp op2 = newTemp(Ity_I64);
4462
4463   assign(op1, get_gpr_dw0(r1));
4464   assign(op2, get_gpr_dw0(r2));
4465   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4466
4467   return "clgr";
4468}
4469
4470static const HChar *
4471s390_irgen_CLGFR(UChar r1, UChar r2)
4472{
4473   IRTemp op1 = newTemp(Ity_I64);
4474   IRTemp op2 = newTemp(Ity_I64);
4475
4476   assign(op1, get_gpr_dw0(r1));
4477   assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4478   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4479
4480   return "clgfr";
4481}
4482
4483static const HChar *
4484s390_irgen_CL(UChar r1, IRTemp op2addr)
4485{
4486   IRTemp op1 = newTemp(Ity_I32);
4487   IRTemp op2 = newTemp(Ity_I32);
4488
4489   assign(op1, get_gpr_w1(r1));
4490   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4491   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4492
4493   return "cl";
4494}
4495
4496static const HChar *
4497s390_irgen_CLY(UChar r1, IRTemp op2addr)
4498{
4499   IRTemp op1 = newTemp(Ity_I32);
4500   IRTemp op2 = newTemp(Ity_I32);
4501
4502   assign(op1, get_gpr_w1(r1));
4503   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4504   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4505
4506   return "cly";
4507}
4508
4509static const HChar *
4510s390_irgen_CLG(UChar r1, IRTemp op2addr)
4511{
4512   IRTemp op1 = newTemp(Ity_I64);
4513   IRTemp op2 = newTemp(Ity_I64);
4514
4515   assign(op1, get_gpr_dw0(r1));
4516   assign(op2, load(Ity_I64, mkexpr(op2addr)));
4517   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4518
4519   return "clg";
4520}
4521
4522static const HChar *
4523s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4524{
4525   IRTemp op1 = newTemp(Ity_I64);
4526   IRTemp op2 = newTemp(Ity_I64);
4527
4528   assign(op1, get_gpr_dw0(r1));
4529   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4530   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4531
4532   return "clgf";
4533}
4534
4535static const HChar *
4536s390_irgen_CLFI(UChar r1, UInt i2)
4537{
4538   IRTemp op1 = newTemp(Ity_I32);
4539   UInt op2;
4540
4541   assign(op1, get_gpr_w1(r1));
4542   op2 = i2;
4543   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4544                       mkU32(op2)));
4545
4546   return "clfi";
4547}
4548
4549static const HChar *
4550s390_irgen_CLGFI(UChar r1, UInt i2)
4551{
4552   IRTemp op1 = newTemp(Ity_I64);
4553   ULong op2;
4554
4555   assign(op1, get_gpr_dw0(r1));
4556   op2 = (ULong)i2;
4557   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4558                       mkU64(op2)));
4559
4560   return "clgfi";
4561}
4562
4563static const HChar *
4564s390_irgen_CLI(UChar i2, IRTemp op1addr)
4565{
4566   IRTemp op1 = newTemp(Ity_I8);
4567   UChar op2;
4568
4569   assign(op1, load(Ity_I8, mkexpr(op1addr)));
4570   op2 = i2;
4571   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4572                       mkU8(op2)));
4573
4574   return "cli";
4575}
4576
4577static const HChar *
4578s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4579{
4580   IRTemp op1 = newTemp(Ity_I8);
4581   UChar op2;
4582
4583   assign(op1, load(Ity_I8, mkexpr(op1addr)));
4584   op2 = i2;
4585   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4586                       mkU8(op2)));
4587
4588   return "cliy";
4589}
4590
4591static const HChar *
4592s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4593{
4594   IRTemp op1 = newTemp(Ity_I32);
4595   UInt op2;
4596
4597   assign(op1, load(Ity_I32, mkexpr(op1addr)));
4598   op2 = (UInt)i2;
4599   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4600                       mkU32(op2)));
4601
4602   return "clfhsi";
4603}
4604
4605static const HChar *
4606s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4607{
4608   IRTemp op1 = newTemp(Ity_I64);
4609   ULong op2;
4610
4611   assign(op1, load(Ity_I64, mkexpr(op1addr)));
4612   op2 = (ULong)i2;
4613   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4614                       mkU64(op2)));
4615
4616   return "clghsi";
4617}
4618
4619static const HChar *
4620s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4621{
4622   IRTemp op1 = newTemp(Ity_I16);
4623   UShort op2;
4624
4625   assign(op1, load(Ity_I16, mkexpr(op1addr)));
4626   op2 = i2;
4627   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4628                       mkU16(op2)));
4629
4630   return "clhhsi";
4631}
4632
4633static const HChar *
4634s390_irgen_CLRL(UChar r1, UInt i2)
4635{
4636   IRTemp op1 = newTemp(Ity_I32);
4637   IRTemp op2 = newTemp(Ity_I32);
4638
4639   assign(op1, get_gpr_w1(r1));
4640   assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4641          i2 << 1))));
4642   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4643
4644   return "clrl";
4645}
4646
4647static const HChar *
4648s390_irgen_CLGRL(UChar r1, UInt i2)
4649{
4650   IRTemp op1 = newTemp(Ity_I64);
4651   IRTemp op2 = newTemp(Ity_I64);
4652
4653   assign(op1, get_gpr_dw0(r1));
4654   assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4655          i2 << 1))));
4656   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4657
4658   return "clgrl";
4659}
4660
4661static const HChar *
4662s390_irgen_CLGFRL(UChar r1, UInt i2)
4663{
4664   IRTemp op1 = newTemp(Ity_I64);
4665   IRTemp op2 = newTemp(Ity_I64);
4666
4667   assign(op1, get_gpr_dw0(r1));
4668   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4669          ((ULong)(Long)(Int)i2 << 1)))));
4670   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4671
4672   return "clgfrl";
4673}
4674
4675static const HChar *
4676s390_irgen_CLHRL(UChar r1, UInt i2)
4677{
4678   IRTemp op1 = newTemp(Ity_I32);
4679   IRTemp op2 = newTemp(Ity_I32);
4680
4681   assign(op1, get_gpr_w1(r1));
4682   assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4683          ((ULong)(Long)(Int)i2 << 1)))));
4684   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4685
4686   return "clhrl";
4687}
4688
4689static const HChar *
4690s390_irgen_CLGHRL(UChar r1, UInt i2)
4691{
4692   IRTemp op1 = newTemp(Ity_I64);
4693   IRTemp op2 = newTemp(Ity_I64);
4694
4695   assign(op1, get_gpr_dw0(r1));
4696   assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4697          ((ULong)(Long)(Int)i2 << 1)))));
4698   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4699
4700   return "clghrl";
4701}
4702
4703static const HChar *
4704s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4705{
4706   IRTemp op1 = newTemp(Ity_I32);
4707   IRTemp op2 = newTemp(Ity_I32);
4708   IRTemp cond = newTemp(Ity_I32);
4709
4710   if (m3 == 0) {
4711   } else {
4712      if (m3 == 14) {
4713         always_goto(mkexpr(op4addr));
4714      } else {
4715         assign(op1, get_gpr_w1(r1));
4716         assign(op2, get_gpr_w1(r2));
4717         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4718                                              op1, op2));
4719         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4720                                    mkexpr(op4addr));
4721      }
4722   }
4723
4724   return "clrb";
4725}
4726
4727static const HChar *
4728s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4729{
4730   IRTemp op1 = newTemp(Ity_I64);
4731   IRTemp op2 = newTemp(Ity_I64);
4732   IRTemp cond = newTemp(Ity_I32);
4733
4734   if (m3 == 0) {
4735   } else {
4736      if (m3 == 14) {
4737         always_goto(mkexpr(op4addr));
4738      } else {
4739         assign(op1, get_gpr_dw0(r1));
4740         assign(op2, get_gpr_dw0(r2));
4741         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4742                                              op1, op2));
4743         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4744                                    mkexpr(op4addr));
4745      }
4746   }
4747
4748   return "clgrb";
4749}
4750
4751static const HChar *
4752s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4753{
4754   IRTemp op1 = newTemp(Ity_I32);
4755   IRTemp op2 = newTemp(Ity_I32);
4756   IRTemp cond = newTemp(Ity_I32);
4757
4758   if (m3 == 0) {
4759   } else {
4760      if (m3 == 14) {
4761         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4762      } else {
4763         assign(op1, get_gpr_w1(r1));
4764         assign(op2, get_gpr_w1(r2));
4765         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4766                                              op1, op2));
4767         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4768                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4769
4770      }
4771   }
4772
4773   return "clrj";
4774}
4775
4776static const HChar *
4777s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4778{
4779   IRTemp op1 = newTemp(Ity_I64);
4780   IRTemp op2 = newTemp(Ity_I64);
4781   IRTemp cond = newTemp(Ity_I32);
4782
4783   if (m3 == 0) {
4784   } else {
4785      if (m3 == 14) {
4786         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4787      } else {
4788         assign(op1, get_gpr_dw0(r1));
4789         assign(op2, get_gpr_dw0(r2));
4790         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4791                                              op1, op2));
4792         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4793                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4794
4795      }
4796   }
4797
4798   return "clgrj";
4799}
4800
4801static const HChar *
4802s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4803{
4804   IRTemp op1 = newTemp(Ity_I32);
4805   UInt op2;
4806   IRTemp cond = newTemp(Ity_I32);
4807
4808   if (m3 == 0) {
4809   } else {
4810      if (m3 == 14) {
4811         always_goto(mkexpr(op4addr));
4812      } else {
4813         assign(op1, get_gpr_w1(r1));
4814         op2 = (UInt)i2;
4815         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4816                                              mktemp(Ity_I32, mkU32(op2))));
4817         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4818                                    mkexpr(op4addr));
4819      }
4820   }
4821
4822   return "clib";
4823}
4824
4825static const HChar *
4826s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4827{
4828   IRTemp op1 = newTemp(Ity_I64);
4829   ULong op2;
4830   IRTemp cond = newTemp(Ity_I32);
4831
4832   if (m3 == 0) {
4833   } else {
4834      if (m3 == 14) {
4835         always_goto(mkexpr(op4addr));
4836      } else {
4837         assign(op1, get_gpr_dw0(r1));
4838         op2 = (ULong)i2;
4839         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4840                                              mktemp(Ity_I64, mkU64(op2))));
4841         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4842                                    mkexpr(op4addr));
4843      }
4844   }
4845
4846   return "clgib";
4847}
4848
4849static const HChar *
4850s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4851{
4852   IRTemp op1 = newTemp(Ity_I32);
4853   UInt op2;
4854   IRTemp cond = newTemp(Ity_I32);
4855
4856   if (m3 == 0) {
4857   } else {
4858      if (m3 == 14) {
4859         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4860      } else {
4861         assign(op1, get_gpr_w1(r1));
4862         op2 = (UInt)i2;
4863         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4864                                              mktemp(Ity_I32, mkU32(op2))));
4865         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4866                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4867
4868      }
4869   }
4870
4871   return "clij";
4872}
4873
4874static const HChar *
4875s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4876{
4877   IRTemp op1 = newTemp(Ity_I64);
4878   ULong op2;
4879   IRTemp cond = newTemp(Ity_I32);
4880
4881   if (m3 == 0) {
4882   } else {
4883      if (m3 == 14) {
4884         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4885      } else {
4886         assign(op1, get_gpr_dw0(r1));
4887         op2 = (ULong)i2;
4888         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4889                                              mktemp(Ity_I64, mkU64(op2))));
4890         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4891                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4892
4893      }
4894   }
4895
4896   return "clgij";
4897}
4898
4899static const HChar *
4900s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4901{
4902   IRTemp op1 = newTemp(Ity_I32);
4903   IRTemp op2 = newTemp(Ity_I32);
4904   IRTemp b0 = newTemp(Ity_I32);
4905   IRTemp b1 = newTemp(Ity_I32);
4906   IRTemp b2 = newTemp(Ity_I32);
4907   IRTemp b3 = newTemp(Ity_I32);
4908   IRTemp c0 = newTemp(Ity_I32);
4909   IRTemp c1 = newTemp(Ity_I32);
4910   IRTemp c2 = newTemp(Ity_I32);
4911   IRTemp c3 = newTemp(Ity_I32);
4912   UChar n;
4913
4914   n = 0;
4915   if ((r3 & 8) != 0) {
4916      assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4917      assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4918      n = n + 1;
4919   } else {
4920      assign(b0, mkU32(0));
4921      assign(c0, mkU32(0));
4922   }
4923   if ((r3 & 4) != 0) {
4924      assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4925      assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4926             mkU64(n)))));
4927      n = n + 1;
4928   } else {
4929      assign(b1, mkU32(0));
4930      assign(c1, mkU32(0));
4931   }
4932   if ((r3 & 2) != 0) {
4933      assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4934      assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4935             mkU64(n)))));
4936      n = n + 1;
4937   } else {
4938      assign(b2, mkU32(0));
4939      assign(c2, mkU32(0));
4940   }
4941   if ((r3 & 1) != 0) {
4942      assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4943      assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4944             mkU64(n)))));
4945      n = n + 1;
4946   } else {
4947      assign(b3, mkU32(0));
4948      assign(c3, mkU32(0));
4949   }
4950   assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4951          mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4952          binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4953   assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4954          mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4955          binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4956   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4957
4958   return "clm";
4959}
4960
4961static const HChar *
4962s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4963{
4964   IRTemp op1 = newTemp(Ity_I32);
4965   IRTemp op2 = newTemp(Ity_I32);
4966   IRTemp b0 = newTemp(Ity_I32);
4967   IRTemp b1 = newTemp(Ity_I32);
4968   IRTemp b2 = newTemp(Ity_I32);
4969   IRTemp b3 = newTemp(Ity_I32);
4970   IRTemp c0 = newTemp(Ity_I32);
4971   IRTemp c1 = newTemp(Ity_I32);
4972   IRTemp c2 = newTemp(Ity_I32);
4973   IRTemp c3 = newTemp(Ity_I32);
4974   UChar n;
4975
4976   n = 0;
4977   if ((r3 & 8) != 0) {
4978      assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4979      assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4980      n = n + 1;
4981   } else {
4982      assign(b0, mkU32(0));
4983      assign(c0, mkU32(0));
4984   }
4985   if ((r3 & 4) != 0) {
4986      assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4987      assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4988             mkU64(n)))));
4989      n = n + 1;
4990   } else {
4991      assign(b1, mkU32(0));
4992      assign(c1, mkU32(0));
4993   }
4994   if ((r3 & 2) != 0) {
4995      assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4996      assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4997             mkU64(n)))));
4998      n = n + 1;
4999   } else {
5000      assign(b2, mkU32(0));
5001      assign(c2, mkU32(0));
5002   }
5003   if ((r3 & 1) != 0) {
5004      assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
5005      assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5006             mkU64(n)))));
5007      n = n + 1;
5008   } else {
5009      assign(b3, mkU32(0));
5010      assign(c3, mkU32(0));
5011   }
5012   assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5013          mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5014          binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5015   assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5016          mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5017          binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5018   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5019
5020   return "clmy";
5021}
5022
5023static const HChar *
5024s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5025{
5026   IRTemp op1 = newTemp(Ity_I32);
5027   IRTemp op2 = newTemp(Ity_I32);
5028   IRTemp b0 = newTemp(Ity_I32);
5029   IRTemp b1 = newTemp(Ity_I32);
5030   IRTemp b2 = newTemp(Ity_I32);
5031   IRTemp b3 = newTemp(Ity_I32);
5032   IRTemp c0 = newTemp(Ity_I32);
5033   IRTemp c1 = newTemp(Ity_I32);
5034   IRTemp c2 = newTemp(Ity_I32);
5035   IRTemp c3 = newTemp(Ity_I32);
5036   UChar n;
5037
5038   n = 0;
5039   if ((r3 & 8) != 0) {
5040      assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5041      assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5042      n = n + 1;
5043   } else {
5044      assign(b0, mkU32(0));
5045      assign(c0, mkU32(0));
5046   }
5047   if ((r3 & 4) != 0) {
5048      assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5049      assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5050             mkU64(n)))));
5051      n = n + 1;
5052   } else {
5053      assign(b1, mkU32(0));
5054      assign(c1, mkU32(0));
5055   }
5056   if ((r3 & 2) != 0) {
5057      assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5058      assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5059             mkU64(n)))));
5060      n = n + 1;
5061   } else {
5062      assign(b2, mkU32(0));
5063      assign(c2, mkU32(0));
5064   }
5065   if ((r3 & 1) != 0) {
5066      assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5067      assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5068             mkU64(n)))));
5069      n = n + 1;
5070   } else {
5071      assign(b3, mkU32(0));
5072      assign(c3, mkU32(0));
5073   }
5074   assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5075          mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5076          binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5077   assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5078          mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5079          binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5080   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5081
5082   return "clmh";
5083}
5084
5085static const HChar *
5086s390_irgen_CLHHR(UChar r1, UChar r2)
5087{
5088   IRTemp op1 = newTemp(Ity_I32);
5089   IRTemp op2 = newTemp(Ity_I32);
5090
5091   assign(op1, get_gpr_w0(r1));
5092   assign(op2, get_gpr_w0(r2));
5093   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5094
5095   return "clhhr";
5096}
5097
5098static const HChar *
5099s390_irgen_CLHLR(UChar r1, UChar r2)
5100{
5101   IRTemp op1 = newTemp(Ity_I32);
5102   IRTemp op2 = newTemp(Ity_I32);
5103
5104   assign(op1, get_gpr_w0(r1));
5105   assign(op2, get_gpr_w1(r2));
5106   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5107
5108   return "clhlr";
5109}
5110
5111static const HChar *
5112s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5113{
5114   IRTemp op1 = newTemp(Ity_I32);
5115   IRTemp op2 = newTemp(Ity_I32);
5116
5117   assign(op1, get_gpr_w0(r1));
5118   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5119   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5120
5121   return "clhf";
5122}
5123
5124static const HChar *
5125s390_irgen_CLIH(UChar r1, UInt i2)
5126{
5127   IRTemp op1 = newTemp(Ity_I32);
5128   UInt op2;
5129
5130   assign(op1, get_gpr_w0(r1));
5131   op2 = i2;
5132   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5133                       mkU32(op2)));
5134
5135   return "clih";
5136}
5137
5138static const HChar *
5139s390_irgen_CPYA(UChar r1, UChar r2)
5140{
5141   put_ar_w0(r1, get_ar_w0(r2));
5142   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5143      s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5144
5145   return "cpya";
5146}
5147
5148static const HChar *
5149s390_irgen_XR(UChar r1, UChar r2)
5150{
5151   IRTemp op1 = newTemp(Ity_I32);
5152   IRTemp op2 = newTemp(Ity_I32);
5153   IRTemp result = newTemp(Ity_I32);
5154
5155   if (r1 == r2) {
5156      assign(result, mkU32(0));
5157   } else {
5158      assign(op1, get_gpr_w1(r1));
5159      assign(op2, get_gpr_w1(r2));
5160      assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5161   }
5162   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5163   put_gpr_w1(r1, mkexpr(result));
5164
5165   return "xr";
5166}
5167
5168static const HChar *
5169s390_irgen_XGR(UChar r1, UChar r2)
5170{
5171   IRTemp op1 = newTemp(Ity_I64);
5172   IRTemp op2 = newTemp(Ity_I64);
5173   IRTemp result = newTemp(Ity_I64);
5174
5175   if (r1 == r2) {
5176      assign(result, mkU64(0));
5177   } else {
5178      assign(op1, get_gpr_dw0(r1));
5179      assign(op2, get_gpr_dw0(r2));
5180      assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5181   }
5182   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5183   put_gpr_dw0(r1, mkexpr(result));
5184
5185   return "xgr";
5186}
5187
5188static const HChar *
5189s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5190{
5191   IRTemp op2 = newTemp(Ity_I32);
5192   IRTemp op3 = newTemp(Ity_I32);
5193   IRTemp result = newTemp(Ity_I32);
5194
5195   assign(op2, get_gpr_w1(r2));
5196   assign(op3, get_gpr_w1(r3));
5197   assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5198   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5199   put_gpr_w1(r1, mkexpr(result));
5200
5201   return "xrk";
5202}
5203
5204static const HChar *
5205s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5206{
5207   IRTemp op2 = newTemp(Ity_I64);
5208   IRTemp op3 = newTemp(Ity_I64);
5209   IRTemp result = newTemp(Ity_I64);
5210
5211   assign(op2, get_gpr_dw0(r2));
5212   assign(op3, get_gpr_dw0(r3));
5213   assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5214   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5215   put_gpr_dw0(r1, mkexpr(result));
5216
5217   return "xgrk";
5218}
5219
5220static const HChar *
5221s390_irgen_X(UChar r1, IRTemp op2addr)
5222{
5223   IRTemp op1 = newTemp(Ity_I32);
5224   IRTemp op2 = newTemp(Ity_I32);
5225   IRTemp result = newTemp(Ity_I32);
5226
5227   assign(op1, get_gpr_w1(r1));
5228   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5229   assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5230   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5231   put_gpr_w1(r1, mkexpr(result));
5232
5233   return "x";
5234}
5235
5236static const HChar *
5237s390_irgen_XY(UChar r1, IRTemp op2addr)
5238{
5239   IRTemp op1 = newTemp(Ity_I32);
5240   IRTemp op2 = newTemp(Ity_I32);
5241   IRTemp result = newTemp(Ity_I32);
5242
5243   assign(op1, get_gpr_w1(r1));
5244   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5245   assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5246   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5247   put_gpr_w1(r1, mkexpr(result));
5248
5249   return "xy";
5250}
5251
5252static const HChar *
5253s390_irgen_XG(UChar r1, IRTemp op2addr)
5254{
5255   IRTemp op1 = newTemp(Ity_I64);
5256   IRTemp op2 = newTemp(Ity_I64);
5257   IRTemp result = newTemp(Ity_I64);
5258
5259   assign(op1, get_gpr_dw0(r1));
5260   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5261   assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5262   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5263   put_gpr_dw0(r1, mkexpr(result));
5264
5265   return "xg";
5266}
5267
5268static const HChar *
5269s390_irgen_XI(UChar i2, IRTemp op1addr)
5270{
5271   IRTemp op1 = newTemp(Ity_I8);
5272   UChar op2;
5273   IRTemp result = newTemp(Ity_I8);
5274
5275   assign(op1, load(Ity_I8, mkexpr(op1addr)));
5276   op2 = i2;
5277   assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5278   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5279   store(mkexpr(op1addr), mkexpr(result));
5280
5281   return "xi";
5282}
5283
5284static const HChar *
5285s390_irgen_XIY(UChar i2, IRTemp op1addr)
5286{
5287   IRTemp op1 = newTemp(Ity_I8);
5288   UChar op2;
5289   IRTemp result = newTemp(Ity_I8);
5290
5291   assign(op1, load(Ity_I8, mkexpr(op1addr)));
5292   op2 = i2;
5293   assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5294   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5295   store(mkexpr(op1addr), mkexpr(result));
5296
5297   return "xiy";
5298}
5299
5300static const HChar *
5301s390_irgen_XIHF(UChar r1, UInt i2)
5302{
5303   IRTemp op1 = newTemp(Ity_I32);
5304   UInt op2;
5305   IRTemp result = newTemp(Ity_I32);
5306
5307   assign(op1, get_gpr_w0(r1));
5308   op2 = i2;
5309   assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5310   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5311   put_gpr_w0(r1, mkexpr(result));
5312
5313   return "xihf";
5314}
5315
5316static const HChar *
5317s390_irgen_XILF(UChar r1, UInt i2)
5318{
5319   IRTemp op1 = newTemp(Ity_I32);
5320   UInt op2;
5321   IRTemp result = newTemp(Ity_I32);
5322
5323   assign(op1, get_gpr_w1(r1));
5324   op2 = i2;
5325   assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5326   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5327   put_gpr_w1(r1, mkexpr(result));
5328
5329   return "xilf";
5330}
5331
5332static const HChar *
5333s390_irgen_EAR(UChar r1, UChar r2)
5334{
5335   put_gpr_w1(r1, get_ar_w0(r2));
5336   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5337      s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5338
5339   return "ear";
5340}
5341
5342static const HChar *
5343s390_irgen_IC(UChar r1, IRTemp op2addr)
5344{
5345   put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5346
5347   return "ic";
5348}
5349
5350static const HChar *
5351s390_irgen_ICY(UChar r1, IRTemp op2addr)
5352{
5353   put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5354
5355   return "icy";
5356}
5357
5358static const HChar *
5359s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5360{
5361   UChar n;
5362   IRTemp result = newTemp(Ity_I32);
5363   UInt mask;
5364
5365   n = 0;
5366   mask = (UInt)r3;
5367   if ((mask & 8) != 0) {
5368      put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5369      n = n + 1;
5370   }
5371   if ((mask & 4) != 0) {
5372      put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5373
5374      n = n + 1;
5375   }
5376   if ((mask & 2) != 0) {
5377      put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5378
5379      n = n + 1;
5380   }
5381   if ((mask & 1) != 0) {
5382      put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5383
5384      n = n + 1;
5385   }
5386   assign(result, get_gpr_w1(r1));
5387   s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5388                       mkU32(mask)));
5389
5390   return "icm";
5391}
5392
5393static const HChar *
5394s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5395{
5396   UChar n;
5397   IRTemp result = newTemp(Ity_I32);
5398   UInt mask;
5399
5400   n = 0;
5401   mask = (UInt)r3;
5402   if ((mask & 8) != 0) {
5403      put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5404      n = n + 1;
5405   }
5406   if ((mask & 4) != 0) {
5407      put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5408
5409      n = n + 1;
5410   }
5411   if ((mask & 2) != 0) {
5412      put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5413
5414      n = n + 1;
5415   }
5416   if ((mask & 1) != 0) {
5417      put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5418
5419      n = n + 1;
5420   }
5421   assign(result, get_gpr_w1(r1));
5422   s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5423                       mkU32(mask)));
5424
5425   return "icmy";
5426}
5427
5428static const HChar *
5429s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5430{
5431   UChar n;
5432   IRTemp result = newTemp(Ity_I32);
5433   UInt mask;
5434
5435   n = 0;
5436   mask = (UInt)r3;
5437   if ((mask & 8) != 0) {
5438      put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5439      n = n + 1;
5440   }
5441   if ((mask & 4) != 0) {
5442      put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5443
5444      n = n + 1;
5445   }
5446   if ((mask & 2) != 0) {
5447      put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5448
5449      n = n + 1;
5450   }
5451   if ((mask & 1) != 0) {
5452      put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5453
5454      n = n + 1;
5455   }
5456   assign(result, get_gpr_w0(r1));
5457   s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5458                       mkU32(mask)));
5459
5460   return "icmh";
5461}
5462
5463static const HChar *
5464s390_irgen_IIHF(UChar r1, UInt i2)
5465{
5466   put_gpr_w0(r1, mkU32(i2));
5467
5468   return "iihf";
5469}
5470
5471static const HChar *
5472s390_irgen_IIHH(UChar r1, UShort i2)
5473{
5474   put_gpr_hw0(r1, mkU16(i2));
5475
5476   return "iihh";
5477}
5478
5479static const HChar *
5480s390_irgen_IIHL(UChar r1, UShort i2)
5481{
5482   put_gpr_hw1(r1, mkU16(i2));
5483
5484   return "iihl";
5485}
5486
5487static const HChar *
5488s390_irgen_IILF(UChar r1, UInt i2)
5489{
5490   put_gpr_w1(r1, mkU32(i2));
5491
5492   return "iilf";
5493}
5494
5495static const HChar *
5496s390_irgen_IILH(UChar r1, UShort i2)
5497{
5498   put_gpr_hw2(r1, mkU16(i2));
5499
5500   return "iilh";
5501}
5502
5503static const HChar *
5504s390_irgen_IILL(UChar r1, UShort i2)
5505{
5506   put_gpr_hw3(r1, mkU16(i2));
5507
5508   return "iill";
5509}
5510
5511static const HChar *
5512s390_irgen_LR(UChar r1, UChar r2)
5513{
5514   put_gpr_w1(r1, get_gpr_w1(r2));
5515
5516   return "lr";
5517}
5518
5519static const HChar *
5520s390_irgen_LGR(UChar r1, UChar r2)
5521{
5522   put_gpr_dw0(r1, get_gpr_dw0(r2));
5523
5524   return "lgr";
5525}
5526
5527static const HChar *
5528s390_irgen_LGFR(UChar r1, UChar r2)
5529{
5530   put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5531
5532   return "lgfr";
5533}
5534
5535static const HChar *
5536s390_irgen_L(UChar r1, IRTemp op2addr)
5537{
5538   put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5539
5540   return "l";
5541}
5542
5543static const HChar *
5544s390_irgen_LY(UChar r1, IRTemp op2addr)
5545{
5546   put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5547
5548   return "ly";
5549}
5550
5551static const HChar *
5552s390_irgen_LG(UChar r1, IRTemp op2addr)
5553{
5554   put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5555
5556   return "lg";
5557}
5558
5559static const HChar *
5560s390_irgen_LGF(UChar r1, IRTemp op2addr)
5561{
5562   put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5563
5564   return "lgf";
5565}
5566
5567static const HChar *
5568s390_irgen_LGFI(UChar r1, UInt i2)
5569{
5570   put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5571
5572   return "lgfi";
5573}
5574
5575static const HChar *
5576s390_irgen_LRL(UChar r1, UInt i2)
5577{
5578   put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5579              i2 << 1))));
5580
5581   return "lrl";
5582}
5583
5584static const HChar *
5585s390_irgen_LGRL(UChar r1, UInt i2)
5586{
5587   put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5588               i2 << 1))));
5589
5590   return "lgrl";
5591}
5592
5593static const HChar *
5594s390_irgen_LGFRL(UChar r1, UInt i2)
5595{
5596   put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5597               ((ULong)(Long)(Int)i2 << 1)))));
5598
5599   return "lgfrl";
5600}
5601
5602static const HChar *
5603s390_irgen_LA(UChar r1, IRTemp op2addr)
5604{
5605   put_gpr_dw0(r1, mkexpr(op2addr));
5606
5607   return "la";
5608}
5609
5610static const HChar *
5611s390_irgen_LAY(UChar r1, IRTemp op2addr)
5612{
5613   put_gpr_dw0(r1, mkexpr(op2addr));
5614
5615   return "lay";
5616}
5617
5618static const HChar *
5619s390_irgen_LAE(UChar r1, IRTemp op2addr)
5620{
5621   put_gpr_dw0(r1, mkexpr(op2addr));
5622
5623   return "lae";
5624}
5625
5626static const HChar *
5627s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5628{
5629   put_gpr_dw0(r1, mkexpr(op2addr));
5630
5631   return "laey";
5632}
5633
5634static const HChar *
5635s390_irgen_LARL(UChar r1, UInt i2)
5636{
5637   put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5638
5639   return "larl";
5640}
5641
5642/* The IR representation of LAA and friends is an approximation of what
5643   happens natively. Essentially a loop containing a compare-and-swap is
5644   constructed which will iterate until the CAS succeeds. As a consequence,
5645   instrumenters may see more memory accesses than happen natively. See also
5646   discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
5647static void
5648s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5649{
5650   IRCAS *cas;
5651   IRTemp old_mem = newTemp(Ity_I32);
5652   IRTemp op2 = newTemp(Ity_I32);
5653   IRTemp op3 = newTemp(Ity_I32);
5654   IRTemp result = newTemp(Ity_I32);
5655
5656   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5657   assign(op3, get_gpr_w1(r3));
5658   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5659
5660   /* Place the addition of second operand and third operand at the
5661      second-operand location everytime */
5662   cas = mkIRCAS(IRTemp_INVALID, old_mem,
5663                 Iend_BE, mkexpr(op2addr),
5664                 NULL, mkexpr(op2), /* expected value */
5665                 NULL, mkexpr(result)  /* new value */);
5666   stmt(IRStmt_CAS(cas));
5667
5668   /* Set CC according to 32-bit addition */
5669   if (is_signed) {
5670      s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5671   } else {
5672      s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5673   }
5674
5675   /* If old_mem contains the expected value, then the CAS succeeded.
5676      Otherwise, it did not */
5677   yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5678   put_gpr_w1(r1, mkexpr(old_mem));
5679}
5680
5681static void
5682s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5683{
5684   IRCAS *cas;
5685   IRTemp old_mem = newTemp(Ity_I64);
5686   IRTemp op2 = newTemp(Ity_I64);
5687   IRTemp op3 = newTemp(Ity_I64);
5688   IRTemp result = newTemp(Ity_I64);
5689
5690   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5691   assign(op3, get_gpr_dw0(r3));
5692   assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5693
5694   /* Place the addition of second operand and third operand at the
5695      second-operand location everytime */
5696   cas = mkIRCAS(IRTemp_INVALID, old_mem,
5697                 Iend_BE, mkexpr(op2addr),
5698                 NULL, mkexpr(op2), /* expected value */
5699                 NULL, mkexpr(result)  /* new value */);
5700   stmt(IRStmt_CAS(cas));
5701
5702   /* Set CC according to 64-bit addition */
5703   if (is_signed) {
5704      s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5705   } else {
5706      s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5707   }
5708
5709   /* If old_mem contains the expected value, then the CAS succeeded.
5710      Otherwise, it did not */
5711   yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5712   put_gpr_dw0(r1, mkexpr(old_mem));
5713}
5714
5715static void
5716s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5717{
5718   IRCAS *cas;
5719   IRTemp old_mem = newTemp(Ity_I32);
5720   IRTemp op2 = newTemp(Ity_I32);
5721   IRTemp op3 = newTemp(Ity_I32);
5722   IRTemp result = newTemp(Ity_I32);
5723
5724   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5725   assign(op3, get_gpr_w1(r3));
5726   assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5727
5728   /* Place the addition of second operand and third operand at the
5729      second-operand location everytime */
5730   cas = mkIRCAS(IRTemp_INVALID, old_mem,
5731                 Iend_BE, mkexpr(op2addr),
5732                 NULL, mkexpr(op2), /* expected value */
5733                 NULL, mkexpr(result)  /* new value */);
5734   stmt(IRStmt_CAS(cas));
5735
5736   /* Set CC according to bitwise operation */
5737   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5738
5739   /* If old_mem contains the expected value, then the CAS succeeded.
5740      Otherwise, it did not */
5741   yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5742   put_gpr_w1(r1, mkexpr(old_mem));
5743}
5744
5745static void
5746s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5747{
5748   IRCAS *cas;
5749   IRTemp old_mem = newTemp(Ity_I64);
5750   IRTemp op2 = newTemp(Ity_I64);
5751   IRTemp op3 = newTemp(Ity_I64);
5752   IRTemp result = newTemp(Ity_I64);
5753
5754   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5755   assign(op3, get_gpr_dw0(r3));
5756   assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5757
5758   /* Place the addition of second operand and third operand at the
5759      second-operand location everytime */
5760   cas = mkIRCAS(IRTemp_INVALID, old_mem,
5761                 Iend_BE, mkexpr(op2addr),
5762                 NULL, mkexpr(op2), /* expected value */
5763                 NULL, mkexpr(result)  /* new value */);
5764   stmt(IRStmt_CAS(cas));
5765
5766   /* Set CC according to bitwise operation */
5767   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5768
5769   /* If old_mem contains the expected value, then the CAS succeeded.
5770      Otherwise, it did not */
5771   yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5772   put_gpr_dw0(r1, mkexpr(old_mem));
5773}
5774
5775static const HChar *
5776s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5777{
5778   s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
5779
5780   return "laa";
5781}
5782
5783static const HChar *
5784s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5785{
5786   s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
5787
5788   return "laag";
5789}
5790
5791static const HChar *
5792s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5793{
5794   s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
5795
5796   return "laal";
5797}
5798
5799static const HChar *
5800s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5801{
5802   s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
5803
5804   return "laalg";
5805}
5806
5807static const HChar *
5808s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5809{
5810   s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
5811
5812   return "lan";
5813}
5814
5815static const HChar *
5816s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5817{
5818   s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
5819
5820   return "lang";
5821}
5822
5823static const HChar *
5824s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5825{
5826   s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
5827
5828   return "lax";
5829}
5830
5831static const HChar *
5832s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5833{
5834   s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
5835
5836   return "laxg";
5837}
5838
5839static const HChar *
5840s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5841{
5842   s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
5843
5844   return "lao";
5845}
5846
5847static const HChar *
5848s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5849{
5850   s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
5851
5852   return "laog";
5853}
5854
5855static const HChar *
5856s390_irgen_LTR(UChar r1, UChar r2)
5857{
5858   IRTemp op2 = newTemp(Ity_I32);
5859
5860   assign(op2, get_gpr_w1(r2));
5861   put_gpr_w1(r1, mkexpr(op2));
5862   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5863
5864   return "ltr";
5865}
5866
5867static const HChar *
5868s390_irgen_LTGR(UChar r1, UChar r2)
5869{
5870   IRTemp op2 = newTemp(Ity_I64);
5871
5872   assign(op2, get_gpr_dw0(r2));
5873   put_gpr_dw0(r1, mkexpr(op2));
5874   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5875
5876   return "ltgr";
5877}
5878
5879static const HChar *
5880s390_irgen_LTGFR(UChar r1, UChar r2)
5881{
5882   IRTemp op2 = newTemp(Ity_I64);
5883
5884   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5885   put_gpr_dw0(r1, mkexpr(op2));
5886   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5887
5888   return "ltgfr";
5889}
5890
5891static const HChar *
5892s390_irgen_LT(UChar r1, IRTemp op2addr)
5893{
5894   IRTemp op2 = newTemp(Ity_I32);
5895
5896   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5897   put_gpr_w1(r1, mkexpr(op2));
5898   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5899
5900   return "lt";
5901}
5902
5903static const HChar *
5904s390_irgen_LTG(UChar r1, IRTemp op2addr)
5905{
5906   IRTemp op2 = newTemp(Ity_I64);
5907
5908   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5909   put_gpr_dw0(r1, mkexpr(op2));
5910   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5911
5912   return "ltg";
5913}
5914
5915static const HChar *
5916s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5917{
5918   IRTemp op2 = newTemp(Ity_I64);
5919
5920   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5921   put_gpr_dw0(r1, mkexpr(op2));
5922   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5923
5924   return "ltgf";
5925}
5926
5927static const HChar *
5928s390_irgen_LBR(UChar r1, UChar r2)
5929{
5930   put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5931
5932   return "lbr";
5933}
5934
5935static const HChar *
5936s390_irgen_LGBR(UChar r1, UChar r2)
5937{
5938   put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5939
5940   return "lgbr";
5941}
5942
5943static const HChar *
5944s390_irgen_LB(UChar r1, IRTemp op2addr)
5945{
5946   put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5947
5948   return "lb";
5949}
5950
5951static const HChar *
5952s390_irgen_LGB(UChar r1, IRTemp op2addr)
5953{
5954   put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5955
5956   return "lgb";
5957}
5958
5959static const HChar *
5960s390_irgen_LBH(UChar r1, IRTemp op2addr)
5961{
5962   put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5963
5964   return "lbh";
5965}
5966
5967static const HChar *
5968s390_irgen_LCR(UChar r1, UChar r2)
5969{
5970   Int op1;
5971   IRTemp op2 = newTemp(Ity_I32);
5972   IRTemp result = newTemp(Ity_I32);
5973
5974   op1 = 0;
5975   assign(op2, get_gpr_w1(r2));
5976   assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5977   put_gpr_w1(r1, mkexpr(result));
5978   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5979                       op1)), op2);
5980
5981   return "lcr";
5982}
5983
5984static const HChar *
5985s390_irgen_LCGR(UChar r1, UChar r2)
5986{
5987   Long op1;
5988   IRTemp op2 = newTemp(Ity_I64);
5989   IRTemp result = newTemp(Ity_I64);
5990
5991   op1 = 0ULL;
5992   assign(op2, get_gpr_dw0(r2));
5993   assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5994   put_gpr_dw0(r1, mkexpr(result));
5995   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5996                       op1)), op2);
5997
5998   return "lcgr";
5999}
6000
6001static const HChar *
6002s390_irgen_LCGFR(UChar r1, UChar r2)
6003{
6004   Long op1;
6005   IRTemp op2 = newTemp(Ity_I64);
6006   IRTemp result = newTemp(Ity_I64);
6007
6008   op1 = 0ULL;
6009   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6010   assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6011   put_gpr_dw0(r1, mkexpr(result));
6012   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6013                       op1)), op2);
6014
6015   return "lcgfr";
6016}
6017
6018static const HChar *
6019s390_irgen_LHR(UChar r1, UChar r2)
6020{
6021   put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
6022
6023   return "lhr";
6024}
6025
6026static const HChar *
6027s390_irgen_LGHR(UChar r1, UChar r2)
6028{
6029   put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6030
6031   return "lghr";
6032}
6033
6034static const HChar *
6035s390_irgen_LH(UChar r1, IRTemp op2addr)
6036{
6037   put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6038
6039   return "lh";
6040}
6041
6042static const HChar *
6043s390_irgen_LHY(UChar r1, IRTemp op2addr)
6044{
6045   put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6046
6047   return "lhy";
6048}
6049
6050static const HChar *
6051s390_irgen_LGH(UChar r1, IRTemp op2addr)
6052{
6053   put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6054
6055   return "lgh";
6056}
6057
6058static const HChar *
6059s390_irgen_LHI(UChar r1, UShort i2)
6060{
6061   put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6062
6063   return "lhi";
6064}
6065
6066static const HChar *
6067s390_irgen_LGHI(UChar r1, UShort i2)
6068{
6069   put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6070
6071   return "lghi";
6072}
6073
6074static const HChar *
6075s390_irgen_LHRL(UChar r1, UInt i2)
6076{
6077   put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6078              ((ULong)(Long)(Int)i2 << 1)))));
6079
6080   return "lhrl";
6081}
6082
6083static const HChar *
6084s390_irgen_LGHRL(UChar r1, UInt i2)
6085{
6086   put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6087               ((ULong)(Long)(Int)i2 << 1)))));
6088
6089   return "lghrl";
6090}
6091
6092static const HChar *
6093s390_irgen_LHH(UChar r1, IRTemp op2addr)
6094{
6095   put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6096
6097   return "lhh";
6098}
6099
6100static const HChar *
6101s390_irgen_LFH(UChar r1, IRTemp op2addr)
6102{
6103   put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6104
6105   return "lfh";
6106}
6107
6108static const HChar *
6109s390_irgen_LLGFR(UChar r1, UChar r2)
6110{
6111   put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6112
6113   return "llgfr";
6114}
6115
6116static const HChar *
6117s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6118{
6119   put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6120
6121   return "llgf";
6122}
6123
6124static const HChar *
6125s390_irgen_LLGFRL(UChar r1, UInt i2)
6126{
6127   put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6128               ((ULong)(Long)(Int)i2 << 1)))));
6129
6130   return "llgfrl";
6131}
6132
6133static const HChar *
6134s390_irgen_LLCR(UChar r1, UChar r2)
6135{
6136   put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6137
6138   return "llcr";
6139}
6140
6141static const HChar *
6142s390_irgen_LLGCR(UChar r1, UChar r2)
6143{
6144   put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6145
6146   return "llgcr";
6147}
6148
6149static const HChar *
6150s390_irgen_LLC(UChar r1, IRTemp op2addr)
6151{
6152   put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6153
6154   return "llc";
6155}
6156
6157static const HChar *
6158s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6159{
6160   put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6161
6162   return "llgc";
6163}
6164
6165static const HChar *
6166s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6167{
6168   put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6169
6170   return "llch";
6171}
6172
6173static const HChar *
6174s390_irgen_LLHR(UChar r1, UChar r2)
6175{
6176   put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6177
6178   return "llhr";
6179}
6180
6181static const HChar *
6182s390_irgen_LLGHR(UChar r1, UChar r2)
6183{
6184   put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6185
6186   return "llghr";
6187}
6188
6189static const HChar *
6190s390_irgen_LLH(UChar r1, IRTemp op2addr)
6191{
6192   put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6193
6194   return "llh";
6195}
6196
6197static const HChar *
6198s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6199{
6200   put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6201
6202   return "llgh";
6203}
6204
6205static const HChar *
6206s390_irgen_LLHRL(UChar r1, UInt i2)
6207{
6208   put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6209              ((ULong)(Long)(Int)i2 << 1)))));
6210
6211   return "llhrl";
6212}
6213
6214static const HChar *
6215s390_irgen_LLGHRL(UChar r1, UInt i2)
6216{
6217   put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6218               ((ULong)(Long)(Int)i2 << 1)))));
6219
6220   return "llghrl";
6221}
6222
6223static const HChar *
6224s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6225{
6226   put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6227
6228   return "llhh";
6229}
6230
6231static const HChar *
6232s390_irgen_LLIHF(UChar r1, UInt i2)
6233{
6234   put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6235
6236   return "llihf";
6237}
6238
6239static const HChar *
6240s390_irgen_LLIHH(UChar r1, UShort i2)
6241{
6242   put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6243
6244   return "llihh";
6245}
6246
6247static const HChar *
6248s390_irgen_LLIHL(UChar r1, UShort i2)
6249{
6250   put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6251
6252   return "llihl";
6253}
6254
6255static const HChar *
6256s390_irgen_LLILF(UChar r1, UInt i2)
6257{
6258   put_gpr_dw0(r1, mkU64(i2));
6259
6260   return "llilf";
6261}
6262
6263static const HChar *
6264s390_irgen_LLILH(UChar r1, UShort i2)
6265{
6266   put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6267
6268   return "llilh";
6269}
6270
6271static const HChar *
6272s390_irgen_LLILL(UChar r1, UShort i2)
6273{
6274   put_gpr_dw0(r1, mkU64(i2));
6275
6276   return "llill";
6277}
6278
6279static const HChar *
6280s390_irgen_LLGTR(UChar r1, UChar r2)
6281{
6282   put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6283               mkU32(2147483647))));
6284
6285   return "llgtr";
6286}
6287
6288static const HChar *
6289s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6290{
6291   put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6292               mkexpr(op2addr)), mkU32(2147483647))));
6293
6294   return "llgt";
6295}
6296
6297static const HChar *
6298s390_irgen_LNR(UChar r1, UChar r2)
6299{
6300   IRTemp op2 = newTemp(Ity_I32);
6301   IRTemp result = newTemp(Ity_I32);
6302
6303   assign(op2, get_gpr_w1(r2));
6304   assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6305          binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6306   put_gpr_w1(r1, mkexpr(result));
6307   s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6308
6309   return "lnr";
6310}
6311
6312static const HChar *
6313s390_irgen_LNGR(UChar r1, UChar r2)
6314{
6315   IRTemp op2 = newTemp(Ity_I64);
6316   IRTemp result = newTemp(Ity_I64);
6317
6318   assign(op2, get_gpr_dw0(r2));
6319   assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6320          binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6321   put_gpr_dw0(r1, mkexpr(result));
6322   s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6323
6324   return "lngr";
6325}
6326
6327static const HChar *
6328s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6329{
6330   IRTemp op2 = newTemp(Ity_I64);
6331   IRTemp result = newTemp(Ity_I64);
6332
6333   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6334   assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6335          binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6336   put_gpr_dw0(r1, mkexpr(result));
6337   s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6338
6339   return "lngfr";
6340}
6341
6342static const HChar *
6343s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6344{
6345   next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
6346   put_gpr_w1(r1, get_gpr_w1(r2));
6347
6348   return "locr";
6349}
6350
6351static const HChar *
6352s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6353{
6354   next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
6355   put_gpr_dw0(r1, get_gpr_dw0(r2));
6356
6357   return "locgr";
6358}
6359
6360static const HChar *
6361s390_irgen_LOC(UChar r1, IRTemp op2addr)
6362{
6363   /* condition is checked in format handler */
6364   put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6365
6366   return "loc";
6367}
6368
6369static const HChar *
6370s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6371{
6372   /* condition is checked in format handler */
6373   put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6374
6375   return "locg";
6376}
6377
6378static const HChar *
6379s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6380{
6381   put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6382   put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6383               ));
6384
6385   return "lpq";
6386}
6387
6388static const HChar *
6389s390_irgen_LPR(UChar r1, UChar r2)
6390{
6391   IRTemp op2 = newTemp(Ity_I32);
6392   IRTemp result = newTemp(Ity_I32);
6393
6394   assign(op2, get_gpr_w1(r2));
6395   assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6396          binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6397   put_gpr_w1(r1, mkexpr(result));
6398   s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6399
6400   return "lpr";
6401}
6402
6403static const HChar *
6404s390_irgen_LPGR(UChar r1, UChar r2)
6405{
6406   IRTemp op2 = newTemp(Ity_I64);
6407   IRTemp result = newTemp(Ity_I64);
6408
6409   assign(op2, get_gpr_dw0(r2));
6410   assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6411          binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6412   put_gpr_dw0(r1, mkexpr(result));
6413   s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6414
6415   return "lpgr";
6416}
6417
6418static const HChar *
6419s390_irgen_LPGFR(UChar r1, UChar r2)
6420{
6421   IRTemp op2 = newTemp(Ity_I64);
6422   IRTemp result = newTemp(Ity_I64);
6423
6424   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6425   assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6426          binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6427   put_gpr_dw0(r1, mkexpr(result));
6428   s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6429
6430   return "lpgfr";
6431}
6432
6433static const HChar *
6434s390_irgen_LRVR(UChar r1, UChar r2)
6435{
6436   IRTemp b0 = newTemp(Ity_I8);
6437   IRTemp b1 = newTemp(Ity_I8);
6438   IRTemp b2 = newTemp(Ity_I8);
6439   IRTemp b3 = newTemp(Ity_I8);
6440
6441   assign(b3, get_gpr_b7(r2));
6442   assign(b2, get_gpr_b6(r2));
6443   assign(b1, get_gpr_b5(r2));
6444   assign(b0, get_gpr_b4(r2));
6445   put_gpr_b4(r1, mkexpr(b3));
6446   put_gpr_b5(r1, mkexpr(b2));
6447   put_gpr_b6(r1, mkexpr(b1));
6448   put_gpr_b7(r1, mkexpr(b0));
6449
6450   return "lrvr";
6451}
6452
6453static const HChar *
6454s390_irgen_LRVGR(UChar r1, UChar r2)
6455{
6456   IRTemp b0 = newTemp(Ity_I8);
6457   IRTemp b1 = newTemp(Ity_I8);
6458   IRTemp b2 = newTemp(Ity_I8);
6459   IRTemp b3 = newTemp(Ity_I8);
6460   IRTemp b4 = newTemp(Ity_I8);
6461   IRTemp b5 = newTemp(Ity_I8);
6462   IRTemp b6 = newTemp(Ity_I8);
6463   IRTemp b7 = newTemp(Ity_I8);
6464
6465   assign(b7, get_gpr_b7(r2));
6466   assign(b6, get_gpr_b6(r2));
6467   assign(b5, get_gpr_b5(r2));
6468   assign(b4, get_gpr_b4(r2));
6469   assign(b3, get_gpr_b3(r2));
6470   assign(b2, get_gpr_b2(r2));
6471   assign(b1, get_gpr_b1(r2));
6472   assign(b0, get_gpr_b0(r2));
6473   put_gpr_b0(r1, mkexpr(b7));
6474   put_gpr_b1(r1, mkexpr(b6));
6475   put_gpr_b2(r1, mkexpr(b5));
6476   put_gpr_b3(r1, mkexpr(b4));
6477   put_gpr_b4(r1, mkexpr(b3));
6478   put_gpr_b5(r1, mkexpr(b2));
6479   put_gpr_b6(r1, mkexpr(b1));
6480   put_gpr_b7(r1, mkexpr(b0));
6481
6482   return "lrvgr";
6483}
6484
6485static const HChar *
6486s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6487{
6488   IRTemp op2 = newTemp(Ity_I16);
6489
6490   assign(op2, load(Ity_I16, mkexpr(op2addr)));
6491   put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6492   put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6493
6494   return "lrvh";
6495}
6496
6497static const HChar *
6498s390_irgen_LRV(UChar r1, IRTemp op2addr)
6499{
6500   IRTemp op2 = newTemp(Ity_I32);
6501
6502   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6503   put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6504   put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6505              mkU8(8)), mkU32(255))));
6506   put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6507              mkU8(16)), mkU32(255))));
6508   put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6509              mkU8(24)), mkU32(255))));
6510
6511   return "lrv";
6512}
6513
6514static const HChar *
6515s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6516{
6517   IRTemp op2 = newTemp(Ity_I64);
6518
6519   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6520   put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6521   put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6522              mkU8(8)), mkU64(255))));
6523   put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6524              mkU8(16)), mkU64(255))));
6525   put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6526              mkU8(24)), mkU64(255))));
6527   put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6528              mkU8(32)), mkU64(255))));
6529   put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6530              mkU8(40)), mkU64(255))));
6531   put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6532              mkU8(48)), mkU64(255))));
6533   put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6534              mkU8(56)), mkU64(255))));
6535
6536   return "lrvg";
6537}
6538
6539static const HChar *
6540s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6541{
6542   store(mkexpr(op1addr), mkU16(i2));
6543
6544   return "mvhhi";
6545}
6546
6547static const HChar *
6548s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6549{
6550   store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6551
6552   return "mvhi";
6553}
6554
6555static const HChar *
6556s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6557{
6558   store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6559
6560   return "mvghi";
6561}
6562
6563static const HChar *
6564s390_irgen_MVI(UChar i2, IRTemp op1addr)
6565{
6566   store(mkexpr(op1addr), mkU8(i2));
6567
6568   return "mvi";
6569}
6570
6571static const HChar *
6572s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6573{
6574   store(mkexpr(op1addr), mkU8(i2));
6575
6576   return "mviy";
6577}
6578
6579static const HChar *
6580s390_irgen_MR(UChar r1, UChar r2)
6581{
6582   IRTemp op1 = newTemp(Ity_I32);
6583   IRTemp op2 = newTemp(Ity_I32);
6584   IRTemp result = newTemp(Ity_I64);
6585
6586   assign(op1, get_gpr_w1(r1 + 1));
6587   assign(op2, get_gpr_w1(r2));
6588   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6589   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6590   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6591
6592   return "mr";
6593}
6594
6595static const HChar *
6596s390_irgen_M(UChar r1, IRTemp op2addr)
6597{
6598   IRTemp op1 = newTemp(Ity_I32);
6599   IRTemp op2 = newTemp(Ity_I32);
6600   IRTemp result = newTemp(Ity_I64);
6601
6602   assign(op1, get_gpr_w1(r1 + 1));
6603   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6604   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6605   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6606   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6607
6608   return "m";
6609}
6610
6611static const HChar *
6612s390_irgen_MFY(UChar r1, IRTemp op2addr)
6613{
6614   IRTemp op1 = newTemp(Ity_I32);
6615   IRTemp op2 = newTemp(Ity_I32);
6616   IRTemp result = newTemp(Ity_I64);
6617
6618   assign(op1, get_gpr_w1(r1 + 1));
6619   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6620   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6621   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6622   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6623
6624   return "mfy";
6625}
6626
6627static const HChar *
6628s390_irgen_MH(UChar r1, IRTemp op2addr)
6629{
6630   IRTemp op1 = newTemp(Ity_I32);
6631   IRTemp op2 = newTemp(Ity_I16);
6632   IRTemp result = newTemp(Ity_I64);
6633
6634   assign(op1, get_gpr_w1(r1));
6635   assign(op2, load(Ity_I16, mkexpr(op2addr)));
6636   assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6637          ));
6638   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6639
6640   return "mh";
6641}
6642
6643static const HChar *
6644s390_irgen_MHY(UChar r1, IRTemp op2addr)
6645{
6646   IRTemp op1 = newTemp(Ity_I32);
6647   IRTemp op2 = newTemp(Ity_I16);
6648   IRTemp result = newTemp(Ity_I64);
6649
6650   assign(op1, get_gpr_w1(r1));
6651   assign(op2, load(Ity_I16, mkexpr(op2addr)));
6652   assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6653          ));
6654   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6655
6656   return "mhy";
6657}
6658
6659static const HChar *
6660s390_irgen_MHI(UChar r1, UShort i2)
6661{
6662   IRTemp op1 = newTemp(Ity_I32);
6663   Short op2;
6664   IRTemp result = newTemp(Ity_I64);
6665
6666   assign(op1, get_gpr_w1(r1));
6667   op2 = (Short)i2;
6668   assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6669          mkU16((UShort)op2))));
6670   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6671
6672   return "mhi";
6673}
6674
6675static const HChar *
6676s390_irgen_MGHI(UChar r1, UShort i2)
6677{
6678   IRTemp op1 = newTemp(Ity_I64);
6679   Short op2;
6680   IRTemp result = newTemp(Ity_I128);
6681
6682   assign(op1, get_gpr_dw0(r1));
6683   op2 = (Short)i2;
6684   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6685          mkU16((UShort)op2))));
6686   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6687
6688   return "mghi";
6689}
6690
6691static const HChar *
6692s390_irgen_MLR(UChar r1, UChar r2)
6693{
6694   IRTemp op1 = newTemp(Ity_I32);
6695   IRTemp op2 = newTemp(Ity_I32);
6696   IRTemp result = newTemp(Ity_I64);
6697
6698   assign(op1, get_gpr_w1(r1 + 1));
6699   assign(op2, get_gpr_w1(r2));
6700   assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6701   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6702   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6703
6704   return "mlr";
6705}
6706
6707static const HChar *
6708s390_irgen_MLGR(UChar r1, UChar r2)
6709{
6710   IRTemp op1 = newTemp(Ity_I64);
6711   IRTemp op2 = newTemp(Ity_I64);
6712   IRTemp result = newTemp(Ity_I128);
6713
6714   assign(op1, get_gpr_dw0(r1 + 1));
6715   assign(op2, get_gpr_dw0(r2));
6716   assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6717   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6718   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6719
6720   return "mlgr";
6721}
6722
6723static const HChar *
6724s390_irgen_ML(UChar r1, IRTemp op2addr)
6725{
6726   IRTemp op1 = newTemp(Ity_I32);
6727   IRTemp op2 = newTemp(Ity_I32);
6728   IRTemp result = newTemp(Ity_I64);
6729
6730   assign(op1, get_gpr_w1(r1 + 1));
6731   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6732   assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6733   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6734   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6735
6736   return "ml";
6737}
6738
6739static const HChar *
6740s390_irgen_MLG(UChar r1, IRTemp op2addr)
6741{
6742   IRTemp op1 = newTemp(Ity_I64);
6743   IRTemp op2 = newTemp(Ity_I64);
6744   IRTemp result = newTemp(Ity_I128);
6745
6746   assign(op1, get_gpr_dw0(r1 + 1));
6747   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6748   assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6749   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6750   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6751
6752   return "mlg";
6753}
6754
6755static const HChar *
6756s390_irgen_MSR(UChar r1, UChar r2)
6757{
6758   IRTemp op1 = newTemp(Ity_I32);
6759   IRTemp op2 = newTemp(Ity_I32);
6760   IRTemp result = newTemp(Ity_I64);
6761
6762   assign(op1, get_gpr_w1(r1));
6763   assign(op2, get_gpr_w1(r2));
6764   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6765   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6766
6767   return "msr";
6768}
6769
6770static const HChar *
6771s390_irgen_MSGR(UChar r1, UChar r2)
6772{
6773   IRTemp op1 = newTemp(Ity_I64);
6774   IRTemp op2 = newTemp(Ity_I64);
6775   IRTemp result = newTemp(Ity_I128);
6776
6777   assign(op1, get_gpr_dw0(r1));
6778   assign(op2, get_gpr_dw0(r2));
6779   assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6780   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6781
6782   return "msgr";
6783}
6784
6785static const HChar *
6786s390_irgen_MSGFR(UChar r1, UChar r2)
6787{
6788   IRTemp op1 = newTemp(Ity_I64);
6789   IRTemp op2 = newTemp(Ity_I32);
6790   IRTemp result = newTemp(Ity_I128);
6791
6792   assign(op1, get_gpr_dw0(r1));
6793   assign(op2, get_gpr_w1(r2));
6794   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6795          ));
6796   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6797
6798   return "msgfr";
6799}
6800
6801static const HChar *
6802s390_irgen_MS(UChar r1, IRTemp op2addr)
6803{
6804   IRTemp op1 = newTemp(Ity_I32);
6805   IRTemp op2 = newTemp(Ity_I32);
6806   IRTemp result = newTemp(Ity_I64);
6807
6808   assign(op1, get_gpr_w1(r1));
6809   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6810   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6811   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6812
6813   return "ms";
6814}
6815
6816static const HChar *
6817s390_irgen_MSY(UChar r1, IRTemp op2addr)
6818{
6819   IRTemp op1 = newTemp(Ity_I32);
6820   IRTemp op2 = newTemp(Ity_I32);
6821   IRTemp result = newTemp(Ity_I64);
6822
6823   assign(op1, get_gpr_w1(r1));
6824   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6825   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6826   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6827
6828   return "msy";
6829}
6830
6831static const HChar *
6832s390_irgen_MSG(UChar r1, IRTemp op2addr)
6833{
6834   IRTemp op1 = newTemp(Ity_I64);
6835   IRTemp op2 = newTemp(Ity_I64);
6836   IRTemp result = newTemp(Ity_I128);
6837
6838   assign(op1, get_gpr_dw0(r1));
6839   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6840   assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6841   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6842
6843   return "msg";
6844}
6845
6846static const HChar *
6847s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6848{
6849   IRTemp op1 = newTemp(Ity_I64);
6850   IRTemp op2 = newTemp(Ity_I32);
6851   IRTemp result = newTemp(Ity_I128);
6852
6853   assign(op1, get_gpr_dw0(r1));
6854   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6855   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6856          ));
6857   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6858
6859   return "msgf";
6860}
6861
6862static const HChar *
6863s390_irgen_MSFI(UChar r1, UInt i2)
6864{
6865   IRTemp op1 = newTemp(Ity_I32);
6866   Int op2;
6867   IRTemp result = newTemp(Ity_I64);
6868
6869   assign(op1, get_gpr_w1(r1));
6870   op2 = (Int)i2;
6871   assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6872   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6873
6874   return "msfi";
6875}
6876
6877static const HChar *
6878s390_irgen_MSGFI(UChar r1, UInt i2)
6879{
6880   IRTemp op1 = newTemp(Ity_I64);
6881   Int op2;
6882   IRTemp result = newTemp(Ity_I128);
6883
6884   assign(op1, get_gpr_dw0(r1));
6885   op2 = (Int)i2;
6886   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6887          op2))));
6888   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6889
6890   return "msgfi";
6891}
6892
6893static const HChar *
6894s390_irgen_OR(UChar r1, UChar r2)
6895{
6896   IRTemp op1 = newTemp(Ity_I32);
6897   IRTemp op2 = newTemp(Ity_I32);
6898   IRTemp result = newTemp(Ity_I32);
6899
6900   assign(op1, get_gpr_w1(r1));
6901   assign(op2, get_gpr_w1(r2));
6902   assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6903   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6904   put_gpr_w1(r1, mkexpr(result));
6905
6906   return "or";
6907}
6908
6909static const HChar *
6910s390_irgen_OGR(UChar r1, UChar r2)
6911{
6912   IRTemp op1 = newTemp(Ity_I64);
6913   IRTemp op2 = newTemp(Ity_I64);
6914   IRTemp result = newTemp(Ity_I64);
6915
6916   assign(op1, get_gpr_dw0(r1));
6917   assign(op2, get_gpr_dw0(r2));
6918   assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6919   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6920   put_gpr_dw0(r1, mkexpr(result));
6921
6922   return "ogr";
6923}
6924
6925static const HChar *
6926s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6927{
6928   IRTemp op2 = newTemp(Ity_I32);
6929   IRTemp op3 = newTemp(Ity_I32);
6930   IRTemp result = newTemp(Ity_I32);
6931
6932   assign(op2, get_gpr_w1(r2));
6933   assign(op3, get_gpr_w1(r3));
6934   assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6935   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6936   put_gpr_w1(r1, mkexpr(result));
6937
6938   return "ork";
6939}
6940
6941static const HChar *
6942s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6943{
6944   IRTemp op2 = newTemp(Ity_I64);
6945   IRTemp op3 = newTemp(Ity_I64);
6946   IRTemp result = newTemp(Ity_I64);
6947
6948   assign(op2, get_gpr_dw0(r2));
6949   assign(op3, get_gpr_dw0(r3));
6950   assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6951   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6952   put_gpr_dw0(r1, mkexpr(result));
6953
6954   return "ogrk";
6955}
6956
6957static const HChar *
6958s390_irgen_O(UChar r1, IRTemp op2addr)
6959{
6960   IRTemp op1 = newTemp(Ity_I32);
6961   IRTemp op2 = newTemp(Ity_I32);
6962   IRTemp result = newTemp(Ity_I32);
6963
6964   assign(op1, get_gpr_w1(r1));
6965   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6966   assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6967   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6968   put_gpr_w1(r1, mkexpr(result));
6969
6970   return "o";
6971}
6972
6973static const HChar *
6974s390_irgen_OY(UChar r1, IRTemp op2addr)
6975{
6976   IRTemp op1 = newTemp(Ity_I32);
6977   IRTemp op2 = newTemp(Ity_I32);
6978   IRTemp result = newTemp(Ity_I32);
6979
6980   assign(op1, get_gpr_w1(r1));
6981   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6982   assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6983   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6984   put_gpr_w1(r1, mkexpr(result));
6985
6986   return "oy";
6987}
6988
6989static const HChar *
6990s390_irgen_OG(UChar r1, IRTemp op2addr)
6991{
6992   IRTemp op1 = newTemp(Ity_I64);
6993   IRTemp op2 = newTemp(Ity_I64);
6994   IRTemp result = newTemp(Ity_I64);
6995
6996   assign(op1, get_gpr_dw0(r1));
6997   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6998   assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6999   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7000   put_gpr_dw0(r1, mkexpr(result));
7001
7002   return "og";
7003}
7004
7005static const HChar *
7006s390_irgen_OI(UChar i2, IRTemp op1addr)
7007{
7008   IRTemp op1 = newTemp(Ity_I8);
7009   UChar op2;
7010   IRTemp result = newTemp(Ity_I8);
7011
7012   assign(op1, load(Ity_I8, mkexpr(op1addr)));
7013   op2 = i2;
7014   assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7015   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7016   store(mkexpr(op1addr), mkexpr(result));
7017
7018   return "oi";
7019}
7020
7021static const HChar *
7022s390_irgen_OIY(UChar i2, IRTemp op1addr)
7023{
7024   IRTemp op1 = newTemp(Ity_I8);
7025   UChar op2;
7026   IRTemp result = newTemp(Ity_I8);
7027
7028   assign(op1, load(Ity_I8, mkexpr(op1addr)));
7029   op2 = i2;
7030   assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7031   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7032   store(mkexpr(op1addr), mkexpr(result));
7033
7034   return "oiy";
7035}
7036
7037static const HChar *
7038s390_irgen_OIHF(UChar r1, UInt i2)
7039{
7040   IRTemp op1 = newTemp(Ity_I32);
7041   UInt op2;
7042   IRTemp result = newTemp(Ity_I32);
7043
7044   assign(op1, get_gpr_w0(r1));
7045   op2 = i2;
7046   assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7047   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7048   put_gpr_w0(r1, mkexpr(result));
7049
7050   return "oihf";
7051}
7052
7053static const HChar *
7054s390_irgen_OIHH(UChar r1, UShort i2)
7055{
7056   IRTemp op1 = newTemp(Ity_I16);
7057   UShort op2;
7058   IRTemp result = newTemp(Ity_I16);
7059
7060   assign(op1, get_gpr_hw0(r1));
7061   op2 = i2;
7062   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7063   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7064   put_gpr_hw0(r1, mkexpr(result));
7065
7066   return "oihh";
7067}
7068
7069static const HChar *
7070s390_irgen_OIHL(UChar r1, UShort i2)
7071{
7072   IRTemp op1 = newTemp(Ity_I16);
7073   UShort op2;
7074   IRTemp result = newTemp(Ity_I16);
7075
7076   assign(op1, get_gpr_hw1(r1));
7077   op2 = i2;
7078   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7079   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7080   put_gpr_hw1(r1, mkexpr(result));
7081
7082   return "oihl";
7083}
7084
7085static const HChar *
7086s390_irgen_OILF(UChar r1, UInt i2)
7087{
7088   IRTemp op1 = newTemp(Ity_I32);
7089   UInt op2;
7090   IRTemp result = newTemp(Ity_I32);
7091
7092   assign(op1, get_gpr_w1(r1));
7093   op2 = i2;
7094   assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7095   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7096   put_gpr_w1(r1, mkexpr(result));
7097
7098   return "oilf";
7099}
7100
7101static const HChar *
7102s390_irgen_OILH(UChar r1, UShort i2)
7103{
7104   IRTemp op1 = newTemp(Ity_I16);
7105   UShort op2;
7106   IRTemp result = newTemp(Ity_I16);
7107
7108   assign(op1, get_gpr_hw2(r1));
7109   op2 = i2;
7110   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7111   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7112   put_gpr_hw2(r1, mkexpr(result));
7113
7114   return "oilh";
7115}
7116
7117static const HChar *
7118s390_irgen_OILL(UChar r1, UShort i2)
7119{
7120   IRTemp op1 = newTemp(Ity_I16);
7121   UShort op2;
7122   IRTemp result = newTemp(Ity_I16);
7123
7124   assign(op1, get_gpr_hw3(r1));
7125   op2 = i2;
7126   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7127   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7128   put_gpr_hw3(r1, mkexpr(result));
7129
7130   return "oill";
7131}
7132
7133static const HChar *
7134s390_irgen_PFD(void)
7135{
7136
7137   return "pfd";
7138}
7139
7140static const HChar *
7141s390_irgen_PFDRL(void)
7142{
7143
7144   return "pfdrl";
7145}
7146
7147static IRExpr *
7148get_rounding_mode_from_gr0(void)
7149{
7150   IRTemp rm_bits = newTemp(Ity_I32);
7151   IRExpr *s390rm;
7152   IRExpr *irrm;
7153
7154   /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7155      when PFPO insn is called. So, extract the bits at [60:63] */
7156   assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7157   s390rm = mkexpr(rm_bits);
7158   irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7159            mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7160            mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7161              mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7162              mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7163                mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7164                mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7165                  mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7166                  mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7167                    mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7168                    mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7169                      mkexpr(encode_dfp_rounding_mode(
7170                               S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7171                      mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7172                        mkexpr(encode_dfp_rounding_mode(
7173                                 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7174                        mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7175                          mkexpr(encode_dfp_rounding_mode(
7176                                   S390_DFP_ROUND_AWAY_0)),
7177                          mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7178                            mkexpr(encode_dfp_rounding_mode(
7179                                     S390_DFP_ROUND_PREPARE_SHORT_15)),
7180                                /* if rounding mode is 0 or invalid (2-7)
7181                                   set S390_DFP_ROUND_PER_FPC_0 */
7182                            mkexpr(encode_dfp_rounding_mode(
7183                                     S390_DFP_ROUND_PER_FPC_0)))))))))));
7184
7185   return irrm;
7186}
7187
7188static IRExpr *
7189s390_call_pfpo_helper(IRExpr *gr0)
7190{
7191   IRExpr **args, *call;
7192
7193   args = mkIRExprVec_1(gr0);
7194   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7195                        "s390_do_pfpo", &s390_do_pfpo, args);
7196   /* Nothing is excluded from definedness checking. */
7197   call->Iex.CCall.cee->mcx_mask = 0;
7198
7199   return call;
7200}
7201
7202static const HChar *
7203s390_irgen_PFPO(void)
7204{
7205   IRTemp gr0 = newTemp(Ity_I32);     /* word 1 [32:63] of GR 0 */
7206   IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7207   IRTemp fn = newTemp(Ity_I32);       /* [33:55] of GR 0 - function code */
7208   IRTemp ef = newTemp(Ity_I32);       /* Emulation Failure */
7209   IRTemp src1 = newTemp(Ity_F32);
7210   IRTemp dst1 = newTemp(Ity_D32);
7211   IRTemp src2 = newTemp(Ity_F32);
7212   IRTemp dst2 = newTemp(Ity_D64);
7213   IRTemp src3 = newTemp(Ity_F32);
7214   IRTemp dst3 = newTemp(Ity_D128);
7215   IRTemp src4 = newTemp(Ity_F64);
7216   IRTemp dst4 = newTemp(Ity_D32);
7217   IRTemp src5 = newTemp(Ity_F64);
7218   IRTemp dst5 = newTemp(Ity_D64);
7219   IRTemp src6 = newTemp(Ity_F64);
7220   IRTemp dst6 = newTemp(Ity_D128);
7221   IRTemp src7 = newTemp(Ity_F128);
7222   IRTemp dst7 = newTemp(Ity_D32);
7223   IRTemp src8 = newTemp(Ity_F128);
7224   IRTemp dst8 = newTemp(Ity_D64);
7225   IRTemp src9 = newTemp(Ity_F128);
7226   IRTemp dst9 = newTemp(Ity_D128);
7227   IRTemp src10 = newTemp(Ity_D32);
7228   IRTemp dst10 = newTemp(Ity_F32);
7229   IRTemp src11 = newTemp(Ity_D32);
7230   IRTemp dst11 = newTemp(Ity_F64);
7231   IRTemp src12 = newTemp(Ity_D32);
7232   IRTemp dst12 = newTemp(Ity_F128);
7233   IRTemp src13 = newTemp(Ity_D64);
7234   IRTemp dst13 = newTemp(Ity_F32);
7235   IRTemp src14 = newTemp(Ity_D64);
7236   IRTemp dst14 = newTemp(Ity_F64);
7237   IRTemp src15 = newTemp(Ity_D64);
7238   IRTemp dst15 = newTemp(Ity_F128);
7239   IRTemp src16 = newTemp(Ity_D128);
7240   IRTemp dst16 = newTemp(Ity_F32);
7241   IRTemp src17 = newTemp(Ity_D128);
7242   IRTemp dst17 = newTemp(Ity_F64);
7243   IRTemp src18 = newTemp(Ity_D128);
7244   IRTemp dst18 = newTemp(Ity_F128);
7245   IRExpr *irrm;
7246
7247   if (! s390_host_has_pfpo) {
7248      emulation_failure(EmFail_S390X_pfpo);
7249      goto done;
7250   }
7251
7252   assign(gr0, get_gpr_w1(0));
7253   /* get function code */
7254   assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7255                    mkU32(0x7fffff)));
7256   /* get validity test bit */
7257   assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7258                          mkU32(0x1)));
7259   irrm = get_rounding_mode_from_gr0();
7260
7261   /* test_bit is 1 */
7262   assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
7263   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7264
7265   /* Return code set in GR1 is usually 0. Non-zero value is set only
7266      when exceptions are raised. See Programming Notes point 5 in the
7267      instrcution description of pfpo in POP. Since valgrind does not
7268      model exception, it might be safe to just set 0 to GR 1. */
7269   put_gpr_w1(1, mkU32(0x0));
7270   next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7271
7272   /* Check validity of function code in GR 0 */
7273   assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
7274   emulation_failure_with_expr(mkexpr(ef));
7275
7276   stmt(
7277        IRStmt_Exit(
7278                    binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7279                    Ijk_EmFail,
7280                    IRConst_U64(guest_IA_next_instr),
7281                    S390X_GUEST_OFFSET(guest_IA)
7282                    )
7283        );
7284
7285   /* F32 -> D32 */
7286   /* get source from FPR 4,6 - already set in src1 */
7287   assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
7288   put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
7289   put_gpr_w1(1, mkU32(0x0));
7290   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
7291   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
7292
7293   /* F32 -> D64 */
7294   assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
7295   assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
7296   put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
7297   put_gpr_w1(1, mkU32(0x0));
7298   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
7299   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
7300
7301   /* F32 -> D128 */
7302   assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
7303   assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
7304   put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7305   put_gpr_w1(1, mkU32(0x0));
7306   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
7307   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
7308
7309   /* F64 -> D32 */
7310   assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7311   assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
7312   put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7313   put_gpr_w1(1, mkU32(0x0));
7314   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
7315   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
7316
7317   /* F64 -> D64 */
7318   assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7319   assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
7320   put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7321   put_gpr_w1(1, mkU32(0x0));
7322   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
7323   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7324
7325   /* F64 -> D128 */
7326   assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7327   assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
7328   put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7329   put_gpr_w1(1, mkU32(0x0));
7330   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
7331   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7332
7333   /* F128 -> D32 */
7334   assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
7335   assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
7336   put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
7337   put_gpr_w1(1, mkU32(0x0));
7338   s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
7339   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
7340
7341   /* F128 -> D64 */
7342   assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
7343   assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
7344   put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
7345   put_gpr_w1(1, mkU32(0x0));
7346   s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
7347   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
7348
7349   /* F128 -> D128 */
7350   assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
7351   assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
7352   put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
7353   put_gpr_w1(1, mkU32(0x0));
7354   s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
7355   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7356
7357   /* D32 -> F32 */
7358   assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
7359   assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
7360   put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
7361   put_gpr_w1(1, mkU32(0x0));
7362   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
7363   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
7364
7365   /* D32 -> F64 */
7366   assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
7367   assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
7368   put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
7369   put_gpr_w1(1, mkU32(0x0));
7370   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
7371   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
7372
7373   /* D32 -> F128 */
7374   assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
7375   assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
7376   put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
7377   put_gpr_w1(1, mkU32(0x0));
7378   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
7379   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
7380
7381   /* D64 -> F32 */
7382   assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7383   assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
7384   put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
7385   put_gpr_w1(1, mkU32(0x0));
7386   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
7387   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
7388
7389   /* D64 -> F64 */
7390   assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7391   assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
7392   put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
7393   put_gpr_w1(1, mkU32(0x0));
7394   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
7395   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7396
7397   /* D64 -> F128 */
7398   assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7399   assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
7400   put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
7401   put_gpr_w1(1, mkU32(0x0));
7402   s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
7403   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
7404
7405   /* D128 -> F32 */
7406   assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
7407   assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
7408   put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
7409   put_gpr_w1(1, mkU32(0x0));
7410   s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
7411   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
7412
7413   /* D128 -> F64 */
7414   assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
7415   assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
7416   put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
7417   put_gpr_w1(1, mkU32(0x0));
7418   s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
7419   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7420
7421   /* D128 -> F128 */
7422   assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
7423   assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
7424   put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
7425   put_gpr_w1(1, mkU32(0x0));
7426   s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
7427   next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7428
7429 done:
7430   return "pfpo";
7431}
7432
7433static const HChar *
7434s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7435{
7436   IRTemp amount = newTemp(Ity_I64);
7437   IRTemp op = newTemp(Ity_I32);
7438
7439   assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7440   assign(op, get_gpr_w1(r3));
7441   put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7442              mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7443              binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7444
7445   return "rll";
7446}
7447
7448static const HChar *
7449s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7450{
7451   IRTemp amount = newTemp(Ity_I64);
7452   IRTemp op = newTemp(Ity_I64);
7453
7454   assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7455   assign(op, get_gpr_dw0(r3));
7456   put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7457               mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7458               binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7459
7460   return "rllg";
7461}
7462
7463static const HChar *
7464s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7465{
7466   UChar from;
7467   UChar to;
7468   UChar rot;
7469   UChar t_bit;
7470   ULong mask;
7471   ULong maskc;
7472   IRTemp result = newTemp(Ity_I64);
7473   IRTemp op2 = newTemp(Ity_I64);
7474
7475   from = i3 & 63;
7476   to = i4 & 63;
7477   rot = i5 & 63;
7478   t_bit = i3 & 128;
7479   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7480          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7481          mkU8(64 - rot))));
7482   if (from <= to) {
7483      mask = ~0ULL;
7484      mask = (mask >> from) & (mask << (63 - to));
7485      maskc = ~mask;
7486   } else {
7487      maskc = ~0ULL;
7488      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7489      mask = ~maskc;
7490   }
7491   assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7492          ), mkU64(mask)));
7493   if (t_bit == 0) {
7494      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7495                  mkU64(maskc)), mkexpr(result)));
7496   }
7497   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7498
7499   return "rnsbg";
7500}
7501
7502static const HChar *
7503s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7504{
7505   UChar from;
7506   UChar to;
7507   UChar rot;
7508   UChar t_bit;
7509   ULong mask;
7510   ULong maskc;
7511   IRTemp result = newTemp(Ity_I64);
7512   IRTemp op2 = newTemp(Ity_I64);
7513
7514   from = i3 & 63;
7515   to = i4 & 63;
7516   rot = i5 & 63;
7517   t_bit = i3 & 128;
7518   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7519          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7520          mkU8(64 - rot))));
7521   if (from <= to) {
7522      mask = ~0ULL;
7523      mask = (mask >> from) & (mask << (63 - to));
7524      maskc = ~mask;
7525   } else {
7526      maskc = ~0ULL;
7527      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7528      mask = ~maskc;
7529   }
7530   assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7531          ), mkU64(mask)));
7532   if (t_bit == 0) {
7533      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7534                  mkU64(maskc)), mkexpr(result)));
7535   }
7536   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7537
7538   return "rxsbg";
7539}
7540
7541static const HChar *
7542s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7543{
7544   UChar from;
7545   UChar to;
7546   UChar rot;
7547   UChar t_bit;
7548   ULong mask;
7549   ULong maskc;
7550   IRTemp result = newTemp(Ity_I64);
7551   IRTemp op2 = newTemp(Ity_I64);
7552
7553   from = i3 & 63;
7554   to = i4 & 63;
7555   rot = i5 & 63;
7556   t_bit = i3 & 128;
7557   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7558          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7559          mkU8(64 - rot))));
7560   if (from <= to) {
7561      mask = ~0ULL;
7562      mask = (mask >> from) & (mask << (63 - to));
7563      maskc = ~mask;
7564   } else {
7565      maskc = ~0ULL;
7566      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7567      mask = ~maskc;
7568   }
7569   assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7570          ), mkU64(mask)));
7571   if (t_bit == 0) {
7572      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7573                  mkU64(maskc)), mkexpr(result)));
7574   }
7575   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7576
7577   return "rosbg";
7578}
7579
7580static const HChar *
7581s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7582{
7583   UChar from;
7584   UChar to;
7585   UChar rot;
7586   UChar z_bit;
7587   ULong mask;
7588   ULong maskc;
7589   IRTemp op2 = newTemp(Ity_I64);
7590   IRTemp result = newTemp(Ity_I64);
7591
7592   from = i3 & 63;
7593   to = i4 & 63;
7594   rot = i5 & 63;
7595   z_bit = i4 & 128;
7596   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7597          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7598          mkU8(64 - rot))));
7599   if (from <= to) {
7600      mask = ~0ULL;
7601      mask = (mask >> from) & (mask << (63 - to));
7602      maskc = ~mask;
7603   } else {
7604      maskc = ~0ULL;
7605      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7606      mask = ~maskc;
7607   }
7608   if (z_bit == 0) {
7609      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7610                  mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7611   } else {
7612      put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7613   }
7614   assign(result, get_gpr_dw0(r1));
7615   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7616
7617   return "risbg";
7618}
7619
7620static const HChar *
7621s390_irgen_SAR(UChar r1, UChar r2)
7622{
7623   put_ar_w0(r1, get_gpr_w1(r2));
7624   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
7625      s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7626
7627   return "sar";
7628}
7629
7630static const HChar *
7631s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7632{
7633   IRTemp p1 = newTemp(Ity_I64);
7634   IRTemp p2 = newTemp(Ity_I64);
7635   IRTemp op = newTemp(Ity_I64);
7636   IRTemp result = newTemp(Ity_I64);
7637   ULong sign_mask;
7638   IRTemp shift_amount = newTemp(Ity_I64);
7639
7640   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7641   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7642   assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7643          ));
7644   sign_mask = 1ULL << 63;
7645   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7646   assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
7647          unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7648          binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
7649   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7650   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7651   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7652
7653   return "slda";
7654}
7655
7656static const HChar *
7657s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7658{
7659   IRTemp p1 = newTemp(Ity_I64);
7660   IRTemp p2 = newTemp(Ity_I64);
7661   IRTemp result = newTemp(Ity_I64);
7662
7663   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7664   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7665   assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7666          mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7667          mkexpr(op2addr), mkU64(63)))));
7668   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7669   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7670
7671   return "sldl";
7672}
7673
7674static const HChar *
7675s390_irgen_SLA(UChar r1, IRTemp op2addr)
7676{
7677   IRTemp uop = newTemp(Ity_I32);
7678   IRTemp result = newTemp(Ity_I32);
7679   UInt sign_mask;
7680   IRTemp shift_amount = newTemp(Ity_I64);
7681   IRTemp op = newTemp(Ity_I32);
7682
7683   assign(op, get_gpr_w1(r1));
7684   assign(uop, get_gpr_w1(r1));
7685   sign_mask = 2147483648U;
7686   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7687   assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7688          unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7689          binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7690   put_gpr_w1(r1, mkexpr(result));
7691   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7692
7693   return "sla";
7694}
7695
7696static const HChar *
7697s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7698{
7699   IRTemp uop = newTemp(Ity_I32);
7700   IRTemp result = newTemp(Ity_I32);
7701   UInt sign_mask;
7702   IRTemp shift_amount = newTemp(Ity_I64);
7703   IRTemp op = newTemp(Ity_I32);
7704
7705   assign(op, get_gpr_w1(r3));
7706   assign(uop, get_gpr_w1(r3));
7707   sign_mask = 2147483648U;
7708   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7709   assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7710          unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7711          binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7712   put_gpr_w1(r1, mkexpr(result));
7713   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7714
7715   return "slak";
7716}
7717
7718static const HChar *
7719s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7720{
7721   IRTemp uop = newTemp(Ity_I64);
7722   IRTemp result = newTemp(Ity_I64);
7723   ULong sign_mask;
7724   IRTemp shift_amount = newTemp(Ity_I64);
7725   IRTemp op = newTemp(Ity_I64);
7726
7727   assign(op, get_gpr_dw0(r3));
7728   assign(uop, get_gpr_dw0(r3));
7729   sign_mask = 9223372036854775808ULL;
7730   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7731   assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7732          unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7733          binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7734   put_gpr_dw0(r1, mkexpr(result));
7735   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7736
7737   return "slag";
7738}
7739
7740static const HChar *
7741s390_irgen_SLL(UChar r1, IRTemp op2addr)
7742{
7743   put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7744              binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7745
7746   return "sll";
7747}
7748
7749static const HChar *
7750s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7751{
7752   put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7753              binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7754
7755   return "sllk";
7756}
7757
7758static const HChar *
7759s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7760{
7761   put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7762               binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7763
7764   return "sllg";
7765}
7766
7767static const HChar *
7768s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7769{
7770   IRTemp p1 = newTemp(Ity_I64);
7771   IRTemp p2 = newTemp(Ity_I64);
7772   IRTemp result = newTemp(Ity_I64);
7773
7774   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7775   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7776   assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7777          mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7778          mkexpr(op2addr), mkU64(63)))));
7779   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7780   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7781   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7782
7783   return "srda";
7784}
7785
7786static const HChar *
7787s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7788{
7789   IRTemp p1 = newTemp(Ity_I64);
7790   IRTemp p2 = newTemp(Ity_I64);
7791   IRTemp result = newTemp(Ity_I64);
7792
7793   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7794   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7795   assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7796          mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7797          mkexpr(op2addr), mkU64(63)))));
7798   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7799   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7800
7801   return "srdl";
7802}
7803
7804static const HChar *
7805s390_irgen_SRA(UChar r1, IRTemp op2addr)
7806{
7807   IRTemp result = newTemp(Ity_I32);
7808   IRTemp op = newTemp(Ity_I32);
7809
7810   assign(op, get_gpr_w1(r1));
7811   assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7812          mkexpr(op2addr), mkU64(63)))));
7813   put_gpr_w1(r1, mkexpr(result));
7814   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7815
7816   return "sra";
7817}
7818
7819static const HChar *
7820s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7821{
7822   IRTemp result = newTemp(Ity_I32);
7823   IRTemp op = newTemp(Ity_I32);
7824
7825   assign(op, get_gpr_w1(r3));
7826   assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7827          mkexpr(op2addr), mkU64(63)))));
7828   put_gpr_w1(r1, mkexpr(result));
7829   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7830
7831   return "srak";
7832}
7833
7834static const HChar *
7835s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7836{
7837   IRTemp result = newTemp(Ity_I64);
7838   IRTemp op = newTemp(Ity_I64);
7839
7840   assign(op, get_gpr_dw0(r3));
7841   assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7842          mkexpr(op2addr), mkU64(63)))));
7843   put_gpr_dw0(r1, mkexpr(result));
7844   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7845
7846   return "srag";
7847}
7848
7849static const HChar *
7850s390_irgen_SRL(UChar r1, IRTemp op2addr)
7851{
7852   IRTemp op = newTemp(Ity_I32);
7853
7854   assign(op, get_gpr_w1(r1));
7855   put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7856              mkexpr(op2addr), mkU64(63)))));
7857
7858   return "srl";
7859}
7860
7861static const HChar *
7862s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7863{
7864   IRTemp op = newTemp(Ity_I32);
7865
7866   assign(op, get_gpr_w1(r3));
7867   put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7868              mkexpr(op2addr), mkU64(63)))));
7869
7870   return "srlk";
7871}
7872
7873static const HChar *
7874s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7875{
7876   IRTemp op = newTemp(Ity_I64);
7877
7878   assign(op, get_gpr_dw0(r3));
7879   put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7880               mkexpr(op2addr), mkU64(63)))));
7881
7882   return "srlg";
7883}
7884
7885static const HChar *
7886s390_irgen_ST(UChar r1, IRTemp op2addr)
7887{
7888   store(mkexpr(op2addr), get_gpr_w1(r1));
7889
7890   return "st";
7891}
7892
7893static const HChar *
7894s390_irgen_STY(UChar r1, IRTemp op2addr)
7895{
7896   store(mkexpr(op2addr), get_gpr_w1(r1));
7897
7898   return "sty";
7899}
7900
7901static const HChar *
7902s390_irgen_STG(UChar r1, IRTemp op2addr)
7903{
7904   store(mkexpr(op2addr), get_gpr_dw0(r1));
7905
7906   return "stg";
7907}
7908
7909static const HChar *
7910s390_irgen_STRL(UChar r1, UInt i2)
7911{
7912   store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7913         get_gpr_w1(r1));
7914
7915   return "strl";
7916}
7917
7918static const HChar *
7919s390_irgen_STGRL(UChar r1, UInt i2)
7920{
7921   store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7922         get_gpr_dw0(r1));
7923
7924   return "stgrl";
7925}
7926
7927static const HChar *
7928s390_irgen_STC(UChar r1, IRTemp op2addr)
7929{
7930   store(mkexpr(op2addr), get_gpr_b7(r1));
7931
7932   return "stc";
7933}
7934
7935static const HChar *
7936s390_irgen_STCY(UChar r1, IRTemp op2addr)
7937{
7938   store(mkexpr(op2addr), get_gpr_b7(r1));
7939
7940   return "stcy";
7941}
7942
7943static const HChar *
7944s390_irgen_STCH(UChar r1, IRTemp op2addr)
7945{
7946   store(mkexpr(op2addr), get_gpr_b3(r1));
7947
7948   return "stch";
7949}
7950
7951static const HChar *
7952s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7953{
7954   UChar mask;
7955   UChar n;
7956
7957   mask = (UChar)r3;
7958   n = 0;
7959   if ((mask & 8) != 0) {
7960      store(mkexpr(op2addr), get_gpr_b4(r1));
7961      n = n + 1;
7962   }
7963   if ((mask & 4) != 0) {
7964      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7965      n = n + 1;
7966   }
7967   if ((mask & 2) != 0) {
7968      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7969      n = n + 1;
7970   }
7971   if ((mask & 1) != 0) {
7972      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7973   }
7974
7975   return "stcm";
7976}
7977
7978static const HChar *
7979s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7980{
7981   UChar mask;
7982   UChar n;
7983
7984   mask = (UChar)r3;
7985   n = 0;
7986   if ((mask & 8) != 0) {
7987      store(mkexpr(op2addr), get_gpr_b4(r1));
7988      n = n + 1;
7989   }
7990   if ((mask & 4) != 0) {
7991      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7992      n = n + 1;
7993   }
7994   if ((mask & 2) != 0) {
7995      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7996      n = n + 1;
7997   }
7998   if ((mask & 1) != 0) {
7999      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
8000   }
8001
8002   return "stcmy";
8003}
8004
8005static const HChar *
8006s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
8007{
8008   UChar mask;
8009   UChar n;
8010
8011   mask = (UChar)r3;
8012   n = 0;
8013   if ((mask & 8) != 0) {
8014      store(mkexpr(op2addr), get_gpr_b0(r1));
8015      n = n + 1;
8016   }
8017   if ((mask & 4) != 0) {
8018      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
8019      n = n + 1;
8020   }
8021   if ((mask & 2) != 0) {
8022      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
8023      n = n + 1;
8024   }
8025   if ((mask & 1) != 0) {
8026      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
8027   }
8028
8029   return "stcmh";
8030}
8031
8032static const HChar *
8033s390_irgen_STH(UChar r1, IRTemp op2addr)
8034{
8035   store(mkexpr(op2addr), get_gpr_hw3(r1));
8036
8037   return "sth";
8038}
8039
8040static const HChar *
8041s390_irgen_STHY(UChar r1, IRTemp op2addr)
8042{
8043   store(mkexpr(op2addr), get_gpr_hw3(r1));
8044
8045   return "sthy";
8046}
8047
8048static const HChar *
8049s390_irgen_STHRL(UChar r1, UInt i2)
8050{
8051   store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8052         get_gpr_hw3(r1));
8053
8054   return "sthrl";
8055}
8056
8057static const HChar *
8058s390_irgen_STHH(UChar r1, IRTemp op2addr)
8059{
8060   store(mkexpr(op2addr), get_gpr_hw1(r1));
8061
8062   return "sthh";
8063}
8064
8065static const HChar *
8066s390_irgen_STFH(UChar r1, IRTemp op2addr)
8067{
8068   store(mkexpr(op2addr), get_gpr_w0(r1));
8069
8070   return "stfh";
8071}
8072
8073static const HChar *
8074s390_irgen_STOC(UChar r1, IRTemp op2addr)
8075{
8076   /* condition is checked in format handler */
8077   store(mkexpr(op2addr), get_gpr_w1(r1));
8078
8079   return "stoc";
8080}
8081
8082static const HChar *
8083s390_irgen_STOCG(UChar r1, IRTemp op2addr)
8084{
8085   /* condition is checked in format handler */
8086   store(mkexpr(op2addr), get_gpr_dw0(r1));
8087
8088   return "stocg";
8089}
8090
8091static const HChar *
8092s390_irgen_STPQ(UChar r1, IRTemp op2addr)
8093{
8094   store(mkexpr(op2addr), get_gpr_dw0(r1));
8095   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
8096
8097   return "stpq";
8098}
8099
8100static const HChar *
8101s390_irgen_STRVH(UChar r1, IRTemp op2addr)
8102{
8103   store(mkexpr(op2addr), get_gpr_b7(r1));
8104   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8105
8106   return "strvh";
8107}
8108
8109static const HChar *
8110s390_irgen_STRV(UChar r1, IRTemp op2addr)
8111{
8112   store(mkexpr(op2addr), get_gpr_b7(r1));
8113   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8114   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8115   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8116
8117   return "strv";
8118}
8119
8120static const HChar *
8121s390_irgen_STRVG(UChar r1, IRTemp op2addr)
8122{
8123   store(mkexpr(op2addr), get_gpr_b7(r1));
8124   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8125   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8126   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8127   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
8128   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
8129   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
8130   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
8131
8132   return "strvg";
8133}
8134
8135static const HChar *
8136s390_irgen_SR(UChar r1, UChar r2)
8137{
8138   IRTemp op1 = newTemp(Ity_I32);
8139   IRTemp op2 = newTemp(Ity_I32);
8140   IRTemp result = newTemp(Ity_I32);
8141
8142   assign(op1, get_gpr_w1(r1));
8143   assign(op2, get_gpr_w1(r2));
8144   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8145   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8146   put_gpr_w1(r1, mkexpr(result));
8147
8148   return "sr";
8149}
8150
8151static const HChar *
8152s390_irgen_SGR(UChar r1, UChar r2)
8153{
8154   IRTemp op1 = newTemp(Ity_I64);
8155   IRTemp op2 = newTemp(Ity_I64);
8156   IRTemp result = newTemp(Ity_I64);
8157
8158   assign(op1, get_gpr_dw0(r1));
8159   assign(op2, get_gpr_dw0(r2));
8160   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8161   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8162   put_gpr_dw0(r1, mkexpr(result));
8163
8164   return "sgr";
8165}
8166
8167static const HChar *
8168s390_irgen_SGFR(UChar r1, UChar r2)
8169{
8170   IRTemp op1 = newTemp(Ity_I64);
8171   IRTemp op2 = newTemp(Ity_I64);
8172   IRTemp result = newTemp(Ity_I64);
8173
8174   assign(op1, get_gpr_dw0(r1));
8175   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8176   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8177   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8178   put_gpr_dw0(r1, mkexpr(result));
8179
8180   return "sgfr";
8181}
8182
8183static const HChar *
8184s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8185{
8186   IRTemp op2 = newTemp(Ity_I32);
8187   IRTemp op3 = newTemp(Ity_I32);
8188   IRTemp result = newTemp(Ity_I32);
8189
8190   assign(op2, get_gpr_w1(r2));
8191   assign(op3, get_gpr_w1(r3));
8192   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8193   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8194   put_gpr_w1(r1, mkexpr(result));
8195
8196   return "srk";
8197}
8198
8199static const HChar *
8200s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8201{
8202   IRTemp op2 = newTemp(Ity_I64);
8203   IRTemp op3 = newTemp(Ity_I64);
8204   IRTemp result = newTemp(Ity_I64);
8205
8206   assign(op2, get_gpr_dw0(r2));
8207   assign(op3, get_gpr_dw0(r3));
8208   assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8209   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8210   put_gpr_dw0(r1, mkexpr(result));
8211
8212   return "sgrk";
8213}
8214
8215static const HChar *
8216s390_irgen_S(UChar r1, IRTemp op2addr)
8217{
8218   IRTemp op1 = newTemp(Ity_I32);
8219   IRTemp op2 = newTemp(Ity_I32);
8220   IRTemp result = newTemp(Ity_I32);
8221
8222   assign(op1, get_gpr_w1(r1));
8223   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8224   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8225   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8226   put_gpr_w1(r1, mkexpr(result));
8227
8228   return "s";
8229}
8230
8231static const HChar *
8232s390_irgen_SY(UChar r1, IRTemp op2addr)
8233{
8234   IRTemp op1 = newTemp(Ity_I32);
8235   IRTemp op2 = newTemp(Ity_I32);
8236   IRTemp result = newTemp(Ity_I32);
8237
8238   assign(op1, get_gpr_w1(r1));
8239   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8240   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8241   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8242   put_gpr_w1(r1, mkexpr(result));
8243
8244   return "sy";
8245}
8246
8247static const HChar *
8248s390_irgen_SG(UChar r1, IRTemp op2addr)
8249{
8250   IRTemp op1 = newTemp(Ity_I64);
8251   IRTemp op2 = newTemp(Ity_I64);
8252   IRTemp result = newTemp(Ity_I64);
8253
8254   assign(op1, get_gpr_dw0(r1));
8255   assign(op2, load(Ity_I64, mkexpr(op2addr)));
8256   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8257   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8258   put_gpr_dw0(r1, mkexpr(result));
8259
8260   return "sg";
8261}
8262
8263static const HChar *
8264s390_irgen_SGF(UChar r1, IRTemp op2addr)
8265{
8266   IRTemp op1 = newTemp(Ity_I64);
8267   IRTemp op2 = newTemp(Ity_I64);
8268   IRTemp result = newTemp(Ity_I64);
8269
8270   assign(op1, get_gpr_dw0(r1));
8271   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8272   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8273   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8274   put_gpr_dw0(r1, mkexpr(result));
8275
8276   return "sgf";
8277}
8278
8279static const HChar *
8280s390_irgen_SH(UChar r1, IRTemp op2addr)
8281{
8282   IRTemp op1 = newTemp(Ity_I32);
8283   IRTemp op2 = newTemp(Ity_I32);
8284   IRTemp result = newTemp(Ity_I32);
8285
8286   assign(op1, get_gpr_w1(r1));
8287   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8288   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8289   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8290   put_gpr_w1(r1, mkexpr(result));
8291
8292   return "sh";
8293}
8294
8295static const HChar *
8296s390_irgen_SHY(UChar r1, IRTemp op2addr)
8297{
8298   IRTemp op1 = newTemp(Ity_I32);
8299   IRTemp op2 = newTemp(Ity_I32);
8300   IRTemp result = newTemp(Ity_I32);
8301
8302   assign(op1, get_gpr_w1(r1));
8303   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8304   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8305   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8306   put_gpr_w1(r1, mkexpr(result));
8307
8308   return "shy";
8309}
8310
8311static const HChar *
8312s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8313{
8314   IRTemp op2 = newTemp(Ity_I32);
8315   IRTemp op3 = newTemp(Ity_I32);
8316   IRTemp result = newTemp(Ity_I32);
8317
8318   assign(op2, get_gpr_w0(r1));
8319   assign(op3, get_gpr_w0(r2));
8320   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8321   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8322   put_gpr_w0(r1, mkexpr(result));
8323
8324   return "shhhr";
8325}
8326
8327static const HChar *
8328s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8329{
8330   IRTemp op2 = newTemp(Ity_I32);
8331   IRTemp op3 = newTemp(Ity_I32);
8332   IRTemp result = newTemp(Ity_I32);
8333
8334   assign(op2, get_gpr_w0(r1));
8335   assign(op3, get_gpr_w1(r2));
8336   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8337   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8338   put_gpr_w0(r1, mkexpr(result));
8339
8340   return "shhlr";
8341}
8342
8343static const HChar *
8344s390_irgen_SLR(UChar r1, UChar r2)
8345{
8346   IRTemp op1 = newTemp(Ity_I32);
8347   IRTemp op2 = newTemp(Ity_I32);
8348   IRTemp result = newTemp(Ity_I32);
8349
8350   assign(op1, get_gpr_w1(r1));
8351   assign(op2, get_gpr_w1(r2));
8352   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8353   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8354   put_gpr_w1(r1, mkexpr(result));
8355
8356   return "slr";
8357}
8358
8359static const HChar *
8360s390_irgen_SLGR(UChar r1, UChar r2)
8361{
8362   IRTemp op1 = newTemp(Ity_I64);
8363   IRTemp op2 = newTemp(Ity_I64);
8364   IRTemp result = newTemp(Ity_I64);
8365
8366   assign(op1, get_gpr_dw0(r1));
8367   assign(op2, get_gpr_dw0(r2));
8368   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8369   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8370   put_gpr_dw0(r1, mkexpr(result));
8371
8372   return "slgr";
8373}
8374
8375static const HChar *
8376s390_irgen_SLGFR(UChar r1, UChar r2)
8377{
8378   IRTemp op1 = newTemp(Ity_I64);
8379   IRTemp op2 = newTemp(Ity_I64);
8380   IRTemp result = newTemp(Ity_I64);
8381
8382   assign(op1, get_gpr_dw0(r1));
8383   assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8384   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8385   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8386   put_gpr_dw0(r1, mkexpr(result));
8387
8388   return "slgfr";
8389}
8390
8391static const HChar *
8392s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8393{
8394   IRTemp op2 = newTemp(Ity_I32);
8395   IRTemp op3 = newTemp(Ity_I32);
8396   IRTemp result = newTemp(Ity_I32);
8397
8398   assign(op2, get_gpr_w1(r2));
8399   assign(op3, get_gpr_w1(r3));
8400   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8401   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8402   put_gpr_w1(r1, mkexpr(result));
8403
8404   return "slrk";
8405}
8406
8407static const HChar *
8408s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8409{
8410   IRTemp op2 = newTemp(Ity_I64);
8411   IRTemp op3 = newTemp(Ity_I64);
8412   IRTemp result = newTemp(Ity_I64);
8413
8414   assign(op2, get_gpr_dw0(r2));
8415   assign(op3, get_gpr_dw0(r3));
8416   assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8417   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8418   put_gpr_dw0(r1, mkexpr(result));
8419
8420   return "slgrk";
8421}
8422
8423static const HChar *
8424s390_irgen_SL(UChar r1, IRTemp op2addr)
8425{
8426   IRTemp op1 = newTemp(Ity_I32);
8427   IRTemp op2 = newTemp(Ity_I32);
8428   IRTemp result = newTemp(Ity_I32);
8429
8430   assign(op1, get_gpr_w1(r1));
8431   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8432   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8433   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8434   put_gpr_w1(r1, mkexpr(result));
8435
8436   return "sl";
8437}
8438
8439static const HChar *
8440s390_irgen_SLY(UChar r1, IRTemp op2addr)
8441{
8442   IRTemp op1 = newTemp(Ity_I32);
8443   IRTemp op2 = newTemp(Ity_I32);
8444   IRTemp result = newTemp(Ity_I32);
8445
8446   assign(op1, get_gpr_w1(r1));
8447   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8448   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8449   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8450   put_gpr_w1(r1, mkexpr(result));
8451
8452   return "sly";
8453}
8454
8455static const HChar *
8456s390_irgen_SLG(UChar r1, IRTemp op2addr)
8457{
8458   IRTemp op1 = newTemp(Ity_I64);
8459   IRTemp op2 = newTemp(Ity_I64);
8460   IRTemp result = newTemp(Ity_I64);
8461
8462   assign(op1, get_gpr_dw0(r1));
8463   assign(op2, load(Ity_I64, mkexpr(op2addr)));
8464   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8465   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8466   put_gpr_dw0(r1, mkexpr(result));
8467
8468   return "slg";
8469}
8470
8471static const HChar *
8472s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8473{
8474   IRTemp op1 = newTemp(Ity_I64);
8475   IRTemp op2 = newTemp(Ity_I64);
8476   IRTemp result = newTemp(Ity_I64);
8477
8478   assign(op1, get_gpr_dw0(r1));
8479   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8480   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8481   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8482   put_gpr_dw0(r1, mkexpr(result));
8483
8484   return "slgf";
8485}
8486
8487static const HChar *
8488s390_irgen_SLFI(UChar r1, UInt i2)
8489{
8490   IRTemp op1 = newTemp(Ity_I32);
8491   UInt op2;
8492   IRTemp result = newTemp(Ity_I32);
8493
8494   assign(op1, get_gpr_w1(r1));
8495   op2 = i2;
8496   assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8497   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8498                       mkU32(op2)));
8499   put_gpr_w1(r1, mkexpr(result));
8500
8501   return "slfi";
8502}
8503
8504static const HChar *
8505s390_irgen_SLGFI(UChar r1, UInt i2)
8506{
8507   IRTemp op1 = newTemp(Ity_I64);
8508   ULong op2;
8509   IRTemp result = newTemp(Ity_I64);
8510
8511   assign(op1, get_gpr_dw0(r1));
8512   op2 = (ULong)i2;
8513   assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8514   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8515                       mkU64(op2)));
8516   put_gpr_dw0(r1, mkexpr(result));
8517
8518   return "slgfi";
8519}
8520
8521static const HChar *
8522s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8523{
8524   IRTemp op2 = newTemp(Ity_I32);
8525   IRTemp op3 = newTemp(Ity_I32);
8526   IRTemp result = newTemp(Ity_I32);
8527
8528   assign(op2, get_gpr_w0(r1));
8529   assign(op3, get_gpr_w0(r2));
8530   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8531   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8532   put_gpr_w0(r1, mkexpr(result));
8533
8534   return "slhhhr";
8535}
8536
8537static const HChar *
8538s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8539{
8540   IRTemp op2 = newTemp(Ity_I32);
8541   IRTemp op3 = newTemp(Ity_I32);
8542   IRTemp result = newTemp(Ity_I32);
8543
8544   assign(op2, get_gpr_w0(r1));
8545   assign(op3, get_gpr_w1(r2));
8546   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8547   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8548   put_gpr_w0(r1, mkexpr(result));
8549
8550   return "slhhlr";
8551}
8552
8553static const HChar *
8554s390_irgen_SLBR(UChar r1, UChar r2)
8555{
8556   IRTemp op1 = newTemp(Ity_I32);
8557   IRTemp op2 = newTemp(Ity_I32);
8558   IRTemp result = newTemp(Ity_I32);
8559   IRTemp borrow_in = newTemp(Ity_I32);
8560
8561   assign(op1, get_gpr_w1(r1));
8562   assign(op2, get_gpr_w1(r2));
8563   assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8564          s390_call_calculate_cc(), mkU8(1))));
8565   assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8566          mkexpr(borrow_in)));
8567   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8568   put_gpr_w1(r1, mkexpr(result));
8569
8570   return "slbr";
8571}
8572
8573static const HChar *
8574s390_irgen_SLBGR(UChar r1, UChar r2)
8575{
8576   IRTemp op1 = newTemp(Ity_I64);
8577   IRTemp op2 = newTemp(Ity_I64);
8578   IRTemp result = newTemp(Ity_I64);
8579   IRTemp borrow_in = newTemp(Ity_I64);
8580
8581   assign(op1, get_gpr_dw0(r1));
8582   assign(op2, get_gpr_dw0(r2));
8583   assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8584          binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8585   assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8586          mkexpr(borrow_in)));
8587   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8588   put_gpr_dw0(r1, mkexpr(result));
8589
8590   return "slbgr";
8591}
8592
8593static const HChar *
8594s390_irgen_SLB(UChar r1, IRTemp op2addr)
8595{
8596   IRTemp op1 = newTemp(Ity_I32);
8597   IRTemp op2 = newTemp(Ity_I32);
8598   IRTemp result = newTemp(Ity_I32);
8599   IRTemp borrow_in = newTemp(Ity_I32);
8600
8601   assign(op1, get_gpr_w1(r1));
8602   assign(op2, load(Ity_I32, mkexpr(op2addr)));
8603   assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8604          s390_call_calculate_cc(), mkU8(1))));
8605   assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8606          mkexpr(borrow_in)));
8607   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8608   put_gpr_w1(r1, mkexpr(result));
8609
8610   return "slb";
8611}
8612
8613static const HChar *
8614s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8615{
8616   IRTemp op1 = newTemp(Ity_I64);
8617   IRTemp op2 = newTemp(Ity_I64);
8618   IRTemp result = newTemp(Ity_I64);
8619   IRTemp borrow_in = newTemp(Ity_I64);
8620
8621   assign(op1, get_gpr_dw0(r1));
8622   assign(op2, load(Ity_I64, mkexpr(op2addr)));
8623   assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8624          binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8625   assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8626          mkexpr(borrow_in)));
8627   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8628   put_gpr_dw0(r1, mkexpr(result));
8629
8630   return "slbg";
8631}
8632
8633static const HChar *
8634s390_irgen_SVC(UChar i)
8635{
8636   IRTemp sysno = newTemp(Ity_I64);
8637
8638   if (i != 0) {
8639      assign(sysno, mkU64(i));
8640   } else {
8641      assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8642   }
8643   system_call(mkexpr(sysno));
8644
8645   return "svc";
8646}
8647
8648static const HChar *
8649s390_irgen_TM(UChar i2, IRTemp op1addr)
8650{
8651   UChar mask;
8652   IRTemp value = newTemp(Ity_I8);
8653
8654   mask = i2;
8655   assign(value, load(Ity_I8, mkexpr(op1addr)));
8656   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8657                       mkU8(mask)));
8658
8659   return "tm";
8660}
8661
8662static const HChar *
8663s390_irgen_TMY(UChar i2, IRTemp op1addr)
8664{
8665   UChar mask;
8666   IRTemp value = newTemp(Ity_I8);
8667
8668   mask = i2;
8669   assign(value, load(Ity_I8, mkexpr(op1addr)));
8670   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8671                       mkU8(mask)));
8672
8673   return "tmy";
8674}
8675
8676static const HChar *
8677s390_irgen_TMHH(UChar r1, UShort i2)
8678{
8679   UShort mask;
8680   IRTemp value = newTemp(Ity_I16);
8681
8682   mask = i2;
8683   assign(value, get_gpr_hw0(r1));
8684   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8685                       mkU16(mask)));
8686
8687   return "tmhh";
8688}
8689
8690static const HChar *
8691s390_irgen_TMHL(UChar r1, UShort i2)
8692{
8693   UShort mask;
8694   IRTemp value = newTemp(Ity_I16);
8695
8696   mask = i2;
8697   assign(value, get_gpr_hw1(r1));
8698   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8699                       mkU16(mask)));
8700
8701   return "tmhl";
8702}
8703
8704static const HChar *
8705s390_irgen_TMLH(UChar r1, UShort i2)
8706{
8707   UShort mask;
8708   IRTemp value = newTemp(Ity_I16);
8709
8710   mask = i2;
8711   assign(value, get_gpr_hw2(r1));
8712   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8713                       mkU16(mask)));
8714
8715   return "tmlh";
8716}
8717
8718static const HChar *
8719s390_irgen_TMLL(UChar r1, UShort i2)
8720{
8721   UShort mask;
8722   IRTemp value = newTemp(Ity_I16);
8723
8724   mask = i2;
8725   assign(value, get_gpr_hw3(r1));
8726   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8727                       mkU16(mask)));
8728
8729   return "tmll";
8730}
8731
8732static const HChar *
8733s390_irgen_EFPC(UChar r1)
8734{
8735   put_gpr_w1(r1, get_fpc_w0());
8736
8737   return "efpc";
8738}
8739
8740static const HChar *
8741s390_irgen_LER(UChar r1, UChar r2)
8742{
8743   put_fpr_w0(r1, get_fpr_w0(r2));
8744
8745   return "ler";
8746}
8747
8748static const HChar *
8749s390_irgen_LDR(UChar r1, UChar r2)
8750{
8751   put_fpr_dw0(r1, get_fpr_dw0(r2));
8752
8753   return "ldr";
8754}
8755
8756static const HChar *
8757s390_irgen_LXR(UChar r1, UChar r2)
8758{
8759   put_fpr_dw0(r1, get_fpr_dw0(r2));
8760   put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8761
8762   return "lxr";
8763}
8764
8765static const HChar *
8766s390_irgen_LE(UChar r1, IRTemp op2addr)
8767{
8768   put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8769
8770   return "le";
8771}
8772
8773static const HChar *
8774s390_irgen_LD(UChar r1, IRTemp op2addr)
8775{
8776   put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8777
8778   return "ld";
8779}
8780
8781static const HChar *
8782s390_irgen_LEY(UChar r1, IRTemp op2addr)
8783{
8784   put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8785
8786   return "ley";
8787}
8788
8789static const HChar *
8790s390_irgen_LDY(UChar r1, IRTemp op2addr)
8791{
8792   put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8793
8794   return "ldy";
8795}
8796
8797static const HChar *
8798s390_irgen_LFPC(IRTemp op2addr)
8799{
8800   put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8801
8802   return "lfpc";
8803}
8804
8805static const HChar *
8806s390_irgen_LZER(UChar r1)
8807{
8808   put_fpr_w0(r1, mkF32i(0x0));
8809
8810   return "lzer";
8811}
8812
8813static const HChar *
8814s390_irgen_LZDR(UChar r1)
8815{
8816   put_fpr_dw0(r1, mkF64i(0x0));
8817
8818   return "lzdr";
8819}
8820
8821static const HChar *
8822s390_irgen_LZXR(UChar r1)
8823{
8824   put_fpr_dw0(r1, mkF64i(0x0));
8825   put_fpr_dw0(r1 + 2, mkF64i(0x0));
8826
8827   return "lzxr";
8828}
8829
8830static const HChar *
8831s390_irgen_SRNM(IRTemp op2addr)
8832{
8833   UInt input_mask, fpc_mask;
8834
8835   input_mask = 3;
8836   fpc_mask = s390_host_has_fpext ? 7 : 3;
8837
8838   put_fpc_w0(binop(Iop_Or32,
8839                    binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8840                    binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8841                          mkU32(input_mask))));
8842   return "srnm";
8843}
8844
8845static const HChar *
8846s390_irgen_SRNMB(IRTemp op2addr)
8847{
8848   UInt input_mask, fpc_mask;
8849
8850   input_mask = 7;
8851   fpc_mask = 7;
8852
8853   put_fpc_w0(binop(Iop_Or32,
8854                    binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8855                    binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8856                          mkU32(input_mask))));
8857   return "srnmb";
8858}
8859
8860static void
8861s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8862{
8863   if (b2 == 0) {  /* This is the typical case */
8864      if (d2 > 3) {
8865         if (s390_host_has_fpext && d2 == 7) {
8866            /* ok */
8867         } else {
8868            emulation_warning(EmWarn_S390X_invalid_rounding);
8869            d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
8870         }
8871      }
8872   }
8873
8874   s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8875}
8876
8877/* Wrapper to validate the parameter as in SRNMB is not required, as all
8878   the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8879static const HChar *
8880s390_irgen_SRNMT(IRTemp op2addr)
8881{
8882   UInt input_mask, fpc_mask;
8883
8884   input_mask = 7;
8885   fpc_mask = 0x70;
8886
8887   /* fpc[25:27] <- op2addr[61:63]
8888      fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8889   put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8890                    binop(Iop_Shl32, binop(Iop_And32,
8891                                           unop(Iop_64to32, mkexpr(op2addr)),
8892                                           mkU32(input_mask)), mkU8(4))));
8893   return "srnmt";
8894}
8895
8896
8897static const HChar *
8898s390_irgen_SFPC(UChar r1)
8899{
8900   put_fpc_w0(get_gpr_w1(r1));
8901
8902   return "sfpc";
8903}
8904
8905static const HChar *
8906s390_irgen_STE(UChar r1, IRTemp op2addr)
8907{
8908   store(mkexpr(op2addr), get_fpr_w0(r1));
8909
8910   return "ste";
8911}
8912
8913static const HChar *
8914s390_irgen_STD(UChar r1, IRTemp op2addr)
8915{
8916   store(mkexpr(op2addr), get_fpr_dw0(r1));
8917
8918   return "std";
8919}
8920
8921static const HChar *
8922s390_irgen_STEY(UChar r1, IRTemp op2addr)
8923{
8924   store(mkexpr(op2addr), get_fpr_w0(r1));
8925
8926   return "stey";
8927}
8928
8929static const HChar *
8930s390_irgen_STDY(UChar r1, IRTemp op2addr)
8931{
8932   store(mkexpr(op2addr), get_fpr_dw0(r1));
8933
8934   return "stdy";
8935}
8936
8937static const HChar *
8938s390_irgen_STFPC(IRTemp op2addr)
8939{
8940   store(mkexpr(op2addr), get_fpc_w0());
8941
8942   return "stfpc";
8943}
8944
8945static const HChar *
8946s390_irgen_AEBR(UChar r1, UChar r2)
8947{
8948   IRTemp op1 = newTemp(Ity_F32);
8949   IRTemp op2 = newTemp(Ity_F32);
8950   IRTemp result = newTemp(Ity_F32);
8951   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
8952
8953   assign(op1, get_fpr_w0(r1));
8954   assign(op2, get_fpr_w0(r2));
8955   assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
8956          mkexpr(op2)));
8957   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8958   put_fpr_w0(r1, mkexpr(result));
8959
8960   return "aebr";
8961}
8962
8963static const HChar *
8964s390_irgen_ADBR(UChar r1, UChar r2)
8965{
8966   IRTemp op1 = newTemp(Ity_F64);
8967   IRTemp op2 = newTemp(Ity_F64);
8968   IRTemp result = newTemp(Ity_F64);
8969   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
8970
8971   assign(op1, get_fpr_dw0(r1));
8972   assign(op2, get_fpr_dw0(r2));
8973   assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
8974          mkexpr(op2)));
8975   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8976   put_fpr_dw0(r1, mkexpr(result));
8977
8978   return "adbr";
8979}
8980
8981static const HChar *
8982s390_irgen_AEB(UChar r1, IRTemp op2addr)
8983{
8984   IRTemp op1 = newTemp(Ity_F32);
8985   IRTemp op2 = newTemp(Ity_F32);
8986   IRTemp result = newTemp(Ity_F32);
8987   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
8988
8989   assign(op1, get_fpr_w0(r1));
8990   assign(op2, load(Ity_F32, mkexpr(op2addr)));
8991   assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
8992          mkexpr(op2)));
8993   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8994   put_fpr_w0(r1, mkexpr(result));
8995
8996   return "aeb";
8997}
8998
8999static const HChar *
9000s390_irgen_ADB(UChar r1, IRTemp op2addr)
9001{
9002   IRTemp op1 = newTemp(Ity_F64);
9003   IRTemp op2 = newTemp(Ity_F64);
9004   IRTemp result = newTemp(Ity_F64);
9005   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9006
9007   assign(op1, get_fpr_dw0(r1));
9008   assign(op2, load(Ity_F64, mkexpr(op2addr)));
9009   assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
9010          mkexpr(op2)));
9011   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9012   put_fpr_dw0(r1, mkexpr(result));
9013
9014   return "adb";
9015}
9016
9017static const HChar *
9018s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
9019                 UChar r1, UChar r2)
9020{
9021   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9022      emulation_warning(EmWarn_S390X_fpext_rounding);
9023      m3 = S390_BFP_ROUND_PER_FPC;
9024   }
9025   IRTemp op2 = newTemp(Ity_I32);
9026
9027   assign(op2, get_gpr_w1(r2));
9028   put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9029                        mkexpr(op2)));
9030
9031   return "cefbr";
9032}
9033
9034static const HChar *
9035s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
9036                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9037{
9038   IRTemp op2 = newTemp(Ity_I32);
9039
9040   assign(op2, get_gpr_w1(r2));
9041   put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
9042
9043   return "cdfbr";
9044}
9045
9046static const HChar *
9047s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
9048                 UChar r1, UChar r2)
9049{
9050   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9051      emulation_warning(EmWarn_S390X_fpext_rounding);
9052      m3 = S390_BFP_ROUND_PER_FPC;
9053   }
9054   IRTemp op2 = newTemp(Ity_I64);
9055
9056   assign(op2, get_gpr_dw0(r2));
9057   put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9058                        mkexpr(op2)));
9059
9060   return "cegbr";
9061}
9062
9063static const HChar *
9064s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
9065                 UChar r1, UChar r2)
9066{
9067   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9068      emulation_warning(EmWarn_S390X_fpext_rounding);
9069      m3 = S390_BFP_ROUND_PER_FPC;
9070   }
9071   IRTemp op2 = newTemp(Ity_I64);
9072
9073   assign(op2, get_gpr_dw0(r2));
9074   put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
9075                         mkexpr(op2)));
9076
9077   return "cdgbr";
9078}
9079
9080static const HChar *
9081s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
9082                  UChar r1, UChar r2)
9083{
9084   if (! s390_host_has_fpext) {
9085      emulation_failure(EmFail_S390X_fpext);
9086   } else {
9087      IRTemp op2 = newTemp(Ity_I32);
9088
9089      assign(op2, get_gpr_w1(r2));
9090      put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9091                           mkexpr(op2)));
9092   }
9093   return "celfbr";
9094}
9095
9096static const HChar *
9097s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
9098                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9099{
9100   if (! s390_host_has_fpext) {
9101      emulation_failure(EmFail_S390X_fpext);
9102   } else {
9103      IRTemp op2 = newTemp(Ity_I32);
9104
9105      assign(op2, get_gpr_w1(r2));
9106      put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
9107   }
9108   return "cdlfbr";
9109}
9110
9111static const HChar *
9112s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
9113                  UChar r1, UChar r2)
9114{
9115   if (! s390_host_has_fpext) {
9116      emulation_failure(EmFail_S390X_fpext);
9117   } else {
9118      IRTemp op2 = newTemp(Ity_I64);
9119
9120      assign(op2, get_gpr_dw0(r2));
9121      put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
9122                           mkexpr(op2)));
9123   }
9124   return "celgbr";
9125}
9126
9127static const HChar *
9128s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
9129                  UChar r1, UChar r2)
9130{
9131   if (! s390_host_has_fpext) {
9132      emulation_failure(EmFail_S390X_fpext);
9133   } else {
9134      IRTemp op2 = newTemp(Ity_I64);
9135
9136      assign(op2, get_gpr_dw0(r2));
9137      put_fpr_dw0(r1, binop(Iop_I64UtoF64,
9138                            mkexpr(encode_bfp_rounding_mode(m3)),
9139                            mkexpr(op2)));
9140   }
9141   return "cdlgbr";
9142}
9143
9144static const HChar *
9145s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9146                  UChar r1, UChar r2)
9147{
9148   if (! s390_host_has_fpext) {
9149      emulation_failure(EmFail_S390X_fpext);
9150   } else {
9151      IRTemp op = newTemp(Ity_F32);
9152      IRTemp result = newTemp(Ity_I32);
9153      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9154
9155      assign(op, get_fpr_w0(r2));
9156      assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
9157                           mkexpr(op)));
9158      put_gpr_w1(r1, mkexpr(result));
9159      s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
9160   }
9161   return "clfebr";
9162}
9163
9164static const HChar *
9165s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9166                  UChar r1, UChar r2)
9167{
9168   if (! s390_host_has_fpext) {
9169      emulation_failure(EmFail_S390X_fpext);
9170   } else {
9171      IRTemp op = newTemp(Ity_F64);
9172      IRTemp result = newTemp(Ity_I32);
9173      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9174
9175      assign(op, get_fpr_dw0(r2));
9176      assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
9177                           mkexpr(op)));
9178      put_gpr_w1(r1, mkexpr(result));
9179      s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
9180   }
9181   return "clfdbr";
9182}
9183
9184static const HChar *
9185s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9186                  UChar r1, UChar r2)
9187{
9188   if (! s390_host_has_fpext) {
9189      emulation_failure(EmFail_S390X_fpext);
9190   } else {
9191      IRTemp op = newTemp(Ity_F32);
9192      IRTemp result = newTemp(Ity_I64);
9193      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9194
9195      assign(op, get_fpr_w0(r2));
9196      assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
9197                           mkexpr(op)));
9198      put_gpr_dw0(r1, mkexpr(result));
9199      s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
9200   }
9201   return "clgebr";
9202}
9203
9204static const HChar *
9205s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9206                  UChar r1, UChar r2)
9207{
9208   if (! s390_host_has_fpext) {
9209      emulation_failure(EmFail_S390X_fpext);
9210   } else {
9211      IRTemp op = newTemp(Ity_F64);
9212      IRTemp result = newTemp(Ity_I64);
9213      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9214
9215      assign(op, get_fpr_dw0(r2));
9216      assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
9217                           mkexpr(op)));
9218      put_gpr_dw0(r1, mkexpr(result));
9219      s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
9220   }
9221   return "clgdbr";
9222}
9223
9224static const HChar *
9225s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9226                 UChar r1, UChar r2)
9227{
9228   IRTemp op = newTemp(Ity_F32);
9229   IRTemp result = newTemp(Ity_I32);
9230   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9231
9232   assign(op, get_fpr_w0(r2));
9233   assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
9234          mkexpr(op)));
9235   put_gpr_w1(r1, mkexpr(result));
9236   s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
9237
9238   return "cfebr";
9239}
9240
9241static const HChar *
9242s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9243                 UChar r1, UChar r2)
9244{
9245   IRTemp op = newTemp(Ity_F64);
9246   IRTemp result = newTemp(Ity_I32);
9247   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9248
9249   assign(op, get_fpr_dw0(r2));
9250   assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
9251          mkexpr(op)));
9252   put_gpr_w1(r1, mkexpr(result));
9253   s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
9254
9255   return "cfdbr";
9256}
9257
9258static const HChar *
9259s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9260                 UChar r1, UChar r2)
9261{
9262   IRTemp op = newTemp(Ity_F32);
9263   IRTemp result = newTemp(Ity_I64);
9264   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9265
9266   assign(op, get_fpr_w0(r2));
9267   assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
9268          mkexpr(op)));
9269   put_gpr_dw0(r1, mkexpr(result));
9270   s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
9271
9272   return "cgebr";
9273}
9274
9275static const HChar *
9276s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9277                 UChar r1, UChar r2)
9278{
9279   IRTemp op = newTemp(Ity_F64);
9280   IRTemp result = newTemp(Ity_I64);
9281   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
9282
9283   assign(op, get_fpr_dw0(r2));
9284   assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
9285          mkexpr(op)));
9286   put_gpr_dw0(r1, mkexpr(result));
9287   s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
9288
9289   return "cgdbr";
9290}
9291
9292static const HChar *
9293s390_irgen_DEBR(UChar r1, UChar r2)
9294{
9295   IRTemp op1 = newTemp(Ity_F32);
9296   IRTemp op2 = newTemp(Ity_F32);
9297   IRTemp result = newTemp(Ity_F32);
9298   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9299
9300   assign(op1, get_fpr_w0(r1));
9301   assign(op2, get_fpr_w0(r2));
9302   assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
9303          mkexpr(op2)));
9304   put_fpr_w0(r1, mkexpr(result));
9305
9306   return "debr";
9307}
9308
9309static const HChar *
9310s390_irgen_DDBR(UChar r1, UChar r2)
9311{
9312   IRTemp op1 = newTemp(Ity_F64);
9313   IRTemp op2 = newTemp(Ity_F64);
9314   IRTemp result = newTemp(Ity_F64);
9315   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9316
9317   assign(op1, get_fpr_dw0(r1));
9318   assign(op2, get_fpr_dw0(r2));
9319   assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
9320          mkexpr(op2)));
9321   put_fpr_dw0(r1, mkexpr(result));
9322
9323   return "ddbr";
9324}
9325
9326static const HChar *
9327s390_irgen_DEB(UChar r1, IRTemp op2addr)
9328{
9329   IRTemp op1 = newTemp(Ity_F32);
9330   IRTemp op2 = newTemp(Ity_F32);
9331   IRTemp result = newTemp(Ity_F32);
9332   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9333
9334   assign(op1, get_fpr_w0(r1));
9335   assign(op2, load(Ity_F32, mkexpr(op2addr)));
9336   assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
9337          mkexpr(op2)));
9338   put_fpr_w0(r1, mkexpr(result));
9339
9340   return "deb";
9341}
9342
9343static const HChar *
9344s390_irgen_DDB(UChar r1, IRTemp op2addr)
9345{
9346   IRTemp op1 = newTemp(Ity_F64);
9347   IRTemp op2 = newTemp(Ity_F64);
9348   IRTemp result = newTemp(Ity_F64);
9349   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9350
9351   assign(op1, get_fpr_dw0(r1));
9352   assign(op2, load(Ity_F64, mkexpr(op2addr)));
9353   assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
9354          mkexpr(op2)));
9355   put_fpr_dw0(r1, mkexpr(result));
9356
9357   return "ddb";
9358}
9359
9360static const HChar *
9361s390_irgen_LTEBR(UChar r1, UChar r2)
9362{
9363   IRTemp result = newTemp(Ity_F32);
9364
9365   assign(result, get_fpr_w0(r2));
9366   put_fpr_w0(r1, mkexpr(result));
9367   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9368
9369   return "ltebr";
9370}
9371
9372static const HChar *
9373s390_irgen_LTDBR(UChar r1, UChar r2)
9374{
9375   IRTemp result = newTemp(Ity_F64);
9376
9377   assign(result, get_fpr_dw0(r2));
9378   put_fpr_dw0(r1, mkexpr(result));
9379   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9380
9381   return "ltdbr";
9382}
9383
9384static const HChar *
9385s390_irgen_LCEBR(UChar r1, UChar r2)
9386{
9387   IRTemp result = newTemp(Ity_F32);
9388
9389   assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9390   put_fpr_w0(r1, mkexpr(result));
9391   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9392
9393   return "lcebr";
9394}
9395
9396static const HChar *
9397s390_irgen_LCDBR(UChar r1, UChar r2)
9398{
9399   IRTemp result = newTemp(Ity_F64);
9400
9401   assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9402   put_fpr_dw0(r1, mkexpr(result));
9403   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9404
9405   return "lcdbr";
9406}
9407
9408static const HChar *
9409s390_irgen_LDEBR(UChar r1, UChar r2)
9410{
9411   IRTemp op = newTemp(Ity_F32);
9412
9413   assign(op, get_fpr_w0(r2));
9414   put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9415
9416   return "ldebr";
9417}
9418
9419static const HChar *
9420s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9421{
9422   IRTemp op = newTemp(Ity_F32);
9423
9424   assign(op, load(Ity_F32, mkexpr(op2addr)));
9425   put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9426
9427   return "ldeb";
9428}
9429
9430static const HChar *
9431s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9432                 UChar r1, UChar r2)
9433{
9434   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
9435      emulation_warning(EmWarn_S390X_fpext_rounding);
9436      m3 = S390_BFP_ROUND_PER_FPC;
9437   }
9438   IRTemp op = newTemp(Ity_F64);
9439
9440   assign(op, get_fpr_dw0(r2));
9441   put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
9442                        mkexpr(op)));
9443
9444   return "ledbr";
9445}
9446
9447static const HChar *
9448s390_irgen_MEEBR(UChar r1, UChar r2)
9449{
9450   IRTemp op1 = newTemp(Ity_F32);
9451   IRTemp op2 = newTemp(Ity_F32);
9452   IRTemp result = newTemp(Ity_F32);
9453   IRRoundingMode rounding_mode =
9454      encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9455
9456   assign(op1, get_fpr_w0(r1));
9457   assign(op2, get_fpr_w0(r2));
9458   assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
9459          mkexpr(op2)));
9460   put_fpr_w0(r1, mkexpr(result));
9461
9462   return "meebr";
9463}
9464
9465static const HChar *
9466s390_irgen_MDBR(UChar r1, UChar r2)
9467{
9468   IRTemp op1 = newTemp(Ity_F64);
9469   IRTemp op2 = newTemp(Ity_F64);
9470   IRTemp result = newTemp(Ity_F64);
9471   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9472
9473   assign(op1, get_fpr_dw0(r1));
9474   assign(op2, get_fpr_dw0(r2));
9475   assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
9476          mkexpr(op2)));
9477   put_fpr_dw0(r1, mkexpr(result));
9478
9479   return "mdbr";
9480}
9481
9482static const HChar *
9483s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9484{
9485   IRTemp op1 = newTemp(Ity_F32);
9486   IRTemp op2 = newTemp(Ity_F32);
9487   IRTemp result = newTemp(Ity_F32);
9488   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9489
9490   assign(op1, get_fpr_w0(r1));
9491   assign(op2, load(Ity_F32, mkexpr(op2addr)));
9492   assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
9493          mkexpr(op2)));
9494   put_fpr_w0(r1, mkexpr(result));
9495
9496   return "meeb";
9497}
9498
9499static const HChar *
9500s390_irgen_MDB(UChar r1, IRTemp op2addr)
9501{
9502   IRTemp op1 = newTemp(Ity_F64);
9503   IRTemp op2 = newTemp(Ity_F64);
9504   IRTemp result = newTemp(Ity_F64);
9505   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9506
9507   assign(op1, get_fpr_dw0(r1));
9508   assign(op2, load(Ity_F64, mkexpr(op2addr)));
9509   assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
9510          mkexpr(op2)));
9511   put_fpr_dw0(r1, mkexpr(result));
9512
9513   return "mdb";
9514}
9515
9516static const HChar *
9517s390_irgen_SEBR(UChar r1, UChar r2)
9518{
9519   IRTemp op1 = newTemp(Ity_F32);
9520   IRTemp op2 = newTemp(Ity_F32);
9521   IRTemp result = newTemp(Ity_F32);
9522   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9523
9524   assign(op1, get_fpr_w0(r1));
9525   assign(op2, get_fpr_w0(r2));
9526   assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
9527          mkexpr(op2)));
9528   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9529   put_fpr_w0(r1, mkexpr(result));
9530
9531   return "sebr";
9532}
9533
9534static const HChar *
9535s390_irgen_SDBR(UChar r1, UChar r2)
9536{
9537   IRTemp op1 = newTemp(Ity_F64);
9538   IRTemp op2 = newTemp(Ity_F64);
9539   IRTemp result = newTemp(Ity_F64);
9540   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9541
9542   assign(op1, get_fpr_dw0(r1));
9543   assign(op2, get_fpr_dw0(r2));
9544   assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
9545          mkexpr(op2)));
9546   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9547   put_fpr_dw0(r1, mkexpr(result));
9548
9549   return "sdbr";
9550}
9551
9552static const HChar *
9553s390_irgen_SEB(UChar r1, IRTemp op2addr)
9554{
9555   IRTemp op1 = newTemp(Ity_F32);
9556   IRTemp op2 = newTemp(Ity_F32);
9557   IRTemp result = newTemp(Ity_F32);
9558   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9559
9560   assign(op1, get_fpr_w0(r1));
9561   assign(op2, load(Ity_F32, mkexpr(op2addr)));
9562   assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
9563          mkexpr(op2)));
9564   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9565   put_fpr_w0(r1, mkexpr(result));
9566
9567   return "seb";
9568}
9569
9570static const HChar *
9571s390_irgen_SDB(UChar r1, IRTemp op2addr)
9572{
9573   IRTemp op1 = newTemp(Ity_F64);
9574   IRTemp op2 = newTemp(Ity_F64);
9575   IRTemp result = newTemp(Ity_F64);
9576   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
9577
9578   assign(op1, get_fpr_dw0(r1));
9579   assign(op2, load(Ity_F64, mkexpr(op2addr)));
9580   assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
9581          mkexpr(op2)));
9582   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9583   put_fpr_dw0(r1, mkexpr(result));
9584
9585   return "sdb";
9586}
9587
9588static const HChar *
9589s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9590{
9591   if (! s390_host_has_dfp) {
9592      emulation_failure(EmFail_S390X_DFP_insn);
9593   } else {
9594      IRTemp op1 = newTemp(Ity_D64);
9595      IRTemp op2 = newTemp(Ity_D64);
9596      IRTemp result = newTemp(Ity_D64);
9597      IRTemp rounding_mode;
9598
9599      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9600         emulation_warning(EmWarn_S390X_fpext_rounding);
9601         m4 = S390_DFP_ROUND_PER_FPC_0;
9602      }
9603
9604      rounding_mode = encode_dfp_rounding_mode(m4);
9605      assign(op1, get_dpr_dw0(r2));
9606      assign(op2, get_dpr_dw0(r3));
9607      assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9608                           mkexpr(op2)));
9609      s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9610      put_dpr_dw0(r1, mkexpr(result));
9611   }
9612   return (m4 == 0) ? "adtr" : "adtra";
9613}
9614
9615static const HChar *
9616s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9617{
9618   if (! s390_host_has_dfp) {
9619      emulation_failure(EmFail_S390X_DFP_insn);
9620   } else {
9621      IRTemp op1 = newTemp(Ity_D128);
9622      IRTemp op2 = newTemp(Ity_D128);
9623      IRTemp result = newTemp(Ity_D128);
9624      IRTemp rounding_mode;
9625
9626      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9627         emulation_warning(EmWarn_S390X_fpext_rounding);
9628         m4 = S390_DFP_ROUND_PER_FPC_0;
9629      }
9630
9631      rounding_mode = encode_dfp_rounding_mode(m4);
9632      assign(op1, get_dpr_pair(r2));
9633      assign(op2, get_dpr_pair(r3));
9634      assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9635                           mkexpr(op2)));
9636      put_dpr_pair(r1, mkexpr(result));
9637
9638      s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9639   }
9640   return (m4 == 0) ? "axtr" : "axtra";
9641}
9642
9643static const HChar *
9644s390_irgen_CDTR(UChar r1, UChar r2)
9645{
9646   IRTemp op1 = newTemp(Ity_D64);
9647   IRTemp op2 = newTemp(Ity_D64);
9648   IRTemp cc_vex  = newTemp(Ity_I32);
9649   IRTemp cc_s390 = newTemp(Ity_I32);
9650
9651   assign(op1, get_dpr_dw0(r1));
9652   assign(op2, get_dpr_dw0(r2));
9653   assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9654
9655   assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9656   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9657
9658   return "cdtr";
9659}
9660
9661static const HChar *
9662s390_irgen_CXTR(UChar r1, UChar r2)
9663{
9664   IRTemp op1 = newTemp(Ity_D128);
9665   IRTemp op2 = newTemp(Ity_D128);
9666   IRTemp cc_vex  = newTemp(Ity_I32);
9667   IRTemp cc_s390 = newTemp(Ity_I32);
9668
9669   assign(op1, get_dpr_pair(r1));
9670   assign(op2, get_dpr_pair(r2));
9671   assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9672
9673   assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9674   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9675
9676   return "cxtr";
9677}
9678
9679static const HChar *
9680s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9681                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9682{
9683   if (! s390_host_has_dfp) {
9684      emulation_failure(EmFail_S390X_DFP_insn);
9685   } else {
9686      if (! s390_host_has_fpext) {
9687         emulation_failure(EmFail_S390X_fpext);
9688      } else {
9689         IRTemp op2 = newTemp(Ity_I32);
9690
9691         assign(op2, get_gpr_w1(r2));
9692         put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9693      }
9694   }
9695   return "cdftr";
9696}
9697
9698static const HChar *
9699s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9700                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9701{
9702   if (! s390_host_has_dfp) {
9703      emulation_failure(EmFail_S390X_DFP_insn);
9704   } else {
9705      if (! s390_host_has_fpext) {
9706         emulation_failure(EmFail_S390X_fpext);
9707      } else {
9708         IRTemp op2 = newTemp(Ity_I32);
9709
9710         assign(op2, get_gpr_w1(r2));
9711         put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9712      }
9713   }
9714   return "cxftr";
9715}
9716
9717static const HChar *
9718s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9719                  UChar r1, UChar r2)
9720{
9721   if (! s390_host_has_dfp) {
9722      emulation_failure(EmFail_S390X_DFP_insn);
9723   } else {
9724      IRTemp op2 = newTemp(Ity_I64);
9725
9726      if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9727         emulation_warning(EmWarn_S390X_fpext_rounding);
9728         m3 = S390_DFP_ROUND_PER_FPC_0;
9729      }
9730
9731      assign(op2, get_gpr_dw0(r2));
9732      put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9733                            mkexpr(op2)));
9734   }
9735   return (m3 == 0) ? "cdgtr" : "cdgtra";
9736}
9737
9738static const HChar *
9739s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9740                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9741{
9742   if (! s390_host_has_dfp) {
9743      emulation_failure(EmFail_S390X_DFP_insn);
9744   } else {
9745      IRTemp op2 = newTemp(Ity_I64);
9746
9747      /* No emulation warning here about an non-zero m3 on hosts without
9748         floating point extension facility. No rounding is performed */
9749
9750      assign(op2, get_gpr_dw0(r2));
9751      put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9752   }
9753   return "cxgtr";
9754}
9755
9756static const HChar *
9757s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9758                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9759{
9760   if (! s390_host_has_dfp) {
9761      emulation_failure(EmFail_S390X_DFP_insn);
9762   } else {
9763      if (! s390_host_has_fpext) {
9764         emulation_failure(EmFail_S390X_fpext);
9765      } else {
9766         IRTemp op2 = newTemp(Ity_I32);
9767
9768         assign(op2, get_gpr_w1(r2));
9769         put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9770      }
9771   }
9772   return "cdlftr";
9773}
9774
9775static const HChar *
9776s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9777                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9778{
9779   if (! s390_host_has_dfp) {
9780      emulation_failure(EmFail_S390X_DFP_insn);
9781   } else {
9782      if (! s390_host_has_fpext) {
9783         emulation_failure(EmFail_S390X_fpext);
9784      } else {
9785         IRTemp op2 = newTemp(Ity_I32);
9786
9787         assign(op2, get_gpr_w1(r2));
9788         put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9789      }
9790   }
9791   return "cxlftr";
9792}
9793
9794static const HChar *
9795s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9796                  UChar r1, UChar r2)
9797{
9798   if (! s390_host_has_dfp) {
9799      emulation_failure(EmFail_S390X_DFP_insn);
9800   } else {
9801      if (! s390_host_has_fpext) {
9802         emulation_failure(EmFail_S390X_fpext);
9803      } else {
9804         IRTemp op2 = newTemp(Ity_I64);
9805
9806         assign(op2, get_gpr_dw0(r2));
9807         put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9808                               mkexpr(encode_dfp_rounding_mode(m3)),
9809                               mkexpr(op2)));
9810      }
9811   }
9812   return "cdlgtr";
9813}
9814
9815static const HChar *
9816s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9817                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9818{
9819   if (! s390_host_has_dfp) {
9820      emulation_failure(EmFail_S390X_DFP_insn);
9821   } else {
9822      if (! s390_host_has_fpext) {
9823         emulation_failure(EmFail_S390X_fpext);
9824      } else {
9825         IRTemp op2 = newTemp(Ity_I64);
9826
9827         assign(op2, get_gpr_dw0(r2));
9828         put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9829      }
9830   }
9831   return "cxlgtr";
9832}
9833
9834static const HChar *
9835s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9836                 UChar r1, UChar r2)
9837{
9838   if (! s390_host_has_dfp) {
9839      emulation_failure(EmFail_S390X_DFP_insn);
9840   } else {
9841      if (! s390_host_has_fpext) {
9842         emulation_failure(EmFail_S390X_fpext);
9843      } else {
9844         IRTemp op = newTemp(Ity_D64);
9845         IRTemp result = newTemp(Ity_I32);
9846         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9847
9848         assign(op, get_dpr_dw0(r2));
9849         assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9850                              mkexpr(op)));
9851         put_gpr_w1(r1, mkexpr(result));
9852         s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9853      }
9854   }
9855   return "cfdtr";
9856}
9857
9858static const HChar *
9859s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9860                 UChar r1, UChar r2)
9861{
9862   if (! s390_host_has_dfp) {
9863      emulation_failure(EmFail_S390X_DFP_insn);
9864   } else {
9865      if (! s390_host_has_fpext) {
9866         emulation_failure(EmFail_S390X_fpext);
9867      } else {
9868         IRTemp op = newTemp(Ity_D128);
9869         IRTemp result = newTemp(Ity_I32);
9870         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9871
9872         assign(op, get_dpr_pair(r2));
9873         assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9874                              mkexpr(op)));
9875         put_gpr_w1(r1, mkexpr(result));
9876         s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op,
9877                                 rounding_mode);
9878      }
9879   }
9880   return "cfxtr";
9881}
9882
9883static const HChar *
9884s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9885                 UChar r1, UChar r2)
9886{
9887   if (! s390_host_has_dfp) {
9888      emulation_failure(EmFail_S390X_DFP_insn);
9889   } else {
9890      IRTemp op = newTemp(Ity_D64);
9891      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9892
9893      /* If fpext is not installed and m3 is in 1:7,
9894         rounding mode performed is unpredictable */
9895      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9896         emulation_warning(EmWarn_S390X_fpext_rounding);
9897         m3 = S390_DFP_ROUND_PER_FPC_0;
9898      }
9899
9900      assign(op, get_dpr_dw0(r2));
9901      put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9902      s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9903   }
9904   return "cgdtr";
9905}
9906
9907static const HChar *
9908s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9909                 UChar r1, UChar r2)
9910{
9911   if (! s390_host_has_dfp) {
9912      emulation_failure(EmFail_S390X_DFP_insn);
9913   } else {
9914      IRTemp op = newTemp(Ity_D128);
9915      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9916
9917      /* If fpext is not installed and m3 is in 1:7,
9918         rounding mode performed is unpredictable */
9919      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9920         emulation_warning(EmWarn_S390X_fpext_rounding);
9921         m3 = S390_DFP_ROUND_PER_FPC_0;
9922      }
9923      assign(op, get_dpr_pair(r2));
9924      put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9925      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9926   }
9927   return "cgxtr";
9928}
9929
9930static const HChar *
9931s390_irgen_CEDTR(UChar r1, UChar r2)
9932{
9933   if (! s390_host_has_dfp) {
9934      emulation_failure(EmFail_S390X_DFP_insn);
9935   } else {
9936      IRTemp op1 = newTemp(Ity_D64);
9937      IRTemp op2 = newTemp(Ity_D64);
9938      IRTemp cc_vex  = newTemp(Ity_I32);
9939      IRTemp cc_s390 = newTemp(Ity_I32);
9940
9941      assign(op1, get_dpr_dw0(r1));
9942      assign(op2, get_dpr_dw0(r2));
9943      assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9944
9945      assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9946      s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9947   }
9948   return "cedtr";
9949}
9950
9951static const HChar *
9952s390_irgen_CEXTR(UChar r1, UChar r2)
9953{
9954   if (! s390_host_has_dfp) {
9955      emulation_failure(EmFail_S390X_DFP_insn);
9956   } else {
9957      IRTemp op1 = newTemp(Ity_D128);
9958      IRTemp op2 = newTemp(Ity_D128);
9959      IRTemp cc_vex  = newTemp(Ity_I32);
9960      IRTemp cc_s390 = newTemp(Ity_I32);
9961
9962      assign(op1, get_dpr_pair(r1));
9963      assign(op2, get_dpr_pair(r2));
9964      assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9965
9966      assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9967      s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9968   }
9969   return "cextr";
9970}
9971
9972static const HChar *
9973s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9974                  UChar r1, UChar r2)
9975{
9976   if (! s390_host_has_dfp) {
9977      emulation_failure(EmFail_S390X_DFP_insn);
9978   } else {
9979      if (! s390_host_has_fpext) {
9980         emulation_failure(EmFail_S390X_fpext);
9981      } else {
9982         IRTemp op = newTemp(Ity_D64);
9983         IRTemp result = newTemp(Ity_I32);
9984         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9985
9986         assign(op, get_dpr_dw0(r2));
9987         assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9988                              mkexpr(op)));
9989         put_gpr_w1(r1, mkexpr(result));
9990         s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9991      }
9992   }
9993   return "clfdtr";
9994}
9995
9996static const HChar *
9997s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9998                  UChar r1, UChar r2)
9999{
10000   if (! s390_host_has_dfp) {
10001      emulation_failure(EmFail_S390X_DFP_insn);
10002   } else {
10003      if (! s390_host_has_fpext) {
10004         emulation_failure(EmFail_S390X_fpext);
10005      } else {
10006         IRTemp op = newTemp(Ity_D128);
10007         IRTemp result = newTemp(Ity_I32);
10008         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10009
10010         assign(op, get_dpr_pair(r2));
10011         assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
10012                              mkexpr(op)));
10013         put_gpr_w1(r1, mkexpr(result));
10014         s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op,
10015                                 rounding_mode);
10016      }
10017   }
10018   return "clfxtr";
10019}
10020
10021static const HChar *
10022s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
10023                  UChar r1, UChar r2)
10024{
10025   if (! s390_host_has_dfp) {
10026      emulation_failure(EmFail_S390X_DFP_insn);
10027   } else {
10028      if (! s390_host_has_fpext) {
10029         emulation_failure(EmFail_S390X_fpext);
10030      } else {
10031         IRTemp op = newTemp(Ity_D64);
10032         IRTemp result = newTemp(Ity_I64);
10033         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10034
10035         assign(op, get_dpr_dw0(r2));
10036         assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
10037                              mkexpr(op)));
10038         put_gpr_dw0(r1, mkexpr(result));
10039         s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
10040      }
10041   }
10042   return "clgdtr";
10043}
10044
10045static const HChar *
10046s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
10047                  UChar r1, UChar r2)
10048{
10049   if (! s390_host_has_dfp) {
10050      emulation_failure(EmFail_S390X_DFP_insn);
10051   } else {
10052      if (! s390_host_has_fpext) {
10053         emulation_failure(EmFail_S390X_fpext);
10054      } else {
10055         IRTemp op = newTemp(Ity_D128);
10056         IRTemp result = newTemp(Ity_I64);
10057         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10058
10059         assign(op, get_dpr_pair(r2));
10060         assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
10061                              mkexpr(op)));
10062         put_gpr_dw0(r1, mkexpr(result));
10063         s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
10064                                 rounding_mode);
10065      }
10066   }
10067   return "clgxtr";
10068}
10069
10070static const HChar *
10071s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10072{
10073   if (! s390_host_has_dfp) {
10074      emulation_failure(EmFail_S390X_DFP_insn);
10075   } else {
10076      IRTemp op1 = newTemp(Ity_D64);
10077      IRTemp op2 = newTemp(Ity_D64);
10078      IRTemp result = newTemp(Ity_D64);
10079      IRTemp rounding_mode;
10080
10081      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10082         emulation_warning(EmWarn_S390X_fpext_rounding);
10083         m4 = S390_DFP_ROUND_PER_FPC_0;
10084      }
10085
10086      rounding_mode = encode_dfp_rounding_mode(m4);
10087      assign(op1, get_dpr_dw0(r2));
10088      assign(op2, get_dpr_dw0(r3));
10089      assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
10090                           mkexpr(op2)));
10091      put_dpr_dw0(r1, mkexpr(result));
10092   }
10093   return (m4 == 0) ? "ddtr" : "ddtra";
10094}
10095
10096static const HChar *
10097s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10098{
10099   if (! s390_host_has_dfp) {
10100      emulation_failure(EmFail_S390X_DFP_insn);
10101   } else {
10102      IRTemp op1 = newTemp(Ity_D128);
10103      IRTemp op2 = newTemp(Ity_D128);
10104      IRTemp result = newTemp(Ity_D128);
10105      IRTemp rounding_mode;
10106
10107      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10108         emulation_warning(EmWarn_S390X_fpext_rounding);
10109         m4 = S390_DFP_ROUND_PER_FPC_0;
10110      }
10111
10112      rounding_mode = encode_dfp_rounding_mode(m4);
10113      assign(op1, get_dpr_pair(r2));
10114      assign(op2, get_dpr_pair(r3));
10115      assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
10116                           mkexpr(op2)));
10117      put_dpr_pair(r1, mkexpr(result));
10118   }
10119   return (m4 == 0) ? "dxtr" : "dxtra";
10120}
10121
10122static const HChar *
10123s390_irgen_EEDTR(UChar r1, UChar r2)
10124{
10125   if (! s390_host_has_dfp) {
10126      emulation_failure(EmFail_S390X_DFP_insn);
10127   } else {
10128      put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
10129   }
10130   return "eedtr";
10131}
10132
10133static const HChar *
10134s390_irgen_EEXTR(UChar r1, UChar r2)
10135{
10136   if (! s390_host_has_dfp) {
10137      emulation_failure(EmFail_S390X_DFP_insn);
10138   } else {
10139      put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
10140   }
10141   return "eextr";
10142}
10143
10144static const HChar *
10145s390_irgen_ESDTR(UChar r1, UChar r2)
10146{
10147   if (! s390_host_has_dfp) {
10148      emulation_failure(EmFail_S390X_DFP_insn);
10149   } else {
10150      put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
10151   }
10152   return "esdtr";
10153}
10154
10155static const HChar *
10156s390_irgen_ESXTR(UChar r1, UChar r2)
10157{
10158   if (! s390_host_has_dfp) {
10159      emulation_failure(EmFail_S390X_DFP_insn);
10160   } else {
10161      put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
10162   }
10163   return "esxtr";
10164}
10165
10166static const HChar *
10167s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
10168{
10169   if (! s390_host_has_dfp) {
10170      emulation_failure(EmFail_S390X_DFP_insn);
10171   } else {
10172      IRTemp op1 = newTemp(Ity_I64);
10173      IRTemp op2 = newTemp(Ity_D64);
10174      IRTemp result = newTemp(Ity_D64);
10175
10176      assign(op1, get_gpr_dw0(r2));
10177      assign(op2, get_dpr_dw0(r3));
10178      assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
10179      put_dpr_dw0(r1, mkexpr(result));
10180   }
10181   return "iedtr";
10182}
10183
10184static const HChar *
10185s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
10186{
10187   if (! s390_host_has_dfp) {
10188      emulation_failure(EmFail_S390X_DFP_insn);
10189   } else {
10190      IRTemp op1 = newTemp(Ity_I64);
10191      IRTemp op2 = newTemp(Ity_D128);
10192      IRTemp result = newTemp(Ity_D128);
10193
10194      assign(op1, get_gpr_dw0(r2));
10195      assign(op2, get_dpr_pair(r3));
10196      assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10197      put_dpr_pair(r1, mkexpr(result));
10198   }
10199   return "iextr";
10200}
10201
10202static const HChar *
10203s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10204{
10205   if (! s390_host_has_dfp) {
10206      emulation_failure(EmFail_S390X_DFP_insn);
10207   } else {
10208      IRTemp op = newTemp(Ity_D32);
10209
10210      assign(op, get_dpr_w0(r2));
10211      put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10212   }
10213   return "ldetr";
10214}
10215
10216static const HChar *
10217s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10218{
10219   IRTemp op = newTemp(Ity_D64);
10220
10221   assign(op, get_dpr_dw0(r2));
10222   put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10223
10224   return "lxdtr";
10225}
10226
10227static const HChar *
10228s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10229                 UChar r1, UChar r2)
10230{
10231   if (! s390_host_has_dfp) {
10232      emulation_failure(EmFail_S390X_DFP_insn);
10233   } else {
10234      /* If fpext is not installed and m3 is in 1:7,
10235         rounding mode performed is unpredictable */
10236      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10237         emulation_warning(EmWarn_S390X_fpext_rounding);
10238         m3 = S390_DFP_ROUND_PER_FPC_0;
10239      }
10240      IRTemp result = newTemp(Ity_D64);
10241
10242      assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10243                           get_dpr_pair(r2)));
10244      put_dpr_dw0(r1, mkexpr(result));
10245   }
10246   return "ldxtr";
10247}
10248
10249static const HChar *
10250s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10251                 UChar r1, UChar r2)
10252{
10253   if (! s390_host_has_dfp) {
10254      emulation_failure(EmFail_S390X_DFP_insn);
10255   } else {
10256      /* If fpext is not installed and m3 is in 1:7,
10257         rounding mode performed is unpredictable */
10258      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10259         emulation_warning(EmWarn_S390X_fpext_rounding);
10260         m3 = S390_DFP_ROUND_PER_FPC_0;
10261      }
10262      IRTemp op = newTemp(Ity_D64);
10263
10264      assign(op, get_dpr_dw0(r2));
10265      put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10266                           mkexpr(op)));
10267   }
10268   return "ledtr";
10269}
10270
10271static const HChar *
10272s390_irgen_LTDTR(UChar r1, UChar r2)
10273{
10274   IRTemp result = newTemp(Ity_D64);
10275
10276   assign(result, get_dpr_dw0(r2));
10277   put_dpr_dw0(r1, mkexpr(result));
10278   s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10279
10280   return "ltdtr";
10281}
10282
10283static const HChar *
10284s390_irgen_LTXTR(UChar r1, UChar r2)
10285{
10286   IRTemp result = newTemp(Ity_D128);
10287
10288   assign(result, get_dpr_pair(r2));
10289   put_dpr_pair(r1, mkexpr(result));
10290   s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10291
10292   return "ltxtr";
10293}
10294
10295static const HChar *
10296s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10297{
10298   if (! s390_host_has_dfp) {
10299      emulation_failure(EmFail_S390X_DFP_insn);
10300   } else {
10301      IRTemp op1 = newTemp(Ity_D64);
10302      IRTemp op2 = newTemp(Ity_D64);
10303      IRTemp result = newTemp(Ity_D64);
10304      IRTemp rounding_mode;
10305
10306      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10307         emulation_warning(EmWarn_S390X_fpext_rounding);
10308         m4 = S390_DFP_ROUND_PER_FPC_0;
10309      }
10310
10311      rounding_mode = encode_dfp_rounding_mode(m4);
10312      assign(op1, get_dpr_dw0(r2));
10313      assign(op2, get_dpr_dw0(r3));
10314      assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10315                           mkexpr(op2)));
10316      put_dpr_dw0(r1, mkexpr(result));
10317   }
10318   return (m4 == 0) ? "mdtr" : "mdtra";
10319}
10320
10321static const HChar *
10322s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10323{
10324   if (! s390_host_has_dfp) {
10325      emulation_failure(EmFail_S390X_DFP_insn);
10326   } else {
10327      IRTemp op1 = newTemp(Ity_D128);
10328      IRTemp op2 = newTemp(Ity_D128);
10329      IRTemp result = newTemp(Ity_D128);
10330      IRTemp rounding_mode;
10331
10332      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10333         emulation_warning(EmWarn_S390X_fpext_rounding);
10334         m4 = S390_DFP_ROUND_PER_FPC_0;
10335      }
10336
10337      rounding_mode = encode_dfp_rounding_mode(m4);
10338      assign(op1, get_dpr_pair(r2));
10339      assign(op2, get_dpr_pair(r3));
10340      assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10341                           mkexpr(op2)));
10342      put_dpr_pair(r1, mkexpr(result));
10343   }
10344   return (m4 == 0) ? "mxtr" : "mxtra";
10345}
10346
10347static const HChar *
10348s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10349{
10350   if (! s390_host_has_dfp) {
10351      emulation_failure(EmFail_S390X_DFP_insn);
10352   } else {
10353      IRTemp op1 = newTemp(Ity_D64);
10354      IRTemp op2 = newTemp(Ity_D64);
10355      IRTemp result = newTemp(Ity_D64);
10356      IRTemp rounding_mode;
10357
10358      /* If fpext is not installed and m4 is in 1:7,
10359         rounding mode performed is unpredictable */
10360      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10361         emulation_warning(EmWarn_S390X_fpext_rounding);
10362         m4 = S390_DFP_ROUND_PER_FPC_0;
10363      }
10364
10365      rounding_mode = encode_dfp_rounding_mode(m4);
10366      assign(op1, get_dpr_dw0(r2));
10367      assign(op2, get_dpr_dw0(r3));
10368      assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10369                           mkexpr(op2)));
10370      put_dpr_dw0(r1, mkexpr(result));
10371   }
10372   return "qadtr";
10373}
10374
10375static const HChar *
10376s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10377{
10378   if (! s390_host_has_dfp) {
10379      emulation_failure(EmFail_S390X_DFP_insn);
10380   } else {
10381      IRTemp op1 = newTemp(Ity_D128);
10382      IRTemp op2 = newTemp(Ity_D128);
10383      IRTemp result = newTemp(Ity_D128);
10384      IRTemp rounding_mode;
10385
10386      /* If fpext is not installed and m4 is in 1:7,
10387         rounding mode performed is unpredictable */
10388      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10389         emulation_warning(EmWarn_S390X_fpext_rounding);
10390         m4 = S390_DFP_ROUND_PER_FPC_0;
10391      }
10392
10393      rounding_mode = encode_dfp_rounding_mode(m4);
10394      assign(op1, get_dpr_pair(r2));
10395      assign(op2, get_dpr_pair(r3));
10396      assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10397                           mkexpr(op2)));
10398      put_dpr_pair(r1, mkexpr(result));
10399   }
10400   return "qaxtr";
10401}
10402
10403static const HChar *
10404s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10405{
10406   if (! s390_host_has_dfp) {
10407      emulation_failure(EmFail_S390X_DFP_insn);
10408   } else {
10409      IRTemp op1 = newTemp(Ity_I8);
10410      IRTemp op2 = newTemp(Ity_D64);
10411      IRTemp result = newTemp(Ity_D64);
10412      IRTemp rounding_mode;
10413
10414      /* If fpext is not installed and m4 is in 1:7,
10415         rounding mode performed is unpredictable */
10416      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10417         emulation_warning(EmWarn_S390X_fpext_rounding);
10418         m4 = S390_DFP_ROUND_PER_FPC_0;
10419      }
10420
10421      rounding_mode = encode_dfp_rounding_mode(m4);
10422      assign(op1, get_gpr_b7(r2));
10423      assign(op2, get_dpr_dw0(r3));
10424      assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10425                           mkexpr(op1), mkexpr(op2)));
10426      put_dpr_dw0(r1, mkexpr(result));
10427   }
10428   return "rrdtr";
10429}
10430
10431static const HChar *
10432s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10433{
10434   if (! s390_host_has_dfp) {
10435      emulation_failure(EmFail_S390X_DFP_insn);
10436   } else {
10437      IRTemp op1 = newTemp(Ity_I8);
10438      IRTemp op2 = newTemp(Ity_D128);
10439      IRTemp result = newTemp(Ity_D128);
10440      IRTemp rounding_mode;
10441
10442      /* If fpext is not installed and m4 is in 1:7,
10443         rounding mode performed is unpredictable */
10444      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10445         emulation_warning(EmWarn_S390X_fpext_rounding);
10446         m4 = S390_DFP_ROUND_PER_FPC_0;
10447      }
10448
10449      rounding_mode = encode_dfp_rounding_mode(m4);
10450      assign(op1, get_gpr_b7(r2));
10451      assign(op2, get_dpr_pair(r3));
10452      assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10453                           mkexpr(op1), mkexpr(op2)));
10454      put_dpr_pair(r1, mkexpr(result));
10455   }
10456   return "rrxtr";
10457}
10458
10459static const HChar *
10460s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10461{
10462   if (! s390_host_has_dfp) {
10463      emulation_failure(EmFail_S390X_DFP_insn);
10464   } else {
10465      IRTemp op1 = newTemp(Ity_D64);
10466      IRTemp op2 = newTemp(Ity_D64);
10467      IRTemp result = newTemp(Ity_D64);
10468      IRTemp rounding_mode;
10469
10470      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10471         emulation_warning(EmWarn_S390X_fpext_rounding);
10472         m4 = S390_DFP_ROUND_PER_FPC_0;
10473      }
10474
10475      rounding_mode = encode_dfp_rounding_mode(m4);
10476      assign(op1, get_dpr_dw0(r2));
10477      assign(op2, get_dpr_dw0(r3));
10478      assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10479                           mkexpr(op2)));
10480      s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10481      put_dpr_dw0(r1, mkexpr(result));
10482   }
10483   return (m4 == 0) ? "sdtr" : "sdtra";
10484}
10485
10486static const HChar *
10487s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10488{
10489   if (! s390_host_has_dfp) {
10490      emulation_failure(EmFail_S390X_DFP_insn);
10491   } else {
10492      IRTemp op1 = newTemp(Ity_D128);
10493      IRTemp op2 = newTemp(Ity_D128);
10494      IRTemp result = newTemp(Ity_D128);
10495      IRTemp rounding_mode;
10496
10497      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10498         emulation_warning(EmWarn_S390X_fpext_rounding);
10499         m4 = S390_DFP_ROUND_PER_FPC_0;
10500      }
10501
10502      rounding_mode = encode_dfp_rounding_mode(m4);
10503      assign(op1, get_dpr_pair(r2));
10504      assign(op2, get_dpr_pair(r3));
10505      assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10506                           mkexpr(op2)));
10507      put_dpr_pair(r1, mkexpr(result));
10508
10509      s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10510   }
10511   return (m4 == 0) ? "sxtr" : "sxtra";
10512}
10513
10514static const HChar *
10515s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10516{
10517   if (! s390_host_has_dfp) {
10518      emulation_failure(EmFail_S390X_DFP_insn);
10519   } else {
10520      IRTemp op = newTemp(Ity_D64);
10521
10522      assign(op, get_dpr_dw0(r3));
10523      put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op),
10524                            unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10525                                                  mkU64(63)))));
10526   }
10527   return "sldt";
10528}
10529
10530static const HChar *
10531s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10532{
10533   if (! s390_host_has_dfp) {
10534      emulation_failure(EmFail_S390X_DFP_insn);
10535   } else {
10536      IRTemp op = newTemp(Ity_D128);
10537
10538      assign(op, get_dpr_pair(r3));
10539      put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op),
10540                             unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10541                                                   mkU64(63)))));
10542   }
10543   return "slxt";
10544}
10545
10546static const HChar *
10547s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10548{
10549   if (! s390_host_has_dfp) {
10550      emulation_failure(EmFail_S390X_DFP_insn);
10551   } else {
10552      IRTemp op = newTemp(Ity_D64);
10553
10554      assign(op, get_dpr_dw0(r3));
10555      put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op),
10556                            unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10557                                                  mkU64(63)))));
10558   }
10559   return "srdt";
10560}
10561
10562static const HChar *
10563s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10564{
10565   if (! s390_host_has_dfp) {
10566      emulation_failure(EmFail_S390X_DFP_insn);
10567   } else {
10568      IRTemp op = newTemp(Ity_D128);
10569
10570      assign(op, get_dpr_pair(r3));
10571      put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op),
10572                             unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10573                                                   mkU64(63)))));
10574   }
10575   return "srxt";
10576}
10577
10578static const HChar *
10579s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10580{
10581   if (! s390_host_has_dfp) {
10582      emulation_failure(EmFail_S390X_DFP_insn);
10583   } else {
10584      IRTemp value = newTemp(Ity_D32);
10585
10586      assign(value, get_dpr_w0(r1));
10587
10588      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10589   }
10590   return "tdcet";
10591}
10592
10593static const HChar *
10594s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10595{
10596   if (! s390_host_has_dfp) {
10597      emulation_failure(EmFail_S390X_DFP_insn);
10598   } else {
10599      IRTemp value = newTemp(Ity_D64);
10600
10601      assign(value, get_dpr_dw0(r1));
10602
10603      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10604   }
10605   return "tdcdt";
10606}
10607
10608static const HChar *
10609s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10610{
10611   if (! s390_host_has_dfp) {
10612      emulation_failure(EmFail_S390X_DFP_insn);
10613   } else {
10614      IRTemp value = newTemp(Ity_D128);
10615
10616      assign(value, get_dpr_pair(r1));
10617
10618      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10619   }
10620   return "tdcxt";
10621}
10622
10623static const HChar *
10624s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10625{
10626   if (! s390_host_has_dfp) {
10627      emulation_failure(EmFail_S390X_DFP_insn);
10628   } else {
10629      IRTemp value = newTemp(Ity_D32);
10630
10631      assign(value, get_dpr_w0(r1));
10632
10633      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10634   }
10635   return "tdget";
10636}
10637
10638static const HChar *
10639s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10640{
10641   if (! s390_host_has_dfp) {
10642      emulation_failure(EmFail_S390X_DFP_insn);
10643   } else {
10644      IRTemp value = newTemp(Ity_D64);
10645
10646      assign(value, get_dpr_dw0(r1));
10647
10648      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10649   }
10650   return "tdgdt";
10651}
10652
10653static const HChar *
10654s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10655{
10656   if (! s390_host_has_dfp) {
10657      emulation_failure(EmFail_S390X_DFP_insn);
10658   } else {
10659      IRTemp value = newTemp(Ity_D128);
10660
10661      assign(value, get_dpr_pair(r1));
10662
10663      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10664   }
10665   return "tdgxt";
10666}
10667
10668static const HChar *
10669s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10670{
10671   IRTemp len = newTemp(Ity_I64);
10672
10673   assign(len, mkU64(length));
10674   s390_irgen_CLC_EX(len, start1, start2);
10675
10676   return "clc";
10677}
10678
10679static const HChar *
10680s390_irgen_CLCL(UChar r1, UChar r2)
10681{
10682   IRTemp addr1 = newTemp(Ity_I64);
10683   IRTemp addr2 = newTemp(Ity_I64);
10684   IRTemp addr1_load = newTemp(Ity_I64);
10685   IRTemp addr2_load = newTemp(Ity_I64);
10686   IRTemp len1 = newTemp(Ity_I32);
10687   IRTemp len2 = newTemp(Ity_I32);
10688   IRTemp r1p1 = newTemp(Ity_I32);   /* contents of r1 + 1 */
10689   IRTemp r2p1 = newTemp(Ity_I32);   /* contents of r2 + 1 */
10690   IRTemp single1 = newTemp(Ity_I8);
10691   IRTemp single2 = newTemp(Ity_I8);
10692   IRTemp pad = newTemp(Ity_I8);
10693
10694   assign(addr1, get_gpr_dw0(r1));
10695   assign(r1p1, get_gpr_w1(r1 + 1));
10696   assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10697   assign(addr2, get_gpr_dw0(r2));
10698   assign(r2p1, get_gpr_w1(r2 + 1));
10699   assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10700   assign(pad, get_gpr_b4(r2 + 1));
10701
10702   /* len1 == 0 and len2 == 0? Exit */
10703   s390_cc_set(0);
10704   next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10705                                         mkexpr(len2)), mkU32(0)));
10706
10707   /* Because mkite evaluates both the then-clause and the else-clause
10708      we cannot load directly from addr1 here. If len1 is 0, then adddr1
10709      may be NULL and loading from there would segfault. So we provide a
10710      valid dummy address in that case. Loading from there does no harm and
10711      the value will be discarded at runtime. */
10712   assign(addr1_load,
10713          mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10714                mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10715   assign(single1,
10716          mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10717                mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10718
10719   assign(addr2_load,
10720          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10721                mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10722   assign(single2,
10723          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10724                mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10725
10726   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10727   /* Fields differ ? */
10728   next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
10729
10730   /* Update len1 and addr1, unless len1 == 0. */
10731   put_gpr_dw0(r1,
10732               mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10733                     mkexpr(addr1),
10734                     binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10735
10736   /* When updating len1 we must not modify bits (r1+1)[0:39] */
10737   put_gpr_w1(r1 + 1,
10738              mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10739                    binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10740                    binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10741
10742   /* Update len2 and addr2, unless len2 == 0. */
10743   put_gpr_dw0(r2,
10744               mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10745                     mkexpr(addr2),
10746                     binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10747
10748   /* When updating len2 we must not modify bits (r2+1)[0:39] */
10749   put_gpr_w1(r2 + 1,
10750              mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10751                    binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10752                    binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10753
10754   iterate();
10755
10756   return "clcl";
10757}
10758
10759static const HChar *
10760s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10761{
10762   IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10763
10764   addr1 = newTemp(Ity_I64);
10765   addr3 = newTemp(Ity_I64);
10766   addr1_load = newTemp(Ity_I64);
10767   addr3_load = newTemp(Ity_I64);
10768   len1 = newTemp(Ity_I64);
10769   len3 = newTemp(Ity_I64);
10770   single1 = newTemp(Ity_I8);
10771   single3 = newTemp(Ity_I8);
10772
10773   assign(addr1, get_gpr_dw0(r1));
10774   assign(len1, get_gpr_dw0(r1 + 1));
10775   assign(addr3, get_gpr_dw0(r3));
10776   assign(len3, get_gpr_dw0(r3 + 1));
10777
10778   /* len1 == 0 and len3 == 0? Exit */
10779   s390_cc_set(0);
10780   next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10781                                        mkexpr(len3)), mkU64(0)));
10782
10783   /* A mux requires both ways to be possible. This is a way to prevent clcle
10784      from reading from addr1 if it should read from the pad. Since the pad
10785      has no address, just read from the instruction, we discard that anyway */
10786   assign(addr1_load,
10787          mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10788                mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10789
10790   /* same for addr3 */
10791   assign(addr3_load,
10792          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10793                mkU64(guest_IA_curr_instr), mkexpr(addr3)));
10794
10795   assign(single1,
10796          mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10797                unop(Iop_64to8, mkexpr(pad2)),
10798                load(Ity_I8, mkexpr(addr1_load))));
10799
10800   assign(single3,
10801          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10802                unop(Iop_64to8, mkexpr(pad2)),
10803                load(Ity_I8, mkexpr(addr3_load))));
10804
10805   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10806   /* Both fields differ ? */
10807   next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
10808
10809   /* If a length in 0 we must not change this length and the address */
10810   put_gpr_dw0(r1,
10811               mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10812                     mkexpr(addr1),
10813                     binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10814
10815   put_gpr_dw0(r1 + 1,
10816               mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10817                     mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
10818
10819   put_gpr_dw0(r3,
10820               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10821                     mkexpr(addr3),
10822                     binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
10823
10824   put_gpr_dw0(r3 + 1,
10825               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10826                     mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
10827
10828   iterate();
10829
10830   return "clcle";
10831}
10832
10833
10834static void
10835s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10836{
10837   s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10838}
10839
10840
10841static void
10842s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10843{
10844   s390_irgen_xonc(Iop_And8, length, start1, start2);
10845}
10846
10847
10848static void
10849s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10850{
10851   s390_irgen_xonc(Iop_Or8, length, start1, start2);
10852}
10853
10854
10855static void
10856s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10857{
10858   IRTemp current1 = newTemp(Ity_I8);
10859   IRTemp current2 = newTemp(Ity_I8);
10860   IRTemp counter = newTemp(Ity_I64);
10861
10862   assign(counter, get_counter_dw0());
10863   put_counter_dw0(mkU64(0));
10864
10865   assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10866                                       mkexpr(counter))));
10867   assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10868                                       mkexpr(counter))));
10869   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10870                      False);
10871
10872   /* Both fields differ ? */
10873   next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
10874
10875   /* Check for end of field */
10876   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10877   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
10878   put_counter_dw0(mkU64(0));
10879}
10880
10881static void
10882s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10883{
10884   IRTemp counter = newTemp(Ity_I64);
10885
10886   assign(counter, get_counter_dw0());
10887
10888   store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10889         load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10890
10891   /* Check for end of field */
10892   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10893   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
10894   put_counter_dw0(mkU64(0));
10895}
10896
10897static void
10898s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10899{
10900   IRTemp op = newTemp(Ity_I8);
10901   IRTemp op1 = newTemp(Ity_I8);
10902   IRTemp result = newTemp(Ity_I64);
10903   IRTemp counter = newTemp(Ity_I64);
10904
10905   assign(counter, get_counter_dw0());
10906
10907   assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10908
10909   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10910
10911   assign(op1, load(Ity_I8, mkexpr(result)));
10912   store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10913
10914   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10915   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
10916   put_counter_dw0(mkU64(0));
10917}
10918
10919
10920static void
10921s390_irgen_EX_SS(UChar r, IRTemp addr2,
10922                 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
10923                 UInt lensize)
10924{
10925   struct SS {
10926      unsigned int op :  8;
10927      unsigned int l  :  8;
10928      unsigned int b1 :  4;
10929      unsigned int d1 : 12;
10930      unsigned int b2 :  4;
10931      unsigned int d2 : 12;
10932   };
10933   union {
10934      struct SS dec;
10935      unsigned long bytes;
10936   } ss;
10937   IRTemp cond;
10938   IRDirty *d;
10939   IRTemp torun;
10940
10941   IRTemp start1 = newTemp(Ity_I64);
10942   IRTemp start2 = newTemp(Ity_I64);
10943   IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10944   cond = newTemp(Ity_I1);
10945   torun = newTemp(Ity_I64);
10946
10947   assign(torun, load(Ity_I64, mkexpr(addr2)));
10948   /* Start with a check that the saved code is still correct */
10949   assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10950   /* If not, save the new value */
10951   d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10952                          mkIRExprVec_1(mkexpr(torun)));
10953   d->guard = mkexpr(cond);
10954   stmt(IRStmt_Dirty(d));
10955
10956   /* and restart */
10957   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
10958                   mkU64(guest_IA_curr_instr)));
10959   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
10960   restart_if(mkexpr(cond));
10961
10962   ss.bytes = last_execute_target;
10963   assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10964          ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10965   assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10966          ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10967   assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10968          r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10969   irgen(len, start1, start2);
10970
10971   last_execute_target = 0;
10972}
10973
10974static const HChar *
10975s390_irgen_EX(UChar r1, IRTemp addr2)
10976{
10977   switch(last_execute_target & 0xff00000000000000ULL) {
10978   case 0:
10979   {
10980      /* no code information yet */
10981      IRDirty *d;
10982
10983      /* so safe the code... */
10984      d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10985                             mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10986      stmt(IRStmt_Dirty(d));
10987      /* and restart */
10988      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
10989                      mkU64(guest_IA_curr_instr)));
10990      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
10991      restart_if(IRExpr_Const(IRConst_U1(True)));
10992
10993      /* we know that this will be invalidated */
10994      put_IA(mkaddr_expr(guest_IA_next_instr));
10995      dis_res->whatNext = Dis_StopHere;
10996      dis_res->jk_StopHere = Ijk_InvalICache;
10997      break;
10998   }
10999
11000   case 0xd200000000000000ULL:
11001      /* special case MVC */
11002      s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
11003      return "ex@mvc";
11004
11005   case 0xd500000000000000ULL:
11006      /* special case CLC */
11007      s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
11008      return "ex@clc";
11009
11010   case 0xd700000000000000ULL:
11011      /* special case XC */
11012      s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
11013      return "ex@xc";
11014
11015   case 0xd600000000000000ULL:
11016      /* special case OC */
11017      s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
11018      return "ex@oc";
11019
11020   case 0xd400000000000000ULL:
11021      /* special case NC */
11022      s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
11023      return "ex@nc";
11024
11025   case 0xdc00000000000000ULL:
11026      /* special case TR */
11027      s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
11028      return "ex@tr";
11029
11030   default:
11031   {
11032      /* everything else will get a self checking prefix that also checks the
11033         register content */
11034      IRDirty *d;
11035      UChar *bytes;
11036      IRTemp cond;
11037      IRTemp orperand;
11038      IRTemp torun;
11039
11040      cond = newTemp(Ity_I1);
11041      orperand = newTemp(Ity_I64);
11042      torun = newTemp(Ity_I64);
11043
11044      if (r1 == 0)
11045         assign(orperand, mkU64(0));
11046      else
11047         assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
11048      /* This code is going to be translated */
11049      assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
11050             binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
11051
11052      /* Start with a check that saved code is still correct */
11053      assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
11054             mkU64(last_execute_target)));
11055      /* If not, save the new value */
11056      d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
11057                             mkIRExprVec_1(mkexpr(torun)));
11058      d->guard = mkexpr(cond);
11059      stmt(IRStmt_Dirty(d));
11060
11061      /* and restart */
11062      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART), mkU64(guest_IA_curr_instr)));
11063      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
11064      restart_if(mkexpr(cond));
11065
11066      /* Now comes the actual translation */
11067      bytes = (UChar *) &last_execute_target;
11068      s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
11069                            dis_res);
11070      if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
11071         vex_printf("    which was executed by\n");
11072      /* dont make useless translations in the next execute */
11073      last_execute_target = 0;
11074   }
11075   }
11076   return "ex";
11077}
11078
11079static const HChar *
11080s390_irgen_EXRL(UChar r1, UInt offset)
11081{
11082   IRTemp addr = newTemp(Ity_I64);
11083   /* we might save one round trip because we know the target */
11084   if (!last_execute_target)
11085      last_execute_target = *(ULong *)(HWord)
11086                             (guest_IA_curr_instr + offset * 2UL);
11087   assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
11088   s390_irgen_EX(r1, addr);
11089   return "exrl";
11090}
11091
11092static const HChar *
11093s390_irgen_IPM(UChar r1)
11094{
11095   // As long as we dont support SPM, lets just assume 0 as program mask
11096   put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
11097                       binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
11098
11099   return "ipm";
11100}
11101
11102
11103static const HChar *
11104s390_irgen_SRST(UChar r1, UChar r2)
11105{
11106   IRTemp address = newTemp(Ity_I64);
11107   IRTemp next = newTemp(Ity_I64);
11108   IRTemp delim = newTemp(Ity_I8);
11109   IRTemp counter = newTemp(Ity_I64);
11110   IRTemp byte = newTemp(Ity_I8);
11111
11112   assign(address, get_gpr_dw0(r2));
11113   assign(next, get_gpr_dw0(r1));
11114
11115   assign(counter, get_counter_dw0());
11116   put_counter_dw0(mkU64(0));
11117
11118   // start = next?  CC=2 and out r1 and r2 unchanged
11119   s390_cc_set(2);
11120   put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
11121   next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
11122
11123   assign(byte, load(Ity_I8, mkexpr(address)));
11124   assign(delim, get_gpr_b7(0));
11125
11126   // byte = delim? CC=1, R1=address
11127   s390_cc_set(1);
11128   put_gpr_dw0(r1,  mkexpr(address));
11129   next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
11130
11131   // else: all equal, no end yet, loop
11132   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11133   put_gpr_dw0(r1, mkexpr(next));
11134   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
11135
11136   iterate();
11137
11138   return "srst";
11139}
11140
11141static const HChar *
11142s390_irgen_CLST(UChar r1, UChar r2)
11143{
11144   IRTemp address1 = newTemp(Ity_I64);
11145   IRTemp address2 = newTemp(Ity_I64);
11146   IRTemp end = newTemp(Ity_I8);
11147   IRTemp counter = newTemp(Ity_I64);
11148   IRTemp byte1 = newTemp(Ity_I8);
11149   IRTemp byte2 = newTemp(Ity_I8);
11150
11151   assign(address1, get_gpr_dw0(r1));
11152   assign(address2, get_gpr_dw0(r2));
11153   assign(end, get_gpr_b7(0));
11154   assign(counter, get_counter_dw0());
11155   put_counter_dw0(mkU64(0));
11156   assign(byte1, load(Ity_I8, mkexpr(address1)));
11157   assign(byte2, load(Ity_I8, mkexpr(address2)));
11158
11159   // end in both? all equal, reset r1 and r2 to start values
11160   s390_cc_set(0);
11161   put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
11162   put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
11163   next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
11164                      binop(Iop_Or8,
11165                            binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
11166                            binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
11167
11168   put_gpr_dw0(r1, mkexpr(address1));
11169   put_gpr_dw0(r2, mkexpr(address2));
11170
11171   // End found in string1
11172   s390_cc_set(1);
11173   next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
11174
11175   // End found in string2
11176   s390_cc_set(2);
11177   next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
11178
11179   // string1 < string2
11180   s390_cc_set(1);
11181   next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
11182                      unop(Iop_8Uto32, mkexpr(byte2))));
11183
11184   // string2 < string1
11185   s390_cc_set(2);
11186   next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
11187                      unop(Iop_8Uto32, mkexpr(byte1))));
11188
11189   // else: all equal, no end yet, loop
11190   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11191   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
11192   put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
11193
11194   iterate();
11195
11196   return "clst";
11197}
11198
11199static void
11200s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11201{
11202   UChar reg;
11203   IRTemp addr = newTemp(Ity_I64);
11204
11205   assign(addr, mkexpr(op2addr));
11206   reg = r1;
11207   do {
11208      IRTemp old = addr;
11209
11210      reg %= 16;
11211      put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
11212      addr = newTemp(Ity_I64);
11213      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11214      reg++;
11215   } while (reg != (r3 + 1));
11216}
11217
11218static const HChar *
11219s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
11220{
11221   s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11222
11223   return "lm";
11224}
11225
11226static const HChar *
11227s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11228{
11229   s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11230
11231   return "lmy";
11232}
11233
11234static const HChar *
11235s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11236{
11237   UChar reg;
11238   IRTemp addr = newTemp(Ity_I64);
11239
11240   assign(addr, mkexpr(op2addr));
11241   reg = r1;
11242   do {
11243      IRTemp old = addr;
11244
11245      reg %= 16;
11246      put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11247      addr = newTemp(Ity_I64);
11248      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11249      reg++;
11250   } while (reg != (r3 + 1));
11251
11252   return "lmh";
11253}
11254
11255static const HChar *
11256s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11257{
11258   UChar reg;
11259   IRTemp addr = newTemp(Ity_I64);
11260
11261   assign(addr, mkexpr(op2addr));
11262   reg = r1;
11263   do {
11264      IRTemp old = addr;
11265
11266      reg %= 16;
11267      put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11268      addr = newTemp(Ity_I64);
11269      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11270      reg++;
11271   } while (reg != (r3 + 1));
11272
11273   return "lmg";
11274}
11275
11276static void
11277s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11278{
11279   UChar reg;
11280   IRTemp addr = newTemp(Ity_I64);
11281
11282   assign(addr, mkexpr(op2addr));
11283   reg = r1;
11284   do {
11285      IRTemp old = addr;
11286
11287      reg %= 16;
11288      store(mkexpr(addr), get_gpr_w1(reg));
11289      addr = newTemp(Ity_I64);
11290      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11291      reg++;
11292   } while( reg != (r3 + 1));
11293}
11294
11295static const HChar *
11296s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11297{
11298   s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11299
11300   return "stm";
11301}
11302
11303static const HChar *
11304s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11305{
11306   s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11307
11308   return "stmy";
11309}
11310
11311static const HChar *
11312s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11313{
11314   UChar reg;
11315   IRTemp addr = newTemp(Ity_I64);
11316
11317   assign(addr, mkexpr(op2addr));
11318   reg = r1;
11319   do {
11320      IRTemp old = addr;
11321
11322      reg %= 16;
11323      store(mkexpr(addr), get_gpr_w0(reg));
11324      addr = newTemp(Ity_I64);
11325      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11326      reg++;
11327   } while( reg != (r3 + 1));
11328
11329   return "stmh";
11330}
11331
11332static const HChar *
11333s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11334{
11335   UChar reg;
11336   IRTemp addr = newTemp(Ity_I64);
11337
11338   assign(addr, mkexpr(op2addr));
11339   reg = r1;
11340   do {
11341      IRTemp old = addr;
11342
11343      reg %= 16;
11344      store(mkexpr(addr), get_gpr_dw0(reg));
11345      addr = newTemp(Ity_I64);
11346      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11347      reg++;
11348   } while( reg != (r3 + 1));
11349
11350   return "stmg";
11351}
11352
11353static void
11354s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
11355{
11356   IRTemp old1 = newTemp(Ity_I8);
11357   IRTemp old2 = newTemp(Ity_I8);
11358   IRTemp new1 = newTemp(Ity_I8);
11359   IRTemp counter = newTemp(Ity_I32);
11360   IRTemp addr1 = newTemp(Ity_I64);
11361
11362   assign(counter, get_counter_w0());
11363
11364   assign(addr1, binop(Iop_Add64, mkexpr(start1),
11365                       unop(Iop_32Uto64, mkexpr(counter))));
11366
11367   assign(old1, load(Ity_I8, mkexpr(addr1)));
11368   assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11369                                   unop(Iop_32Uto64,mkexpr(counter)))));
11370   assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11371
11372   /* Special case: xc is used to zero memory */
11373   if (op == Iop_Xor8) {
11374      store(mkexpr(addr1),
11375            mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11376                  mkU8(0), mkexpr(new1)));
11377   } else
11378      store(mkexpr(addr1), mkexpr(new1));
11379   put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11380                        get_counter_w1()));
11381
11382   /* Check for end of field */
11383   put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
11384   iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
11385   s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11386                      False);
11387   put_counter_dw0(mkU64(0));
11388}
11389
11390static const HChar *
11391s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11392{
11393   IRTemp len = newTemp(Ity_I32);
11394
11395   assign(len, mkU32(length));
11396   s390_irgen_xonc(Iop_Xor8, len, start1, start2);
11397
11398   return "xc";
11399}
11400
11401static void
11402s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11403{
11404   IRTemp counter = newTemp(Ity_I32);
11405   IRTemp start = newTemp(Ity_I64);
11406   IRTemp addr  = newTemp(Ity_I64);
11407
11408   assign(start,
11409          binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11410
11411   if (length < 8) {
11412      UInt i;
11413
11414      for (i = 0; i <= length; ++i) {
11415         store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11416      }
11417   } else {
11418     assign(counter, get_counter_w0());
11419
11420     assign(addr, binop(Iop_Add64, mkexpr(start),
11421                        unop(Iop_32Uto64, mkexpr(counter))));
11422
11423     store(mkexpr(addr), mkU8(0));
11424
11425     /* Check for end of field */
11426     put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
11427     iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
11428
11429     /* Reset counter */
11430     put_counter_dw0(mkU64(0));
11431   }
11432
11433   s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11434
11435   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
11436      s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11437}
11438
11439static const HChar *
11440s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11441{
11442   IRTemp len = newTemp(Ity_I32);
11443
11444   assign(len, mkU32(length));
11445   s390_irgen_xonc(Iop_And8, len, start1, start2);
11446
11447   return "nc";
11448}
11449
11450static const HChar *
11451s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11452{
11453   IRTemp len = newTemp(Ity_I32);
11454
11455   assign(len, mkU32(length));
11456   s390_irgen_xonc(Iop_Or8, len, start1, start2);
11457
11458   return "oc";
11459}
11460
11461
11462static const HChar *
11463s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11464{
11465   IRTemp len = newTemp(Ity_I64);
11466
11467   assign(len, mkU64(length));
11468   s390_irgen_MVC_EX(len, start1, start2);
11469
11470   return "mvc";
11471}
11472
11473static const HChar *
11474s390_irgen_MVCL(UChar r1, UChar r2)
11475{
11476   IRTemp addr1 = newTemp(Ity_I64);
11477   IRTemp addr2 = newTemp(Ity_I64);
11478   IRTemp addr2_load = newTemp(Ity_I64);
11479   IRTemp r1p1 = newTemp(Ity_I32);   /* contents of r1 + 1 */
11480   IRTemp r2p1 = newTemp(Ity_I32);   /* contents of r2 + 1 */
11481   IRTemp len1 = newTemp(Ity_I32);
11482   IRTemp len2 = newTemp(Ity_I32);
11483   IRTemp pad = newTemp(Ity_I8);
11484   IRTemp single = newTemp(Ity_I8);
11485
11486   assign(addr1, get_gpr_dw0(r1));
11487   assign(r1p1, get_gpr_w1(r1 + 1));
11488   assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11489   assign(addr2, get_gpr_dw0(r2));
11490   assign(r2p1, get_gpr_w1(r2 + 1));
11491   assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11492   assign(pad, get_gpr_b4(r2 + 1));
11493
11494   /* len1 == 0 ? */
11495   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
11496   next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
11497
11498   /* Check for destructive overlap:
11499      addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11500   s390_cc_set(3);
11501   IRTemp cond1 = newTemp(Ity_I32);
11502   assign(cond1, unop(Iop_1Uto32,
11503                      binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11504   IRTemp cond2 = newTemp(Ity_I32);
11505   assign(cond2, unop(Iop_1Uto32,
11506                      binop(Iop_CmpLT64U, mkexpr(addr1),
11507                            binop(Iop_Add64, mkexpr(addr2),
11508                                  unop(Iop_32Uto64, mkexpr(len1))))));
11509   IRTemp cond3 = newTemp(Ity_I32);
11510   assign(cond3, unop(Iop_1Uto32,
11511                      binop(Iop_CmpLT64U,
11512                            mkexpr(addr1),
11513                            binop(Iop_Add64, mkexpr(addr2),
11514                                  unop(Iop_32Uto64, mkexpr(len2))))));
11515
11516   next_insn_if(binop(Iop_CmpEQ32,
11517                      binop(Iop_And32,
11518                            binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11519                            mkexpr(cond3)),
11520                      mkU32(1)));
11521
11522   /* See s390_irgen_CLCL for explanation why we cannot load directly
11523      and need two steps. */
11524   assign(addr2_load,
11525          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11526                mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11527   assign(single,
11528          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11529                mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11530
11531   store(mkexpr(addr1), mkexpr(single));
11532
11533   /* Update addr1 and len1 */
11534   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11535   put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11536
11537   /* Update addr2 and len2 */
11538   put_gpr_dw0(r2,
11539               mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11540                     mkexpr(addr2),
11541                     binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11542
11543   /* When updating len2 we must not modify bits (r2+1)[0:39] */
11544   put_gpr_w1(r2 + 1,
11545              mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11546                    binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11547                    binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11548
11549   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
11550   iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
11551
11552   return "mvcl";
11553}
11554
11555
11556static const HChar *
11557s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11558{
11559   IRTemp addr1, addr3, addr3_load, len1, len3, single;
11560
11561   addr1 = newTemp(Ity_I64);
11562   addr3 = newTemp(Ity_I64);
11563   addr3_load = newTemp(Ity_I64);
11564   len1 = newTemp(Ity_I64);
11565   len3 = newTemp(Ity_I64);
11566   single = newTemp(Ity_I8);
11567
11568   assign(addr1, get_gpr_dw0(r1));
11569   assign(len1, get_gpr_dw0(r1 + 1));
11570   assign(addr3, get_gpr_dw0(r3));
11571   assign(len3, get_gpr_dw0(r3 + 1));
11572
11573   // len1 == 0 ?
11574   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
11575   next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
11576
11577   /* This is a hack to prevent mvcle from reading from addr3 if it
11578      should read from the pad. Since the pad has no address, just
11579      read from the instruction, we discard that anyway */
11580   assign(addr3_load,
11581          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11582                mkU64(guest_IA_curr_instr), mkexpr(addr3)));
11583
11584   assign(single,
11585          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11586                unop(Iop_64to8, mkexpr(pad2)),
11587                load(Ity_I8, mkexpr(addr3_load))));
11588   store(mkexpr(addr1), mkexpr(single));
11589
11590   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11591
11592   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11593
11594   put_gpr_dw0(r3,
11595               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11596                     mkexpr(addr3),
11597                     binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
11598
11599   put_gpr_dw0(r3 + 1,
11600               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11601                     mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
11602
11603   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
11604   iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
11605
11606   return "mvcle";
11607}
11608
11609static const HChar *
11610s390_irgen_MVST(UChar r1, UChar r2)
11611{
11612   IRTemp addr1 = newTemp(Ity_I64);
11613   IRTemp addr2 = newTemp(Ity_I64);
11614   IRTemp end = newTemp(Ity_I8);
11615   IRTemp byte = newTemp(Ity_I8);
11616   IRTemp counter = newTemp(Ity_I64);
11617
11618   assign(addr1, get_gpr_dw0(r1));
11619   assign(addr2, get_gpr_dw0(r2));
11620   assign(counter, get_counter_dw0());
11621   assign(end, get_gpr_b7(0));
11622   assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11623   store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11624
11625   // We use unlimited as cpu-determined number
11626   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11627   iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
11628
11629   // and always set cc=1 at the end + update r1
11630   s390_cc_set(1);
11631   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11632   put_counter_dw0(mkU64(0));
11633
11634   return "mvst";
11635}
11636
11637static void
11638s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11639{
11640   IRTemp op1 = newTemp(Ity_I64);
11641   IRTemp result = newTemp(Ity_I64);
11642
11643   assign(op1, binop(Iop_32HLto64,
11644                     get_gpr_w1(r1),         // high 32 bits
11645                     get_gpr_w1(r1 + 1)));   // low  32 bits
11646   assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11647   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));   // remainder
11648   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11649}
11650
11651static void
11652s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11653{
11654   IRTemp op1 = newTemp(Ity_I128);
11655   IRTemp result = newTemp(Ity_I128);
11656
11657   assign(op1, binop(Iop_64HLto128,
11658                     get_gpr_dw0(r1),         // high 64 bits
11659                     get_gpr_dw0(r1 + 1)));   // low  64 bits
11660   assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11661   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));   // remainder
11662   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11663}
11664
11665static void
11666s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11667{
11668   IRTemp op1 = newTemp(Ity_I64);
11669   IRTemp result = newTemp(Ity_I128);
11670
11671   assign(op1, get_gpr_dw0(r1 + 1));
11672   assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11673   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));   // remainder
11674   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11675}
11676
11677static const HChar *
11678s390_irgen_DR(UChar r1, UChar r2)
11679{
11680   IRTemp op2 = newTemp(Ity_I32);
11681
11682   assign(op2, get_gpr_w1(r2));
11683
11684   s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11685
11686   return "dr";
11687}
11688
11689static const HChar *
11690s390_irgen_D(UChar r1, IRTemp op2addr)
11691{
11692   IRTemp op2 = newTemp(Ity_I32);
11693
11694   assign(op2, load(Ity_I32, mkexpr(op2addr)));
11695
11696   s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11697
11698   return "d";
11699}
11700
11701static const HChar *
11702s390_irgen_DLR(UChar r1, UChar r2)
11703{
11704   IRTemp op2 = newTemp(Ity_I32);
11705
11706   assign(op2, get_gpr_w1(r2));
11707
11708   s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11709
11710   return "dlr";
11711}
11712
11713static const HChar *
11714s390_irgen_DL(UChar r1, IRTemp op2addr)
11715{
11716   IRTemp op2 = newTemp(Ity_I32);
11717
11718   assign(op2, load(Ity_I32, mkexpr(op2addr)));
11719
11720   s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11721
11722   return "dl";
11723}
11724
11725static const HChar *
11726s390_irgen_DLG(UChar r1, IRTemp op2addr)
11727{
11728   IRTemp op2 = newTemp(Ity_I64);
11729
11730   assign(op2, load(Ity_I64, mkexpr(op2addr)));
11731
11732   s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11733
11734   return "dlg";
11735}
11736
11737static const HChar *
11738s390_irgen_DLGR(UChar r1, UChar r2)
11739{
11740   IRTemp op2 = newTemp(Ity_I64);
11741
11742   assign(op2, get_gpr_dw0(r2));
11743
11744   s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11745
11746   return "dlgr";
11747}
11748
11749static const HChar *
11750s390_irgen_DSGR(UChar r1, UChar r2)
11751{
11752   IRTemp op2 = newTemp(Ity_I64);
11753
11754   assign(op2, get_gpr_dw0(r2));
11755
11756   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11757
11758   return "dsgr";
11759}
11760
11761static const HChar *
11762s390_irgen_DSG(UChar r1, IRTemp op2addr)
11763{
11764   IRTemp op2 = newTemp(Ity_I64);
11765
11766   assign(op2, load(Ity_I64, mkexpr(op2addr)));
11767
11768   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11769
11770   return "dsg";
11771}
11772
11773static const HChar *
11774s390_irgen_DSGFR(UChar r1, UChar r2)
11775{
11776   IRTemp op2 = newTemp(Ity_I64);
11777
11778   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11779
11780   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11781
11782   return "dsgfr";
11783}
11784
11785static const HChar *
11786s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11787{
11788   IRTemp op2 = newTemp(Ity_I64);
11789
11790   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11791
11792   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11793
11794   return "dsgf";
11795}
11796
11797static void
11798s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11799{
11800   UChar reg;
11801   IRTemp addr = newTemp(Ity_I64);
11802
11803   assign(addr, mkexpr(op2addr));
11804   reg = r1;
11805   do {
11806      IRTemp old = addr;
11807
11808      reg %= 16;
11809      put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11810      addr = newTemp(Ity_I64);
11811      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11812      reg++;
11813   } while (reg != (r3 + 1));
11814}
11815
11816static const HChar *
11817s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11818{
11819   s390_irgen_load_ar_multiple(r1, r3, op2addr);
11820
11821   return "lam";
11822}
11823
11824static const HChar *
11825s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11826{
11827   s390_irgen_load_ar_multiple(r1, r3, op2addr);
11828
11829   return "lamy";
11830}
11831
11832static void
11833s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11834{
11835   UChar reg;
11836   IRTemp addr = newTemp(Ity_I64);
11837
11838   assign(addr, mkexpr(op2addr));
11839   reg = r1;
11840   do {
11841      IRTemp old = addr;
11842
11843      reg %= 16;
11844      store(mkexpr(addr), get_ar_w0(reg));
11845      addr = newTemp(Ity_I64);
11846      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11847      reg++;
11848   } while (reg != (r3 + 1));
11849}
11850
11851static const HChar *
11852s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11853{
11854   s390_irgen_store_ar_multiple(r1, r3, op2addr);
11855
11856   return "stam";
11857}
11858
11859static const HChar *
11860s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11861{
11862   s390_irgen_store_ar_multiple(r1, r3, op2addr);
11863
11864   return "stamy";
11865}
11866
11867
11868/* Implementation for 32-bit compare-and-swap */
11869static void
11870s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11871{
11872   IRCAS *cas;
11873   IRTemp op1 = newTemp(Ity_I32);
11874   IRTemp old_mem = newTemp(Ity_I32);
11875   IRTemp op3 = newTemp(Ity_I32);
11876   IRTemp result = newTemp(Ity_I32);
11877   IRTemp nequal = newTemp(Ity_I1);
11878
11879   assign(op1, get_gpr_w1(r1));
11880   assign(op3, get_gpr_w1(r3));
11881
11882   /* The first and second operands are compared. If they are equal,
11883      the third operand is stored at the second- operand location. */
11884   cas = mkIRCAS(IRTemp_INVALID, old_mem,
11885                 Iend_BE, mkexpr(op2addr),
11886                 NULL, mkexpr(op1), /* expected value */
11887                 NULL, mkexpr(op3)  /* new value */);
11888   stmt(IRStmt_CAS(cas));
11889
11890   /* Set CC. Operands compared equal -> 0, else 1. */
11891   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11892   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11893
11894   /* If operands were equal (cc == 0) just store the old value op1 in r1.
11895      Otherwise, store the old_value from memory in r1 and yield. */
11896   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11897   put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
11898   yield_if(mkexpr(nequal));
11899}
11900
11901static const HChar *
11902s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11903{
11904   s390_irgen_cas_32(r1, r3, op2addr);
11905
11906   return "cs";
11907}
11908
11909static const HChar *
11910s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11911{
11912   s390_irgen_cas_32(r1, r3, op2addr);
11913
11914   return "csy";
11915}
11916
11917static const HChar *
11918s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11919{
11920   IRCAS *cas;
11921   IRTemp op1 = newTemp(Ity_I64);
11922   IRTemp old_mem = newTemp(Ity_I64);
11923   IRTemp op3 = newTemp(Ity_I64);
11924   IRTemp result = newTemp(Ity_I64);
11925   IRTemp nequal = newTemp(Ity_I1);
11926
11927   assign(op1, get_gpr_dw0(r1));
11928   assign(op3, get_gpr_dw0(r3));
11929
11930   /* The first and second operands are compared. If they are equal,
11931      the third operand is stored at the second- operand location. */
11932   cas = mkIRCAS(IRTemp_INVALID, old_mem,
11933                 Iend_BE, mkexpr(op2addr),
11934                 NULL, mkexpr(op1), /* expected value */
11935                 NULL, mkexpr(op3)  /* new value */);
11936   stmt(IRStmt_CAS(cas));
11937
11938   /* Set CC. Operands compared equal -> 0, else 1. */
11939   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11940   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11941
11942   /* If operands were equal (cc == 0) just store the old value op1 in r1.
11943      Otherwise, store the old_value from memory in r1 and yield. */
11944   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11945   put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
11946   yield_if(mkexpr(nequal));
11947
11948   return "csg";
11949}
11950
11951/* Implementation for 32-bit compare-double-and-swap */
11952static void
11953s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11954{
11955   IRCAS *cas;
11956   IRTemp op1_high = newTemp(Ity_I32);
11957   IRTemp op1_low  = newTemp(Ity_I32);
11958   IRTemp old_mem_high = newTemp(Ity_I32);
11959   IRTemp old_mem_low  = newTemp(Ity_I32);
11960   IRTemp op3_high = newTemp(Ity_I32);
11961   IRTemp op3_low  = newTemp(Ity_I32);
11962   IRTemp result = newTemp(Ity_I32);
11963   IRTemp nequal = newTemp(Ity_I1);
11964
11965   assign(op1_high, get_gpr_w1(r1));
11966   assign(op1_low,  get_gpr_w1(r1+1));
11967   assign(op3_high, get_gpr_w1(r3));
11968   assign(op3_low,  get_gpr_w1(r3+1));
11969
11970   /* The first and second operands are compared. If they are equal,
11971      the third operand is stored at the second-operand location. */
11972   cas = mkIRCAS(old_mem_high, old_mem_low,
11973                 Iend_BE, mkexpr(op2addr),
11974                 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11975                 mkexpr(op3_high), mkexpr(op3_low)  /* new value */);
11976   stmt(IRStmt_CAS(cas));
11977
11978   /* Set CC. Operands compared equal -> 0, else 1. */
11979   assign(result, unop(Iop_1Uto32,
11980          binop(Iop_CmpNE32,
11981                binop(Iop_Or32,
11982                      binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11983                      binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11984                mkU32(0))));
11985
11986   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11987
11988   /* If operands were equal (cc == 0) just store the old value op1 in r1.
11989      Otherwise, store the old_value from memory in r1 and yield. */
11990   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11991   put_gpr_w1(r1,   mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11992   put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low),  mkexpr(op1_low)));
11993   yield_if(mkexpr(nequal));
11994}
11995
11996static const HChar *
11997s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11998{
11999   s390_irgen_cdas_32(r1, r3, op2addr);
12000
12001   return "cds";
12002}
12003
12004static const HChar *
12005s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
12006{
12007   s390_irgen_cdas_32(r1, r3, op2addr);
12008
12009   return "cdsy";
12010}
12011
12012static const HChar *
12013s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
12014{
12015   IRCAS *cas;
12016   IRTemp op1_high = newTemp(Ity_I64);
12017   IRTemp op1_low  = newTemp(Ity_I64);
12018   IRTemp old_mem_high = newTemp(Ity_I64);
12019   IRTemp old_mem_low  = newTemp(Ity_I64);
12020   IRTemp op3_high = newTemp(Ity_I64);
12021   IRTemp op3_low  = newTemp(Ity_I64);
12022   IRTemp result = newTemp(Ity_I64);
12023   IRTemp nequal = newTemp(Ity_I1);
12024
12025   assign(op1_high, get_gpr_dw0(r1));
12026   assign(op1_low,  get_gpr_dw0(r1+1));
12027   assign(op3_high, get_gpr_dw0(r3));
12028   assign(op3_low,  get_gpr_dw0(r3+1));
12029
12030   /* The first and second operands are compared. If they are equal,
12031      the third operand is stored at the second-operand location. */
12032   cas = mkIRCAS(old_mem_high, old_mem_low,
12033                 Iend_BE, mkexpr(op2addr),
12034                 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
12035                 mkexpr(op3_high), mkexpr(op3_low)  /* new value */);
12036   stmt(IRStmt_CAS(cas));
12037
12038   /* Set CC. Operands compared equal -> 0, else 1. */
12039   assign(result, unop(Iop_1Uto64,
12040          binop(Iop_CmpNE64,
12041                binop(Iop_Or64,
12042                      binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
12043                      binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
12044                mkU64(0))));
12045
12046   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12047
12048   /* If operands were equal (cc == 0) just store the old value op1 in r1.
12049      Otherwise, store the old_value from memory in r1 and yield. */
12050   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12051   put_gpr_dw0(r1,   mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
12052   put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low),  mkexpr(op1_low)));
12053   yield_if(mkexpr(nequal));
12054
12055   return "cdsg";
12056}
12057
12058
12059/* Binary floating point */
12060
12061static const HChar *
12062s390_irgen_AXBR(UChar r1, UChar r2)
12063{
12064   IRTemp op1 = newTemp(Ity_F128);
12065   IRTemp op2 = newTemp(Ity_F128);
12066   IRTemp result = newTemp(Ity_F128);
12067   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12068
12069   assign(op1, get_fpr_pair(r1));
12070   assign(op2, get_fpr_pair(r2));
12071   assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
12072                        mkexpr(op2)));
12073   put_fpr_pair(r1, mkexpr(result));
12074
12075   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12076
12077   return "axbr";
12078}
12079
12080static const HChar *
12081s390_irgen_CEBR(UChar r1, UChar r2)
12082{
12083   IRTemp op1 = newTemp(Ity_F32);
12084   IRTemp op2 = newTemp(Ity_F32);
12085   IRTemp cc_vex  = newTemp(Ity_I32);
12086   IRTemp cc_s390 = newTemp(Ity_I32);
12087
12088   assign(op1, get_fpr_w0(r1));
12089   assign(op2, get_fpr_w0(r2));
12090   assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12091
12092   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12093   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12094
12095   return "cebr";
12096}
12097
12098static const HChar *
12099s390_irgen_CDBR(UChar r1, UChar r2)
12100{
12101   IRTemp op1 = newTemp(Ity_F64);
12102   IRTemp op2 = newTemp(Ity_F64);
12103   IRTemp cc_vex  = newTemp(Ity_I32);
12104   IRTemp cc_s390 = newTemp(Ity_I32);
12105
12106   assign(op1, get_fpr_dw0(r1));
12107   assign(op2, get_fpr_dw0(r2));
12108   assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12109
12110   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12111   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12112
12113   return "cdbr";
12114}
12115
12116static const HChar *
12117s390_irgen_CXBR(UChar r1, UChar r2)
12118{
12119   IRTemp op1 = newTemp(Ity_F128);
12120   IRTemp op2 = newTemp(Ity_F128);
12121   IRTemp cc_vex  = newTemp(Ity_I32);
12122   IRTemp cc_s390 = newTemp(Ity_I32);
12123
12124   assign(op1, get_fpr_pair(r1));
12125   assign(op2, get_fpr_pair(r2));
12126   assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
12127
12128   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12129   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12130
12131   return "cxbr";
12132}
12133
12134static const HChar *
12135s390_irgen_CEB(UChar r1, IRTemp op2addr)
12136{
12137   IRTemp op1 = newTemp(Ity_F32);
12138   IRTemp op2 = newTemp(Ity_F32);
12139   IRTemp cc_vex  = newTemp(Ity_I32);
12140   IRTemp cc_s390 = newTemp(Ity_I32);
12141
12142   assign(op1, get_fpr_w0(r1));
12143   assign(op2, load(Ity_F32, mkexpr(op2addr)));
12144   assign(cc_vex,  binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12145
12146   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12147   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12148
12149   return "ceb";
12150}
12151
12152static const HChar *
12153s390_irgen_CDB(UChar r1, IRTemp op2addr)
12154{
12155   IRTemp op1 = newTemp(Ity_F64);
12156   IRTemp op2 = newTemp(Ity_F64);
12157   IRTemp cc_vex  = newTemp(Ity_I32);
12158   IRTemp cc_s390 = newTemp(Ity_I32);
12159
12160   assign(op1, get_fpr_dw0(r1));
12161   assign(op2, load(Ity_F64, mkexpr(op2addr)));
12162   assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12163
12164   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
12165   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12166
12167   return "cdb";
12168}
12169
12170static const HChar *
12171s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
12172                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12173{
12174   IRTemp op2 = newTemp(Ity_I32);
12175
12176   assign(op2, get_gpr_w1(r2));
12177   put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
12178
12179   return "cxfbr";
12180}
12181
12182static const HChar *
12183s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
12184                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12185{
12186   if (! s390_host_has_fpext) {
12187      emulation_failure(EmFail_S390X_fpext);
12188   } else {
12189      IRTemp op2 = newTemp(Ity_I32);
12190
12191      assign(op2, get_gpr_w1(r2));
12192      put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
12193   }
12194   return "cxlfbr";
12195}
12196
12197
12198static const HChar *
12199s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
12200                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12201{
12202   IRTemp op2 = newTemp(Ity_I64);
12203
12204   assign(op2, get_gpr_dw0(r2));
12205   put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
12206
12207   return "cxgbr";
12208}
12209
12210static const HChar *
12211s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
12212                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12213{
12214   if (! s390_host_has_fpext) {
12215      emulation_failure(EmFail_S390X_fpext);
12216   } else {
12217      IRTemp op2 = newTemp(Ity_I64);
12218
12219      assign(op2, get_gpr_dw0(r2));
12220      put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
12221   }
12222   return "cxlgbr";
12223}
12224
12225static const HChar *
12226s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
12227                 UChar r1, UChar r2)
12228{
12229   IRTemp op = newTemp(Ity_F128);
12230   IRTemp result = newTemp(Ity_I32);
12231   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12232
12233   assign(op, get_fpr_pair(r2));
12234   assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
12235                        mkexpr(op)));
12236   put_gpr_w1(r1, mkexpr(result));
12237   s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
12238
12239   return "cfxbr";
12240}
12241
12242static const HChar *
12243s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12244                  UChar r1, UChar r2)
12245{
12246   if (! s390_host_has_fpext) {
12247      emulation_failure(EmFail_S390X_fpext);
12248   } else {
12249      IRTemp op = newTemp(Ity_F128);
12250      IRTemp result = newTemp(Ity_I32);
12251      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12252
12253      assign(op, get_fpr_pair(r2));
12254      assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
12255                           mkexpr(op)));
12256      put_gpr_w1(r1, mkexpr(result));
12257      s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
12258   }
12259   return "clfxbr";
12260}
12261
12262
12263static const HChar *
12264s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12265                 UChar r1, UChar r2)
12266{
12267   IRTemp op = newTemp(Ity_F128);
12268   IRTemp result = newTemp(Ity_I64);
12269   IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12270
12271   assign(op, get_fpr_pair(r2));
12272   assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
12273                        mkexpr(op)));
12274   put_gpr_dw0(r1, mkexpr(result));
12275   s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
12276
12277   return "cgxbr";
12278}
12279
12280static const HChar *
12281s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12282                  UChar r1, UChar r2)
12283{
12284   if (! s390_host_has_fpext) {
12285      emulation_failure(EmFail_S390X_fpext);
12286   } else {
12287      IRTemp op = newTemp(Ity_F128);
12288      IRTemp result = newTemp(Ity_I64);
12289      IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
12290
12291      assign(op, get_fpr_pair(r2));
12292      assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
12293                           mkexpr(op)));
12294      put_gpr_dw0(r1, mkexpr(result));
12295      s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12296                              rounding_mode);
12297   }
12298   return "clgxbr";
12299}
12300
12301static const HChar *
12302s390_irgen_DXBR(UChar r1, UChar r2)
12303{
12304   IRTemp op1 = newTemp(Ity_F128);
12305   IRTemp op2 = newTemp(Ity_F128);
12306   IRTemp result = newTemp(Ity_F128);
12307   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12308
12309   assign(op1, get_fpr_pair(r1));
12310   assign(op2, get_fpr_pair(r2));
12311   assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
12312                        mkexpr(op2)));
12313   put_fpr_pair(r1, mkexpr(result));
12314
12315   return "dxbr";
12316}
12317
12318static const HChar *
12319s390_irgen_LTXBR(UChar r1, UChar r2)
12320{
12321   IRTemp result = newTemp(Ity_F128);
12322
12323   assign(result, get_fpr_pair(r2));
12324   put_fpr_pair(r1, mkexpr(result));
12325   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12326
12327   return "ltxbr";
12328}
12329
12330static const HChar *
12331s390_irgen_LCXBR(UChar r1, UChar r2)
12332{
12333   IRTemp result = newTemp(Ity_F128);
12334
12335   assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
12336   put_fpr_pair(r1, mkexpr(result));
12337   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12338
12339   return "lcxbr";
12340}
12341
12342static const HChar *
12343s390_irgen_LXDBR(UChar r1, UChar r2)
12344{
12345   IRTemp op = newTemp(Ity_F64);
12346
12347   assign(op, get_fpr_dw0(r2));
12348   put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12349
12350   return "lxdbr";
12351}
12352
12353static const HChar *
12354s390_irgen_LXEBR(UChar r1, UChar r2)
12355{
12356   IRTemp op = newTemp(Ity_F32);
12357
12358   assign(op, get_fpr_w0(r2));
12359   put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12360
12361   return "lxebr";
12362}
12363
12364static const HChar *
12365s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12366{
12367   IRTemp op = newTemp(Ity_F64);
12368
12369   assign(op, load(Ity_F64, mkexpr(op2addr)));
12370   put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12371
12372   return "lxdb";
12373}
12374
12375static const HChar *
12376s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12377{
12378   IRTemp op = newTemp(Ity_F32);
12379
12380   assign(op, load(Ity_F32, mkexpr(op2addr)));
12381   put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12382
12383   return "lxeb";
12384}
12385
12386static const HChar *
12387s390_irgen_LNEBR(UChar r1, UChar r2)
12388{
12389   IRTemp result = newTemp(Ity_F32);
12390
12391   assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12392   put_fpr_w0(r1, mkexpr(result));
12393   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12394
12395   return "lnebr";
12396}
12397
12398static const HChar *
12399s390_irgen_LNDBR(UChar r1, UChar r2)
12400{
12401   IRTemp result = newTemp(Ity_F64);
12402
12403   assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12404   put_fpr_dw0(r1, mkexpr(result));
12405   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12406
12407   return "lndbr";
12408}
12409
12410static const HChar *
12411s390_irgen_LNXBR(UChar r1, UChar r2)
12412{
12413   IRTemp result = newTemp(Ity_F128);
12414
12415   assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12416   put_fpr_pair(r1, mkexpr(result));
12417   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12418
12419   return "lnxbr";
12420}
12421
12422static const HChar *
12423s390_irgen_LPEBR(UChar r1, UChar r2)
12424{
12425   IRTemp result = newTemp(Ity_F32);
12426
12427   assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12428   put_fpr_w0(r1, mkexpr(result));
12429   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12430
12431   return "lpebr";
12432}
12433
12434static const HChar *
12435s390_irgen_LPDBR(UChar r1, UChar r2)
12436{
12437   IRTemp result = newTemp(Ity_F64);
12438
12439   assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12440   put_fpr_dw0(r1, mkexpr(result));
12441   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12442
12443   return "lpdbr";
12444}
12445
12446static const HChar *
12447s390_irgen_LPXBR(UChar r1, UChar r2)
12448{
12449   IRTemp result = newTemp(Ity_F128);
12450
12451   assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12452   put_fpr_pair(r1, mkexpr(result));
12453   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12454
12455   return "lpxbr";
12456}
12457
12458static const HChar *
12459s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12460                 UChar r1, UChar r2)
12461{
12462   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
12463      emulation_warning(EmWarn_S390X_fpext_rounding);
12464      m3 = S390_BFP_ROUND_PER_FPC;
12465   }
12466   IRTemp result = newTemp(Ity_F64);
12467
12468   assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
12469                        get_fpr_pair(r2)));
12470   put_fpr_dw0(r1, mkexpr(result));
12471
12472   return "ldxbr";
12473}
12474
12475static const HChar *
12476s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12477                 UChar r1, UChar r2)
12478{
12479   if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
12480      emulation_warning(EmWarn_S390X_fpext_rounding);
12481      m3 = S390_BFP_ROUND_PER_FPC;
12482   }
12483   IRTemp result = newTemp(Ity_F32);
12484
12485   assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
12486                        get_fpr_pair(r2)));
12487   put_fpr_w0(r1, mkexpr(result));
12488
12489   return "lexbr";
12490}
12491
12492static const HChar *
12493s390_irgen_MXBR(UChar r1, UChar r2)
12494{
12495   IRTemp op1 = newTemp(Ity_F128);
12496   IRTemp op2 = newTemp(Ity_F128);
12497   IRTemp result = newTemp(Ity_F128);
12498   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12499
12500   assign(op1, get_fpr_pair(r1));
12501   assign(op2, get_fpr_pair(r2));
12502   assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
12503                        mkexpr(op2)));
12504   put_fpr_pair(r1, mkexpr(result));
12505
12506   return "mxbr";
12507}
12508
12509static const HChar *
12510s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12511{
12512   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12513
12514   put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
12515                      get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
12516
12517   return "maebr";
12518}
12519
12520static const HChar *
12521s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12522{
12523   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12524
12525   put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
12526                       get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
12527
12528   return "madbr";
12529}
12530
12531static const HChar *
12532s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12533{
12534   IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
12535   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12536
12537   put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
12538                      get_fpr_w0(r3), op2, get_fpr_w0(r1)));
12539
12540   return "maeb";
12541}
12542
12543static const HChar *
12544s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12545{
12546   IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
12547   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12548
12549   put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
12550                       get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
12551
12552   return "madb";
12553}
12554
12555static const HChar *
12556s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12557{
12558   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12559
12560   put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
12561                      get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
12562
12563   return "msebr";
12564}
12565
12566static const HChar *
12567s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12568{
12569   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12570
12571   put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
12572                       get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
12573
12574   return "msdbr";
12575}
12576
12577static const HChar *
12578s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12579{
12580   IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
12581   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12582
12583   put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
12584                      get_fpr_w0(r3), op2, get_fpr_w0(r1)));
12585
12586   return "mseb";
12587}
12588
12589static const HChar *
12590s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12591{
12592   IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
12593   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12594
12595   put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
12596                       get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
12597
12598   return "msdb";
12599}
12600
12601static const HChar *
12602s390_irgen_SQEBR(UChar r1, UChar r2)
12603{
12604   IRTemp result = newTemp(Ity_F32);
12605   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12606
12607   assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
12608   put_fpr_w0(r1, mkexpr(result));
12609
12610   return "sqebr";
12611}
12612
12613static const HChar *
12614s390_irgen_SQDBR(UChar r1, UChar r2)
12615{
12616   IRTemp result = newTemp(Ity_F64);
12617   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12618
12619   assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
12620   put_fpr_dw0(r1, mkexpr(result));
12621
12622   return "sqdbr";
12623}
12624
12625static const HChar *
12626s390_irgen_SQXBR(UChar r1, UChar r2)
12627{
12628   IRTemp result = newTemp(Ity_F128);
12629   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12630
12631   assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12632                        get_fpr_pair(r2)));
12633   put_fpr_pair(r1, mkexpr(result));
12634
12635   return "sqxbr";
12636}
12637
12638static const HChar *
12639s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12640{
12641   IRTemp op = newTemp(Ity_F32);
12642   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12643
12644   assign(op, load(Ity_F32, mkexpr(op2addr)));
12645   put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
12646
12647   return "sqeb";
12648}
12649
12650static const HChar *
12651s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12652{
12653   IRTemp op = newTemp(Ity_F64);
12654   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12655
12656   assign(op, load(Ity_F64, mkexpr(op2addr)));
12657   put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
12658
12659   return "sqdb";
12660}
12661
12662static const HChar *
12663s390_irgen_SXBR(UChar r1, UChar r2)
12664{
12665   IRTemp op1 = newTemp(Ity_F128);
12666   IRTemp op2 = newTemp(Ity_F128);
12667   IRTemp result = newTemp(Ity_F128);
12668   IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
12669
12670   assign(op1, get_fpr_pair(r1));
12671   assign(op2, get_fpr_pair(r2));
12672   assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
12673                        mkexpr(op2)));
12674   put_fpr_pair(r1, mkexpr(result));
12675   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12676
12677   return "sxbr";
12678}
12679
12680static const HChar *
12681s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12682{
12683   IRTemp value = newTemp(Ity_F32);
12684
12685   assign(value, get_fpr_w0(r1));
12686
12687   s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12688
12689   return "tceb";
12690}
12691
12692static const HChar *
12693s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12694{
12695   IRTemp value = newTemp(Ity_F64);
12696
12697   assign(value, get_fpr_dw0(r1));
12698
12699   s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12700
12701   return "tcdb";
12702}
12703
12704static const HChar *
12705s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12706{
12707   IRTemp value = newTemp(Ity_F128);
12708
12709   assign(value, get_fpr_pair(r1));
12710
12711   s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12712
12713   return "tcxb";
12714}
12715
12716static const HChar *
12717s390_irgen_LCDFR(UChar r1, UChar r2)
12718{
12719   IRTemp result = newTemp(Ity_F64);
12720
12721   assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12722   put_fpr_dw0(r1, mkexpr(result));
12723
12724   return "lcdfr";
12725}
12726
12727static const HChar *
12728s390_irgen_LNDFR(UChar r1, UChar r2)
12729{
12730   IRTemp result = newTemp(Ity_F64);
12731
12732   assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12733   put_fpr_dw0(r1, mkexpr(result));
12734
12735   return "lndfr";
12736}
12737
12738static const HChar *
12739s390_irgen_LPDFR(UChar r1, UChar r2)
12740{
12741   IRTemp result = newTemp(Ity_F64);
12742
12743   assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12744   put_fpr_dw0(r1, mkexpr(result));
12745
12746   return "lpdfr";
12747}
12748
12749static const HChar *
12750s390_irgen_LDGR(UChar r1, UChar r2)
12751{
12752   put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12753
12754   return "ldgr";
12755}
12756
12757static const HChar *
12758s390_irgen_LGDR(UChar r1, UChar r2)
12759{
12760   put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12761
12762   return "lgdr";
12763}
12764
12765
12766static const HChar *
12767s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12768{
12769   IRTemp sign  = newTemp(Ity_I64);
12770   IRTemp value = newTemp(Ity_I64);
12771
12772   assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12773                      mkU64(1ULL << 63)));
12774   assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12775                       mkU64((1ULL << 63) - 1)));
12776   put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12777                                                    mkexpr(sign))));
12778
12779   return "cpsdr";
12780}
12781
12782
12783static IRExpr *
12784s390_call_cvb(IRExpr *in)
12785{
12786   IRExpr **args, *call;
12787
12788   args = mkIRExprVec_1(in);
12789   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12790                        "s390_do_cvb", &s390_do_cvb, args);
12791
12792   /* Nothing is excluded from definedness checking. */
12793   call->Iex.CCall.cee->mcx_mask = 0;
12794
12795   return call;
12796}
12797
12798static const HChar *
12799s390_irgen_CVB(UChar r1, IRTemp op2addr)
12800{
12801   put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12802
12803   return "cvb";
12804}
12805
12806static const HChar *
12807s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12808{
12809   put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12810
12811   return "cvby";
12812}
12813
12814
12815static IRExpr *
12816s390_call_cvd(IRExpr *in)
12817{
12818   IRExpr **args, *call;
12819
12820   args = mkIRExprVec_1(in);
12821   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12822                        "s390_do_cvd", &s390_do_cvd, args);
12823
12824   /* Nothing is excluded from definedness checking. */
12825   call->Iex.CCall.cee->mcx_mask = 0;
12826
12827   return call;
12828}
12829
12830static const HChar *
12831s390_irgen_CVD(UChar r1, IRTemp op2addr)
12832{
12833   store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
12834
12835   return "cvd";
12836}
12837
12838static const HChar *
12839s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12840{
12841   store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12842
12843   return "cvdy";
12844}
12845
12846static const HChar *
12847s390_irgen_FLOGR(UChar r1, UChar r2)
12848{
12849   IRTemp input    = newTemp(Ity_I64);
12850   IRTemp not_zero = newTemp(Ity_I64);
12851   IRTemp tmpnum   = newTemp(Ity_I64);
12852   IRTemp num      = newTemp(Ity_I64);
12853   IRTemp shift_amount = newTemp(Ity_I8);
12854
12855   /* We use the "count leading zeroes" operator because the number of
12856      leading zeroes is identical with the bit position of the first '1' bit.
12857      However, that operator does not work when the input value is zero.
12858      Therefore, we set the LSB of the input value to 1 and use Clz64 on
12859      the modified value. If input == 0, then the result is 64. Otherwise,
12860      the result of Clz64 is what we want. */
12861
12862   assign(input, get_gpr_dw0(r2));
12863   assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12864   assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12865
12866   /* num = (input == 0) ? 64 : tmpnum */
12867   assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12868                     /* == 0 */ mkU64(64),
12869                     /* != 0 */ mkexpr(tmpnum)));
12870
12871   put_gpr_dw0(r1, mkexpr(num));
12872
12873   /* Set the leftmost '1' bit of the input value to zero. The general scheme
12874      is to first shift the input value by NUM + 1 bits to the left which
12875      causes the leftmost '1' bit to disappear. Then we shift logically to
12876      the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12877      Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12878      the width of the value-to-be-shifted, we need to special case
12879      NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12880      For both such INPUT values the result will be 0. */
12881
12882   assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12883                          mkU64(1))));
12884
12885   put_gpr_dw0(r1 + 1,
12886               mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12887                     /* == 0 || == 1*/ mkU64(0),
12888                     /* otherwise */
12889                     binop(Iop_Shr64,
12890                           binop(Iop_Shl64, mkexpr(input),
12891                                 mkexpr(shift_amount)),
12892                           mkexpr(shift_amount))));
12893
12894   /* Compare the original value as an unsigned integer with 0. */
12895   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12896                      mktemp(Ity_I64, mkU64(0)), False);
12897
12898   return "flogr";
12899}
12900
12901static const HChar *
12902s390_irgen_STCK(IRTemp op2addr)
12903{
12904   IRDirty *d;
12905   IRTemp cc = newTemp(Ity_I64);
12906
12907   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12908                         &s390x_dirtyhelper_STCK,
12909                         mkIRExprVec_1(mkexpr(op2addr)));
12910   d->mFx   = Ifx_Write;
12911   d->mAddr = mkexpr(op2addr);
12912   d->mSize = 8;
12913   stmt(IRStmt_Dirty(d));
12914   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12915                      mkexpr(cc), mkU64(0), mkU64(0));
12916   return "stck";
12917}
12918
12919static const HChar *
12920s390_irgen_STCKF(IRTemp op2addr)
12921{
12922   if (! s390_host_has_stckf) {
12923      emulation_failure(EmFail_S390X_stckf);
12924   } else {
12925      IRTemp cc = newTemp(Ity_I64);
12926
12927      IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12928                                     &s390x_dirtyhelper_STCKF,
12929                                     mkIRExprVec_1(mkexpr(op2addr)));
12930      d->mFx   = Ifx_Write;
12931      d->mAddr = mkexpr(op2addr);
12932      d->mSize = 8;
12933      stmt(IRStmt_Dirty(d));
12934      s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12935                         mkexpr(cc), mkU64(0), mkU64(0));
12936   }
12937   return "stckf";
12938}
12939
12940static const HChar *
12941s390_irgen_STCKE(IRTemp op2addr)
12942{
12943   IRDirty *d;
12944   IRTemp cc = newTemp(Ity_I64);
12945
12946   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12947                         &s390x_dirtyhelper_STCKE,
12948                         mkIRExprVec_1(mkexpr(op2addr)));
12949   d->mFx   = Ifx_Write;
12950   d->mAddr = mkexpr(op2addr);
12951   d->mSize = 16;
12952   stmt(IRStmt_Dirty(d));
12953   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12954                      mkexpr(cc), mkU64(0), mkU64(0));
12955   return "stcke";
12956}
12957
12958static const HChar *
12959s390_irgen_STFLE(IRTemp op2addr)
12960{
12961   if (! s390_host_has_stfle) {
12962      emulation_failure(EmFail_S390X_stfle);
12963      return "stfle";
12964   }
12965
12966   IRDirty *d;
12967   IRTemp cc = newTemp(Ity_I64);
12968
12969   /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper */
12970   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12971                         &s390x_dirtyhelper_STFLE,
12972                         mkIRExprVec_2(IRExpr_BBPTR(), mkexpr(op2addr)));
12973
12974   d->nFxState = 1;
12975   vex_bzero(&d->fxState, sizeof(d->fxState));
12976
12977   d->fxState[0].fx     = Ifx_Modify;  /* read then write */
12978   d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12979   d->fxState[0].size   = sizeof(ULong);
12980
12981   d->mAddr = mkexpr(op2addr);
12982   /* Pretend all double words are written */
12983   d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12984   d->mFx   = Ifx_Write;
12985
12986   stmt(IRStmt_Dirty(d));
12987
12988   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12989
12990   return "stfle";
12991}
12992
12993static const HChar *
12994s390_irgen_CKSM(UChar r1,UChar r2)
12995{
12996   IRTemp addr = newTemp(Ity_I64);
12997   IRTemp op = newTemp(Ity_I32);
12998   IRTemp len = newTemp(Ity_I64);
12999   IRTemp oldval = newTemp(Ity_I32);
13000   IRTemp mask = newTemp(Ity_I32);
13001   IRTemp newop = newTemp(Ity_I32);
13002   IRTemp result = newTemp(Ity_I32);
13003   IRTemp result1 = newTemp(Ity_I32);
13004   IRTemp inc = newTemp(Ity_I64);
13005
13006   assign(oldval, get_gpr_w1(r1));
13007   assign(addr, get_gpr_dw0(r2));
13008   assign(len, get_gpr_dw0(r2+1));
13009
13010   /* Condition code is always zero. */
13011   s390_cc_set(0);
13012
13013   /* If length is zero, there is no need to calculate the checksum */
13014   next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
13015
13016   /* Assiging the increment variable to adjust address and length
13017      later on. */
13018   assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
13019                           mkexpr(len), mkU64(4)));
13020
13021   /* If length < 4 the final 4-byte 2nd operand value is computed by
13022      appending the remaining bytes to the right with 0. This is done
13023      by AND'ing the 4 bytes loaded from memory with an appropriate
13024      mask. If length >= 4, that mask is simply 0xffffffff. */
13025
13026   assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
13027                      /* Mask computation when len < 4:
13028                         0xffffffff << (32 - (len % 4)*8) */
13029                      binop(Iop_Shl32, mkU32(0xffffffff),
13030                            unop(Iop_32to8,
13031                                 binop(Iop_Sub32, mkU32(32),
13032                                       binop(Iop_Shl32,
13033                                             unop(Iop_64to32,
13034                                                  binop(Iop_And64,
13035                                                        mkexpr(len), mkU64(3))),
13036                                             mkU8(3))))),
13037                      mkU32(0xffffffff)));
13038
13039   assign(op, load(Ity_I32, mkexpr(addr)));
13040   assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
13041   assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
13042
13043   /* Checking for carry */
13044   assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
13045                         binop(Iop_Add32, mkexpr(result), mkU32(1)),
13046                         mkexpr(result)));
13047
13048   put_gpr_w1(r1, mkexpr(result1));
13049   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
13050   put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
13051
13052   iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
13053
13054   return "cksm";
13055}
13056
13057static const HChar *
13058s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
13059{
13060   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13061   src_addr = newTemp(Ity_I64);
13062   des_addr = newTemp(Ity_I64);
13063   tab_addr = newTemp(Ity_I64);
13064   test_byte = newTemp(Ity_I8);
13065   src_len = newTemp(Ity_I64);
13066
13067   assign(src_addr, get_gpr_dw0(r2));
13068   assign(des_addr, get_gpr_dw0(r1));
13069   assign(tab_addr, get_gpr_dw0(1));
13070   assign(src_len, get_gpr_dw0(r1+1));
13071   assign(test_byte, get_gpr_b7(0));
13072
13073   IRTemp op = newTemp(Ity_I8);
13074   IRTemp op1 = newTemp(Ity_I8);
13075   IRTemp result = newTemp(Ity_I64);
13076
13077   /* End of source string? We're done; proceed to next insn */
13078   s390_cc_set(0);
13079   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13080
13081   /* Load character from source string, index translation table and
13082      store translated character in op1. */
13083   assign(op, load(Ity_I8, mkexpr(src_addr)));
13084
13085   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13086                        mkexpr(tab_addr)));
13087   assign(op1, load(Ity_I8, mkexpr(result)));
13088
13089   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13090      s390_cc_set(1);
13091      next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
13092   }
13093   store(get_gpr_dw0(r1), mkexpr(op1));
13094
13095   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13096   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13097   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13098
13099   iterate();
13100
13101   return "troo";
13102}
13103
13104static const HChar *
13105s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
13106{
13107   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13108   src_addr = newTemp(Ity_I64);
13109   des_addr = newTemp(Ity_I64);
13110   tab_addr = newTemp(Ity_I64);
13111   test_byte = newTemp(Ity_I8);
13112   src_len = newTemp(Ity_I64);
13113
13114   assign(src_addr, get_gpr_dw0(r2));
13115   assign(des_addr, get_gpr_dw0(r1));
13116   assign(tab_addr, get_gpr_dw0(1));
13117   assign(src_len, get_gpr_dw0(r1+1));
13118   assign(test_byte, get_gpr_b7(0));
13119
13120   IRTemp op = newTemp(Ity_I16);
13121   IRTemp op1 = newTemp(Ity_I8);
13122   IRTemp result = newTemp(Ity_I64);
13123
13124   /* End of source string? We're done; proceed to next insn */
13125   s390_cc_set(0);
13126   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13127
13128   /* Load character from source string, index translation table and
13129      store translated character in op1. */
13130   assign(op, load(Ity_I16, mkexpr(src_addr)));
13131
13132   assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13133                        mkexpr(tab_addr)));
13134
13135   assign(op1, load(Ity_I8, mkexpr(result)));
13136
13137   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13138      s390_cc_set(1);
13139      next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
13140   }
13141   store(get_gpr_dw0(r1), mkexpr(op1));
13142
13143   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13144   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13145   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13146
13147   iterate();
13148
13149   return "trto";
13150}
13151
13152static const HChar *
13153s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
13154{
13155   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13156   src_addr = newTemp(Ity_I64);
13157   des_addr = newTemp(Ity_I64);
13158   tab_addr = newTemp(Ity_I64);
13159   test_byte = newTemp(Ity_I16);
13160   src_len = newTemp(Ity_I64);
13161
13162   assign(src_addr, get_gpr_dw0(r2));
13163   assign(des_addr, get_gpr_dw0(r1));
13164   assign(tab_addr, get_gpr_dw0(1));
13165   assign(src_len, get_gpr_dw0(r1+1));
13166   assign(test_byte, get_gpr_hw3(0));
13167
13168   IRTemp op = newTemp(Ity_I8);
13169   IRTemp op1 = newTemp(Ity_I16);
13170   IRTemp result = newTemp(Ity_I64);
13171
13172   /* End of source string? We're done; proceed to next insn */
13173   s390_cc_set(0);
13174   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13175
13176   /* Load character from source string, index translation table and
13177      store translated character in op1. */
13178   assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
13179
13180   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13181                        mkexpr(tab_addr)));
13182   assign(op1, load(Ity_I16, mkexpr(result)));
13183
13184   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13185      s390_cc_set(1);
13186      next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
13187   }
13188   store(get_gpr_dw0(r1), mkexpr(op1));
13189
13190   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13191   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13192   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13193
13194   iterate();
13195
13196   return "trot";
13197}
13198
13199static const HChar *
13200s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
13201{
13202   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13203   src_addr = newTemp(Ity_I64);
13204   des_addr = newTemp(Ity_I64);
13205   tab_addr = newTemp(Ity_I64);
13206   test_byte = newTemp(Ity_I16);
13207   src_len = newTemp(Ity_I64);
13208
13209   assign(src_addr, get_gpr_dw0(r2));
13210   assign(des_addr, get_gpr_dw0(r1));
13211   assign(tab_addr, get_gpr_dw0(1));
13212   assign(src_len, get_gpr_dw0(r1+1));
13213   assign(test_byte, get_gpr_hw3(0));
13214
13215   IRTemp op = newTemp(Ity_I16);
13216   IRTemp op1 = newTemp(Ity_I16);
13217   IRTemp result = newTemp(Ity_I64);
13218
13219   /* End of source string? We're done; proceed to next insn */
13220   s390_cc_set(0);
13221   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13222
13223   /* Load character from source string, index translation table and
13224      store translated character in op1. */
13225   assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
13226
13227   assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13228                        mkexpr(tab_addr)));
13229   assign(op1, load(Ity_I16, mkexpr(result)));
13230
13231   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13232      s390_cc_set(1);
13233      next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
13234   }
13235
13236   store(get_gpr_dw0(r1), mkexpr(op1));
13237
13238   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13239   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13240   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13241
13242   iterate();
13243
13244   return "trtt";
13245}
13246
13247static const HChar *
13248s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13249{
13250   IRTemp len = newTemp(Ity_I64);
13251
13252   assign(len, mkU64(length));
13253   s390_irgen_TR_EX(len, start1, start2);
13254
13255   return "tr";
13256}
13257
13258static const HChar *
13259s390_irgen_TRE(UChar r1,UChar r2)
13260{
13261   IRTemp src_addr, tab_addr, src_len, test_byte;
13262   src_addr = newTemp(Ity_I64);
13263   tab_addr = newTemp(Ity_I64);
13264   src_len = newTemp(Ity_I64);
13265   test_byte = newTemp(Ity_I8);
13266
13267   assign(src_addr, get_gpr_dw0(r1));
13268   assign(src_len, get_gpr_dw0(r1+1));
13269   assign(tab_addr, get_gpr_dw0(r2));
13270   assign(test_byte, get_gpr_b7(0));
13271
13272   IRTemp op = newTemp(Ity_I8);
13273   IRTemp op1 = newTemp(Ity_I8);
13274   IRTemp result = newTemp(Ity_I64);
13275
13276   /* End of source string? We're done; proceed to next insn */
13277   s390_cc_set(0);
13278   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
13279
13280   /* Load character from source string and compare with test byte */
13281   assign(op, load(Ity_I8, mkexpr(src_addr)));
13282
13283   s390_cc_set(1);
13284   next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
13285
13286   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13287			mkexpr(tab_addr)));
13288
13289   assign(op1, load(Ity_I8, mkexpr(result)));
13290
13291   store(get_gpr_dw0(r1), mkexpr(op1));
13292   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13293   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13294
13295   iterate();
13296
13297   return "tre";
13298}
13299
13300static IRExpr *
13301s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13302{
13303   IRExpr **args, *call;
13304   args = mkIRExprVec_2(srcval, low_surrogate);
13305   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13306                       "s390_do_cu21", &s390_do_cu21, args);
13307
13308   /* Nothing is excluded from definedness checking. */
13309   call->Iex.CCall.cee->mcx_mask = 0;
13310
13311   return call;
13312}
13313
13314static const HChar *
13315s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13316{
13317   IRTemp addr1 = newTemp(Ity_I64);
13318   IRTemp addr2 = newTemp(Ity_I64);
13319   IRTemp len1 = newTemp(Ity_I64);
13320   IRTemp len2 = newTemp(Ity_I64);
13321
13322   assign(addr1, get_gpr_dw0(r1));
13323   assign(addr2, get_gpr_dw0(r2));
13324   assign(len1, get_gpr_dw0(r1 + 1));
13325   assign(len2, get_gpr_dw0(r2 + 1));
13326
13327   /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13328      there are less than 2 bytes left, then the 2nd operand is exhausted
13329      and we're done here. cc = 0 */
13330   s390_cc_set(0);
13331   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
13332
13333   /* There are at least two bytes there. Read them. */
13334   IRTemp srcval = newTemp(Ity_I32);
13335   assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13336
13337   /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13338      inside the interval [0xd800 - 0xdbff] */
13339   IRTemp  is_high_surrogate = newTemp(Ity_I32);
13340   IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13341                         mkU32(1), mkU32(0));
13342   IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13343                         mkU32(1), mkU32(0));
13344   assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13345
13346   /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13347      then the 2nd operand is exhausted and we're done here. cc = 0 */
13348   IRExpr *not_enough_bytes =
13349      mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13350
13351   next_insn_if(binop(Iop_CmpEQ32,
13352                      binop(Iop_And32, mkexpr(is_high_surrogate),
13353                            not_enough_bytes), mkU32(1)));
13354
13355   /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13356      surrogate, read the next two bytes (low surrogate). */
13357   IRTemp  low_surrogate = newTemp(Ity_I32);
13358   IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13359
13360   assign(low_surrogate,
13361          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13362                unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13363                mkU32(0)));  // any value is fine; it will not be used
13364
13365   /* Call the helper */
13366   IRTemp retval = newTemp(Ity_I64);
13367   assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13368                                 unop(Iop_32Uto64, mkexpr(low_surrogate))));
13369
13370   /* Before we can test whether the 1st operand is exhausted we need to
13371      test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13372   if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13373      IRExpr *invalid_low_surrogate =
13374         binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13375
13376      s390_cc_set(2);
13377      next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
13378   }
13379
13380   /* Now test whether the 1st operand is exhausted */
13381   IRTemp num_bytes = newTemp(Ity_I64);
13382   assign(num_bytes, binop(Iop_And64,
13383                           binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13384                           mkU64(0xff)));
13385   s390_cc_set(1);
13386   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13387
13388   /* Extract the bytes to be stored at addr1 */
13389   IRTemp data = newTemp(Ity_I64);
13390   assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13391
13392   /* To store the bytes construct 4 dirty helper calls. The helper calls
13393      are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13394      one of them will be called at runtime. */
13395   UInt i;
13396   for (i = 1; i <= 4; ++i) {
13397      IRDirty *d;
13398
13399      d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13400                            &s390x_dirtyhelper_CUxy,
13401                            mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13402                                          mkexpr(num_bytes)));
13403      d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13404      d->mFx   = Ifx_Write;
13405      d->mAddr = mkexpr(addr1);
13406      d->mSize = i;
13407      stmt(IRStmt_Dirty(d));
13408   }
13409
13410   /* Update source address and length */
13411   IRTemp num_src_bytes = newTemp(Ity_I64);
13412   assign(num_src_bytes,
13413          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13414                mkU64(4), mkU64(2)));
13415   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13416   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
13417
13418   /* Update destination address and length */
13419   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13420   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13421
13422   iterate();
13423
13424   return "cu21";
13425}
13426
13427static IRExpr *
13428s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13429{
13430   IRExpr **args, *call;
13431   args = mkIRExprVec_2(srcval, low_surrogate);
13432   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13433                       "s390_do_cu24", &s390_do_cu24, args);
13434
13435   /* Nothing is excluded from definedness checking. */
13436   call->Iex.CCall.cee->mcx_mask = 0;
13437
13438   return call;
13439}
13440
13441static const HChar *
13442s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13443{
13444   IRTemp addr1 = newTemp(Ity_I64);
13445   IRTemp addr2 = newTemp(Ity_I64);
13446   IRTemp len1 = newTemp(Ity_I64);
13447   IRTemp len2 = newTemp(Ity_I64);
13448
13449   assign(addr1, get_gpr_dw0(r1));
13450   assign(addr2, get_gpr_dw0(r2));
13451   assign(len1, get_gpr_dw0(r1 + 1));
13452   assign(len2, get_gpr_dw0(r2 + 1));
13453
13454   /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13455      there are less than 2 bytes left, then the 2nd operand is exhausted
13456      and we're done here. cc = 0 */
13457   s390_cc_set(0);
13458   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
13459
13460   /* There are at least two bytes there. Read them. */
13461   IRTemp srcval = newTemp(Ity_I32);
13462   assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13463
13464   /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13465      inside the interval [0xd800 - 0xdbff] */
13466   IRTemp  is_high_surrogate = newTemp(Ity_I32);
13467   IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13468                         mkU32(1), mkU32(0));
13469   IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13470                         mkU32(1), mkU32(0));
13471   assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13472
13473   /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13474      then the 2nd operand is exhausted and we're done here. cc = 0 */
13475   IRExpr *not_enough_bytes =
13476      mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13477
13478   next_insn_if(binop(Iop_CmpEQ32,
13479                      binop(Iop_And32, mkexpr(is_high_surrogate),
13480                            not_enough_bytes),
13481                      mkU32(1)));
13482
13483   /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13484      surrogate, read the next two bytes (low surrogate). */
13485   IRTemp  low_surrogate = newTemp(Ity_I32);
13486   IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13487
13488   assign(low_surrogate,
13489          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13490                unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13491                mkU32(0)));  // any value is fine; it will not be used
13492
13493   /* Call the helper */
13494   IRTemp retval = newTemp(Ity_I64);
13495   assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13496                                 unop(Iop_32Uto64, mkexpr(low_surrogate))));
13497
13498   /* Before we can test whether the 1st operand is exhausted we need to
13499      test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13500   if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13501      IRExpr *invalid_low_surrogate =
13502         binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13503
13504      s390_cc_set(2);
13505      next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
13506   }
13507
13508   /* Now test whether the 1st operand is exhausted */
13509   s390_cc_set(1);
13510   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
13511
13512   /* Extract the bytes to be stored at addr1 */
13513   IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13514
13515   store(mkexpr(addr1), data);
13516
13517   /* Update source address and length */
13518   IRTemp num_src_bytes = newTemp(Ity_I64);
13519   assign(num_src_bytes,
13520          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13521                mkU64(4), mkU64(2)));
13522   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13523   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
13524
13525   /* Update destination address and length */
13526   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13527   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkU64(4)));
13528
13529   iterate();
13530
13531   return "cu24";
13532}
13533
13534static IRExpr *
13535s390_call_cu42(IRExpr *srcval)
13536{
13537   IRExpr **args, *call;
13538   args = mkIRExprVec_1(srcval);
13539   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13540                       "s390_do_cu42", &s390_do_cu42, args);
13541
13542   /* Nothing is excluded from definedness checking. */
13543   call->Iex.CCall.cee->mcx_mask = 0;
13544
13545   return call;
13546}
13547
13548static const HChar *
13549s390_irgen_CU42(UChar r1, UChar r2)
13550{
13551   IRTemp addr1 = newTemp(Ity_I64);
13552   IRTemp addr2 = newTemp(Ity_I64);
13553   IRTemp len1 = newTemp(Ity_I64);
13554   IRTemp len2 = newTemp(Ity_I64);
13555
13556   assign(addr1, get_gpr_dw0(r1));
13557   assign(addr2, get_gpr_dw0(r2));
13558   assign(len1, get_gpr_dw0(r1 + 1));
13559   assign(len2, get_gpr_dw0(r2 + 1));
13560
13561   /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13562      there are less than 4 bytes left, then the 2nd operand is exhausted
13563      and we're done here. cc = 0 */
13564   s390_cc_set(0);
13565   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13566
13567   /* Read the 2nd operand. */
13568   IRTemp srcval = newTemp(Ity_I32);
13569   assign(srcval, load(Ity_I32, mkexpr(addr2)));
13570
13571   /* Call the helper */
13572   IRTemp retval = newTemp(Ity_I64);
13573   assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
13574
13575   /* If the UTF-32 character was invalid, set cc=2 and we're done.
13576      cc=2 outranks cc=1 (1st operand exhausted) */
13577   IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13578
13579   s390_cc_set(2);
13580   next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13581
13582   /* Now test whether the 1st operand is exhausted */
13583   IRTemp num_bytes = newTemp(Ity_I64);
13584   assign(num_bytes, binop(Iop_And64,
13585                           binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13586                           mkU64(0xff)));
13587   s390_cc_set(1);
13588   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13589
13590   /* Extract the bytes to be stored at addr1 */
13591   IRTemp data = newTemp(Ity_I64);
13592   assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13593
13594   /* To store the bytes construct 2 dirty helper calls. The helper calls
13595      are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13596      that only one of them will be called at runtime. */
13597
13598   Int i;
13599   for (i = 2; i <= 4; ++i) {
13600      IRDirty *d;
13601
13602      if (i == 3) continue;  // skip this one
13603
13604      d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13605                            &s390x_dirtyhelper_CUxy,
13606                            mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13607                                          mkexpr(num_bytes)));
13608      d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13609      d->mFx   = Ifx_Write;
13610      d->mAddr = mkexpr(addr1);
13611      d->mSize = i;
13612      stmt(IRStmt_Dirty(d));
13613   }
13614
13615   /* Update source address and length */
13616   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13617   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkU64(4)));
13618
13619   /* Update destination address and length */
13620   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13621   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13622
13623   iterate();
13624
13625   return "cu42";
13626}
13627
13628static IRExpr *
13629s390_call_cu41(IRExpr *srcval)
13630{
13631   IRExpr **args, *call;
13632   args = mkIRExprVec_1(srcval);
13633   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13634                       "s390_do_cu41", &s390_do_cu41, args);
13635
13636   /* Nothing is excluded from definedness checking. */
13637   call->Iex.CCall.cee->mcx_mask = 0;
13638
13639   return call;
13640}
13641
13642static const HChar *
13643s390_irgen_CU41(UChar r1, UChar r2)
13644{
13645   IRTemp addr1 = newTemp(Ity_I64);
13646   IRTemp addr2 = newTemp(Ity_I64);
13647   IRTemp len1 = newTemp(Ity_I64);
13648   IRTemp len2 = newTemp(Ity_I64);
13649
13650   assign(addr1, get_gpr_dw0(r1));
13651   assign(addr2, get_gpr_dw0(r2));
13652   assign(len1, get_gpr_dw0(r1 + 1));
13653   assign(len2, get_gpr_dw0(r2 + 1));
13654
13655   /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13656      there are less than 4 bytes left, then the 2nd operand is exhausted
13657      and we're done here. cc = 0 */
13658   s390_cc_set(0);
13659   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13660
13661   /* Read the 2nd operand. */
13662   IRTemp srcval = newTemp(Ity_I32);
13663   assign(srcval, load(Ity_I32, mkexpr(addr2)));
13664
13665   /* Call the helper */
13666   IRTemp retval = newTemp(Ity_I64);
13667   assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
13668
13669   /* If the UTF-32 character was invalid, set cc=2 and we're done.
13670      cc=2 outranks cc=1 (1st operand exhausted) */
13671   IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13672
13673   s390_cc_set(2);
13674   next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13675
13676   /* Now test whether the 1st operand is exhausted */
13677   IRTemp num_bytes = newTemp(Ity_I64);
13678   assign(num_bytes, binop(Iop_And64,
13679                           binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13680                           mkU64(0xff)));
13681   s390_cc_set(1);
13682   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13683
13684   /* Extract the bytes to be stored at addr1 */
13685   IRTemp data = newTemp(Ity_I64);
13686   assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13687
13688   /* To store the bytes construct 4 dirty helper calls. The helper calls
13689      are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13690      one of them will be called at runtime. */
13691   UInt i;
13692   for (i = 1; i <= 4; ++i) {
13693      IRDirty *d;
13694
13695      d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13696                            &s390x_dirtyhelper_CUxy,
13697                            mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13698                                          mkexpr(num_bytes)));
13699      d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13700      d->mFx   = Ifx_Write;
13701      d->mAddr = mkexpr(addr1);
13702      d->mSize = i;
13703      stmt(IRStmt_Dirty(d));
13704   }
13705
13706   /* Update source address and length */
13707   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13708   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkU64(4)));
13709
13710   /* Update destination address and length */
13711   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13712   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13713
13714   iterate();
13715
13716   return "cu41";
13717}
13718
13719static IRExpr *
13720s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
13721{
13722   IRExpr **args, *call;
13723   args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
13724   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13725                        &s390_do_cu12_cu14_helper1, args);
13726
13727   /* Nothing is excluded from definedness checking. */
13728   call->Iex.CCall.cee->mcx_mask = 0;
13729
13730   return call;
13731}
13732
13733static IRExpr *
13734s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13735                       IRExpr *byte4, IRExpr *stuff)
13736{
13737   IRExpr **args, *call;
13738   args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13739   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13740                        "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13741
13742   /* Nothing is excluded from definedness checking. */
13743   call->Iex.CCall.cee->mcx_mask = 0;
13744
13745   return call;
13746}
13747
13748static IRExpr *
13749s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13750                       IRExpr *byte4, IRExpr *stuff)
13751{
13752   IRExpr **args, *call;
13753   args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13754   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13755                        "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13756
13757   /* Nothing is excluded from definedness checking. */
13758   call->Iex.CCall.cee->mcx_mask = 0;
13759
13760   return call;
13761}
13762
13763static void
13764s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
13765{
13766   IRTemp addr1 = newTemp(Ity_I64);
13767   IRTemp addr2 = newTemp(Ity_I64);
13768   IRTemp len1 = newTemp(Ity_I64);
13769   IRTemp len2 = newTemp(Ity_I64);
13770
13771   assign(addr1, get_gpr_dw0(r1));
13772   assign(addr2, get_gpr_dw0(r2));
13773   assign(len1, get_gpr_dw0(r1 + 1));
13774   assign(len2, get_gpr_dw0(r2 + 1));
13775
13776   UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13777
13778   /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13779      there is less than 1 byte left, then the 2nd operand is exhausted
13780      and we're done here. cc = 0 */
13781   s390_cc_set(0);
13782   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13783
13784   /* There is at least one byte there. Read it. */
13785   IRTemp byte1 = newTemp(Ity_I64);
13786   assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
13787
13788   /* Call the helper to get number of bytes and invalid byte indicator */
13789   IRTemp retval1 = newTemp(Ity_I64);
13790   assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
13791                                               mkU64(extended_checking)));
13792
13793   /* Check for invalid 1st byte */
13794   IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13795   s390_cc_set(2);
13796   next_insn_if(is_invalid);
13797
13798   /* How many bytes do we have to read? */
13799   IRTemp num_src_bytes = newTemp(Ity_I64);
13800   assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13801
13802   /* Now test whether the 2nd operand is exhausted */
13803   s390_cc_set(0);
13804   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13805
13806   /* Read the remaining bytes */
13807   IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13808
13809   cond  = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13810   addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
13811   byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
13812   cond  = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13813   addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13814   byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
13815   cond  = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13816   addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
13817   byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
13818
13819   /* Call the helper to get the converted value and invalid byte indicator.
13820      We can pass at most 5 arguments; therefore some encoding is needed
13821      here */
13822   IRExpr *stuff = binop(Iop_Or64,
13823                         binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13824                         mkU64(extended_checking));
13825   IRTemp retval2 = newTemp(Ity_I64);
13826
13827   if (is_cu12) {
13828      assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13829                                             byte4, stuff));
13830   } else {
13831      assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13832                                             byte4, stuff));
13833   }
13834
13835   /* Check for invalid character */
13836   s390_cc_set(2);
13837   is_invalid = unop(Iop_64to1, mkexpr(retval2));
13838   next_insn_if(is_invalid);
13839
13840   /* Now test whether the 1st operand is exhausted */
13841   IRTemp num_bytes = newTemp(Ity_I64);
13842   assign(num_bytes, binop(Iop_And64,
13843                           binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13844                           mkU64(0xff)));
13845   s390_cc_set(1);
13846   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13847
13848   /* Extract the bytes to be stored at addr1 */
13849   IRTemp data = newTemp(Ity_I64);
13850   assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13851
13852   if (is_cu12) {
13853      /* To store the bytes construct 2 dirty helper calls. The helper calls
13854         are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13855         that only one of them will be called at runtime. */
13856
13857      Int i;
13858      for (i = 2; i <= 4; ++i) {
13859         IRDirty *d;
13860
13861         if (i == 3) continue;  // skip this one
13862
13863         d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13864                               &s390x_dirtyhelper_CUxy,
13865                               mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13866                                             mkexpr(num_bytes)));
13867         d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13868         d->mFx   = Ifx_Write;
13869         d->mAddr = mkexpr(addr1);
13870         d->mSize = i;
13871         stmt(IRStmt_Dirty(d));
13872      }
13873   } else {
13874      // cu14
13875      store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
13876   }
13877
13878   /* Update source address and length */
13879   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13880   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
13881
13882   /* Update destination address and length */
13883   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13884   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
13885
13886   iterate();
13887}
13888
13889static const HChar *
13890s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13891{
13892   s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
13893
13894   return "cu12";
13895}
13896
13897static const HChar *
13898s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13899{
13900   s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13901
13902   return "cu14";
13903}
13904
13905static IRExpr *
13906s390_call_ecag(IRExpr *op2addr)
13907{
13908   IRExpr **args, *call;
13909
13910   args = mkIRExprVec_1(op2addr);
13911   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13912                        "s390_do_ecag", &s390_do_ecag, args);
13913
13914   /* Nothing is excluded from definedness checking. */
13915   call->Iex.CCall.cee->mcx_mask = 0;
13916
13917   return call;
13918}
13919
13920static const HChar *
13921s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
13922{
13923   if (! s390_host_has_gie) {
13924      emulation_failure(EmFail_S390X_ecag);
13925   } else {
13926      put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13927   }
13928
13929   return "ecag";
13930}
13931
13932
13933/* New insns are added here.
13934   If an insn is contingent on a facility being installed also
13935   check whether the list of supported facilities in function
13936   s390x_dirtyhelper_STFLE needs updating */
13937
13938/*------------------------------------------------------------*/
13939/*--- Build IR for special instructions                    ---*/
13940/*------------------------------------------------------------*/
13941
13942static void
13943s390_irgen_client_request(void)
13944{
13945   if (0)
13946      vex_printf("%%R3 = client_request ( %%R2 )\n");
13947
13948   Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13949                                     + S390_SPECIAL_OP_SIZE;
13950
13951   dis_res->jk_StopHere = Ijk_ClientReq;
13952   dis_res->whatNext = Dis_StopHere;
13953
13954   put_IA(mkaddr_expr(next));
13955}
13956
13957static void
13958s390_irgen_guest_NRADDR(void)
13959{
13960   if (0)
13961      vex_printf("%%R3 = guest_NRADDR\n");
13962
13963   put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
13964}
13965
13966static void
13967s390_irgen_call_noredir(void)
13968{
13969   Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13970                                     + S390_SPECIAL_OP_SIZE;
13971
13972   /* Continue after special op */
13973   put_gpr_dw0(14, mkaddr_expr(next));
13974
13975   /* The address is in REG1, all parameters are in the right (guest) places */
13976   put_IA(get_gpr_dw0(1));
13977
13978   dis_res->whatNext = Dis_StopHere;
13979   dis_res->jk_StopHere = Ijk_NoRedir;
13980}
13981
13982/* Force proper alignment for the structures below. */
13983#pragma pack(1)
13984
13985
13986static s390_decode_t
13987s390_decode_2byte_and_irgen(const UChar *bytes)
13988{
13989   typedef union {
13990      struct {
13991         unsigned int op : 16;
13992      } E;
13993      struct {
13994         unsigned int op :  8;
13995         unsigned int i  :  8;
13996      } I;
13997      struct {
13998         unsigned int op :  8;
13999         unsigned int r1 :  4;
14000         unsigned int r2 :  4;
14001      } RR;
14002   } formats;
14003   union {
14004      formats fmt;
14005      UShort value;
14006   } ovl;
14007
14008   vassert(sizeof(formats) == 2);
14009
14010   ((UChar *)(&ovl.value))[0] = bytes[0];
14011   ((UChar *)(&ovl.value))[1] = bytes[1];
14012
14013   switch (ovl.value & 0xffff) {
14014   case 0x0101: /* PR */ goto unimplemented;
14015   case 0x0102: /* UPT */ goto unimplemented;
14016   case 0x0104: /* PTFF */ goto unimplemented;
14017   case 0x0107: /* SCKPF */ goto unimplemented;
14018   case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
14019   case 0x010b: /* TAM */ goto unimplemented;
14020   case 0x010c: /* SAM24 */ goto unimplemented;
14021   case 0x010d: /* SAM31 */ goto unimplemented;
14022   case 0x010e: /* SAM64 */ goto unimplemented;
14023   case 0x01ff: /* TRAP2 */ goto unimplemented;
14024   }
14025
14026   switch ((ovl.value & 0xff00) >> 8) {
14027   case 0x04: /* SPM */ goto unimplemented;
14028   case 0x05: /* BALR */ goto unimplemented;
14029   case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14030                                goto ok;
14031   case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14032                             goto ok;
14033   case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i);  goto ok;
14034   case 0x0b: /* BSM */ goto unimplemented;
14035   case 0x0c: /* BASSM */ goto unimplemented;
14036   case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14037                                goto ok;
14038   case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14039                             goto ok;
14040   case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14041                             goto ok;
14042   case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14043                                goto ok;
14044   case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14045                                goto ok;
14046   case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14047                                goto ok;
14048   case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14049                                goto ok;
14050   case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14051                                goto ok;
14052   case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14053                                goto ok;
14054   case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14055                                goto ok;
14056   case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14057                                goto ok;
14058   case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14059                                goto ok;
14060   case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14061                                goto ok;
14062   case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14063                                goto ok;
14064   case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14065                                goto ok;
14066   case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14067                                goto ok;
14068   case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14069                                goto ok;
14070   case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14071                                goto ok;
14072   case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14073                                goto ok;
14074   case 0x20: /* LPDR */ goto unimplemented;
14075   case 0x21: /* LNDR */ goto unimplemented;
14076   case 0x22: /* LTDR */ goto unimplemented;
14077   case 0x23: /* LCDR */ goto unimplemented;
14078   case 0x24: /* HDR */ goto unimplemented;
14079   case 0x25: /* LDXR */ goto unimplemented;
14080   case 0x26: /* MXR */ goto unimplemented;
14081   case 0x27: /* MXDR */ goto unimplemented;
14082   case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14083                                goto ok;
14084   case 0x29: /* CDR */ goto unimplemented;
14085   case 0x2a: /* ADR */ goto unimplemented;
14086   case 0x2b: /* SDR */ goto unimplemented;
14087   case 0x2c: /* MDR */ goto unimplemented;
14088   case 0x2d: /* DDR */ goto unimplemented;
14089   case 0x2e: /* AWR */ goto unimplemented;
14090   case 0x2f: /* SWR */ goto unimplemented;
14091   case 0x30: /* LPER */ goto unimplemented;
14092   case 0x31: /* LNER */ goto unimplemented;
14093   case 0x32: /* LTER */ goto unimplemented;
14094   case 0x33: /* LCER */ goto unimplemented;
14095   case 0x34: /* HER */ goto unimplemented;
14096   case 0x35: /* LEDR */ goto unimplemented;
14097   case 0x36: /* AXR */ goto unimplemented;
14098   case 0x37: /* SXR */ goto unimplemented;
14099   case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14100                                goto ok;
14101   case 0x39: /* CER */ goto unimplemented;
14102   case 0x3a: /* AER */ goto unimplemented;
14103   case 0x3b: /* SER */ goto unimplemented;
14104   case 0x3c: /* MDER */ goto unimplemented;
14105   case 0x3d: /* DER */ goto unimplemented;
14106   case 0x3e: /* AUR */ goto unimplemented;
14107   case 0x3f: /* SUR */ goto unimplemented;
14108   }
14109
14110   return S390_DECODE_UNKNOWN_INSN;
14111
14112ok:
14113   return S390_DECODE_OK;
14114
14115unimplemented:
14116   return S390_DECODE_UNIMPLEMENTED_INSN;
14117}
14118
14119static s390_decode_t
14120s390_decode_4byte_and_irgen(const UChar *bytes)
14121{
14122   typedef union {
14123      struct {
14124         unsigned int op1 :  8;
14125         unsigned int r1  :  4;
14126         unsigned int op2 :  4;
14127         unsigned int i2  : 16;
14128      } RI;
14129      struct {
14130         unsigned int op : 16;
14131         unsigned int    :  8;
14132         unsigned int r1 :  4;
14133         unsigned int r2 :  4;
14134      } RRE;
14135      struct {
14136         unsigned int op : 16;
14137         unsigned int r1 :  4;
14138         unsigned int    :  4;
14139         unsigned int r3 :  4;
14140         unsigned int r2 :  4;
14141      } RRF;
14142      struct {
14143         unsigned int op : 16;
14144         unsigned int m3 :  4;
14145         unsigned int m4 :  4;
14146         unsigned int r1 :  4;
14147         unsigned int r2 :  4;
14148      } RRF2;
14149      struct {
14150         unsigned int op : 16;
14151         unsigned int r3 :  4;
14152         unsigned int    :  4;
14153         unsigned int r1 :  4;
14154         unsigned int r2 :  4;
14155      } RRF3;
14156      struct {
14157         unsigned int op : 16;
14158         unsigned int r3 :  4;
14159         unsigned int    :  4;
14160         unsigned int r1 :  4;
14161         unsigned int r2 :  4;
14162      } RRR;
14163      struct {
14164         unsigned int op : 16;
14165         unsigned int r3 :  4;
14166         unsigned int m4 :  4;
14167         unsigned int r1 :  4;
14168         unsigned int r2 :  4;
14169      } RRF4;
14170      struct {
14171         unsigned int op : 16;
14172         unsigned int    :  4;
14173         unsigned int m4 :  4;
14174         unsigned int r1 :  4;
14175         unsigned int r2 :  4;
14176      } RRF5;
14177      struct {
14178         unsigned int op :  8;
14179         unsigned int r1 :  4;
14180         unsigned int r3 :  4;
14181         unsigned int b2 :  4;
14182         unsigned int d2 : 12;
14183      } RS;
14184      struct {
14185         unsigned int op :  8;
14186         unsigned int r1 :  4;
14187         unsigned int r3 :  4;
14188         unsigned int i2 : 16;
14189      } RSI;
14190      struct {
14191         unsigned int op :  8;
14192         unsigned int r1 :  4;
14193         unsigned int x2 :  4;
14194         unsigned int b2 :  4;
14195         unsigned int d2 : 12;
14196      } RX;
14197      struct {
14198         unsigned int op : 16;
14199         unsigned int b2 :  4;
14200         unsigned int d2 : 12;
14201      } S;
14202      struct {
14203         unsigned int op :  8;
14204         unsigned int i2 :  8;
14205         unsigned int b1 :  4;
14206         unsigned int d1 : 12;
14207      } SI;
14208   } formats;
14209   union {
14210      formats fmt;
14211      UInt value;
14212   } ovl;
14213
14214   vassert(sizeof(formats) == 4);
14215
14216   ((UChar *)(&ovl.value))[0] = bytes[0];
14217   ((UChar *)(&ovl.value))[1] = bytes[1];
14218   ((UChar *)(&ovl.value))[2] = bytes[2];
14219   ((UChar *)(&ovl.value))[3] = bytes[3];
14220
14221   switch ((ovl.value & 0xff0f0000) >> 16) {
14222   case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
14223                                  ovl.fmt.RI.i2);  goto ok;
14224   case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
14225                                  ovl.fmt.RI.i2);  goto ok;
14226   case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14227                                  ovl.fmt.RI.i2);  goto ok;
14228   case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14229                                  ovl.fmt.RI.i2);  goto ok;
14230   case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14231                                  ovl.fmt.RI.i2);  goto ok;
14232   case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14233                                  ovl.fmt.RI.i2);  goto ok;
14234   case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14235                                  ovl.fmt.RI.i2);  goto ok;
14236   case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14237                                  ovl.fmt.RI.i2);  goto ok;
14238   case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14239                                  ovl.fmt.RI.i2);  goto ok;
14240   case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14241                                  ovl.fmt.RI.i2);  goto ok;
14242   case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14243                                  ovl.fmt.RI.i2);  goto ok;
14244   case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14245                                  ovl.fmt.RI.i2);  goto ok;
14246   case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14247                                  ovl.fmt.RI.i2);  goto ok;
14248   case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14249                                  ovl.fmt.RI.i2);  goto ok;
14250   case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14251                                  ovl.fmt.RI.i2);  goto ok;
14252   case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14253                                  ovl.fmt.RI.i2);  goto ok;
14254   case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14255                                  ovl.fmt.RI.i2);  goto ok;
14256   case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14257                                  ovl.fmt.RI.i2);  goto ok;
14258   case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14259                                  ovl.fmt.RI.i2);  goto ok;
14260   case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14261                                  ovl.fmt.RI.i2);  goto ok;
14262   case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14263                               goto ok;
14264   case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14265                                  ovl.fmt.RI.i2);  goto ok;
14266   case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14267                                  ovl.fmt.RI.i2);  goto ok;
14268   case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14269                                  ovl.fmt.RI.i2);  goto ok;
14270   case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14271                                  goto ok;
14272   case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14273                                  ovl.fmt.RI.i2);  goto ok;
14274   case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14275                                  goto ok;
14276   case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14277                                  ovl.fmt.RI.i2);  goto ok;
14278   case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14279                                  goto ok;
14280   case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14281                                  ovl.fmt.RI.i2);  goto ok;
14282   case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14283                                  goto ok;
14284   case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14285                                  ovl.fmt.RI.i2);  goto ok;
14286   }
14287
14288   switch ((ovl.value & 0xffff0000) >> 16) {
14289   case 0x8000: /* SSM */ goto unimplemented;
14290   case 0x8200: /* LPSW */ goto unimplemented;
14291   case 0x9300: /* TS */ goto unimplemented;
14292   case 0xb202: /* STIDP */ goto unimplemented;
14293   case 0xb204: /* SCK */ goto unimplemented;
14294   case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14295                goto ok;
14296   case 0xb206: /* SCKC */ goto unimplemented;
14297   case 0xb207: /* STCKC */ goto unimplemented;
14298   case 0xb208: /* SPT */ goto unimplemented;
14299   case 0xb209: /* STPT */ goto unimplemented;
14300   case 0xb20a: /* SPKA */ goto unimplemented;
14301   case 0xb20b: /* IPK */ goto unimplemented;
14302   case 0xb20d: /* PTLB */ goto unimplemented;
14303   case 0xb210: /* SPX */ goto unimplemented;
14304   case 0xb211: /* STPX */ goto unimplemented;
14305   case 0xb212: /* STAP */ goto unimplemented;
14306   case 0xb214: /* SIE */ goto unimplemented;
14307   case 0xb218: /* PC */ goto unimplemented;
14308   case 0xb219: /* SAC */ goto unimplemented;
14309   case 0xb21a: /* CFC */ goto unimplemented;
14310   case 0xb221: /* IPTE */ goto unimplemented;
14311   case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1);  goto ok;
14312   case 0xb223: /* IVSK */ goto unimplemented;
14313   case 0xb224: /* IAC */ goto unimplemented;
14314   case 0xb225: /* SSAR */ goto unimplemented;
14315   case 0xb226: /* EPAR */ goto unimplemented;
14316   case 0xb227: /* ESAR */ goto unimplemented;
14317   case 0xb228: /* PT */ goto unimplemented;
14318   case 0xb229: /* ISKE */ goto unimplemented;
14319   case 0xb22a: /* RRBE */ goto unimplemented;
14320   case 0xb22b: /* SSKE */ goto unimplemented;
14321   case 0xb22c: /* TB */ goto unimplemented;
14322   case 0xb22d: /* DXR */ goto unimplemented;
14323   case 0xb22e: /* PGIN */ goto unimplemented;
14324   case 0xb22f: /* PGOUT */ goto unimplemented;
14325   case 0xb230: /* CSCH */ goto unimplemented;
14326   case 0xb231: /* HSCH */ goto unimplemented;
14327   case 0xb232: /* MSCH */ goto unimplemented;
14328   case 0xb233: /* SSCH */ goto unimplemented;
14329   case 0xb234: /* STSCH */ goto unimplemented;
14330   case 0xb235: /* TSCH */ goto unimplemented;
14331   case 0xb236: /* TPI */ goto unimplemented;
14332   case 0xb237: /* SAL */ goto unimplemented;
14333   case 0xb238: /* RSCH */ goto unimplemented;
14334   case 0xb239: /* STCRW */ goto unimplemented;
14335   case 0xb23a: /* STCPS */ goto unimplemented;
14336   case 0xb23b: /* RCHP */ goto unimplemented;
14337   case 0xb23c: /* SCHM */ goto unimplemented;
14338   case 0xb240: /* BAKR */ goto unimplemented;
14339   case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14340                                ovl.fmt.RRE.r2);  goto ok;
14341   case 0xb244: /* SQDR */ goto unimplemented;
14342   case 0xb245: /* SQER */ goto unimplemented;
14343   case 0xb246: /* STURA */ goto unimplemented;
14344   case 0xb247: /* MSTA */ goto unimplemented;
14345   case 0xb248: /* PALB */ goto unimplemented;
14346   case 0xb249: /* EREG */ goto unimplemented;
14347   case 0xb24a: /* ESTA */ goto unimplemented;
14348   case 0xb24b: /* LURA */ goto unimplemented;
14349   case 0xb24c: /* TAR */ goto unimplemented;
14350   case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14351                                ovl.fmt.RRE.r2);  goto ok;
14352   case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14353                                goto ok;
14354   case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14355                                goto ok;
14356   case 0xb250: /* CSP */ goto unimplemented;
14357   case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14358                                   ovl.fmt.RRE.r2);  goto ok;
14359   case 0xb254: /* MVPG */ goto unimplemented;
14360   case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14361                                   ovl.fmt.RRE.r2);  goto ok;
14362   case 0xb257: /* CUSE */ goto unimplemented;
14363   case 0xb258: /* BSG */ goto unimplemented;
14364   case 0xb25a: /* BSA */ goto unimplemented;
14365   case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14366                                   ovl.fmt.RRE.r2);  goto ok;
14367   case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14368                                   ovl.fmt.RRE.r2);  goto ok;
14369   case 0xb263: /* CMPSC */ goto unimplemented;
14370   case 0xb274: /* SIGA */ goto unimplemented;
14371   case 0xb276: /* XSCH */ goto unimplemented;
14372   case 0xb277: /* RP */ goto unimplemented;
14373   case 0xb278: s390_format_S_RD(s390_irgen_STCKE, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
14374   case 0xb279: /* SACF */ goto unimplemented;
14375   case 0xb27c: s390_format_S_RD(s390_irgen_STCKF, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
14376   case 0xb27d: /* STSI */ goto unimplemented;
14377   case 0xb280: /* LPP */ goto unimplemented;
14378   case 0xb284: /* LCCTL */ goto unimplemented;
14379   case 0xb285: /* LPCTL */ goto unimplemented;
14380   case 0xb286: /* QSI */ goto unimplemented;
14381   case 0xb287: /* LSCTL */ goto unimplemented;
14382   case 0xb28e: /* QCTRI */ goto unimplemented;
14383   case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14384                                 goto ok;
14385   case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14386                                 goto ok;
14387   case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14388                                 goto ok;
14389   case 0xb2a5: s390_format_RRE_FF(s390_irgen_TRE, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);  goto ok;
14390   case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14391                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14392      goto ok;
14393   case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14394                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14395      goto ok;
14396   case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14397                                 goto ok;
14398   case 0xb2b1: /* STFL */ goto unimplemented;
14399   case 0xb2b2: /* LPSWE */ goto unimplemented;
14400   case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14401      goto ok;
14402   case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14403      goto ok;
14404   case 0xb2bd: /* LFAS */ goto unimplemented;
14405   case 0xb2e0: /* SCCTR */ goto unimplemented;
14406   case 0xb2e1: /* SPCTR */ goto unimplemented;
14407   case 0xb2e4: /* ECCTR */ goto unimplemented;
14408   case 0xb2e5: /* EPCTR */ goto unimplemented;
14409   case 0xb2e8: /* PPA */ goto unimplemented;
14410   case 0xb2ec: /* ETND */ goto unimplemented;
14411   case 0xb2ed: /* ECPGA */ goto unimplemented;
14412   case 0xb2f8: /* TEND */ goto unimplemented;
14413   case 0xb2fa: /* NIAI */ goto unimplemented;
14414   case 0xb2fc: /* TABORT */ goto unimplemented;
14415   case 0xb2ff: /* TRAP4 */ goto unimplemented;
14416   case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14417                                   ovl.fmt.RRE.r2);  goto ok;
14418   case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14419                                   ovl.fmt.RRE.r2);  goto ok;
14420   case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14421                                   ovl.fmt.RRE.r2);  goto ok;
14422   case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14423                                   ovl.fmt.RRE.r2);  goto ok;
14424   case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14425                                   ovl.fmt.RRE.r2);  goto ok;
14426   case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14427                                   ovl.fmt.RRE.r2);  goto ok;
14428   case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14429                                   ovl.fmt.RRE.r2);  goto ok;
14430   case 0xb307: /* MXDBR */ goto unimplemented;
14431   case 0xb308: /* KEBR */ goto unimplemented;
14432   case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14433                                   ovl.fmt.RRE.r2);  goto ok;
14434   case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14435                                   ovl.fmt.RRE.r2);  goto ok;
14436   case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14437                                   ovl.fmt.RRE.r2);  goto ok;
14438   case 0xb30c: /* MDEBR */ goto unimplemented;
14439   case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14440                                   ovl.fmt.RRE.r2);  goto ok;
14441   case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14442                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14443   case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14444                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14445   case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14446                                   ovl.fmt.RRE.r2);  goto ok;
14447   case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14448                                   ovl.fmt.RRE.r2);  goto ok;
14449   case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14450                                   ovl.fmt.RRE.r2);  goto ok;
14451   case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14452                                   ovl.fmt.RRE.r2);  goto ok;
14453   case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14454                                   ovl.fmt.RRE.r2);  goto ok;
14455   case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14456                                   ovl.fmt.RRE.r2);  goto ok;
14457   case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14458                                   ovl.fmt.RRE.r2);  goto ok;
14459   case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14460                                   ovl.fmt.RRE.r2);  goto ok;
14461   case 0xb318: /* KDBR */ goto unimplemented;
14462   case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14463                                   ovl.fmt.RRE.r2);  goto ok;
14464   case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14465                                   ovl.fmt.RRE.r2);  goto ok;
14466   case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14467                                   ovl.fmt.RRE.r2);  goto ok;
14468   case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14469                                   ovl.fmt.RRE.r2);  goto ok;
14470   case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14471                                   ovl.fmt.RRE.r2);  goto ok;
14472   case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14473                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14474   case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14475                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
14476   case 0xb324: /* LDER */ goto unimplemented;
14477   case 0xb325: /* LXDR */ goto unimplemented;
14478   case 0xb326: /* LXER */ goto unimplemented;
14479   case 0xb32e: /* MAER */ goto unimplemented;
14480   case 0xb32f: /* MSER */ goto unimplemented;
14481   case 0xb336: /* SQXR */ goto unimplemented;
14482   case 0xb337: /* MEER */ goto unimplemented;
14483   case 0xb338: /* MAYLR */ goto unimplemented;
14484   case 0xb339: /* MYLR */ goto unimplemented;
14485   case 0xb33a: /* MAYR */ goto unimplemented;
14486   case 0xb33b: /* MYR */ goto unimplemented;
14487   case 0xb33c: /* MAYHR */ goto unimplemented;
14488   case 0xb33d: /* MYHR */ goto unimplemented;
14489   case 0xb33e: /* MADR */ goto unimplemented;
14490   case 0xb33f: /* MSDR */ goto unimplemented;
14491   case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14492                                   ovl.fmt.RRE.r2);  goto ok;
14493   case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14494                                   ovl.fmt.RRE.r2);  goto ok;
14495   case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14496                                   ovl.fmt.RRE.r2);  goto ok;
14497   case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14498                                   ovl.fmt.RRE.r2);  goto ok;
14499   case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14500                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14501                                     ovl.fmt.RRF2.r2);  goto ok;
14502   case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14503                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14504                                     ovl.fmt.RRF2.r2);  goto ok;
14505   case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14506                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14507                                     ovl.fmt.RRF2.r2);  goto ok;
14508   case 0xb347: /* FIXBR */ goto unimplemented;
14509   case 0xb348: /* KXBR */ goto unimplemented;
14510   case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14511                                   ovl.fmt.RRE.r2);  goto ok;
14512   case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14513                                   ovl.fmt.RRE.r2);  goto ok;
14514   case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14515                                   ovl.fmt.RRE.r2);  goto ok;
14516   case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14517                                   ovl.fmt.RRE.r2);  goto ok;
14518   case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14519                                   ovl.fmt.RRE.r2);  goto ok;
14520   case 0xb350: /* TBEDR */ goto unimplemented;
14521   case 0xb351: /* TBDR */ goto unimplemented;
14522   case 0xb353: /* DIEBR */ goto unimplemented;
14523   case 0xb357: /* FIEBR */ goto unimplemented;
14524   case 0xb358: /* THDER */ goto unimplemented;
14525   case 0xb359: /* THDR */ goto unimplemented;
14526   case 0xb35b: /* DIDBR */ goto unimplemented;
14527   case 0xb35f: /* FIDBR */ goto unimplemented;
14528   case 0xb360: /* LPXR */ goto unimplemented;
14529   case 0xb361: /* LNXR */ goto unimplemented;
14530   case 0xb362: /* LTXR */ goto unimplemented;
14531   case 0xb363: /* LCXR */ goto unimplemented;
14532   case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14533                                   ovl.fmt.RRE.r2);  goto ok;
14534   case 0xb366: /* LEXR */ goto unimplemented;
14535   case 0xb367: /* FIXR */ goto unimplemented;
14536   case 0xb369: /* CXR */ goto unimplemented;
14537   case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14538                                   ovl.fmt.RRE.r2);  goto ok;
14539   case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14540                                   ovl.fmt.RRE.r2);  goto ok;
14541   case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14542                                      ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14543                                      goto ok;
14544   case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14545                                   ovl.fmt.RRE.r2);  goto ok;
14546   case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1);  goto ok;
14547   case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1);  goto ok;
14548   case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1);  goto ok;
14549   case 0xb377: /* FIER */ goto unimplemented;
14550   case 0xb37f: /* FIDR */ goto unimplemented;
14551   case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1);  goto ok;
14552   case 0xb385: /* SFASR */ goto unimplemented;
14553   case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1);  goto ok;
14554   case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14555                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14556                                     ovl.fmt.RRF2.r2);  goto ok;
14557   case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14558                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14559                                     ovl.fmt.RRF2.r2);  goto ok;
14560   case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14561                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14562                                     ovl.fmt.RRF2.r2);  goto ok;
14563   case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14564                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14565                                     ovl.fmt.RRF2.r2);  goto ok;
14566   case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14567                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14568                                     ovl.fmt.RRF2.r2);  goto ok;
14569   case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14570                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14571                                     ovl.fmt.RRF2.r2);  goto ok;
14572   case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14573                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14574                                     ovl.fmt.RRF2.r2);  goto ok;
14575   case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14576                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14577                                     ovl.fmt.RRF2.r2);  goto ok;
14578   case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14579                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14580                                     ovl.fmt.RRF2.r2);  goto ok;
14581   case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14582                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14583                                     ovl.fmt.RRF2.r2);  goto ok;
14584   case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14585                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14586                                     ovl.fmt.RRF2.r2);  goto ok;
14587   case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14588                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14589                                     ovl.fmt.RRF2.r2);  goto ok;
14590   case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14591                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14592                                     ovl.fmt.RRF2.r2);  goto ok;
14593   case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14594                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14595                                     ovl.fmt.RRF2.r2);  goto ok;
14596   case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14597                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14598                                     ovl.fmt.RRF2.r2);  goto ok;
14599   case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14600                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14601                                     ovl.fmt.RRF2.r2);  goto ok;
14602   case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14603                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14604                                     ovl.fmt.RRF2.r2);  goto ok;
14605   case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14606                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14607                                     ovl.fmt.RRF2.r2);  goto ok;
14608   case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14609                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14610                                     ovl.fmt.RRF2.r2);  goto ok;
14611   case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14612                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14613                                     ovl.fmt.RRF2.r2);  goto ok;
14614   case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14615                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14616                                     ovl.fmt.RRF2.r2);  goto ok;
14617   case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14618                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14619                                     ovl.fmt.RRF2.r2);  goto ok;
14620   case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14621                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14622                                     ovl.fmt.RRF2.r2);  goto ok;
14623   case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14624                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14625                                     ovl.fmt.RRF2.r2);  goto ok;
14626   case 0xb3b4: /* CEFR */ goto unimplemented;
14627   case 0xb3b5: /* CDFR */ goto unimplemented;
14628   case 0xb3b6: /* CXFR */ goto unimplemented;
14629   case 0xb3b8: /* CFER */ goto unimplemented;
14630   case 0xb3b9: /* CFDR */ goto unimplemented;
14631   case 0xb3ba: /* CFXR */ goto unimplemented;
14632   case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14633                                   ovl.fmt.RRE.r2);  goto ok;
14634   case 0xb3c4: /* CEGR */ goto unimplemented;
14635   case 0xb3c5: /* CDGR */ goto unimplemented;
14636   case 0xb3c6: /* CXGR */ goto unimplemented;
14637   case 0xb3c8: /* CGER */ goto unimplemented;
14638   case 0xb3c9: /* CGDR */ goto unimplemented;
14639   case 0xb3ca: /* CGXR */ goto unimplemented;
14640   case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14641                                   ovl.fmt.RRE.r2);  goto ok;
14642   case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14643                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14644                                      ovl.fmt.RRF4.r2); goto ok;
14645   case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14646                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14647                                      ovl.fmt.RRF4.r2); goto ok;
14648   case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14649                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14650                                      ovl.fmt.RRF4.r2); goto ok;
14651   case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14652                                      ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14653                                      ovl.fmt.RRF4.r2); goto ok;
14654   case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14655                                     ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14656   case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14657                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14658                                     ovl.fmt.RRF2.r2);  goto ok;
14659   case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14660                                   ovl.fmt.RRE.r2);  goto ok;
14661   case 0xb3d7: /* FIDTR */ goto unimplemented;
14662   case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14663                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14664                                     ovl.fmt.RRF4.r2); goto ok;
14665   case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14666                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14667                                     ovl.fmt.RRF4.r2); goto ok;
14668   case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14669                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14670                                     ovl.fmt.RRF4.r2); goto ok;
14671   case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14672                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14673                                     ovl.fmt.RRF4.r2); goto ok;
14674   case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14675                                     ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14676   case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14677                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14678                                     ovl.fmt.RRF2.r2);  goto ok;
14679   case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14680                                   ovl.fmt.RRE.r2);  goto ok;
14681   case 0xb3df: /* FIXTR */ goto unimplemented;
14682   case 0xb3e0: /* KDTR */ goto unimplemented;
14683   case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14684                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14685                                     ovl.fmt.RRF2.r2);  goto ok;
14686   case 0xb3e2: /* CUDTR */ goto unimplemented;
14687   case 0xb3e3: /* CSDTR */ goto unimplemented;
14688   case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14689                                   ovl.fmt.RRE.r2);  goto ok;
14690   case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14691                                   ovl.fmt.RRE.r2);  goto ok;
14692   case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14693                                   ovl.fmt.RRE.r2);  goto ok;
14694   case 0xb3e8: /* KXTR */ goto unimplemented;
14695   case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14696                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14697                                     ovl.fmt.RRF2.r2);  goto ok;
14698   case 0xb3ea: /* CUXTR */ goto unimplemented;
14699   case 0xb3eb: /* CSXTR */ goto unimplemented;
14700   case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14701                                   ovl.fmt.RRE.r2);  goto ok;
14702   case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14703                                   ovl.fmt.RRE.r2);  goto ok;
14704   case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14705                                   ovl.fmt.RRE.r2);  goto ok;
14706   case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14707                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14708                                     ovl.fmt.RRF2.r2);  goto ok;
14709   case 0xb3f2: /* CDUTR */ goto unimplemented;
14710   case 0xb3f3: /* CDSTR */ goto unimplemented;
14711   case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14712                                   ovl.fmt.RRE.r2);  goto ok;
14713   case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14714                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14715                                     ovl.fmt.RRF4.r2); goto ok;
14716   case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14717                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14718   case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14719                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14720                                     ovl.fmt.RRF4.r2); goto ok;
14721   case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14722                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14723                                     ovl.fmt.RRF2.r2);  goto ok;
14724   case 0xb3fa: /* CXUTR */ goto unimplemented;
14725   case 0xb3fb: /* CXSTR */ goto unimplemented;
14726   case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14727                                   ovl.fmt.RRE.r2);  goto ok;
14728   case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14729                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14730                                     ovl.fmt.RRF4.r2); goto ok;
14731   case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14732                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14733   case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14734                                     ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14735                                     ovl.fmt.RRF4.r2); goto ok;
14736   case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14737                                   ovl.fmt.RRE.r2);  goto ok;
14738   case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14739                                   ovl.fmt.RRE.r2);  goto ok;
14740   case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14741                                   ovl.fmt.RRE.r2);  goto ok;
14742   case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14743                                   ovl.fmt.RRE.r2);  goto ok;
14744   case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14745                                   ovl.fmt.RRE.r2);  goto ok;
14746   case 0xb905: /* LURAG */ goto unimplemented;
14747   case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14748                                   ovl.fmt.RRE.r2);  goto ok;
14749   case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14750                                   ovl.fmt.RRE.r2);  goto ok;
14751   case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14752                                   ovl.fmt.RRE.r2);  goto ok;
14753   case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14754                                   ovl.fmt.RRE.r2);  goto ok;
14755   case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14756                                   ovl.fmt.RRE.r2);  goto ok;
14757   case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14758                                   ovl.fmt.RRE.r2);  goto ok;
14759   case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14760                                   ovl.fmt.RRE.r2);  goto ok;
14761   case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14762                                   ovl.fmt.RRE.r2);  goto ok;
14763   case 0xb90e: /* EREGG */ goto unimplemented;
14764   case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14765                                   ovl.fmt.RRE.r2);  goto ok;
14766   case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14767                                   ovl.fmt.RRE.r2);  goto ok;
14768   case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14769                                   ovl.fmt.RRE.r2);  goto ok;
14770   case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14771                                   ovl.fmt.RRE.r2);  goto ok;
14772   case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14773                                   ovl.fmt.RRE.r2);  goto ok;
14774   case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14775                                   ovl.fmt.RRE.r2);  goto ok;
14776   case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14777                                   ovl.fmt.RRE.r2);  goto ok;
14778   case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14779                                   ovl.fmt.RRE.r2);  goto ok;
14780   case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14781                                   ovl.fmt.RRE.r2);  goto ok;
14782   case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14783                                   ovl.fmt.RRE.r2);  goto ok;
14784   case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14785                                   ovl.fmt.RRE.r2);  goto ok;
14786   case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14787                                   ovl.fmt.RRE.r2);  goto ok;
14788   case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14789                                   ovl.fmt.RRE.r2);  goto ok;
14790   case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14791                                   ovl.fmt.RRE.r2);  goto ok;
14792   case 0xb91e: /* KMAC */ goto unimplemented;
14793   case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14794                                   ovl.fmt.RRE.r2);  goto ok;
14795   case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14796                                   ovl.fmt.RRE.r2);  goto ok;
14797   case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14798                                   ovl.fmt.RRE.r2);  goto ok;
14799   case 0xb925: /* STURG */ goto unimplemented;
14800   case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14801                                   ovl.fmt.RRE.r2);  goto ok;
14802   case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14803                                   ovl.fmt.RRE.r2);  goto ok;
14804   case 0xb928: /* PCKMO */ goto unimplemented;
14805   case 0xb92a: /* KMF */ goto unimplemented;
14806   case 0xb92b: /* KMO */ goto unimplemented;
14807   case 0xb92c: /* PCC */ goto unimplemented;
14808   case 0xb92d: /* KMCTR */ goto unimplemented;
14809   case 0xb92e: /* KM */ goto unimplemented;
14810   case 0xb92f: /* KMC */ goto unimplemented;
14811   case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14812                                   ovl.fmt.RRE.r2);  goto ok;
14813   case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14814                                   ovl.fmt.RRE.r2);  goto ok;
14815   case 0xb93e: /* KIMD */ goto unimplemented;
14816   case 0xb93f: /* KLMD */ goto unimplemented;
14817   case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14818                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14819                                     ovl.fmt.RRF2.r2);  goto ok;
14820   case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14821                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14822                                     ovl.fmt.RRF2.r2);  goto ok;
14823   case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14824                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14825                                     ovl.fmt.RRF2.r2);  goto ok;
14826   case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14827                                   ovl.fmt.RRE.r2);  goto ok;
14828   case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14829                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14830                                     ovl.fmt.RRF2.r2);  goto ok;
14831   case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14832                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14833                                     ovl.fmt.RRF2.r2);  goto ok;
14834   case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14835                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14836                                     ovl.fmt.RRF2.r2);  goto ok;
14837   case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14838                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14839                                     ovl.fmt.RRF2.r2);  goto ok;
14840   case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14841                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14842                                     ovl.fmt.RRF2.r2);  goto ok;
14843   case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14844                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14845                                     ovl.fmt.RRF2.r2);  goto ok;
14846   case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14847                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14848                                     ovl.fmt.RRF2.r2);  goto ok;
14849   case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14850                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14851                                     ovl.fmt.RRF2.r2);  goto ok;
14852   case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14853                                     ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14854                                     ovl.fmt.RRF2.r2);  goto ok;
14855   case 0xb960: /* CGRT */ goto unimplemented;
14856   case 0xb961: /* CLGRT */ goto unimplemented;
14857   case 0xb972: /* CRT */ goto unimplemented;
14858   case 0xb973: /* CLRT */ goto unimplemented;
14859   case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14860                                   ovl.fmt.RRE.r2);  goto ok;
14861   case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14862                                   ovl.fmt.RRE.r2);  goto ok;
14863   case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14864                                   ovl.fmt.RRE.r2);  goto ok;
14865   case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14866                                   ovl.fmt.RRE.r2);  goto ok;
14867   case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14868                                   ovl.fmt.RRE.r2);  goto ok;
14869   case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14870                                   ovl.fmt.RRE.r2);  goto ok;
14871   case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14872                                   ovl.fmt.RRE.r2);  goto ok;
14873   case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14874                                   ovl.fmt.RRE.r2);  goto ok;
14875   case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14876                                   ovl.fmt.RRE.r2);  goto ok;
14877   case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14878                                   ovl.fmt.RRE.r2);  goto ok;
14879   case 0xb98a: /* CSPG */ goto unimplemented;
14880   case 0xb98d: /* EPSW */ goto unimplemented;
14881   case 0xb98e: /* IDTE */ goto unimplemented;
14882   case 0xb98f: /* CRDTE */ goto unimplemented;
14883   case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14884                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
14885   case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14886                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
14887   case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14888                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
14889   case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14890                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
14891   case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14892                                   ovl.fmt.RRE.r2);  goto ok;
14893   case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14894                                   ovl.fmt.RRE.r2);  goto ok;
14895   case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14896                                   ovl.fmt.RRE.r2);  goto ok;
14897   case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14898                                   ovl.fmt.RRE.r2);  goto ok;
14899   case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14900                                   ovl.fmt.RRE.r2);  goto ok;
14901   case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14902                                   ovl.fmt.RRE.r2);  goto ok;
14903   case 0xb99a: /* EPAIR */ goto unimplemented;
14904   case 0xb99b: /* ESAIR */ goto unimplemented;
14905   case 0xb99d: /* ESEA */ goto unimplemented;
14906   case 0xb99e: /* PTI */ goto unimplemented;
14907   case 0xb99f: /* SSAIR */ goto unimplemented;
14908   case 0xb9a2: /* PTF */ goto unimplemented;
14909   case 0xb9aa: /* LPTEA */ goto unimplemented;
14910   case 0xb9ae: /* RRBM */ goto unimplemented;
14911   case 0xb9af: /* PFMF */ goto unimplemented;
14912   case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14913                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14914      goto ok;
14915   case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14916                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14917      goto ok;
14918   case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14919                                   ovl.fmt.RRE.r2);  goto ok;
14920   case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14921                                   ovl.fmt.RRE.r2);  goto ok;
14922   case 0xb9bd: /* TRTRE */ goto unimplemented;
14923   case 0xb9be: /* SRSTU */ goto unimplemented;
14924   case 0xb9bf: /* TRTE */ goto unimplemented;
14925   case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14926                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14927                                      goto ok;
14928   case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14929                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14930                                      goto ok;
14931   case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14932                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14933                                      goto ok;
14934   case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14935                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14936                                      goto ok;
14937   case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14938                                   ovl.fmt.RRE.r2);  goto ok;
14939   case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14940                                   ovl.fmt.RRE.r2);  goto ok;
14941   case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14942                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14943                                      goto ok;
14944   case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14945                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14946                                      goto ok;
14947   case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14948                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14949                                      goto ok;
14950   case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14951                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14952                                      goto ok;
14953   case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14954                                   ovl.fmt.RRE.r2);  goto ok;
14955   case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14956                                   ovl.fmt.RRE.r2);  goto ok;
14957   case 0xb9e1: /* POPCNT */ goto unimplemented;
14958   case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14959                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14960                                     S390_XMNM_LOCGR);  goto ok;
14961   case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14962                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14963                                      goto ok;
14964   case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14965                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14966                                      goto ok;
14967   case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14968                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14969                                      goto ok;
14970   case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14971                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14972                                      goto ok;
14973   case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14974                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14975                                      goto ok;
14976   case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14977                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14978                                      goto ok;
14979   case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14980                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14981                                      goto ok;
14982   case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14983                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14984                                     S390_XMNM_LOCR);  goto ok;
14985   case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14986                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14987                                      goto ok;
14988   case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14989                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14990                                      goto ok;
14991   case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14992                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14993                                      goto ok;
14994   case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14995                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14996                                      goto ok;
14997   case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14998                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14999                                      goto ok;
15000   case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
15001                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15002                                      goto ok;
15003   case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
15004                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15005                                      goto ok;
15006   }
15007
15008   switch ((ovl.value & 0xff000000) >> 24) {
15009   case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15010                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15011   case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15012                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15013   case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15014                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15015   case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15016                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15017   case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15018                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15019   case 0x45: /* BAL */ goto unimplemented;
15020   case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15021                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15022   case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15023                             ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15024   case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15025                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15026   case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15027                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15028   case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15029                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15030   case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15031                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15032   case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15033                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15034   case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15035                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15036   case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15037                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15038   case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15039                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15040   case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15041                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15042   case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15043                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15044   case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15045                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15046   case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15047                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15048   case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15049                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15050   case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15051                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15052   case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15053                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15054   case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15055                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15056   case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15057                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15058   case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15059                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15060   case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15061                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15062   case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15063                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15064   case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15065                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15066   case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15067                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15068   case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15069                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15070   case 0x67: /* MXD */ goto unimplemented;
15071   case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15072                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15073   case 0x69: /* CD */ goto unimplemented;
15074   case 0x6a: /* AD */ goto unimplemented;
15075   case 0x6b: /* SD */ goto unimplemented;
15076   case 0x6c: /* MD */ goto unimplemented;
15077   case 0x6d: /* DD */ goto unimplemented;
15078   case 0x6e: /* AW */ goto unimplemented;
15079   case 0x6f: /* SW */ goto unimplemented;
15080   case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15081                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15082   case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15083                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15084   case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15085                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
15086   case 0x79: /* CE */ goto unimplemented;
15087   case 0x7a: /* AE */ goto unimplemented;
15088   case 0x7b: /* SE */ goto unimplemented;
15089   case 0x7c: /* MDE */ goto unimplemented;
15090   case 0x7d: /* DE */ goto unimplemented;
15091   case 0x7e: /* AU */ goto unimplemented;
15092   case 0x7f: /* SU */ goto unimplemented;
15093   case 0x83: /* DIAG */ goto unimplemented;
15094   case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
15095                                  ovl.fmt.RSI.r3, ovl.fmt.RSI.i2);  goto ok;
15096   case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
15097                                  ovl.fmt.RSI.r3, ovl.fmt.RSI.i2);  goto ok;
15098   case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15099                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15100   case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15101                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15102   case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15103                                  ovl.fmt.RS.d2);  goto ok;
15104   case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15105                                  ovl.fmt.RS.d2);  goto ok;
15106   case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15107                                  ovl.fmt.RS.d2);  goto ok;
15108   case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15109                                  ovl.fmt.RS.d2);  goto ok;
15110   case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15111                                  ovl.fmt.RS.d2);  goto ok;
15112   case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15113                                  ovl.fmt.RS.d2);  goto ok;
15114   case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15115                                  ovl.fmt.RS.d2);  goto ok;
15116   case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15117                                  ovl.fmt.RS.d2);  goto ok;
15118   case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15119                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15120   case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15121                                 ovl.fmt.SI.d1);  goto ok;
15122   case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15123                                 ovl.fmt.SI.d1);  goto ok;
15124   case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15125                                 ovl.fmt.SI.d1);  goto ok;
15126   case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15127                                 ovl.fmt.SI.d1);  goto ok;
15128   case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15129                                 ovl.fmt.SI.d1);  goto ok;
15130   case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15131                                 ovl.fmt.SI.d1);  goto ok;
15132   case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15133                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15134   case 0x99: /* TRACE */ goto unimplemented;
15135   case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15136                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15137   case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15138                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15139   case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
15140                                  ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15141                                  goto ok;
15142   case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
15143                                  ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15144                                  goto ok;
15145   case 0xac: /* STNSM */ goto unimplemented;
15146   case 0xad: /* STOSM */ goto unimplemented;
15147   case 0xae: /* SIGP */ goto unimplemented;
15148   case 0xaf: /* MC */ goto unimplemented;
15149   case 0xb1: /* LRA */ goto unimplemented;
15150   case 0xb6: /* STCTL */ goto unimplemented;
15151   case 0xb7: /* LCTL */ goto unimplemented;
15152   case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15153                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15154   case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15155                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15156   case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15157                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15158   case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15159                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15160   case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15161                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
15162   }
15163
15164   return S390_DECODE_UNKNOWN_INSN;
15165
15166ok:
15167   return S390_DECODE_OK;
15168
15169unimplemented:
15170   return S390_DECODE_UNIMPLEMENTED_INSN;
15171}
15172
15173static s390_decode_t
15174s390_decode_6byte_and_irgen(const UChar *bytes)
15175{
15176   typedef union {
15177      struct {
15178         unsigned int op1 :  8;
15179         unsigned int r1  :  4;
15180         unsigned int r3  :  4;
15181         unsigned int i2  : 16;
15182         unsigned int     :  8;
15183         unsigned int op2 :  8;
15184      } RIE;
15185      struct {
15186         unsigned int op1 :  8;
15187         unsigned int r1  :  4;
15188         unsigned int r2  :  4;
15189         unsigned int i3  :  8;
15190         unsigned int i4  :  8;
15191         unsigned int i5  :  8;
15192         unsigned int op2 :  8;
15193      } RIE_RRUUU;
15194      struct {
15195         unsigned int op1 :  8;
15196         unsigned int r1  :  4;
15197         unsigned int     :  4;
15198         unsigned int i2  : 16;
15199         unsigned int m3  :  4;
15200         unsigned int     :  4;
15201         unsigned int op2 :  8;
15202      } RIEv1;
15203      struct {
15204         unsigned int op1 :  8;
15205         unsigned int r1  :  4;
15206         unsigned int r2  :  4;
15207         unsigned int i4  : 16;
15208         unsigned int m3  :  4;
15209         unsigned int     :  4;
15210         unsigned int op2 :  8;
15211      } RIE_RRPU;
15212      struct {
15213         unsigned int op1 :  8;
15214         unsigned int r1  :  4;
15215         unsigned int m3  :  4;
15216         unsigned int i4  : 16;
15217         unsigned int i2  :  8;
15218         unsigned int op2 :  8;
15219      } RIEv3;
15220      struct {
15221         unsigned int op1 :  8;
15222         unsigned int r1  :  4;
15223         unsigned int op2 :  4;
15224         unsigned int i2  : 32;
15225      } RIL;
15226      struct {
15227         unsigned int op1 :  8;
15228         unsigned int r1  :  4;
15229         unsigned int m3  :  4;
15230         unsigned int b4  :  4;
15231         unsigned int d4  : 12;
15232         unsigned int i2  :  8;
15233         unsigned int op2 :  8;
15234      } RIS;
15235      struct {
15236         unsigned int op1 :  8;
15237         unsigned int r1  :  4;
15238         unsigned int r2  :  4;
15239         unsigned int b4  :  4;
15240         unsigned int d4  : 12;
15241         unsigned int m3  :  4;
15242         unsigned int     :  4;
15243         unsigned int op2 :  8;
15244      } RRS;
15245      struct {
15246         unsigned int op1 :  8;
15247         unsigned int l1  :  4;
15248         unsigned int     :  4;
15249         unsigned int b1  :  4;
15250         unsigned int d1  : 12;
15251         unsigned int     :  8;
15252         unsigned int op2 :  8;
15253      } RSL;
15254      struct {
15255         unsigned int op1 :  8;
15256         unsigned int r1  :  4;
15257         unsigned int r3  :  4;
15258         unsigned int b2  :  4;
15259         unsigned int dl2 : 12;
15260         unsigned int dh2 :  8;
15261         unsigned int op2 :  8;
15262      } RSY;
15263      struct {
15264         unsigned int op1 :  8;
15265         unsigned int r1  :  4;
15266         unsigned int x2  :  4;
15267         unsigned int b2  :  4;
15268         unsigned int d2  : 12;
15269         unsigned int     :  8;
15270         unsigned int op2 :  8;
15271      } RXE;
15272      struct {
15273         unsigned int op1 :  8;
15274         unsigned int r3  :  4;
15275         unsigned int x2  :  4;
15276         unsigned int b2  :  4;
15277         unsigned int d2  : 12;
15278         unsigned int r1  :  4;
15279         unsigned int     :  4;
15280         unsigned int op2 :  8;
15281      } RXF;
15282      struct {
15283         unsigned int op1 :  8;
15284         unsigned int r1  :  4;
15285         unsigned int x2  :  4;
15286         unsigned int b2  :  4;
15287         unsigned int dl2 : 12;
15288         unsigned int dh2 :  8;
15289         unsigned int op2 :  8;
15290      } RXY;
15291      struct {
15292         unsigned int op1 :  8;
15293         unsigned int i2  :  8;
15294         unsigned int b1  :  4;
15295         unsigned int dl1 : 12;
15296         unsigned int dh1 :  8;
15297         unsigned int op2 :  8;
15298      } SIY;
15299      struct {
15300         unsigned int op :  8;
15301         unsigned int l  :  8;
15302         unsigned int b1 :  4;
15303         unsigned int d1 : 12;
15304         unsigned int b2 :  4;
15305         unsigned int d2 : 12;
15306      } SS;
15307      struct {
15308         unsigned int op :  8;
15309         unsigned int l1 :  4;
15310         unsigned int l2 :  4;
15311         unsigned int b1 :  4;
15312         unsigned int d1 : 12;
15313         unsigned int b2 :  4;
15314         unsigned int d2 : 12;
15315      } SS_LLRDRD;
15316      struct {
15317         unsigned int op :  8;
15318         unsigned int r1 :  4;
15319         unsigned int r3 :  4;
15320         unsigned int b2 :  4;
15321         unsigned int d2 : 12;
15322         unsigned int b4 :  4;
15323         unsigned int d4 : 12;
15324      } SS_RRRDRD2;
15325      struct {
15326         unsigned int op : 16;
15327         unsigned int b1 :  4;
15328         unsigned int d1 : 12;
15329         unsigned int b2 :  4;
15330         unsigned int d2 : 12;
15331      } SSE;
15332      struct {
15333         unsigned int op1 :  8;
15334         unsigned int r3  :  4;
15335         unsigned int op2 :  4;
15336         unsigned int b1  :  4;
15337         unsigned int d1  : 12;
15338         unsigned int b2  :  4;
15339         unsigned int d2  : 12;
15340      } SSF;
15341      struct {
15342         unsigned int op : 16;
15343         unsigned int b1 :  4;
15344         unsigned int d1 : 12;
15345         unsigned int i2 : 16;
15346      } SIL;
15347   } formats;
15348   union {
15349      formats fmt;
15350      ULong value;
15351   } ovl;
15352
15353   vassert(sizeof(formats) == 6);
15354
15355   ((UChar *)(&ovl.value))[0] = bytes[0];
15356   ((UChar *)(&ovl.value))[1] = bytes[1];
15357   ((UChar *)(&ovl.value))[2] = bytes[2];
15358   ((UChar *)(&ovl.value))[3] = bytes[3];
15359   ((UChar *)(&ovl.value))[4] = bytes[4];
15360   ((UChar *)(&ovl.value))[5] = bytes[5];
15361   ((UChar *)(&ovl.value))[6] = 0x0;
15362   ((UChar *)(&ovl.value))[7] = 0x0;
15363
15364   switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15365   case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15366                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15367                                                ovl.fmt.RXY.dl2,
15368                                                ovl.fmt.RXY.dh2);  goto ok;
15369   case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15370   case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15371                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15372                                                ovl.fmt.RXY.dl2,
15373                                                ovl.fmt.RXY.dh2);  goto ok;
15374   case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15375                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15376                                                ovl.fmt.RXY.dl2,
15377                                                ovl.fmt.RXY.dh2);  goto ok;
15378   case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15379                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15380                                                ovl.fmt.RXY.dl2,
15381                                                ovl.fmt.RXY.dh2);  goto ok;
15382   case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15383                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15384                                                ovl.fmt.RXY.dl2,
15385                                                ovl.fmt.RXY.dh2);  goto ok;
15386   case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15387                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15388                                                ovl.fmt.RXY.dl2,
15389                                                ovl.fmt.RXY.dh2);  goto ok;
15390   case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15391                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15392                                                ovl.fmt.RXY.dl2,
15393                                                ovl.fmt.RXY.dh2);  goto ok;
15394   case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15395                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15396                                                ovl.fmt.RXY.dl2,
15397                                                ovl.fmt.RXY.dh2);  goto ok;
15398   case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15399                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15400                                                ovl.fmt.RXY.dl2,
15401                                                ovl.fmt.RXY.dh2);  goto ok;
15402   case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15403   case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
15404                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15405                                                ovl.fmt.RXY.dl2,
15406                                                ovl.fmt.RXY.dh2);  goto ok;
15407   case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
15408                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15409                                                ovl.fmt.RXY.dl2,
15410                                                ovl.fmt.RXY.dh2);  goto ok;
15411   case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15412   case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15413                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15414                                                ovl.fmt.RXY.dl2,
15415                                                ovl.fmt.RXY.dh2);  goto ok;
15416   case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15417                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15418                                                ovl.fmt.RXY.dl2,
15419                                                ovl.fmt.RXY.dh2);  goto ok;
15420   case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15421                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15422                                                ovl.fmt.RXY.dl2,
15423                                                ovl.fmt.RXY.dh2);  goto ok;
15424   case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15425                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15426                                                ovl.fmt.RXY.dl2,
15427                                                ovl.fmt.RXY.dh2);  goto ok;
15428   case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15429                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15430                                                ovl.fmt.RXY.dl2,
15431                                                ovl.fmt.RXY.dh2);  goto ok;
15432   case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15433                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15434                                                ovl.fmt.RXY.dl2,
15435                                                ovl.fmt.RXY.dh2);  goto ok;
15436   case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15437                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15438                                                ovl.fmt.RXY.dl2,
15439                                                ovl.fmt.RXY.dh2);  goto ok;
15440   case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15441                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15442                                                ovl.fmt.RXY.dl2,
15443                                                ovl.fmt.RXY.dh2);  goto ok;
15444   case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15445                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15446                                                ovl.fmt.RXY.dl2,
15447                                                ovl.fmt.RXY.dh2);  goto ok;
15448   case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15449                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15450                                                ovl.fmt.RXY.dl2,
15451                                                ovl.fmt.RXY.dh2);  goto ok;
15452   case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15453                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15454                                                ovl.fmt.RXY.dl2,
15455                                                ovl.fmt.RXY.dh2);  goto ok;
15456   case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15457                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15458                                                ovl.fmt.RXY.dl2,
15459                                                ovl.fmt.RXY.dh2);  goto ok;
15460   case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15461                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15462                                                ovl.fmt.RXY.dl2,
15463                                                ovl.fmt.RXY.dh2);  goto ok;
15464   case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15465                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15466                                                ovl.fmt.RXY.dl2,
15467                                                ovl.fmt.RXY.dh2);  goto ok;
15468   case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15469                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15470                                                ovl.fmt.RXY.dl2,
15471                                                ovl.fmt.RXY.dh2);  goto ok;
15472   case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
15473   case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15474                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15475                                                ovl.fmt.RXY.dl2,
15476                                                ovl.fmt.RXY.dh2);  goto ok;
15477   case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15478   case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15479                                                ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15480                                                ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15481                                                ovl.fmt.RXY.dh2);  goto ok;
15482   case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15483                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15484                                                ovl.fmt.RXY.dl2,
15485                                                ovl.fmt.RXY.dh2);  goto ok;
15486   case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15487                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15488                                                ovl.fmt.RXY.dl2,
15489                                                ovl.fmt.RXY.dh2);  goto ok;
15490   case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15491                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15492                                                ovl.fmt.RXY.dl2,
15493                                                ovl.fmt.RXY.dh2);  goto ok;
15494   case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15495                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15496                                                ovl.fmt.RXY.dl2,
15497                                                ovl.fmt.RXY.dh2);  goto ok;
15498   case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15499                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15500                                                ovl.fmt.RXY.dl2,
15501                                                ovl.fmt.RXY.dh2);  goto ok;
15502   case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15503                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15504                                                ovl.fmt.RXY.dl2,
15505                                                ovl.fmt.RXY.dh2);  goto ok;
15506   case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15507                                                ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15508                                                ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15509                                                ovl.fmt.RXY.dh2);  goto ok;
15510   case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15511                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15512                                                ovl.fmt.RXY.dl2,
15513                                                ovl.fmt.RXY.dh2);  goto ok;
15514   case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15515                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15516                                                ovl.fmt.RXY.dl2,
15517                                                ovl.fmt.RXY.dh2);  goto ok;
15518   case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15519                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15520                                                ovl.fmt.RXY.dl2,
15521                                                ovl.fmt.RXY.dh2);  goto ok;
15522   case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15523                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15524                                                ovl.fmt.RXY.dl2,
15525                                                ovl.fmt.RXY.dh2);  goto ok;
15526   case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15527                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15528                                                ovl.fmt.RXY.dl2,
15529                                                ovl.fmt.RXY.dh2);  goto ok;
15530   case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15531                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15532                                                ovl.fmt.RXY.dl2,
15533                                                ovl.fmt.RXY.dh2);  goto ok;
15534   case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15535                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15536                                                ovl.fmt.RXY.dl2,
15537                                                ovl.fmt.RXY.dh2);  goto ok;
15538   case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15539                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15540                                                ovl.fmt.RXY.dl2,
15541                                                ovl.fmt.RXY.dh2);  goto ok;
15542   case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15543                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15544                                                ovl.fmt.RXY.dl2,
15545                                                ovl.fmt.RXY.dh2);  goto ok;
15546   case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15547                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15548                                                ovl.fmt.RXY.dl2,
15549                                                ovl.fmt.RXY.dh2);  goto ok;
15550   case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15551                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15552                                                ovl.fmt.RXY.dl2,
15553                                                ovl.fmt.RXY.dh2);  goto ok;
15554   case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15555                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15556                                                ovl.fmt.RXY.dl2,
15557                                                ovl.fmt.RXY.dh2);  goto ok;
15558   case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15559                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15560                                                ovl.fmt.RXY.dl2,
15561                                                ovl.fmt.RXY.dh2);  goto ok;
15562   case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15563                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15564                                                ovl.fmt.RXY.dl2,
15565                                                ovl.fmt.RXY.dh2);  goto ok;
15566   case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15567                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15568                                                ovl.fmt.RXY.dl2,
15569                                                ovl.fmt.RXY.dh2);  goto ok;
15570   case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15571                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15572                                                ovl.fmt.RXY.dl2,
15573                                                ovl.fmt.RXY.dh2);  goto ok;
15574   case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15575                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15576                                                ovl.fmt.RXY.dl2,
15577                                                ovl.fmt.RXY.dh2);  goto ok;
15578   case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15579                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15580                                                ovl.fmt.RXY.dl2,
15581                                                ovl.fmt.RXY.dh2);  goto ok;
15582   case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15583                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15584                                                ovl.fmt.RXY.dl2,
15585                                                ovl.fmt.RXY.dh2);  goto ok;
15586   case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15587                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15588                                                ovl.fmt.RXY.dl2,
15589                                                ovl.fmt.RXY.dh2);  goto ok;
15590   case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15591                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15592                                                ovl.fmt.RXY.dl2,
15593                                                ovl.fmt.RXY.dh2);  goto ok;
15594   case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15595                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15596                                                ovl.fmt.RXY.dl2,
15597                                                ovl.fmt.RXY.dh2);  goto ok;
15598   case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15599                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15600                                                ovl.fmt.RXY.dl2,
15601                                                ovl.fmt.RXY.dh2);  goto ok;
15602   case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15603                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15604                                                ovl.fmt.RXY.dl2,
15605                                                ovl.fmt.RXY.dh2);  goto ok;
15606   case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15607                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15608                                                ovl.fmt.RXY.dl2,
15609                                                ovl.fmt.RXY.dh2);  goto ok;
15610   case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15611                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15612                                                ovl.fmt.RXY.dl2,
15613                                                ovl.fmt.RXY.dh2);  goto ok;
15614   case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15615                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15616                                                ovl.fmt.RXY.dl2,
15617                                                ovl.fmt.RXY.dh2);  goto ok;
15618   case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15619                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15620                                                ovl.fmt.RXY.dl2,
15621                                                ovl.fmt.RXY.dh2);  goto ok;
15622   case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15623                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15624                                                ovl.fmt.RXY.dl2,
15625                                                ovl.fmt.RXY.dh2);  goto ok;
15626   case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
15627   case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15628                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15629                                                ovl.fmt.RXY.dl2,
15630                                                ovl.fmt.RXY.dh2);  goto ok;
15631   case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15632                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15633                                                ovl.fmt.RXY.dl2,
15634                                                ovl.fmt.RXY.dh2);  goto ok;
15635   case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15636                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15637                                                ovl.fmt.RXY.dl2,
15638                                                ovl.fmt.RXY.dh2);  goto ok;
15639   case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15640                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15641                                                ovl.fmt.RXY.dl2,
15642                                                ovl.fmt.RXY.dh2);  goto ok;
15643   case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15644                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15645                                                ovl.fmt.RXY.dl2,
15646                                                ovl.fmt.RXY.dh2);  goto ok;
15647   case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15648                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15649                                                ovl.fmt.RXY.dl2,
15650                                                ovl.fmt.RXY.dh2);  goto ok;
15651   case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15652                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15653                                                ovl.fmt.RXY.dl2,
15654                                                ovl.fmt.RXY.dh2);  goto ok;
15655   case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15656                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15657                                                ovl.fmt.RXY.dl2,
15658                                                ovl.fmt.RXY.dh2);  goto ok;
15659   case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15660                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15661                                                ovl.fmt.RXY.dl2,
15662                                                ovl.fmt.RXY.dh2);  goto ok;
15663   case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15664                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15665                                                ovl.fmt.RXY.dl2,
15666                                                ovl.fmt.RXY.dh2);  goto ok;
15667   case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15668                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15669                                                ovl.fmt.RXY.dl2,
15670                                                ovl.fmt.RXY.dh2);  goto ok;
15671   case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15672                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15673                                                ovl.fmt.RXY.dl2,
15674                                                ovl.fmt.RXY.dh2);  goto ok;
15675   case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15676                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15677                                                ovl.fmt.RXY.dl2,
15678                                                ovl.fmt.RXY.dh2);  goto ok;
15679   case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15680                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15681                                                ovl.fmt.RXY.dl2,
15682                                                ovl.fmt.RXY.dh2);  goto ok;
15683   case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15684   case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15685   case 0xe3000000009fULL: /* LAT */ goto unimplemented;
15686   case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15687                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15688                                                ovl.fmt.RXY.dl2,
15689                                                ovl.fmt.RXY.dh2);  goto ok;
15690   case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15691                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15692                                                ovl.fmt.RXY.dl2,
15693                                                ovl.fmt.RXY.dh2);  goto ok;
15694   case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15695                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15696                                                ovl.fmt.RXY.dl2,
15697                                                ovl.fmt.RXY.dh2);  goto ok;
15698   case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15699                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15700                                                ovl.fmt.RXY.dl2,
15701                                                ovl.fmt.RXY.dh2);  goto ok;
15702   case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15703                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15704                                                ovl.fmt.RXY.dl2,
15705                                                ovl.fmt.RXY.dh2);  goto ok;
15706   case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15707                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15708                                                ovl.fmt.RXY.dl2,
15709                                                ovl.fmt.RXY.dh2);  goto ok;
15710   case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
15711   case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15712                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15713                                                ovl.fmt.RXY.dl2,
15714                                                ovl.fmt.RXY.dh2);  goto ok;
15715   case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15716                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15717                                                ovl.fmt.RXY.dl2,
15718                                                ovl.fmt.RXY.dh2);  goto ok;
15719   case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15720                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15721                                                ovl.fmt.RXY.dl2,
15722                                                ovl.fmt.RXY.dh2);  goto ok;
15723   case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15724                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15725                                                ovl.fmt.RXY.dl2,
15726                                                ovl.fmt.RXY.dh2);  goto ok;
15727   case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15728                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15729                                                ovl.fmt.RSY.dl2,
15730                                                ovl.fmt.RSY.dh2);  goto ok;
15731   case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15732                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15733                                                ovl.fmt.RSY.dl2,
15734                                                ovl.fmt.RSY.dh2);  goto ok;
15735   case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15736                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15737                                                ovl.fmt.RSY.dl2,
15738                                                ovl.fmt.RSY.dh2);  goto ok;
15739   case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15740                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15741                                                ovl.fmt.RSY.dl2,
15742                                                ovl.fmt.RSY.dh2);  goto ok;
15743   case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15744                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15745                                                ovl.fmt.RSY.dl2,
15746                                                ovl.fmt.RSY.dh2);  goto ok;
15747   case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15748   case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15749                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15750                                                ovl.fmt.RSY.dl2,
15751                                                ovl.fmt.RSY.dh2);  goto ok;
15752   case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15753                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15754                                                ovl.fmt.RSY.dl2,
15755                                                ovl.fmt.RSY.dh2);  goto ok;
15756   case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15757                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15758                                                ovl.fmt.RSY.dl2,
15759                                                ovl.fmt.RSY.dh2);  goto ok;
15760   case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15761                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15762                                                ovl.fmt.RSY.dl2,
15763                                                ovl.fmt.RSY.dh2);  goto ok;
15764   case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15765                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15766                                                ovl.fmt.RSY.dl2,
15767                                                ovl.fmt.RSY.dh2);  goto ok;
15768   case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
15769   case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15770                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15771                                                ovl.fmt.RSY.dl2,
15772                                                ovl.fmt.RSY.dh2);  goto ok;
15773   case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15774   case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15775                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15776                                                ovl.fmt.RSY.dl2,
15777                                                ovl.fmt.RSY.dh2);  goto ok;
15778   case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
15779   case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15780                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15781                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15782                                                ovl.fmt.RSY.dh2);  goto ok;
15783   case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15784                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15785                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15786                                                ovl.fmt.RSY.dh2);  goto ok;
15787   case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15788   case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15789                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15790                                                ovl.fmt.RSY.dl2,
15791                                                ovl.fmt.RSY.dh2);  goto ok;
15792   case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15793                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15794                                                ovl.fmt.RSY.dl2,
15795                                                ovl.fmt.RSY.dh2);  goto ok;
15796   case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15797                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15798                                                ovl.fmt.RSY.dl2,
15799                                                ovl.fmt.RSY.dh2);  goto ok;
15800   case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15801                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15802                                                ovl.fmt.RSY.dl2,
15803                                                ovl.fmt.RSY.dh2);  goto ok;
15804   case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15805                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15806                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15807                                                ovl.fmt.RSY.dh2);  goto ok;
15808   case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15809                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15810                                                ovl.fmt.RSY.dl2,
15811                                                ovl.fmt.RSY.dh2);  goto ok;
15812   case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15813                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15814                                               ovl.fmt.SIY.dh1);  goto ok;
15815   case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15816                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15817                                               ovl.fmt.SIY.dh1);  goto ok;
15818   case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15819                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15820                                               ovl.fmt.SIY.dh1);  goto ok;
15821   case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15822                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15823                                               ovl.fmt.SIY.dh1);  goto ok;
15824   case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15825                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15826                                               ovl.fmt.SIY.dh1);  goto ok;
15827   case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15828                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15829                                               ovl.fmt.SIY.dh1);  goto ok;
15830   case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15831                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15832                                               ovl.fmt.SIY.dh1);  goto ok;
15833   case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15834                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15835                                               ovl.fmt.SIY.dh1);  goto ok;
15836   case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15837                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15838                                               ovl.fmt.SIY.dh1);  goto ok;
15839   case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15840                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15841                                               ovl.fmt.SIY.dh1);  goto ok;
15842   case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15843                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15844                                                ovl.fmt.RSY.dl2,
15845                                                ovl.fmt.RSY.dh2);  goto ok;
15846   case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15847                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15848                                                ovl.fmt.RSY.dl2,
15849                                                ovl.fmt.RSY.dh2);  goto ok;
15850   case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15851   case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15852   case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15853                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15854                                                ovl.fmt.RSY.dl2,
15855                                                ovl.fmt.RSY.dh2);  goto ok;
15856   case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15857                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15858                                                ovl.fmt.RSY.dl2,
15859                                                ovl.fmt.RSY.dh2);  goto ok;
15860   case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15861                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15862                                                ovl.fmt.RSY.dl2,
15863                                                ovl.fmt.RSY.dh2);  goto ok;
15864   case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15865                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15866                                                ovl.fmt.RSY.dl2,
15867                                                ovl.fmt.RSY.dh2);  goto ok;
15868   case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15869                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15870                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15871                                                ovl.fmt.RSY.dh2);  goto ok;
15872   case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15873   case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15874                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15875                                                ovl.fmt.RSY.dl2,
15876                                                ovl.fmt.RSY.dh2);  goto ok;
15877   case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15878                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15879                                                ovl.fmt.RSY.dl2,
15880                                                ovl.fmt.RSY.dh2);  goto ok;
15881   case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15882                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15883                                                ovl.fmt.RSY.dl2,
15884                                                ovl.fmt.RSY.dh2);  goto ok;
15885   case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15886                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15887                                                ovl.fmt.RSY.dl2,
15888                                                ovl.fmt.RSY.dh2);  goto ok;
15889   case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15890                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15891                                                ovl.fmt.RSY.dl2,
15892                                                ovl.fmt.RSY.dh2,
15893                                                S390_XMNM_LOCG);  goto ok;
15894   case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15895                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15896                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15897                                                ovl.fmt.RSY.dh2,
15898                                                S390_XMNM_STOCG);  goto ok;
15899   case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15900                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15901                                                ovl.fmt.RSY.dl2,
15902                                                ovl.fmt.RSY.dh2);  goto ok;
15903   case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15904                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15905                                                ovl.fmt.RSY.dl2,
15906                                                ovl.fmt.RSY.dh2);  goto ok;
15907   case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15908                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15909                                                ovl.fmt.RSY.dl2,
15910                                                ovl.fmt.RSY.dh2);  goto ok;
15911   case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15912                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15913                                                ovl.fmt.RSY.dl2,
15914                                                ovl.fmt.RSY.dh2);  goto ok;
15915   case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15916                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15917                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15918                                                ovl.fmt.RSY.dh2);  goto ok;
15919   case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15920                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15921                                                ovl.fmt.RSY.dl2,
15922                                                ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15923                                                goto ok;
15924   case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15925                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15926                                                ovl.fmt.RSY.dl2,
15927                                                ovl.fmt.RSY.dh2,
15928                                                S390_XMNM_STOC);  goto ok;
15929   case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15930                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15931                                                ovl.fmt.RSY.dl2,
15932                                                ovl.fmt.RSY.dh2);  goto ok;
15933   case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15934                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15935                                                ovl.fmt.RSY.dl2,
15936                                                ovl.fmt.RSY.dh2);  goto ok;
15937   case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15938                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15939                                                ovl.fmt.RSY.dl2,
15940                                                ovl.fmt.RSY.dh2);  goto ok;
15941   case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, 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 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, 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 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15950                                               ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15951                                               goto ok;
15952   case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15953                                               ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15954                                               goto ok;
15955   case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15956   case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15957                                                 ovl.fmt.RIE_RRUUU.r1,
15958                                                 ovl.fmt.RIE_RRUUU.r2,
15959                                                 ovl.fmt.RIE_RRUUU.i3,
15960                                                 ovl.fmt.RIE_RRUUU.i4,
15961                                                 ovl.fmt.RIE_RRUUU.i5);
15962                                                 goto ok;
15963   case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15964                                                 ovl.fmt.RIE_RRUUU.r1,
15965                                                 ovl.fmt.RIE_RRUUU.r2,
15966                                                 ovl.fmt.RIE_RRUUU.i3,
15967                                                 ovl.fmt.RIE_RRUUU.i4,
15968                                                 ovl.fmt.RIE_RRUUU.i5);
15969                                                 goto ok;
15970   case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15971                                                 ovl.fmt.RIE_RRUUU.r1,
15972                                                 ovl.fmt.RIE_RRUUU.r2,
15973                                                 ovl.fmt.RIE_RRUUU.i3,
15974                                                 ovl.fmt.RIE_RRUUU.i4,
15975                                                 ovl.fmt.RIE_RRUUU.i5);
15976                                                 goto ok;
15977   case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15978                                                 ovl.fmt.RIE_RRUUU.r1,
15979                                                 ovl.fmt.RIE_RRUUU.r2,
15980                                                 ovl.fmt.RIE_RRUUU.i3,
15981                                                 ovl.fmt.RIE_RRUUU.i4,
15982                                                 ovl.fmt.RIE_RRUUU.i5);
15983                                                 goto ok;
15984   case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
15985   case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15986   case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15987                                                ovl.fmt.RIE_RRPU.r1,
15988                                                ovl.fmt.RIE_RRPU.r2,
15989                                                ovl.fmt.RIE_RRPU.i4,
15990                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
15991   case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15992                                                ovl.fmt.RIE_RRPU.r1,
15993                                                ovl.fmt.RIE_RRPU.r2,
15994                                                ovl.fmt.RIE_RRPU.i4,
15995                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
15996   case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15997   case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15998   case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15999   case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
16000   case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
16001                                                ovl.fmt.RIE_RRPU.r1,
16002                                                ovl.fmt.RIE_RRPU.r2,
16003                                                ovl.fmt.RIE_RRPU.i4,
16004                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
16005   case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
16006                                                ovl.fmt.RIE_RRPU.r1,
16007                                                ovl.fmt.RIE_RRPU.r2,
16008                                                ovl.fmt.RIE_RRPU.i4,
16009                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
16010   case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
16011                                                ovl.fmt.RIEv3.r1,
16012                                                ovl.fmt.RIEv3.m3,
16013                                                ovl.fmt.RIEv3.i4,
16014                                                ovl.fmt.RIEv3.i2);  goto ok;
16015   case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
16016                                                ovl.fmt.RIEv3.r1,
16017                                                ovl.fmt.RIEv3.m3,
16018                                                ovl.fmt.RIEv3.i4,
16019                                                ovl.fmt.RIEv3.i2);  goto ok;
16020   case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
16021                                                ovl.fmt.RIEv3.r1,
16022                                                ovl.fmt.RIEv3.m3,
16023                                                ovl.fmt.RIEv3.i4,
16024                                                ovl.fmt.RIEv3.i2);  goto ok;
16025   case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
16026                                                ovl.fmt.RIEv3.r1,
16027                                                ovl.fmt.RIEv3.m3,
16028                                                ovl.fmt.RIEv3.i4,
16029                                                ovl.fmt.RIEv3.i2);  goto ok;
16030   case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
16031                                                ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
16032                                                goto ok;
16033   case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
16034                                                ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16035                                                ovl.fmt.RIE.i2);  goto ok;
16036   case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
16037                                                ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16038                                                ovl.fmt.RIE.i2);  goto ok;
16039   case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
16040                                                ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16041                                                ovl.fmt.RIE.i2);  goto ok;
16042   case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
16043                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16044                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16045                                           goto ok;
16046   case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
16047                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16048                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16049                                           goto ok;
16050   case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
16051                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16052                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16053                                           goto ok;
16054   case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
16055                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16056                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16057                                           goto ok;
16058   case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
16059                                                 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16060                                                 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16061                                                 ovl.fmt.RIS.i2);  goto ok;
16062   case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
16063                                                 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16064                                                 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16065                                                 ovl.fmt.RIS.i2);  goto ok;
16066   case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
16067                                                 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
16068                                                 ovl.fmt.RIS.d4,
16069                                                 ovl.fmt.RIS.i2);  goto ok;
16070   case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
16071                                                 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16072                                                 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16073                                                 ovl.fmt.RIS.i2);  goto ok;
16074   case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
16075                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16076                                                ovl.fmt.RXE.d2);  goto ok;
16077   case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
16078                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16079                                                ovl.fmt.RXE.d2);  goto ok;
16080   case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
16081                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16082                                                ovl.fmt.RXE.d2);  goto ok;
16083   case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
16084   case 0xed0000000008ULL: /* KEB */ goto unimplemented;
16085   case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
16086                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16087                                                ovl.fmt.RXE.d2);  goto ok;
16088   case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
16089                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16090                                                ovl.fmt.RXE.d2);  goto ok;
16091   case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
16092                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16093                                                ovl.fmt.RXE.d2);  goto ok;
16094   case 0xed000000000cULL: /* MDEB */ goto unimplemented;
16095   case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
16096                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16097                                                ovl.fmt.RXE.d2);  goto ok;
16098   case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
16099                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16100                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16101                                                 ovl.fmt.RXF.r1);  goto ok;
16102   case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
16103                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16104                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16105                                                 ovl.fmt.RXF.r1);  goto ok;
16106   case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
16107                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16108                                                ovl.fmt.RXE.d2);  goto ok;
16109   case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
16110                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16111                                                ovl.fmt.RXE.d2);  goto ok;
16112   case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
16113                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16114                                                ovl.fmt.RXE.d2);  goto ok;
16115   case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
16116                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16117                                                ovl.fmt.RXE.d2);  goto ok;
16118   case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
16119                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16120                                                ovl.fmt.RXE.d2);  goto ok;
16121   case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
16122                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16123                                                ovl.fmt.RXE.d2);  goto ok;
16124   case 0xed0000000018ULL: /* KDB */ goto unimplemented;
16125   case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
16126                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16127                                                ovl.fmt.RXE.d2);  goto ok;
16128   case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
16129                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16130                                                ovl.fmt.RXE.d2);  goto ok;
16131   case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
16132                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16133                                                ovl.fmt.RXE.d2);  goto ok;
16134   case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
16135                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16136                                                ovl.fmt.RXE.d2);  goto ok;
16137   case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
16138                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16139                                                ovl.fmt.RXE.d2);  goto ok;
16140   case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
16141                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16142                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16143                                                 ovl.fmt.RXF.r1);  goto ok;
16144   case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
16145                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16146                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16147                                                 ovl.fmt.RXF.r1);  goto ok;
16148   case 0xed0000000024ULL: /* LDE */ goto unimplemented;
16149   case 0xed0000000025ULL: /* LXD */ goto unimplemented;
16150   case 0xed0000000026ULL: /* LXE */ goto unimplemented;
16151   case 0xed000000002eULL: /* MAE */ goto unimplemented;
16152   case 0xed000000002fULL: /* MSE */ goto unimplemented;
16153   case 0xed0000000034ULL: /* SQE */ goto unimplemented;
16154   case 0xed0000000035ULL: /* SQD */ goto unimplemented;
16155   case 0xed0000000037ULL: /* MEE */ goto unimplemented;
16156   case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
16157   case 0xed0000000039ULL: /* MYL */ goto unimplemented;
16158   case 0xed000000003aULL: /* MAY */ goto unimplemented;
16159   case 0xed000000003bULL: /* MY */ goto unimplemented;
16160   case 0xed000000003cULL: /* MAYH */ goto unimplemented;
16161   case 0xed000000003dULL: /* MYH */ goto unimplemented;
16162   case 0xed000000003eULL: /* MAD */ goto unimplemented;
16163   case 0xed000000003fULL: /* MSD */ goto unimplemented;
16164   case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
16165                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16166                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16167                                                 ovl.fmt.RXF.r1);  goto ok;
16168   case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
16169                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16170                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16171                                                 ovl.fmt.RXF.r1);  goto ok;
16172   case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
16173                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16174                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16175                                                 ovl.fmt.RXF.r1);  goto ok;
16176   case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
16177                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16178                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16179                                                 ovl.fmt.RXF.r1);  goto ok;
16180   case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
16181                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16182                                                ovl.fmt.RXE.d2);  goto ok;
16183   case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
16184                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16185                                                ovl.fmt.RXE.d2);  goto ok;
16186   case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
16187                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16188                                                ovl.fmt.RXE.d2);  goto ok;
16189   case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
16190                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16191                                                ovl.fmt.RXE.d2);  goto ok;
16192   case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
16193                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16194                                                ovl.fmt.RXE.d2);  goto ok;
16195   case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
16196                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16197                                                ovl.fmt.RXE.d2);  goto ok;
16198   case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
16199                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16200                                                ovl.fmt.RXY.dl2,
16201                                                ovl.fmt.RXY.dh2);  goto ok;
16202   case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
16203                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16204                                                ovl.fmt.RXY.dl2,
16205                                                ovl.fmt.RXY.dh2);  goto ok;
16206   case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
16207                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16208                                                ovl.fmt.RXY.dl2,
16209                                                ovl.fmt.RXY.dh2);  goto ok;
16210   case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
16211                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16212                                                ovl.fmt.RXY.dl2,
16213                                                ovl.fmt.RXY.dh2);  goto ok;
16214   case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
16215   case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
16216   case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
16217   case 0xed00000000abULL: /* CXZT */ goto unimplemented;
16218   }
16219
16220   switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
16221   case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
16222                                      ovl.fmt.RIL.i2);  goto ok;
16223   case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
16224                                      ovl.fmt.RIL.i2);  goto ok;
16225   case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
16226                                   ovl.fmt.RIL.i2);  goto ok;
16227   case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16228                                      ovl.fmt.RIL.i2);  goto ok;
16229   case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16230                                      ovl.fmt.RIL.i2);  goto ok;
16231   case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16232                                      ovl.fmt.RIL.i2);  goto ok;
16233   case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16234                                      ovl.fmt.RIL.i2);  goto ok;
16235   case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16236                                      ovl.fmt.RIL.i2);  goto ok;
16237   case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16238                                      ovl.fmt.RIL.i2);  goto ok;
16239   case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16240                                      ovl.fmt.RIL.i2);  goto ok;
16241   case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16242                                      ovl.fmt.RIL.i2);  goto ok;
16243   case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16244                                      ovl.fmt.RIL.i2);  goto ok;
16245   case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16246                                      ovl.fmt.RIL.i2);  goto ok;
16247   case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16248                                      ovl.fmt.RIL.i2);  goto ok;
16249   case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16250                                      ovl.fmt.RIL.i2);  goto ok;
16251   case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16252                                      ovl.fmt.RIL.i2);  goto ok;
16253   case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16254                                      ovl.fmt.RIL.i2);  goto ok;
16255   case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16256                                      ovl.fmt.RIL.i2);  goto ok;
16257   case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16258                                      ovl.fmt.RIL.i2);  goto ok;
16259   case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16260                                      ovl.fmt.RIL.i2);  goto ok;
16261   case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16262                                      ovl.fmt.RIL.i2);  goto ok;
16263   case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16264                                      ovl.fmt.RIL.i2);  goto ok;
16265   case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16266                                      ovl.fmt.RIL.i2);  goto ok;
16267   case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16268                                      ovl.fmt.RIL.i2);  goto ok;
16269   case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16270                                      ovl.fmt.RIL.i2);  goto ok;
16271   case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16272                                      ovl.fmt.RIL.i2);  goto ok;
16273   case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16274                                      ovl.fmt.RIL.i2);  goto ok;
16275   case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16276                                      ovl.fmt.RIL.i2);  goto ok;
16277   case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16278                                      ovl.fmt.RIL.i2);  goto ok;
16279   case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16280                                      ovl.fmt.RIL.i2);  goto ok;
16281   case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16282                                      ovl.fmt.RIL.i2);  goto ok;
16283   case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16284                                      ovl.fmt.RIL.i2);  goto ok;
16285   case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16286                                      ovl.fmt.RIL.i2);  goto ok;
16287   case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16288                                      ovl.fmt.RIL.i2);  goto ok;
16289   case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16290                                      ovl.fmt.RIL.i2);  goto ok;
16291   case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16292                                      ovl.fmt.RIL.i2);  goto ok;
16293   case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16294                                      ovl.fmt.RIL.i2);  goto ok;
16295   case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16296                                      ovl.fmt.RIL.i2);  goto ok;
16297   case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16298                                      ovl.fmt.RIL.i2);  goto ok;
16299   case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16300                                      ovl.fmt.RIL.i2);  goto ok;
16301   case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16302                                      ovl.fmt.RIL.i2);  goto ok;
16303   case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16304                                      ovl.fmt.RIL.i2);  goto ok;
16305   case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16306                                      ovl.fmt.RIL.i2);  goto ok;
16307   case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16308                                      ovl.fmt.RIL.i2);  goto ok;
16309   case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16310                                      ovl.fmt.RIL.i2);  goto ok;
16311   case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16312                                      ovl.fmt.RIL.i2);  goto ok;
16313   case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16314                                      ovl.fmt.RIL.i2);  goto ok;
16315   case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16316                                      ovl.fmt.RIL.i2);  goto ok;
16317   case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16318                                      ovl.fmt.RIL.i2);  goto ok;
16319   case 0xc800ULL: /* MVCOS */ goto unimplemented;
16320   case 0xc801ULL: /* ECTG */ goto unimplemented;
16321   case 0xc802ULL: /* CSST */ goto unimplemented;
16322   case 0xc804ULL: /* LPD */ goto unimplemented;
16323   case 0xc805ULL: /* LPDG */ goto unimplemented;
16324   case 0xcc06ULL: /* BRCTH */ goto unimplemented;
16325   case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16326                                      ovl.fmt.RIL.i2);  goto ok;
16327   case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16328                                      ovl.fmt.RIL.i2);  goto ok;
16329   case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16330                                      ovl.fmt.RIL.i2);  goto ok;
16331   case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16332                                      ovl.fmt.RIL.i2);  goto ok;
16333   case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16334                                      ovl.fmt.RIL.i2);  goto ok;
16335   }
16336
16337   switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
16338   case 0xc5ULL: /* BPRP */ goto unimplemented;
16339   case 0xc7ULL: /* BPP */ goto unimplemented;
16340   case 0xd0ULL: /* TRTR */ goto unimplemented;
16341   case 0xd1ULL: /* MVN */ goto unimplemented;
16342   case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16343                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16344                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16345   case 0xd3ULL: /* MVZ */ goto unimplemented;
16346   case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16347                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16348                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16349   case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16350                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16351                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16352   case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16353                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16354                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16355   case 0xd7ULL:
16356      if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16357         s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16358      else
16359        s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16360                              ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16361                              ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16362      goto ok;
16363   case 0xd9ULL: /* MVCK */ goto unimplemented;
16364   case 0xdaULL: /* MVCP */ goto unimplemented;
16365   case 0xdbULL: /* MVCS */ goto unimplemented;
16366   case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16367                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16368                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
16369   case 0xddULL: /* TRT */ goto unimplemented;
16370   case 0xdeULL: /* ED */ goto unimplemented;
16371   case 0xdfULL: /* EDMK */ goto unimplemented;
16372   case 0xe1ULL: /* PKU */ goto unimplemented;
16373   case 0xe2ULL: /* UNPKU */ goto unimplemented;
16374   case 0xe8ULL: /* MVCIN */ goto unimplemented;
16375   case 0xe9ULL: /* PKA */ goto unimplemented;
16376   case 0xeaULL: /* UNPKA */ goto unimplemented;
16377   case 0xeeULL: /* PLO */ goto unimplemented;
16378   case 0xefULL: /* LMD */ goto unimplemented;
16379   case 0xf0ULL: /* SRP */ goto unimplemented;
16380   case 0xf1ULL: /* MVO */ goto unimplemented;
16381   case 0xf2ULL: /* PACK */ goto unimplemented;
16382   case 0xf3ULL: /* UNPK */ goto unimplemented;
16383   case 0xf8ULL: /* ZAP */ goto unimplemented;
16384   case 0xf9ULL: /* CP */ goto unimplemented;
16385   case 0xfaULL: /* AP */ goto unimplemented;
16386   case 0xfbULL: /* SP */ goto unimplemented;
16387   case 0xfcULL: /* MP */ goto unimplemented;
16388   case 0xfdULL: /* DP */ goto unimplemented;
16389   }
16390
16391   switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16392   case 0xe500ULL: /* LASP */ goto unimplemented;
16393   case 0xe501ULL: /* TPROT */ goto unimplemented;
16394   case 0xe502ULL: /* STRAG */ goto unimplemented;
16395   case 0xe50eULL: /* MVCSK */ goto unimplemented;
16396   case 0xe50fULL: /* MVCDK */ goto unimplemented;
16397   case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16398                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16399                                       goto ok;
16400   case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16401                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16402                                       goto ok;
16403   case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16404                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16405                                       goto ok;
16406   case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16407                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16408                                       goto ok;
16409   case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16410                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16411                                       goto ok;
16412   case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16413                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16414                                       goto ok;
16415   case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16416                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16417                                       goto ok;
16418   case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16419                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16420                                       goto ok;
16421   case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16422                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16423                                       goto ok;
16424   case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16425   case 0xe561ULL: /* TBEGINC */ goto unimplemented;
16426   }
16427
16428   return S390_DECODE_UNKNOWN_INSN;
16429
16430ok:
16431   return S390_DECODE_OK;
16432
16433unimplemented:
16434   return S390_DECODE_UNIMPLEMENTED_INSN;
16435}
16436
16437/* Handle "special" instructions. */
16438static s390_decode_t
16439s390_decode_special_and_irgen(const UChar *bytes)
16440{
16441   s390_decode_t status = S390_DECODE_OK;
16442
16443   /* Got a "Special" instruction preamble.  Which one is it? */
16444   if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16445      s390_irgen_client_request();
16446   } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16447      s390_irgen_guest_NRADDR();
16448   } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16449      s390_irgen_call_noredir();
16450   } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16451      vex_inject_ir(irsb, Iend_BE);
16452
16453      /* Invalidate the current insn. The reason is that the IRop we're
16454         injecting here can change. In which case the translation has to
16455         be redone. For ease of handling, we simply invalidate all the
16456         time. */
16457      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
16458                      mkU64(guest_IA_curr_instr)));
16459      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN),
16460                      mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16461      vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16462              S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16463
16464      put_IA(mkaddr_expr(guest_IA_next_instr));
16465      dis_res->whatNext    = Dis_StopHere;
16466      dis_res->jk_StopHere = Ijk_InvalICache;
16467   } else {
16468      /* We don't know what it is. */
16469      return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16470   }
16471
16472   dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16473
16474   return status;
16475}
16476
16477
16478/* Function returns # bytes that were decoded or 0 in case of failure */
16479static UInt
16480s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres)
16481{
16482   s390_decode_t status;
16483
16484   dis_res = dres;
16485
16486   /* Spot the 8-byte preamble:   18ff lr r15,r15
16487                                  1811 lr r1,r1
16488                                  1822 lr r2,r2
16489                                  1833 lr r3,r3 */
16490   if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16491       bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16492       bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16493
16494      /* Handle special instruction that follows that preamble. */
16495      if (0) vex_printf("special function handling...\n");
16496
16497      insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16498      guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16499
16500      status =
16501         s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
16502   } else {
16503      /* Handle normal instructions. */
16504      switch (insn_length) {
16505      case 2:
16506         status = s390_decode_2byte_and_irgen(bytes);
16507         break;
16508
16509      case 4:
16510         status = s390_decode_4byte_and_irgen(bytes);
16511         break;
16512
16513      case 6:
16514         status = s390_decode_6byte_and_irgen(bytes);
16515         break;
16516
16517      default:
16518        status = S390_DECODE_ERROR;
16519        break;
16520      }
16521   }
16522   /* If next instruction is execute, stop here */
16523   if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16524      put_IA(mkaddr_expr(guest_IA_next_instr));
16525      dis_res->whatNext = Dis_StopHere;
16526      dis_res->jk_StopHere = Ijk_Boring;
16527   }
16528
16529   if (status == S390_DECODE_OK) return insn_length;  /* OK */
16530
16531   /* Decoding failed somehow */
16532   if (sigill_diag) {
16533      vex_printf("vex s390->IR: ");
16534      switch (status) {
16535      case S390_DECODE_UNKNOWN_INSN:
16536         vex_printf("unknown insn: ");
16537         break;
16538
16539      case S390_DECODE_UNIMPLEMENTED_INSN:
16540         vex_printf("unimplemented insn: ");
16541         break;
16542
16543      case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16544         vex_printf("unimplemented special insn: ");
16545         break;
16546
16547      case S390_DECODE_ERROR:
16548         vex_printf("decoding error: ");
16549         break;
16550
16551      default:
16552         vpanic("s390_decode_and_irgen");
16553      }
16554
16555      vex_printf("%02x%02x", bytes[0], bytes[1]);
16556      if (insn_length > 2) {
16557         vex_printf(" %02x%02x", bytes[2], bytes[3]);
16558      }
16559      if (insn_length > 4) {
16560         vex_printf(" %02x%02x", bytes[4], bytes[5]);
16561      }
16562      vex_printf("\n");
16563   }
16564
16565   return 0;  /* Failed */
16566}
16567
16568
16569/* Disassemble a single instruction INSN into IR. */
16570static DisResult
16571disInstr_S390_WRK(const UChar *insn)
16572{
16573   UChar byte;
16574   UInt  insn_length;
16575   DisResult dres;
16576
16577   /* ---------------------------------------------------- */
16578   /* --- Compute instruction length                    -- */
16579   /* ---------------------------------------------------- */
16580
16581   /* Get the first byte of the insn. */
16582   byte = insn[0];
16583
16584   /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16585      00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16586   insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16587
16588   guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16589
16590   /* ---------------------------------------------------- */
16591   /* --- Initialise the DisResult data                 -- */
16592   /* ---------------------------------------------------- */
16593   dres.whatNext   = Dis_Continue;
16594   dres.len        = insn_length;
16595   dres.continueAt = 0;
16596   dres.jk_StopHere = Ijk_INVALID;
16597
16598   /* fixs390: consider chasing of conditional jumps */
16599
16600   /* Normal and special instruction handling starts here. */
16601   if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16602      /* All decode failures end up here. The decoder has already issued an
16603         error message.
16604         Tell the dispatcher that this insn cannot be decoded, and so has
16605         not been executed, and (is currently) the next to be executed.
16606         The insn address in the guest state needs to be set to
16607         guest_IA_curr_instr, otherwise the complaint will report an
16608         incorrect address. */
16609      put_IA(mkaddr_expr(guest_IA_curr_instr));
16610
16611      dres.len         = 0;
16612      dres.whatNext    = Dis_StopHere;
16613      dres.jk_StopHere = Ijk_NoDecode;
16614      dres.continueAt  = 0;
16615   } else {
16616      /* Decode success */
16617      switch (dres.whatNext) {
16618      case Dis_Continue:
16619         put_IA(mkaddr_expr(guest_IA_next_instr));
16620         break;
16621      case Dis_ResteerU:
16622      case Dis_ResteerC:
16623         put_IA(mkaddr_expr(dres.continueAt));
16624         break;
16625      case Dis_StopHere:
16626         if (dres.jk_StopHere == Ijk_EmWarn ||
16627             dres.jk_StopHere == Ijk_EmFail) {
16628            /* We assume here, that emulation warnings are not given for
16629               insns that transfer control. There is no good way to
16630               do that. */
16631            put_IA(mkaddr_expr(guest_IA_next_instr));
16632         }
16633         break;
16634      default:
16635         vpanic("disInstr_S390_WRK");
16636      }
16637   }
16638
16639   return dres;
16640}
16641
16642
16643/*------------------------------------------------------------*/
16644/*--- Top-level fn                                         ---*/
16645/*------------------------------------------------------------*/
16646
16647/* Disassemble a single instruction into IR.  The instruction
16648   is located in host memory at &guest_code[delta]. */
16649
16650DisResult
16651disInstr_S390(IRSB        *irsb_IN,
16652              Bool       (*resteerOkFn)(void *, Addr),
16653              Bool         resteerCisOk,
16654              void        *callback_opaque,
16655              const UChar *guest_code,
16656              Long         delta,
16657              Addr         guest_IP,
16658              VexArch      guest_arch,
16659              const VexArchInfo *archinfo,
16660              const VexAbiInfo  *abiinfo,
16661              VexEndness   host_endness,
16662              Bool         sigill_diag_IN)
16663{
16664   vassert(guest_arch == VexArchS390X);
16665
16666   /* The instruction decoder requires a big-endian machine. */
16667   vassert(host_endness == VexEndnessBE);
16668
16669   /* Set globals (see top of this file) */
16670   guest_IA_curr_instr = guest_IP;
16671   irsb = irsb_IN;
16672   resteer_fn = resteerOkFn;
16673   resteer_data = callback_opaque;
16674   sigill_diag = sigill_diag_IN;
16675
16676   return disInstr_S390_WRK(guest_code + delta);
16677}
16678
16679/*---------------------------------------------------------------*/
16680/*--- end                                   guest_s390_toIR.c ---*/
16681/*---------------------------------------------------------------*/
16682