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-2012
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.h"                  /* needed for bb_to_IR.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 "host_s390_disasm.h"
44#include "host_s390_defs.h"          /* S390_ROUND_xyzzy */
45
46
47/*------------------------------------------------------------*/
48/*--- Forward declarations                                 ---*/
49/*------------------------------------------------------------*/
50static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
51static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
52static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
53
54
55/*------------------------------------------------------------*/
56/*--- Globals                                              ---*/
57/*------------------------------------------------------------*/
58
59/* The IRSB* into which we're generating code. */
60static IRSB *irsb;
61
62/* The guest address for the instruction currently being
63   translated. */
64static Addr64 guest_IA_curr_instr;
65
66/* The guest address for the instruction following the current instruction. */
67static Addr64 guest_IA_next_instr;
68
69/* Result of disassembly step. */
70static DisResult *dis_res;
71
72/* Resteer function and callback data */
73static Bool (*resteer_fn)(void *, Addr64);
74static void *resteer_data;
75
76/* The last seen execute target instruction */
77ULong last_execute_target;
78
79/* The possible outcomes of a decoding operation */
80typedef enum {
81   S390_DECODE_OK,
82   S390_DECODE_UNKNOWN_INSN,
83   S390_DECODE_UNIMPLEMENTED_INSN,
84   S390_DECODE_UNKNOWN_SPECIAL_INSN,
85   S390_DECODE_ERROR
86} s390_decode_t;
87
88
89/*------------------------------------------------------------*/
90/*--- Helpers for constructing IR.                         ---*/
91/*------------------------------------------------------------*/
92
93/* Sign extend a value with the given number of bits. This is a
94   macro because it allows us to overload the type of the value.
95   Note that VALUE must have a signed type! */
96#undef sign_extend
97#define sign_extend(value,num_bits) \
98(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
99 (sizeof(__typeof__(value)) * 8 - (num_bits)))
100
101
102/* Add a statement to the current irsb. */
103static __inline__ void
104stmt(IRStmt *st)
105{
106   addStmtToIRSB(irsb, st);
107}
108
109/* Allocate a new temporary of the given type. */
110static __inline__ IRTemp
111newTemp(IRType type)
112{
113   vassert(isPlausibleIRType(type));
114
115   return newIRTemp(irsb->tyenv, type);
116}
117
118/* Create an expression node for a temporary */
119static __inline__ IRExpr *
120mkexpr(IRTemp tmp)
121{
122   return IRExpr_RdTmp(tmp);
123}
124
125/* Generate an expression node for an address. */
126static __inline__ IRExpr *
127mkaddr_expr(Addr64 addr)
128{
129   return IRExpr_Const(IRConst_U64(addr));
130}
131
132/* Add a statement that assigns to a temporary */
133static __inline__ void
134assign(IRTemp dst, IRExpr *expr)
135{
136   stmt(IRStmt_WrTmp(dst, expr));
137}
138
139/* Write an address into the guest_IA */
140static __inline__ void
141put_IA(IRExpr *address)
142{
143   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
144}
145
146/* Create a temporary of the given type and assign the expression to it */
147static __inline__ IRTemp
148mktemp(IRType type, IRExpr *expr)
149{
150   IRTemp temp = newTemp(type);
151
152   assign(temp, expr);
153
154   return temp;
155}
156
157/* Create a unary expression */
158static __inline__ IRExpr *
159unop(IROp kind, IRExpr *op)
160{
161   return IRExpr_Unop(kind, op);
162}
163
164/* Create a binary expression */
165static __inline__ IRExpr *
166binop(IROp kind, IRExpr *op1, IRExpr *op2)
167{
168   return IRExpr_Binop(kind, op1, op2);
169}
170
171/* Create a ternary expression */
172static __inline__ IRExpr *
173triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
174{
175   return IRExpr_Triop(kind, op1, op2, op3);
176}
177
178/* Create a quaternary expression */
179static __inline__  IRExpr *
180qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
181{
182   return IRExpr_Qop(kind, op1, op2, op3, op4);
183}
184
185/* Create an expression node for an 8-bit integer constant */
186static __inline__ IRExpr *
187mkU8(UInt value)
188{
189   vassert(value < 256);
190
191   return IRExpr_Const(IRConst_U8((UChar)value));
192}
193
194/* Create an expression node for a 16-bit integer constant */
195static __inline__ IRExpr *
196mkU16(UInt value)
197{
198   vassert(value < 65536);
199
200   return IRExpr_Const(IRConst_U16((UShort)value));
201}
202
203/* Create an expression node for a 32-bit integer constant */
204static __inline__ IRExpr *
205mkU32(UInt value)
206{
207   return IRExpr_Const(IRConst_U32(value));
208}
209
210/* Create an expression node for a 64-bit integer constant */
211static __inline__ IRExpr *
212mkU64(ULong value)
213{
214   return IRExpr_Const(IRConst_U64(value));
215}
216
217/* Create an expression node for a 32-bit floating point constant
218   whose value is given by a bit pattern. */
219static __inline__ IRExpr *
220mkF32i(UInt value)
221{
222   return IRExpr_Const(IRConst_F32i(value));
223}
224
225/* Create an expression node for a 32-bit floating point constant
226   whose value is given by a bit pattern. */
227static __inline__ IRExpr *
228mkF64i(ULong value)
229{
230   return IRExpr_Const(IRConst_F64i(value));
231}
232
233/* Little helper function for my sanity. ITE = if-then-else */
234static IRExpr *
235mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
236{
237   vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
238
239   return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
240}
241
242/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
243static void __inline__
244store(IRExpr *addr, IRExpr *data)
245{
246   stmt(IRStmt_Store(Iend_BE, addr, data));
247}
248
249/* Create an expression that loads a TYPE sized value from ADDR.
250   This is a big-endian machine. */
251static __inline__ IRExpr *
252load(IRType type, IRExpr *addr)
253{
254   return IRExpr_Load(Iend_BE, type, addr);
255}
256
257/* Function call */
258static void
259call_function(IRExpr *callee_address)
260{
261   put_IA(callee_address);
262
263   dis_res->whatNext    = Dis_StopHere;
264   dis_res->jk_StopHere = Ijk_Call;
265}
266
267/* Function call with known target. */
268static void
269call_function_and_chase(Addr64 callee_address)
270{
271   if (resteer_fn(resteer_data, callee_address)) {
272      dis_res->whatNext   = Dis_ResteerU;
273      dis_res->continueAt = callee_address;
274   } else {
275      put_IA(mkaddr_expr(callee_address));
276
277      dis_res->whatNext = Dis_StopHere;
278      dis_res->jk_StopHere = Ijk_Call;
279   }
280}
281
282/* Function return sequence */
283static void
284return_from_function(IRExpr *return_address)
285{
286   put_IA(return_address);
287
288   dis_res->whatNext    = Dis_StopHere;
289   dis_res->jk_StopHere = Ijk_Ret;
290}
291
292/* A conditional branch whose target is not known at instrumentation time.
293
294   if (condition) goto computed_target;
295
296   Needs to be represented as:
297
298   if (! condition) goto next_instruction;
299   goto computed_target;
300*/
301static void
302if_condition_goto_computed(IRExpr *condition, IRExpr *target)
303{
304   vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
305
306   condition = unop(Iop_Not1, condition);
307
308   stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
309                    S390X_GUEST_OFFSET(guest_IA)));
310
311   put_IA(target);
312
313   dis_res->whatNext    = Dis_StopHere;
314   dis_res->jk_StopHere = Ijk_Boring;
315}
316
317/* A conditional branch whose target is known at instrumentation time. */
318static void
319if_condition_goto(IRExpr *condition, Addr64 target)
320{
321   vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
322
323   stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
324                    S390X_GUEST_OFFSET(guest_IA)));
325
326   put_IA(mkaddr_expr(guest_IA_next_instr));
327
328   dis_res->whatNext    = Dis_StopHere;
329   dis_res->jk_StopHere = Ijk_Boring;
330}
331
332/* An unconditional branch. Target may or may not be known at instrumentation
333   time. */
334static void
335always_goto(IRExpr *target)
336{
337   put_IA(target);
338
339   dis_res->whatNext    = Dis_StopHere;
340   dis_res->jk_StopHere = Ijk_Boring;
341}
342
343
344/* An unconditional branch to a known target. */
345static void
346always_goto_and_chase(Addr64 target)
347{
348   if (resteer_fn(resteer_data, target)) {
349      /* Follow into the target */
350      dis_res->whatNext   = Dis_ResteerU;
351      dis_res->continueAt = target;
352   } else {
353      put_IA(mkaddr_expr(target));
354
355      dis_res->whatNext    = Dis_StopHere;
356      dis_res->jk_StopHere = Ijk_Boring;
357   }
358}
359
360/* A system call */
361static void
362system_call(IRExpr *sysno)
363{
364   /* Store the system call number in the pseudo register. */
365   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
366
367   /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
368   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
369                   mkU64(guest_IA_curr_instr)));
370
371   put_IA(mkaddr_expr(guest_IA_next_instr));
372
373   /* It's important that all ArchRegs carry their up-to-date value
374      at this point.  So we declare an end-of-block here, which
375      forces any TempRegs caching ArchRegs to be flushed. */
376   dis_res->whatNext    = Dis_StopHere;
377   dis_res->jk_StopHere = Ijk_Sys_syscall;
378}
379
380/* A side exit that branches back to the current insn if CONDITION is
381   true. Does not set DisResult. */
382static void
383iterate_if(IRExpr *condition)
384{
385   vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
386
387   stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
388                    S390X_GUEST_OFFSET(guest_IA)));
389}
390
391/* A side exit that branches back to the current insn.
392   Does not set DisResult. */
393static __inline__ void
394iterate(void)
395{
396   iterate_if(IRExpr_Const(IRConst_U1(True)));
397}
398
399/* A side exit that branches back to the insn immediately following the
400   current insn if CONDITION is true. Does not set DisResult. */
401static void
402next_insn_if(IRExpr *condition)
403{
404   vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
405
406   stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
407                    S390X_GUEST_OFFSET(guest_IA)));
408}
409
410/* Convenience function to restart the current insn */
411static void
412restart_if(IRExpr *condition)
413{
414   vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
415
416   stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
417                    S390X_GUEST_OFFSET(guest_IA)));
418}
419
420/* Convenience function to yield to thread scheduler */
421static void
422yield_if(IRExpr *condition)
423{
424   stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
425                    S390X_GUEST_OFFSET(guest_IA)));
426}
427
428/* Encode the s390 rounding mode as it appears in the m3/m4 fields of certain
429   instructions to VEX's IRRoundingMode. */
430static IRRoundingMode
431encode_rounding_mode(UChar mode)
432{
433   switch (mode) {
434   case S390_ROUND_NEAREST_EVEN:  return Irrm_NEAREST;
435   case S390_ROUND_ZERO:          return Irrm_ZERO;
436   case S390_ROUND_POSINF:        return Irrm_PosINF;
437   case S390_ROUND_NEGINF:        return Irrm_NegINF;
438   }
439   vpanic("encode_rounding_mode");
440}
441
442static __inline__ IRExpr *get_fpr_dw0(UInt);
443static __inline__ void    put_fpr_dw0(UInt, IRExpr *);
444
445/* Read a floating point register pair and combine their contents into a
446   128-bit value */
447static IRExpr *
448get_fpr_pair(UInt archreg)
449{
450   IRExpr *high = get_fpr_dw0(archreg);
451   IRExpr *low  = get_fpr_dw0(archreg + 2);
452
453   return binop(Iop_F64HLtoF128, high, low);
454}
455
456/* Write a 128-bit floating point value into a register pair. */
457static void
458put_fpr_pair(UInt archreg, IRExpr *expr)
459{
460   IRExpr *high = unop(Iop_F128HItoF64, expr);
461   IRExpr *low  = unop(Iop_F128LOtoF64, expr);
462
463   put_fpr_dw0(archreg,     high);
464   put_fpr_dw0(archreg + 2, low);
465}
466
467
468/*------------------------------------------------------------*/
469/*--- IR Debugging aids.                                   ---*/
470/*------------------------------------------------------------*/
471#if 0
472
473static ULong
474s390_do_print(HChar *text, ULong value)
475{
476   vex_printf("%s %llu\n", text, value);
477   return 0;
478}
479
480static void
481s390_print(HChar *text, IRExpr *value)
482{
483   IRDirty *d;
484
485   d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
486                         mkIRExprVec_2(mkU64((ULong)text), value));
487   stmt(IRStmt_Dirty(d));
488}
489#endif
490
491
492/*------------------------------------------------------------*/
493/*--- Build the flags thunk.                               ---*/
494/*------------------------------------------------------------*/
495
496/* Completely fill the flags thunk. We're always filling all fields.
497   Apparently, that is better for redundant PUT elimination. */
498static void
499s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
500{
501   UInt op_off, dep1_off, dep2_off, ndep_off;
502
503   op_off   = S390X_GUEST_OFFSET(guest_CC_OP);
504   dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
505   dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
506   ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
507
508   stmt(IRStmt_Put(op_off,   op));
509   stmt(IRStmt_Put(dep1_off, dep1));
510   stmt(IRStmt_Put(dep2_off, dep2));
511   stmt(IRStmt_Put(ndep_off, ndep));
512}
513
514
515/* Create an expression for V and widen the result to 64 bit. */
516static IRExpr *
517s390_cc_widen(IRTemp v, Bool sign_extend)
518{
519   IRExpr *expr;
520
521   expr = mkexpr(v);
522
523   switch (typeOfIRTemp(irsb->tyenv, v)) {
524   case Ity_I64:
525      break;
526   case Ity_I32:
527      expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
528      break;
529   case Ity_I16:
530      expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
531      break;
532   case Ity_I8:
533      expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
534      break;
535   default:
536      vpanic("s390_cc_widen");
537   }
538
539   return expr;
540}
541
542static void
543s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
544{
545   IRExpr *op, *dep1, *dep2, *ndep;
546
547   op   = mkU64(opc);
548   dep1 = s390_cc_widen(d1, sign_extend);
549   dep2 = mkU64(0);
550   ndep = mkU64(0);
551
552   s390_cc_thunk_fill(op, dep1, dep2, ndep);
553}
554
555
556static void
557s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
558{
559   IRExpr *op, *dep1, *dep2, *ndep;
560
561   op   = mkU64(opc);
562   dep1 = s390_cc_widen(d1, sign_extend);
563   dep2 = s390_cc_widen(d2, sign_extend);
564   ndep = mkU64(0);
565
566   s390_cc_thunk_fill(op, dep1, dep2, ndep);
567}
568
569
570/* memcheck believes that the NDEP field in the flags thunk is always
571   defined. But for some flag computations (e.g. add with carry) that is
572   just not true. We therefore need to convey to memcheck that the value
573   of the ndep field does matter and therefore we make the DEP2 field
574   depend on it:
575
576   DEP2 = original_DEP2 ^ NDEP
577
578   In s390_calculate_cc we exploit that  (a^b)^b == a
579   I.e. we xor the DEP2 value with the NDEP value to recover the
580   original_DEP2 value. */
581static void
582s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
583{
584   IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
585
586   op   = mkU64(opc);
587   dep1 = s390_cc_widen(d1, sign_extend);
588   dep2 = s390_cc_widen(d2, sign_extend);
589   ndep = s390_cc_widen(nd, sign_extend);
590
591   dep2x = binop(Iop_Xor64, dep2, ndep);
592
593   s390_cc_thunk_fill(op, dep1, dep2x, ndep);
594}
595
596
597/* Write one floating point value into the flags thunk */
598static void
599s390_cc_thunk_put1f(UInt opc, IRTemp d1)
600{
601   IRExpr *op, *dep1, *dep2, *ndep;
602
603   op   = mkU64(opc);
604   dep1 = mkexpr(d1);
605   dep2 = mkU64(0);
606   ndep = mkU64(0);
607
608   s390_cc_thunk_fill(op, dep1, dep2, ndep);
609}
610
611
612/* Write a floating point value and an integer into the flags thunk. The
613   integer value is zero-extended first. */
614static void
615s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
616{
617   IRExpr *op, *dep1, *dep2, *ndep;
618
619   op   = mkU64(opc);
620   dep1 = mkexpr(d1);
621   dep2 = s390_cc_widen(d2, False);
622   ndep = mkU64(0);
623
624   s390_cc_thunk_fill(op, dep1, dep2, ndep);
625}
626
627
628/* Write a 128-bit floating point value into the flags thunk. This is
629   done by splitting the value into two 64-bits values. */
630static void
631s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
632{
633   IRExpr *op, *hi, *lo, *ndep;
634
635   op   = mkU64(opc);
636   hi   = unop(Iop_F128HItoF64, mkexpr(d1));
637   lo   = unop(Iop_F128LOtoF64, mkexpr(d1));
638   ndep = mkU64(0);
639
640   s390_cc_thunk_fill(op, hi, lo, ndep);
641}
642
643
644/* Write a 128-bit floating point value and an integer into the flags thunk.
645   The integer value is zero-extended first. */
646static void
647s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
648{
649   IRExpr *op, *hi, *lo, *lox, *ndep;
650
651   op   = mkU64(opc);
652   hi   = unop(Iop_F128HItoF64, mkexpr(d1));
653   lo   = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
654   ndep = s390_cc_widen(nd, False);
655
656   lox = binop(Iop_Xor64, lo, ndep);  /* convey dependency */
657
658   s390_cc_thunk_fill(op, hi, lox, ndep);
659}
660
661
662static void
663s390_cc_set(UInt val)
664{
665   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
666                      mkU64(val), mkU64(0), mkU64(0));
667}
668
669/* Build IR to calculate the condition code from flags thunk.
670   Returns an expression of type Ity_I32 */
671static IRExpr *
672s390_call_calculate_cc(void)
673{
674   IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
675
676   op   = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP),   Ity_I64);
677   dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
678   dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
679   ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
680
681   args = mkIRExprVec_4(op, dep1, dep2, ndep);
682   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
683                        "s390_calculate_cc", &s390_calculate_cc, args);
684
685   /* Exclude OP and NDEP from definedness checking.  We're only
686      interested in DEP1 and DEP2. */
687   call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
688
689   return call;
690}
691
692/* Build IR to calculate the internal condition code for a "compare and branch"
693   insn. Returns an expression of type Ity_I32 */
694static IRExpr *
695s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
696{
697   IRExpr **args, *call, *op, *dep1, *dep2, *mask;
698
699   switch (opc) {
700   case S390_CC_OP_SIGNED_COMPARE:
701      dep1 = s390_cc_widen(op1, True);
702      dep2 = s390_cc_widen(op2, True);
703      break;
704
705   case S390_CC_OP_UNSIGNED_COMPARE:
706      dep1 = s390_cc_widen(op1, False);
707      dep2 = s390_cc_widen(op2, False);
708      break;
709
710   default:
711      vpanic("s390_call_calculate_icc");
712   }
713
714   mask = mkU64(m);
715   op   = mkU64(opc);
716
717   args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
718   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
719                        "s390_calculate_cond", &s390_calculate_cond, args);
720
721   /* Exclude the requested condition, OP and NDEP from definedness
722      checking.  We're only interested in DEP1 and DEP2. */
723   call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
724
725   return call;
726}
727
728/* Build IR to calculate the condition code from flags thunk.
729   Returns an expression of type Ity_I32 */
730static IRExpr *
731s390_call_calculate_cond(UInt m)
732{
733   IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
734
735   mask = mkU64(m);
736   op   = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP),   Ity_I64);
737   dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
738   dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
739   ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
740
741   args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
742   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
743                        "s390_calculate_cond", &s390_calculate_cond, args);
744
745   /* Exclude the requested condition, OP and NDEP from definedness
746      checking.  We're only interested in DEP1 and DEP2. */
747   call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
748
749   return call;
750}
751
752#define s390_cc_thunk_putZ(op,dep1)  s390_cc_thunk_put1(op,dep1,False)
753#define s390_cc_thunk_putS(op,dep1)  s390_cc_thunk_put1(op,dep1,True)
754#define s390_cc_thunk_putF(op,dep1)  s390_cc_thunk_put1f(op,dep1)
755#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
756#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
757#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
758#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
759        s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
760#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
761        s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
762
763
764
765
766/*------------------------------------------------------------*/
767/*--- Guest register access                                ---*/
768/*------------------------------------------------------------*/
769
770
771/*------------------------------------------------------------*/
772/*--- ar registers                                         ---*/
773/*------------------------------------------------------------*/
774
775/* Return the guest state offset of a ar register. */
776static UInt
777ar_offset(UInt archreg)
778{
779   static const UInt offset[16] = {
780      S390X_GUEST_OFFSET(guest_a0),
781      S390X_GUEST_OFFSET(guest_a1),
782      S390X_GUEST_OFFSET(guest_a2),
783      S390X_GUEST_OFFSET(guest_a3),
784      S390X_GUEST_OFFSET(guest_a4),
785      S390X_GUEST_OFFSET(guest_a5),
786      S390X_GUEST_OFFSET(guest_a6),
787      S390X_GUEST_OFFSET(guest_a7),
788      S390X_GUEST_OFFSET(guest_a8),
789      S390X_GUEST_OFFSET(guest_a9),
790      S390X_GUEST_OFFSET(guest_a10),
791      S390X_GUEST_OFFSET(guest_a11),
792      S390X_GUEST_OFFSET(guest_a12),
793      S390X_GUEST_OFFSET(guest_a13),
794      S390X_GUEST_OFFSET(guest_a14),
795      S390X_GUEST_OFFSET(guest_a15),
796   };
797
798   vassert(archreg < 16);
799
800   return offset[archreg];
801}
802
803
804/* Return the guest state offset of word #0 of a ar register. */
805static __inline__ UInt
806ar_w0_offset(UInt archreg)
807{
808   return ar_offset(archreg) + 0;
809}
810
811/* Write word #0 of a ar to the guest state. */
812static __inline__ void
813put_ar_w0(UInt archreg, IRExpr *expr)
814{
815   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
816
817   stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
818}
819
820/* Read word #0 of a ar register. */
821static __inline__ IRExpr *
822get_ar_w0(UInt archreg)
823{
824   return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
825}
826
827
828/*------------------------------------------------------------*/
829/*--- fpr registers                                        ---*/
830/*------------------------------------------------------------*/
831
832/* Return the guest state offset of a fpr register. */
833static UInt
834fpr_offset(UInt archreg)
835{
836   static const UInt offset[16] = {
837      S390X_GUEST_OFFSET(guest_f0),
838      S390X_GUEST_OFFSET(guest_f1),
839      S390X_GUEST_OFFSET(guest_f2),
840      S390X_GUEST_OFFSET(guest_f3),
841      S390X_GUEST_OFFSET(guest_f4),
842      S390X_GUEST_OFFSET(guest_f5),
843      S390X_GUEST_OFFSET(guest_f6),
844      S390X_GUEST_OFFSET(guest_f7),
845      S390X_GUEST_OFFSET(guest_f8),
846      S390X_GUEST_OFFSET(guest_f9),
847      S390X_GUEST_OFFSET(guest_f10),
848      S390X_GUEST_OFFSET(guest_f11),
849      S390X_GUEST_OFFSET(guest_f12),
850      S390X_GUEST_OFFSET(guest_f13),
851      S390X_GUEST_OFFSET(guest_f14),
852      S390X_GUEST_OFFSET(guest_f15),
853   };
854
855   vassert(archreg < 16);
856
857   return offset[archreg];
858}
859
860
861/* Return the guest state offset of word #0 of a fpr register. */
862static __inline__ UInt
863fpr_w0_offset(UInt archreg)
864{
865   return fpr_offset(archreg) + 0;
866}
867
868/* Write word #0 of a fpr to the guest state. */
869static __inline__ void
870put_fpr_w0(UInt archreg, IRExpr *expr)
871{
872   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
873
874   stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
875}
876
877/* Read word #0 of a fpr register. */
878static __inline__ IRExpr *
879get_fpr_w0(UInt archreg)
880{
881   return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
882}
883
884/* Return the guest state offset of double word #0 of a fpr register. */
885static __inline__ UInt
886fpr_dw0_offset(UInt archreg)
887{
888   return fpr_offset(archreg) + 0;
889}
890
891/* Write double word #0 of a fpr to the guest state. */
892static __inline__ void
893put_fpr_dw0(UInt archreg, IRExpr *expr)
894{
895   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
896
897   stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
898}
899
900/* Read double word #0 of a fpr register. */
901static __inline__ IRExpr *
902get_fpr_dw0(UInt archreg)
903{
904   return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
905}
906
907
908/*------------------------------------------------------------*/
909/*--- gpr registers                                        ---*/
910/*------------------------------------------------------------*/
911
912/* Return the guest state offset of a gpr register. */
913static UInt
914gpr_offset(UInt archreg)
915{
916   static const UInt offset[16] = {
917      S390X_GUEST_OFFSET(guest_r0),
918      S390X_GUEST_OFFSET(guest_r1),
919      S390X_GUEST_OFFSET(guest_r2),
920      S390X_GUEST_OFFSET(guest_r3),
921      S390X_GUEST_OFFSET(guest_r4),
922      S390X_GUEST_OFFSET(guest_r5),
923      S390X_GUEST_OFFSET(guest_r6),
924      S390X_GUEST_OFFSET(guest_r7),
925      S390X_GUEST_OFFSET(guest_r8),
926      S390X_GUEST_OFFSET(guest_r9),
927      S390X_GUEST_OFFSET(guest_r10),
928      S390X_GUEST_OFFSET(guest_r11),
929      S390X_GUEST_OFFSET(guest_r12),
930      S390X_GUEST_OFFSET(guest_r13),
931      S390X_GUEST_OFFSET(guest_r14),
932      S390X_GUEST_OFFSET(guest_r15),
933   };
934
935   vassert(archreg < 16);
936
937   return offset[archreg];
938}
939
940
941/* Return the guest state offset of word #0 of a gpr register. */
942static __inline__ UInt
943gpr_w0_offset(UInt archreg)
944{
945   return gpr_offset(archreg) + 0;
946}
947
948/* Write word #0 of a gpr to the guest state. */
949static __inline__ void
950put_gpr_w0(UInt archreg, IRExpr *expr)
951{
952   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
953
954   stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
955}
956
957/* Read word #0 of a gpr register. */
958static __inline__ IRExpr *
959get_gpr_w0(UInt archreg)
960{
961   return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
962}
963
964/* Return the guest state offset of double word #0 of a gpr register. */
965static __inline__ UInt
966gpr_dw0_offset(UInt archreg)
967{
968   return gpr_offset(archreg) + 0;
969}
970
971/* Write double word #0 of a gpr to the guest state. */
972static __inline__ void
973put_gpr_dw0(UInt archreg, IRExpr *expr)
974{
975   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
976
977   stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
978}
979
980/* Read double word #0 of a gpr register. */
981static __inline__ IRExpr *
982get_gpr_dw0(UInt archreg)
983{
984   return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
985}
986
987/* Return the guest state offset of half word #1 of a gpr register. */
988static __inline__ UInt
989gpr_hw1_offset(UInt archreg)
990{
991   return gpr_offset(archreg) + 2;
992}
993
994/* Write half word #1 of a gpr to the guest state. */
995static __inline__ void
996put_gpr_hw1(UInt archreg, IRExpr *expr)
997{
998   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
999
1000   stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1001}
1002
1003/* Read half word #1 of a gpr register. */
1004static __inline__ IRExpr *
1005get_gpr_hw1(UInt archreg)
1006{
1007   return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1008}
1009
1010/* Return the guest state offset of byte #6 of a gpr register. */
1011static __inline__ UInt
1012gpr_b6_offset(UInt archreg)
1013{
1014   return gpr_offset(archreg) + 6;
1015}
1016
1017/* Write byte #6 of a gpr to the guest state. */
1018static __inline__ void
1019put_gpr_b6(UInt archreg, IRExpr *expr)
1020{
1021   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1022
1023   stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1024}
1025
1026/* Read byte #6 of a gpr register. */
1027static __inline__ IRExpr *
1028get_gpr_b6(UInt archreg)
1029{
1030   return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1031}
1032
1033/* Return the guest state offset of byte #3 of a gpr register. */
1034static __inline__ UInt
1035gpr_b3_offset(UInt archreg)
1036{
1037   return gpr_offset(archreg) + 3;
1038}
1039
1040/* Write byte #3 of a gpr to the guest state. */
1041static __inline__ void
1042put_gpr_b3(UInt archreg, IRExpr *expr)
1043{
1044   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1045
1046   stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1047}
1048
1049/* Read byte #3 of a gpr register. */
1050static __inline__ IRExpr *
1051get_gpr_b3(UInt archreg)
1052{
1053   return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1054}
1055
1056/* Return the guest state offset of byte #0 of a gpr register. */
1057static __inline__ UInt
1058gpr_b0_offset(UInt archreg)
1059{
1060   return gpr_offset(archreg) + 0;
1061}
1062
1063/* Write byte #0 of a gpr to the guest state. */
1064static __inline__ void
1065put_gpr_b0(UInt archreg, IRExpr *expr)
1066{
1067   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1068
1069   stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1070}
1071
1072/* Read byte #0 of a gpr register. */
1073static __inline__ IRExpr *
1074get_gpr_b0(UInt archreg)
1075{
1076   return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1077}
1078
1079/* Return the guest state offset of word #1 of a gpr register. */
1080static __inline__ UInt
1081gpr_w1_offset(UInt archreg)
1082{
1083   return gpr_offset(archreg) + 4;
1084}
1085
1086/* Write word #1 of a gpr to the guest state. */
1087static __inline__ void
1088put_gpr_w1(UInt archreg, IRExpr *expr)
1089{
1090   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1091
1092   stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1093}
1094
1095/* Read word #1 of a gpr register. */
1096static __inline__ IRExpr *
1097get_gpr_w1(UInt archreg)
1098{
1099   return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1100}
1101
1102/* Return the guest state offset of half word #3 of a gpr register. */
1103static __inline__ UInt
1104gpr_hw3_offset(UInt archreg)
1105{
1106   return gpr_offset(archreg) + 6;
1107}
1108
1109/* Write half word #3 of a gpr to the guest state. */
1110static __inline__ void
1111put_gpr_hw3(UInt archreg, IRExpr *expr)
1112{
1113   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1114
1115   stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1116}
1117
1118/* Read half word #3 of a gpr register. */
1119static __inline__ IRExpr *
1120get_gpr_hw3(UInt archreg)
1121{
1122   return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1123}
1124
1125/* Return the guest state offset of byte #7 of a gpr register. */
1126static __inline__ UInt
1127gpr_b7_offset(UInt archreg)
1128{
1129   return gpr_offset(archreg) + 7;
1130}
1131
1132/* Write byte #7 of a gpr to the guest state. */
1133static __inline__ void
1134put_gpr_b7(UInt archreg, IRExpr *expr)
1135{
1136   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1137
1138   stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1139}
1140
1141/* Read byte #7 of a gpr register. */
1142static __inline__ IRExpr *
1143get_gpr_b7(UInt archreg)
1144{
1145   return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1146}
1147
1148/* Return the guest state offset of half word #0 of a gpr register. */
1149static __inline__ UInt
1150gpr_hw0_offset(UInt archreg)
1151{
1152   return gpr_offset(archreg) + 0;
1153}
1154
1155/* Write half word #0 of a gpr to the guest state. */
1156static __inline__ void
1157put_gpr_hw0(UInt archreg, IRExpr *expr)
1158{
1159   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1160
1161   stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1162}
1163
1164/* Read half word #0 of a gpr register. */
1165static __inline__ IRExpr *
1166get_gpr_hw0(UInt archreg)
1167{
1168   return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1169}
1170
1171/* Return the guest state offset of byte #4 of a gpr register. */
1172static __inline__ UInt
1173gpr_b4_offset(UInt archreg)
1174{
1175   return gpr_offset(archreg) + 4;
1176}
1177
1178/* Write byte #4 of a gpr to the guest state. */
1179static __inline__ void
1180put_gpr_b4(UInt archreg, IRExpr *expr)
1181{
1182   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1183
1184   stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1185}
1186
1187/* Read byte #4 of a gpr register. */
1188static __inline__ IRExpr *
1189get_gpr_b4(UInt archreg)
1190{
1191   return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1192}
1193
1194/* Return the guest state offset of byte #1 of a gpr register. */
1195static __inline__ UInt
1196gpr_b1_offset(UInt archreg)
1197{
1198   return gpr_offset(archreg) + 1;
1199}
1200
1201/* Write byte #1 of a gpr to the guest state. */
1202static __inline__ void
1203put_gpr_b1(UInt archreg, IRExpr *expr)
1204{
1205   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1206
1207   stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1208}
1209
1210/* Read byte #1 of a gpr register. */
1211static __inline__ IRExpr *
1212get_gpr_b1(UInt archreg)
1213{
1214   return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1215}
1216
1217/* Return the guest state offset of half word #2 of a gpr register. */
1218static __inline__ UInt
1219gpr_hw2_offset(UInt archreg)
1220{
1221   return gpr_offset(archreg) + 4;
1222}
1223
1224/* Write half word #2 of a gpr to the guest state. */
1225static __inline__ void
1226put_gpr_hw2(UInt archreg, IRExpr *expr)
1227{
1228   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1229
1230   stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1231}
1232
1233/* Read half word #2 of a gpr register. */
1234static __inline__ IRExpr *
1235get_gpr_hw2(UInt archreg)
1236{
1237   return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1238}
1239
1240/* Return the guest state offset of byte #5 of a gpr register. */
1241static __inline__ UInt
1242gpr_b5_offset(UInt archreg)
1243{
1244   return gpr_offset(archreg) + 5;
1245}
1246
1247/* Write byte #5 of a gpr to the guest state. */
1248static __inline__ void
1249put_gpr_b5(UInt archreg, IRExpr *expr)
1250{
1251   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1252
1253   stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1254}
1255
1256/* Read byte #5 of a gpr register. */
1257static __inline__ IRExpr *
1258get_gpr_b5(UInt archreg)
1259{
1260   return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1261}
1262
1263/* Return the guest state offset of byte #2 of a gpr register. */
1264static __inline__ UInt
1265gpr_b2_offset(UInt archreg)
1266{
1267   return gpr_offset(archreg) + 2;
1268}
1269
1270/* Write byte #2 of a gpr to the guest state. */
1271static __inline__ void
1272put_gpr_b2(UInt archreg, IRExpr *expr)
1273{
1274   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1275
1276   stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1277}
1278
1279/* Read byte #2 of a gpr register. */
1280static __inline__ IRExpr *
1281get_gpr_b2(UInt archreg)
1282{
1283   return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1284}
1285
1286/* Return the guest state offset of the counter register. */
1287static UInt
1288counter_offset(void)
1289{
1290   return S390X_GUEST_OFFSET(guest_counter);
1291}
1292
1293/* Return the guest state offset of double word #0 of the counter register. */
1294static __inline__ UInt
1295counter_dw0_offset(void)
1296{
1297   return counter_offset() + 0;
1298}
1299
1300/* Write double word #0 of the counter to the guest state. */
1301static __inline__ void
1302put_counter_dw0(IRExpr *expr)
1303{
1304   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1305
1306   stmt(IRStmt_Put(counter_dw0_offset(), expr));
1307}
1308
1309/* Read double word #0 of the counter register. */
1310static __inline__ IRExpr *
1311get_counter_dw0(void)
1312{
1313   return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1314}
1315
1316/* Return the guest state offset of word #0 of the counter register. */
1317static __inline__ UInt
1318counter_w0_offset(void)
1319{
1320   return counter_offset() + 0;
1321}
1322
1323/* Return the guest state offset of word #1 of the counter register. */
1324static __inline__ UInt
1325counter_w1_offset(void)
1326{
1327   return counter_offset() + 4;
1328}
1329
1330/* Write word #0 of the counter to the guest state. */
1331static __inline__ void
1332put_counter_w0(IRExpr *expr)
1333{
1334   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1335
1336   stmt(IRStmt_Put(counter_w0_offset(), expr));
1337}
1338
1339/* Read word #0 of the counter register. */
1340static __inline__ IRExpr *
1341get_counter_w0(void)
1342{
1343   return IRExpr_Get(counter_w0_offset(), Ity_I32);
1344}
1345
1346/* Write word #1 of the counter to the guest state. */
1347static __inline__ void
1348put_counter_w1(IRExpr *expr)
1349{
1350   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1351
1352   stmt(IRStmt_Put(counter_w1_offset(), expr));
1353}
1354
1355/* Read word #1 of the counter register. */
1356static __inline__ IRExpr *
1357get_counter_w1(void)
1358{
1359   return IRExpr_Get(counter_w1_offset(), Ity_I32);
1360}
1361
1362/* Return the guest state offset of the fpc register. */
1363static UInt
1364fpc_offset(void)
1365{
1366   return S390X_GUEST_OFFSET(guest_fpc);
1367}
1368
1369/* Return the guest state offset of word #0 of the fpc register. */
1370static __inline__ UInt
1371fpc_w0_offset(void)
1372{
1373   return fpc_offset() + 0;
1374}
1375
1376/* Write word #0 of the fpc to the guest state. */
1377static __inline__ void
1378put_fpc_w0(IRExpr *expr)
1379{
1380   vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1381
1382   stmt(IRStmt_Put(fpc_w0_offset(), expr));
1383}
1384
1385/* Read word #0 of the fpc register. */
1386static __inline__ IRExpr *
1387get_fpc_w0(void)
1388{
1389   return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1390}
1391
1392
1393/*------------------------------------------------------------*/
1394/*--- Build IR for formats                                 ---*/
1395/*------------------------------------------------------------*/
1396static void
1397s390_format_I(HChar *(*irgen)(UChar i),
1398              UChar i)
1399{
1400   HChar *mnm = irgen(i);
1401
1402   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1403      s390_disasm(ENC2(MNM, UINT), mnm, i);
1404}
1405
1406static void
1407s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1408               UChar r1, UShort i2)
1409{
1410   irgen(r1, i2);
1411}
1412
1413static void
1414s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1415                  UChar r1, UShort i2)
1416{
1417   HChar *mnm = irgen(r1, i2);
1418
1419   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1420      s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1421}
1422
1423static void
1424s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1425                  UChar r1, UShort i2)
1426{
1427   HChar *mnm = irgen(r1, i2);
1428
1429   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1430      s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1431}
1432
1433static void
1434s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1435                  UChar r1, UShort i2)
1436{
1437   HChar *mnm = irgen(r1, i2);
1438
1439   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1440      s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1441}
1442
1443static void
1444s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1445                    UChar r1, UChar r3, UShort i2)
1446{
1447   HChar *mnm = irgen(r1, r3, i2);
1448
1449   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1450      s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1451}
1452
1453static void
1454s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1455                     UChar r1, UChar r3, UShort i2)
1456{
1457   HChar *mnm = irgen(r1, r3, i2);
1458
1459   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1460      s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1461}
1462
1463static void
1464s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1465                      UChar i5),
1466                      UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1467{
1468   HChar *mnm = irgen(r1, r2, i3, i4, i5);
1469
1470   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1471      s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1472                  i5);
1473}
1474
1475static void
1476s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1477                     UChar r1, UChar r2, UShort i4, UChar m3)
1478{
1479   HChar *mnm = irgen(r1, r2, i4, m3);
1480
1481   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1482      s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1483                  r2, m3, (Int)(Short)i4);
1484}
1485
1486static void
1487s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1488                     UChar r1, UChar m3, UShort i4, UChar i2)
1489{
1490   HChar *mnm = irgen(r1, m3, i4, i2);
1491
1492   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1493      s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1494                  r1, i2, m3, (Int)(Short)i4);
1495}
1496
1497static void
1498s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1499                     UChar r1, UChar m3, UShort i4, UChar i2)
1500{
1501   HChar *mnm = irgen(r1, m3, i4, i2);
1502
1503   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1504      s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1505                  (Int)(Char)i2, m3, (Int)(Short)i4);
1506}
1507
1508static void
1509s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1510                UChar r1, UInt i2)
1511{
1512   irgen(r1, i2);
1513}
1514
1515static void
1516s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1517                   UChar r1, UInt i2)
1518{
1519   HChar *mnm = irgen(r1, i2);
1520
1521   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1522      s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1523}
1524
1525static void
1526s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1527                   UChar r1, UInt i2)
1528{
1529   HChar *mnm = irgen(r1, i2);
1530
1531   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1532      s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1533}
1534
1535static void
1536s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1537                   UChar r1, UInt i2)
1538{
1539   HChar *mnm = irgen(r1, i2);
1540
1541   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1542      s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1543}
1544
1545static void
1546s390_format_RIL_UP(HChar *(*irgen)(void),
1547                   UChar r1, UInt i2)
1548{
1549   HChar *mnm = irgen();
1550
1551   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1552      s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1553}
1554
1555static void
1556s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1557                      IRTemp op4addr),
1558                      UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1559{
1560   HChar *mnm;
1561   IRTemp op4addr = newTemp(Ity_I64);
1562
1563   assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1564          mkU64(0)));
1565
1566   mnm = irgen(r1, m3, i2, op4addr);
1567
1568   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1569      s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1570                  (Int)(Char)i2, m3, d4, 0, b4);
1571}
1572
1573static void
1574s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1575                      IRTemp op4addr),
1576                      UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1577{
1578   HChar *mnm;
1579   IRTemp op4addr = newTemp(Ity_I64);
1580
1581   assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1582          mkU64(0)));
1583
1584   mnm = irgen(r1, m3, i2, op4addr);
1585
1586   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1587      s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1588                  i2, m3, d4, 0, b4);
1589}
1590
1591static void
1592s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1593               UChar r1, UChar r2)
1594{
1595   irgen(r1, r2);
1596}
1597
1598static void
1599s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1600                  UChar r1, UChar r2)
1601{
1602   HChar *mnm = irgen(r1, r2);
1603
1604   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1605      s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1606}
1607
1608static void
1609s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1610                  UChar r1, UChar r2)
1611{
1612   HChar *mnm = irgen(r1, r2);
1613
1614   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1615      s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1616}
1617
1618static void
1619s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1620                UChar r1, UChar r2)
1621{
1622   irgen(r1, r2);
1623}
1624
1625static void
1626s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1627                   UChar r1, UChar r2)
1628{
1629   HChar *mnm = irgen(r1, r2);
1630
1631   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1632      s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1633}
1634
1635static void
1636s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1637                   UChar r1, UChar r2)
1638{
1639   HChar *mnm = irgen(r1, r2);
1640
1641   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1642      s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1643}
1644
1645static void
1646s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1647                   UChar r1, UChar r2)
1648{
1649   HChar *mnm = irgen(r1, r2);
1650
1651   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1652      s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1653}
1654
1655static void
1656s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1657                   UChar r1, UChar r2)
1658{
1659   HChar *mnm = irgen(r1, r2);
1660
1661   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1662      s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1663}
1664
1665static void
1666s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1667                   UChar r1)
1668{
1669   HChar *mnm = irgen(r1);
1670
1671   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1672      s390_disasm(ENC2(MNM, GPR), mnm, r1);
1673}
1674
1675static void
1676s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1677                   UChar r1)
1678{
1679   HChar *mnm = irgen(r1);
1680
1681   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1682      s390_disasm(ENC2(MNM, FPR), mnm, r1);
1683}
1684
1685static void
1686s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1687                       UChar m3, UChar r1, UChar r2)
1688{
1689   HChar *mnm = irgen(m3, r1, r2);
1690
1691   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1692      s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
1693}
1694
1695static void
1696s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1697                     UChar r1, UChar r3, UChar r2)
1698{
1699   HChar *mnm = irgen(r1, r3, r2);
1700
1701   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1702      s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1703}
1704
1705static void
1706s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1707                     UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1708{
1709   irgen(m3, r1, r2);
1710
1711   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1712      s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1713}
1714
1715static void
1716s390_format_RRF_U0RF(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1717                     UChar r3, UChar r1, UChar r2)
1718{
1719   HChar *mnm = irgen(r3, r1, r2);
1720
1721   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1722      s390_disasm(ENC4(MNM, GPR, UINT, FPR), mnm, r1, r3, r2);
1723}
1724
1725static void
1726s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1727                      UChar r3, UChar r1, UChar r2)
1728{
1729   HChar *mnm = irgen(r3, r1, r2);
1730
1731   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1732      s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1733}
1734
1735static void
1736s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1737                      UChar r3, UChar r1, UChar r2)
1738{
1739   HChar *mnm = irgen(r3, r1, r2);
1740
1741   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1742      s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1743}
1744
1745static void
1746s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1747                UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1748{
1749   HChar *mnm;
1750   IRTemp op4addr = newTemp(Ity_I64);
1751
1752   assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1753          mkU64(0)));
1754
1755   mnm = irgen(r1, r2, m3, op4addr);
1756
1757   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1758      s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1759                  r2, m3, d4, 0, b4);
1760}
1761
1762static void
1763s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1764                    UChar r1, UChar b2, UShort d2)
1765{
1766   HChar *mnm;
1767   IRTemp op2addr = newTemp(Ity_I64);
1768
1769   assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1770          mkU64(0)));
1771
1772   mnm = irgen(r1, op2addr);
1773
1774   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1775      s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1776}
1777
1778static void
1779s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1780                    UChar r1, UChar r3, UChar b2, UShort d2)
1781{
1782   HChar *mnm;
1783   IRTemp op2addr = newTemp(Ity_I64);
1784
1785   assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1786          mkU64(0)));
1787
1788   mnm = irgen(r1, r3, op2addr);
1789
1790   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1791      s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1792}
1793
1794static void
1795s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1796                    UChar r1, UChar r3, UChar b2, UShort d2)
1797{
1798   HChar *mnm;
1799   IRTemp op2addr = newTemp(Ity_I64);
1800
1801   assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1802          mkU64(0)));
1803
1804   mnm = irgen(r1, r3, op2addr);
1805
1806   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1807      s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
1808}
1809
1810static void
1811s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1812                    UChar r1, UChar r3, UChar b2, UShort d2)
1813{
1814   HChar *mnm;
1815   IRTemp op2addr = newTemp(Ity_I64);
1816
1817   assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1818          mkU64(0)));
1819
1820   mnm = irgen(r1, r3, op2addr);
1821
1822   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1823      s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
1824}
1825
1826static void
1827s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1828                    UChar r1, UChar r3, UShort i2)
1829{
1830   HChar *mnm = irgen(r1, r3, i2);
1831
1832   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1833      s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1834}
1835
1836static void
1837s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1838                     UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1839{
1840   HChar *mnm;
1841   IRTemp op2addr = newTemp(Ity_I64);
1842   IRTemp d2 = newTemp(Ity_I64);
1843
1844   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1845   assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1846          mkU64(0)));
1847
1848   mnm = irgen(r1, r3, op2addr);
1849
1850   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1851      s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1852}
1853
1854static void
1855s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1856                     UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1857{
1858   HChar *mnm;
1859   IRTemp op2addr = newTemp(Ity_I64);
1860   IRTemp d2 = newTemp(Ity_I64);
1861
1862   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1863   assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1864          mkU64(0)));
1865
1866   mnm = irgen(r1, r3, op2addr);
1867
1868   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1869      s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1870}
1871
1872static void
1873s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1874                     UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1875{
1876   HChar *mnm;
1877   IRTemp op2addr = newTemp(Ity_I64);
1878   IRTemp d2 = newTemp(Ity_I64);
1879
1880   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1881   assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1882          mkU64(0)));
1883
1884   mnm = irgen(r1, r3, op2addr);
1885
1886   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1887      s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1888}
1889
1890static void
1891s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1892                     UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
1893                     Int xmnm_kind)
1894{
1895   IRTemp op2addr = newTemp(Ity_I64);
1896   IRTemp d2 = newTemp(Ity_I64);
1897
1898   next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
1899
1900   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1901   assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1902          mkU64(0)));
1903
1904   irgen(r1, op2addr);
1905
1906   vassert(dis_res->whatNext == Dis_Continue);
1907
1908   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1909      s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
1910}
1911
1912static void
1913s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
1914               IRTemp op2addr),
1915               UChar r1, UChar x2, UChar b2, UShort d2)
1916{
1917   IRTemp op2addr = newTemp(Ity_I64);
1918
1919   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1920          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1921          mkU64(0)));
1922
1923   irgen(r1, x2, b2, d2, op2addr);
1924}
1925
1926static void
1927s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1928                    UChar r1, UChar x2, UChar b2, UShort d2)
1929{
1930   HChar *mnm;
1931   IRTemp op2addr = newTemp(Ity_I64);
1932
1933   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1934          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1935          mkU64(0)));
1936
1937   mnm = irgen(r1, op2addr);
1938
1939   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1940      s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
1941}
1942
1943static void
1944s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1945                    UChar r1, UChar x2, UChar b2, UShort d2)
1946{
1947   HChar *mnm;
1948   IRTemp op2addr = newTemp(Ity_I64);
1949
1950   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1951          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1952          mkU64(0)));
1953
1954   mnm = irgen(r1, op2addr);
1955
1956   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1957      s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1958}
1959
1960static void
1961s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1962                     UChar r1, UChar x2, UChar b2, UShort d2)
1963{
1964   HChar *mnm;
1965   IRTemp op2addr = newTemp(Ity_I64);
1966
1967   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1968          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1969          mkU64(0)));
1970
1971   mnm = irgen(r1, op2addr);
1972
1973   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1974      s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1975}
1976
1977static void
1978s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
1979                      UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
1980{
1981   HChar *mnm;
1982   IRTemp op2addr = newTemp(Ity_I64);
1983
1984   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1985          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1986          mkU64(0)));
1987
1988   mnm = irgen(r3, op2addr, r1);
1989
1990   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1991      s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
1992}
1993
1994static void
1995s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1996                     UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
1997{
1998   HChar *mnm;
1999   IRTemp op2addr = newTemp(Ity_I64);
2000   IRTemp d2 = newTemp(Ity_I64);
2001
2002   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2003   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2004          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2005          mkU64(0)));
2006
2007   mnm = irgen(r1, op2addr);
2008
2009   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2010      s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2011}
2012
2013static void
2014s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2015                     UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2016{
2017   HChar *mnm;
2018   IRTemp op2addr = newTemp(Ity_I64);
2019   IRTemp d2 = newTemp(Ity_I64);
2020
2021   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2022   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2023          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2024          mkU64(0)));
2025
2026   mnm = irgen(r1, op2addr);
2027
2028   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2029      s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2030}
2031
2032static void
2033s390_format_RXY_URRD(HChar *(*irgen)(void),
2034                     UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2035{
2036   HChar *mnm;
2037   IRTemp op2addr = newTemp(Ity_I64);
2038   IRTemp d2 = newTemp(Ity_I64);
2039
2040   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2041   assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2042          b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2043          mkU64(0)));
2044
2045   mnm = irgen();
2046
2047   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2048      s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2049}
2050
2051static void
2052s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
2053                 UChar b2, UShort d2)
2054{
2055   HChar *mnm;
2056   IRTemp op2addr = newTemp(Ity_I64);
2057
2058   assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2059          mkU64(0)));
2060
2061   mnm = irgen(op2addr);
2062
2063   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2064      s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2065}
2066
2067static void
2068s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2069                   UChar i2, UChar b1, UShort d1)
2070{
2071   HChar *mnm;
2072   IRTemp op1addr = newTemp(Ity_I64);
2073
2074   assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2075          mkU64(0)));
2076
2077   mnm = irgen(i2, op1addr);
2078
2079   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2080      s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2081}
2082
2083static void
2084s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2085                    UChar i2, UChar b1, UShort dl1, UChar dh1)
2086{
2087   HChar *mnm;
2088   IRTemp op1addr = newTemp(Ity_I64);
2089   IRTemp d1 = newTemp(Ity_I64);
2090
2091   assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2092   assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2093          mkU64(0)));
2094
2095   mnm = irgen(i2, op1addr);
2096
2097   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2098      s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2099}
2100
2101static void
2102s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2103                    UChar i2, UChar b1, UShort dl1, UChar dh1)
2104{
2105   HChar *mnm;
2106   IRTemp op1addr = newTemp(Ity_I64);
2107   IRTemp d1 = newTemp(Ity_I64);
2108
2109   assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2110   assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2111          mkU64(0)));
2112
2113   mnm = irgen(i2, op1addr);
2114
2115   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2116      s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2117}
2118
2119static void
2120s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2121                      UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2122{
2123   HChar *mnm;
2124   IRTemp op1addr = newTemp(Ity_I64);
2125   IRTemp op2addr = newTemp(Ity_I64);
2126
2127   assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2128          mkU64(0)));
2129   assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2130          mkU64(0)));
2131
2132   mnm = irgen(l, op1addr, op2addr);
2133
2134   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2135      s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2136}
2137
2138static void
2139s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2140                    UChar b1, UShort d1, UShort i2)
2141{
2142   HChar *mnm;
2143   IRTemp op1addr = newTemp(Ity_I64);
2144
2145   assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2146          mkU64(0)));
2147
2148   mnm = irgen(i2, op1addr);
2149
2150   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2151      s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2152}
2153
2154static void
2155s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2156                    UChar b1, UShort d1, UShort i2)
2157{
2158   HChar *mnm;
2159   IRTemp op1addr = newTemp(Ity_I64);
2160
2161   assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2162          mkU64(0)));
2163
2164   mnm = irgen(i2, op1addr);
2165
2166   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2167      s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2168}
2169
2170
2171
2172/*------------------------------------------------------------*/
2173/*--- Build IR for opcodes                                 ---*/
2174/*------------------------------------------------------------*/
2175
2176static HChar *
2177s390_irgen_AR(UChar r1, UChar r2)
2178{
2179   IRTemp op1 = newTemp(Ity_I32);
2180   IRTemp op2 = newTemp(Ity_I32);
2181   IRTemp result = newTemp(Ity_I32);
2182
2183   assign(op1, get_gpr_w1(r1));
2184   assign(op2, get_gpr_w1(r2));
2185   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2186   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2187   put_gpr_w1(r1, mkexpr(result));
2188
2189   return "ar";
2190}
2191
2192static HChar *
2193s390_irgen_AGR(UChar r1, UChar r2)
2194{
2195   IRTemp op1 = newTemp(Ity_I64);
2196   IRTemp op2 = newTemp(Ity_I64);
2197   IRTemp result = newTemp(Ity_I64);
2198
2199   assign(op1, get_gpr_dw0(r1));
2200   assign(op2, get_gpr_dw0(r2));
2201   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2202   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2203   put_gpr_dw0(r1, mkexpr(result));
2204
2205   return "agr";
2206}
2207
2208static HChar *
2209s390_irgen_AGFR(UChar r1, UChar r2)
2210{
2211   IRTemp op1 = newTemp(Ity_I64);
2212   IRTemp op2 = newTemp(Ity_I64);
2213   IRTemp result = newTemp(Ity_I64);
2214
2215   assign(op1, get_gpr_dw0(r1));
2216   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2217   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2218   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2219   put_gpr_dw0(r1, mkexpr(result));
2220
2221   return "agfr";
2222}
2223
2224static HChar *
2225s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2226{
2227   IRTemp op2 = newTemp(Ity_I32);
2228   IRTemp op3 = newTemp(Ity_I32);
2229   IRTemp result = newTemp(Ity_I32);
2230
2231   assign(op2, get_gpr_w1(r2));
2232   assign(op3, get_gpr_w1(r3));
2233   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2234   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2235   put_gpr_w1(r1, mkexpr(result));
2236
2237   return "ark";
2238}
2239
2240static HChar *
2241s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2242{
2243   IRTemp op2 = newTemp(Ity_I64);
2244   IRTemp op3 = newTemp(Ity_I64);
2245   IRTemp result = newTemp(Ity_I64);
2246
2247   assign(op2, get_gpr_dw0(r2));
2248   assign(op3, get_gpr_dw0(r3));
2249   assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2250   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2251   put_gpr_dw0(r1, mkexpr(result));
2252
2253   return "agrk";
2254}
2255
2256static HChar *
2257s390_irgen_A(UChar r1, IRTemp op2addr)
2258{
2259   IRTemp op1 = newTemp(Ity_I32);
2260   IRTemp op2 = newTemp(Ity_I32);
2261   IRTemp result = newTemp(Ity_I32);
2262
2263   assign(op1, get_gpr_w1(r1));
2264   assign(op2, load(Ity_I32, mkexpr(op2addr)));
2265   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2266   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2267   put_gpr_w1(r1, mkexpr(result));
2268
2269   return "a";
2270}
2271
2272static HChar *
2273s390_irgen_AY(UChar r1, IRTemp op2addr)
2274{
2275   IRTemp op1 = newTemp(Ity_I32);
2276   IRTemp op2 = newTemp(Ity_I32);
2277   IRTemp result = newTemp(Ity_I32);
2278
2279   assign(op1, get_gpr_w1(r1));
2280   assign(op2, load(Ity_I32, mkexpr(op2addr)));
2281   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2282   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2283   put_gpr_w1(r1, mkexpr(result));
2284
2285   return "ay";
2286}
2287
2288static HChar *
2289s390_irgen_AG(UChar r1, IRTemp op2addr)
2290{
2291   IRTemp op1 = newTemp(Ity_I64);
2292   IRTemp op2 = newTemp(Ity_I64);
2293   IRTemp result = newTemp(Ity_I64);
2294
2295   assign(op1, get_gpr_dw0(r1));
2296   assign(op2, load(Ity_I64, mkexpr(op2addr)));
2297   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2298   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2299   put_gpr_dw0(r1, mkexpr(result));
2300
2301   return "ag";
2302}
2303
2304static HChar *
2305s390_irgen_AGF(UChar r1, IRTemp op2addr)
2306{
2307   IRTemp op1 = newTemp(Ity_I64);
2308   IRTemp op2 = newTemp(Ity_I64);
2309   IRTemp result = newTemp(Ity_I64);
2310
2311   assign(op1, get_gpr_dw0(r1));
2312   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2313   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2314   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2315   put_gpr_dw0(r1, mkexpr(result));
2316
2317   return "agf";
2318}
2319
2320static HChar *
2321s390_irgen_AFI(UChar r1, UInt i2)
2322{
2323   IRTemp op1 = newTemp(Ity_I32);
2324   Int op2;
2325   IRTemp result = newTemp(Ity_I32);
2326
2327   assign(op1, get_gpr_w1(r1));
2328   op2 = (Int)i2;
2329   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2330   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2331                       mkU32((UInt)op2)));
2332   put_gpr_w1(r1, mkexpr(result));
2333
2334   return "afi";
2335}
2336
2337static HChar *
2338s390_irgen_AGFI(UChar r1, UInt i2)
2339{
2340   IRTemp op1 = newTemp(Ity_I64);
2341   Long op2;
2342   IRTemp result = newTemp(Ity_I64);
2343
2344   assign(op1, get_gpr_dw0(r1));
2345   op2 = (Long)(Int)i2;
2346   assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2347   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2348                       mkU64((ULong)op2)));
2349   put_gpr_dw0(r1, mkexpr(result));
2350
2351   return "agfi";
2352}
2353
2354static HChar *
2355s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2356{
2357   Int op2;
2358   IRTemp op3 = newTemp(Ity_I32);
2359   IRTemp result = newTemp(Ity_I32);
2360
2361   op2 = (Int)(Short)i2;
2362   assign(op3, get_gpr_w1(r3));
2363   assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2364   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2365                       op2)), op3);
2366   put_gpr_w1(r1, mkexpr(result));
2367
2368   return "ahik";
2369}
2370
2371static HChar *
2372s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2373{
2374   Long op2;
2375   IRTemp op3 = newTemp(Ity_I64);
2376   IRTemp result = newTemp(Ity_I64);
2377
2378   op2 = (Long)(Short)i2;
2379   assign(op3, get_gpr_dw0(r3));
2380   assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2381   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2382                       op2)), op3);
2383   put_gpr_dw0(r1, mkexpr(result));
2384
2385   return "aghik";
2386}
2387
2388static HChar *
2389s390_irgen_ASI(UChar i2, IRTemp op1addr)
2390{
2391   IRTemp op1 = newTemp(Ity_I32);
2392   Int op2;
2393   IRTemp result = newTemp(Ity_I32);
2394
2395   assign(op1, load(Ity_I32, mkexpr(op1addr)));
2396   op2 = (Int)(Char)i2;
2397   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2398   store(mkexpr(op1addr), mkexpr(result));
2399   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2400                       mkU32((UInt)op2)));
2401
2402   return "asi";
2403}
2404
2405static HChar *
2406s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2407{
2408   IRTemp op1 = newTemp(Ity_I64);
2409   Long op2;
2410   IRTemp result = newTemp(Ity_I64);
2411
2412   assign(op1, load(Ity_I64, mkexpr(op1addr)));
2413   op2 = (Long)(Char)i2;
2414   assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2415   store(mkexpr(op1addr), mkexpr(result));
2416   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2417                       mkU64((ULong)op2)));
2418
2419   return "agsi";
2420}
2421
2422static HChar *
2423s390_irgen_AH(UChar r1, IRTemp op2addr)
2424{
2425   IRTemp op1 = newTemp(Ity_I32);
2426   IRTemp op2 = newTemp(Ity_I32);
2427   IRTemp result = newTemp(Ity_I32);
2428
2429   assign(op1, get_gpr_w1(r1));
2430   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2431   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2432   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2433   put_gpr_w1(r1, mkexpr(result));
2434
2435   return "ah";
2436}
2437
2438static HChar *
2439s390_irgen_AHY(UChar r1, IRTemp op2addr)
2440{
2441   IRTemp op1 = newTemp(Ity_I32);
2442   IRTemp op2 = newTemp(Ity_I32);
2443   IRTemp result = newTemp(Ity_I32);
2444
2445   assign(op1, get_gpr_w1(r1));
2446   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2447   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2448   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2449   put_gpr_w1(r1, mkexpr(result));
2450
2451   return "ahy";
2452}
2453
2454static HChar *
2455s390_irgen_AHI(UChar r1, UShort i2)
2456{
2457   IRTemp op1 = newTemp(Ity_I32);
2458   Int op2;
2459   IRTemp result = newTemp(Ity_I32);
2460
2461   assign(op1, get_gpr_w1(r1));
2462   op2 = (Int)(Short)i2;
2463   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2464   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2465                       mkU32((UInt)op2)));
2466   put_gpr_w1(r1, mkexpr(result));
2467
2468   return "ahi";
2469}
2470
2471static HChar *
2472s390_irgen_AGHI(UChar r1, UShort i2)
2473{
2474   IRTemp op1 = newTemp(Ity_I64);
2475   Long op2;
2476   IRTemp result = newTemp(Ity_I64);
2477
2478   assign(op1, get_gpr_dw0(r1));
2479   op2 = (Long)(Short)i2;
2480   assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2481   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2482                       mkU64((ULong)op2)));
2483   put_gpr_dw0(r1, mkexpr(result));
2484
2485   return "aghi";
2486}
2487
2488static HChar *
2489s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2490{
2491   IRTemp op2 = newTemp(Ity_I32);
2492   IRTemp op3 = newTemp(Ity_I32);
2493   IRTemp result = newTemp(Ity_I32);
2494
2495   assign(op2, get_gpr_w0(r2));
2496   assign(op3, get_gpr_w0(r3));
2497   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2498   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2499   put_gpr_w0(r1, mkexpr(result));
2500
2501   return "ahhhr";
2502}
2503
2504static HChar *
2505s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2506{
2507   IRTemp op2 = newTemp(Ity_I32);
2508   IRTemp op3 = newTemp(Ity_I32);
2509   IRTemp result = newTemp(Ity_I32);
2510
2511   assign(op2, get_gpr_w0(r2));
2512   assign(op3, get_gpr_w1(r3));
2513   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2514   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2515   put_gpr_w0(r1, mkexpr(result));
2516
2517   return "ahhlr";
2518}
2519
2520static HChar *
2521s390_irgen_AIH(UChar r1, UInt i2)
2522{
2523   IRTemp op1 = newTemp(Ity_I32);
2524   Int op2;
2525   IRTemp result = newTemp(Ity_I32);
2526
2527   assign(op1, get_gpr_w0(r1));
2528   op2 = (Int)i2;
2529   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2530   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2531                       mkU32((UInt)op2)));
2532   put_gpr_w0(r1, mkexpr(result));
2533
2534   return "aih";
2535}
2536
2537static HChar *
2538s390_irgen_ALR(UChar r1, UChar r2)
2539{
2540   IRTemp op1 = newTemp(Ity_I32);
2541   IRTemp op2 = newTemp(Ity_I32);
2542   IRTemp result = newTemp(Ity_I32);
2543
2544   assign(op1, get_gpr_w1(r1));
2545   assign(op2, get_gpr_w1(r2));
2546   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2547   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2548   put_gpr_w1(r1, mkexpr(result));
2549
2550   return "alr";
2551}
2552
2553static HChar *
2554s390_irgen_ALGR(UChar r1, UChar r2)
2555{
2556   IRTemp op1 = newTemp(Ity_I64);
2557   IRTemp op2 = newTemp(Ity_I64);
2558   IRTemp result = newTemp(Ity_I64);
2559
2560   assign(op1, get_gpr_dw0(r1));
2561   assign(op2, get_gpr_dw0(r2));
2562   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2563   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2564   put_gpr_dw0(r1, mkexpr(result));
2565
2566   return "algr";
2567}
2568
2569static HChar *
2570s390_irgen_ALGFR(UChar r1, UChar r2)
2571{
2572   IRTemp op1 = newTemp(Ity_I64);
2573   IRTemp op2 = newTemp(Ity_I64);
2574   IRTemp result = newTemp(Ity_I64);
2575
2576   assign(op1, get_gpr_dw0(r1));
2577   assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2578   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2579   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2580   put_gpr_dw0(r1, mkexpr(result));
2581
2582   return "algfr";
2583}
2584
2585static HChar *
2586s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2587{
2588   IRTemp op2 = newTemp(Ity_I32);
2589   IRTemp op3 = newTemp(Ity_I32);
2590   IRTemp result = newTemp(Ity_I32);
2591
2592   assign(op2, get_gpr_w1(r2));
2593   assign(op3, get_gpr_w1(r3));
2594   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2595   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2596   put_gpr_w1(r1, mkexpr(result));
2597
2598   return "alrk";
2599}
2600
2601static HChar *
2602s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2603{
2604   IRTemp op2 = newTemp(Ity_I64);
2605   IRTemp op3 = newTemp(Ity_I64);
2606   IRTemp result = newTemp(Ity_I64);
2607
2608   assign(op2, get_gpr_dw0(r2));
2609   assign(op3, get_gpr_dw0(r3));
2610   assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2611   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2612   put_gpr_dw0(r1, mkexpr(result));
2613
2614   return "algrk";
2615}
2616
2617static HChar *
2618s390_irgen_AL(UChar r1, IRTemp op2addr)
2619{
2620   IRTemp op1 = newTemp(Ity_I32);
2621   IRTemp op2 = newTemp(Ity_I32);
2622   IRTemp result = newTemp(Ity_I32);
2623
2624   assign(op1, get_gpr_w1(r1));
2625   assign(op2, load(Ity_I32, mkexpr(op2addr)));
2626   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2627   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2628   put_gpr_w1(r1, mkexpr(result));
2629
2630   return "al";
2631}
2632
2633static HChar *
2634s390_irgen_ALY(UChar r1, IRTemp op2addr)
2635{
2636   IRTemp op1 = newTemp(Ity_I32);
2637   IRTemp op2 = newTemp(Ity_I32);
2638   IRTemp result = newTemp(Ity_I32);
2639
2640   assign(op1, get_gpr_w1(r1));
2641   assign(op2, load(Ity_I32, mkexpr(op2addr)));
2642   assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2643   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2644   put_gpr_w1(r1, mkexpr(result));
2645
2646   return "aly";
2647}
2648
2649static HChar *
2650s390_irgen_ALG(UChar r1, IRTemp op2addr)
2651{
2652   IRTemp op1 = newTemp(Ity_I64);
2653   IRTemp op2 = newTemp(Ity_I64);
2654   IRTemp result = newTemp(Ity_I64);
2655
2656   assign(op1, get_gpr_dw0(r1));
2657   assign(op2, load(Ity_I64, mkexpr(op2addr)));
2658   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2659   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2660   put_gpr_dw0(r1, mkexpr(result));
2661
2662   return "alg";
2663}
2664
2665static HChar *
2666s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2667{
2668   IRTemp op1 = newTemp(Ity_I64);
2669   IRTemp op2 = newTemp(Ity_I64);
2670   IRTemp result = newTemp(Ity_I64);
2671
2672   assign(op1, get_gpr_dw0(r1));
2673   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2674   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2675   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2676   put_gpr_dw0(r1, mkexpr(result));
2677
2678   return "algf";
2679}
2680
2681static HChar *
2682s390_irgen_ALFI(UChar r1, UInt i2)
2683{
2684   IRTemp op1 = newTemp(Ity_I32);
2685   UInt op2;
2686   IRTemp result = newTemp(Ity_I32);
2687
2688   assign(op1, get_gpr_w1(r1));
2689   op2 = i2;
2690   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2691   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2692                       mkU32(op2)));
2693   put_gpr_w1(r1, mkexpr(result));
2694
2695   return "alfi";
2696}
2697
2698static HChar *
2699s390_irgen_ALGFI(UChar r1, UInt i2)
2700{
2701   IRTemp op1 = newTemp(Ity_I64);
2702   ULong op2;
2703   IRTemp result = newTemp(Ity_I64);
2704
2705   assign(op1, get_gpr_dw0(r1));
2706   op2 = (ULong)i2;
2707   assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2708   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2709                       mkU64(op2)));
2710   put_gpr_dw0(r1, mkexpr(result));
2711
2712   return "algfi";
2713}
2714
2715static HChar *
2716s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2717{
2718   IRTemp op2 = newTemp(Ity_I32);
2719   IRTemp op3 = newTemp(Ity_I32);
2720   IRTemp result = newTemp(Ity_I32);
2721
2722   assign(op2, get_gpr_w0(r2));
2723   assign(op3, get_gpr_w0(r3));
2724   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2725   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2726   put_gpr_w0(r1, mkexpr(result));
2727
2728   return "alhhhr";
2729}
2730
2731static HChar *
2732s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2733{
2734   IRTemp op2 = newTemp(Ity_I32);
2735   IRTemp op3 = newTemp(Ity_I32);
2736   IRTemp result = newTemp(Ity_I32);
2737
2738   assign(op2, get_gpr_w0(r2));
2739   assign(op3, get_gpr_w1(r3));
2740   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2741   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2742   put_gpr_w0(r1, mkexpr(result));
2743
2744   return "alhhlr";
2745}
2746
2747static HChar *
2748s390_irgen_ALCR(UChar r1, UChar r2)
2749{
2750   IRTemp op1 = newTemp(Ity_I32);
2751   IRTemp op2 = newTemp(Ity_I32);
2752   IRTemp result = newTemp(Ity_I32);
2753   IRTemp carry_in = newTemp(Ity_I32);
2754
2755   assign(op1, get_gpr_w1(r1));
2756   assign(op2, get_gpr_w1(r2));
2757   assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2758   assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2759          mkexpr(carry_in)));
2760   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2761   put_gpr_w1(r1, mkexpr(result));
2762
2763   return "alcr";
2764}
2765
2766static HChar *
2767s390_irgen_ALCGR(UChar r1, UChar r2)
2768{
2769   IRTemp op1 = newTemp(Ity_I64);
2770   IRTemp op2 = newTemp(Ity_I64);
2771   IRTemp result = newTemp(Ity_I64);
2772   IRTemp carry_in = newTemp(Ity_I64);
2773
2774   assign(op1, get_gpr_dw0(r1));
2775   assign(op2, get_gpr_dw0(r2));
2776   assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2777          mkU8(1))));
2778   assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2779          mkexpr(carry_in)));
2780   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2781   put_gpr_dw0(r1, mkexpr(result));
2782
2783   return "alcgr";
2784}
2785
2786static HChar *
2787s390_irgen_ALC(UChar r1, IRTemp op2addr)
2788{
2789   IRTemp op1 = newTemp(Ity_I32);
2790   IRTemp op2 = newTemp(Ity_I32);
2791   IRTemp result = newTemp(Ity_I32);
2792   IRTemp carry_in = newTemp(Ity_I32);
2793
2794   assign(op1, get_gpr_w1(r1));
2795   assign(op2, load(Ity_I32, mkexpr(op2addr)));
2796   assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2797   assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2798          mkexpr(carry_in)));
2799   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2800   put_gpr_w1(r1, mkexpr(result));
2801
2802   return "alc";
2803}
2804
2805static HChar *
2806s390_irgen_ALCG(UChar r1, IRTemp op2addr)
2807{
2808   IRTemp op1 = newTemp(Ity_I64);
2809   IRTemp op2 = newTemp(Ity_I64);
2810   IRTemp result = newTemp(Ity_I64);
2811   IRTemp carry_in = newTemp(Ity_I64);
2812
2813   assign(op1, get_gpr_dw0(r1));
2814   assign(op2, load(Ity_I64, mkexpr(op2addr)));
2815   assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2816          mkU8(1))));
2817   assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2818          mkexpr(carry_in)));
2819   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2820   put_gpr_dw0(r1, mkexpr(result));
2821
2822   return "alcg";
2823}
2824
2825static HChar *
2826s390_irgen_ALSI(UChar i2, IRTemp op1addr)
2827{
2828   IRTemp op1 = newTemp(Ity_I32);
2829   UInt op2;
2830   IRTemp result = newTemp(Ity_I32);
2831
2832   assign(op1, load(Ity_I32, mkexpr(op1addr)));
2833   op2 = (UInt)(Int)(Char)i2;
2834   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2835   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2836                       mkU32(op2)));
2837   store(mkexpr(op1addr), mkexpr(result));
2838
2839   return "alsi";
2840}
2841
2842static HChar *
2843s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
2844{
2845   IRTemp op1 = newTemp(Ity_I64);
2846   ULong op2;
2847   IRTemp result = newTemp(Ity_I64);
2848
2849   assign(op1, load(Ity_I64, mkexpr(op1addr)));
2850   op2 = (ULong)(Long)(Char)i2;
2851   assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2852   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2853                       mkU64(op2)));
2854   store(mkexpr(op1addr), mkexpr(result));
2855
2856   return "algsi";
2857}
2858
2859static HChar *
2860s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
2861{
2862   UInt op2;
2863   IRTemp op3 = newTemp(Ity_I32);
2864   IRTemp result = newTemp(Ity_I32);
2865
2866   op2 = (UInt)(Int)(Short)i2;
2867   assign(op3, get_gpr_w1(r3));
2868   assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
2869   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
2870                       op3);
2871   put_gpr_w1(r1, mkexpr(result));
2872
2873   return "alhsik";
2874}
2875
2876static HChar *
2877s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
2878{
2879   ULong op2;
2880   IRTemp op3 = newTemp(Ity_I64);
2881   IRTemp result = newTemp(Ity_I64);
2882
2883   op2 = (ULong)(Long)(Short)i2;
2884   assign(op3, get_gpr_dw0(r3));
2885   assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
2886   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
2887                       op3);
2888   put_gpr_dw0(r1, mkexpr(result));
2889
2890   return "alghsik";
2891}
2892
2893static HChar *
2894s390_irgen_ALSIH(UChar r1, UInt i2)
2895{
2896   IRTemp op1 = newTemp(Ity_I32);
2897   UInt op2;
2898   IRTemp result = newTemp(Ity_I32);
2899
2900   assign(op1, get_gpr_w0(r1));
2901   op2 = i2;
2902   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2903   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2904                       mkU32(op2)));
2905   put_gpr_w0(r1, mkexpr(result));
2906
2907   return "alsih";
2908}
2909
2910static HChar *
2911s390_irgen_ALSIHN(UChar r1, UInt i2)
2912{
2913   IRTemp op1 = newTemp(Ity_I32);
2914   UInt op2;
2915   IRTemp result = newTemp(Ity_I32);
2916
2917   assign(op1, get_gpr_w0(r1));
2918   op2 = i2;
2919   assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2920   put_gpr_w0(r1, mkexpr(result));
2921
2922   return "alsihn";
2923}
2924
2925static HChar *
2926s390_irgen_NR(UChar r1, UChar r2)
2927{
2928   IRTemp op1 = newTemp(Ity_I32);
2929   IRTemp op2 = newTemp(Ity_I32);
2930   IRTemp result = newTemp(Ity_I32);
2931
2932   assign(op1, get_gpr_w1(r1));
2933   assign(op2, get_gpr_w1(r2));
2934   assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2935   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2936   put_gpr_w1(r1, mkexpr(result));
2937
2938   return "nr";
2939}
2940
2941static HChar *
2942s390_irgen_NGR(UChar r1, UChar r2)
2943{
2944   IRTemp op1 = newTemp(Ity_I64);
2945   IRTemp op2 = newTemp(Ity_I64);
2946   IRTemp result = newTemp(Ity_I64);
2947
2948   assign(op1, get_gpr_dw0(r1));
2949   assign(op2, get_gpr_dw0(r2));
2950   assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
2951   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2952   put_gpr_dw0(r1, mkexpr(result));
2953
2954   return "ngr";
2955}
2956
2957static HChar *
2958s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
2959{
2960   IRTemp op2 = newTemp(Ity_I32);
2961   IRTemp op3 = newTemp(Ity_I32);
2962   IRTemp result = newTemp(Ity_I32);
2963
2964   assign(op2, get_gpr_w1(r2));
2965   assign(op3, get_gpr_w1(r3));
2966   assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
2967   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2968   put_gpr_w1(r1, mkexpr(result));
2969
2970   return "nrk";
2971}
2972
2973static HChar *
2974s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
2975{
2976   IRTemp op2 = newTemp(Ity_I64);
2977   IRTemp op3 = newTemp(Ity_I64);
2978   IRTemp result = newTemp(Ity_I64);
2979
2980   assign(op2, get_gpr_dw0(r2));
2981   assign(op3, get_gpr_dw0(r3));
2982   assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
2983   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2984   put_gpr_dw0(r1, mkexpr(result));
2985
2986   return "ngrk";
2987}
2988
2989static HChar *
2990s390_irgen_N(UChar r1, IRTemp op2addr)
2991{
2992   IRTemp op1 = newTemp(Ity_I32);
2993   IRTemp op2 = newTemp(Ity_I32);
2994   IRTemp result = newTemp(Ity_I32);
2995
2996   assign(op1, get_gpr_w1(r1));
2997   assign(op2, load(Ity_I32, mkexpr(op2addr)));
2998   assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2999   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3000   put_gpr_w1(r1, mkexpr(result));
3001
3002   return "n";
3003}
3004
3005static HChar *
3006s390_irgen_NY(UChar r1, IRTemp op2addr)
3007{
3008   IRTemp op1 = newTemp(Ity_I32);
3009   IRTemp op2 = newTemp(Ity_I32);
3010   IRTemp result = newTemp(Ity_I32);
3011
3012   assign(op1, get_gpr_w1(r1));
3013   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3014   assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3015   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3016   put_gpr_w1(r1, mkexpr(result));
3017
3018   return "ny";
3019}
3020
3021static HChar *
3022s390_irgen_NG(UChar r1, IRTemp op2addr)
3023{
3024   IRTemp op1 = newTemp(Ity_I64);
3025   IRTemp op2 = newTemp(Ity_I64);
3026   IRTemp result = newTemp(Ity_I64);
3027
3028   assign(op1, get_gpr_dw0(r1));
3029   assign(op2, load(Ity_I64, mkexpr(op2addr)));
3030   assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3031   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3032   put_gpr_dw0(r1, mkexpr(result));
3033
3034   return "ng";
3035}
3036
3037static HChar *
3038s390_irgen_NI(UChar i2, IRTemp op1addr)
3039{
3040   IRTemp op1 = newTemp(Ity_I8);
3041   UChar op2;
3042   IRTemp result = newTemp(Ity_I8);
3043
3044   assign(op1, load(Ity_I8, mkexpr(op1addr)));
3045   op2 = i2;
3046   assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3047   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3048   store(mkexpr(op1addr), mkexpr(result));
3049
3050   return "ni";
3051}
3052
3053static HChar *
3054s390_irgen_NIY(UChar i2, IRTemp op1addr)
3055{
3056   IRTemp op1 = newTemp(Ity_I8);
3057   UChar op2;
3058   IRTemp result = newTemp(Ity_I8);
3059
3060   assign(op1, load(Ity_I8, mkexpr(op1addr)));
3061   op2 = i2;
3062   assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3063   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3064   store(mkexpr(op1addr), mkexpr(result));
3065
3066   return "niy";
3067}
3068
3069static HChar *
3070s390_irgen_NIHF(UChar r1, UInt i2)
3071{
3072   IRTemp op1 = newTemp(Ity_I32);
3073   UInt op2;
3074   IRTemp result = newTemp(Ity_I32);
3075
3076   assign(op1, get_gpr_w0(r1));
3077   op2 = i2;
3078   assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3079   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3080   put_gpr_w0(r1, mkexpr(result));
3081
3082   return "nihf";
3083}
3084
3085static HChar *
3086s390_irgen_NIHH(UChar r1, UShort i2)
3087{
3088   IRTemp op1 = newTemp(Ity_I16);
3089   UShort op2;
3090   IRTemp result = newTemp(Ity_I16);
3091
3092   assign(op1, get_gpr_hw0(r1));
3093   op2 = i2;
3094   assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3095   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3096   put_gpr_hw0(r1, mkexpr(result));
3097
3098   return "nihh";
3099}
3100
3101static HChar *
3102s390_irgen_NIHL(UChar r1, UShort i2)
3103{
3104   IRTemp op1 = newTemp(Ity_I16);
3105   UShort op2;
3106   IRTemp result = newTemp(Ity_I16);
3107
3108   assign(op1, get_gpr_hw1(r1));
3109   op2 = i2;
3110   assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3111   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3112   put_gpr_hw1(r1, mkexpr(result));
3113
3114   return "nihl";
3115}
3116
3117static HChar *
3118s390_irgen_NILF(UChar r1, UInt i2)
3119{
3120   IRTemp op1 = newTemp(Ity_I32);
3121   UInt op2;
3122   IRTemp result = newTemp(Ity_I32);
3123
3124   assign(op1, get_gpr_w1(r1));
3125   op2 = i2;
3126   assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3127   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3128   put_gpr_w1(r1, mkexpr(result));
3129
3130   return "nilf";
3131}
3132
3133static HChar *
3134s390_irgen_NILH(UChar r1, UShort i2)
3135{
3136   IRTemp op1 = newTemp(Ity_I16);
3137   UShort op2;
3138   IRTemp result = newTemp(Ity_I16);
3139
3140   assign(op1, get_gpr_hw2(r1));
3141   op2 = i2;
3142   assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3143   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3144   put_gpr_hw2(r1, mkexpr(result));
3145
3146   return "nilh";
3147}
3148
3149static HChar *
3150s390_irgen_NILL(UChar r1, UShort i2)
3151{
3152   IRTemp op1 = newTemp(Ity_I16);
3153   UShort op2;
3154   IRTemp result = newTemp(Ity_I16);
3155
3156   assign(op1, get_gpr_hw3(r1));
3157   op2 = i2;
3158   assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3159   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3160   put_gpr_hw3(r1, mkexpr(result));
3161
3162   return "nill";
3163}
3164
3165static HChar *
3166s390_irgen_BASR(UChar r1, UChar r2)
3167{
3168   IRTemp target = newTemp(Ity_I64);
3169
3170   if (r2 == 0) {
3171      put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3172   } else {
3173      if (r1 != r2) {
3174         put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3175         call_function(get_gpr_dw0(r2));
3176      } else {
3177         assign(target, get_gpr_dw0(r2));
3178         put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3179         call_function(mkexpr(target));
3180      }
3181   }
3182
3183   return "basr";
3184}
3185
3186static HChar *
3187s390_irgen_BAS(UChar r1, IRTemp op2addr)
3188{
3189   IRTemp target = newTemp(Ity_I64);
3190
3191   put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3192   assign(target, mkexpr(op2addr));
3193   call_function(mkexpr(target));
3194
3195   return "bas";
3196}
3197
3198static HChar *
3199s390_irgen_BCR(UChar r1, UChar r2)
3200{
3201   IRTemp cond = newTemp(Ity_I32);
3202
3203   if (r2 == 0 && (r1 >= 14)) {    /* serialization */
3204      stmt(IRStmt_MBE(Imbe_Fence));
3205   }
3206
3207   if ((r2 == 0) || (r1 == 0)) {
3208   } else {
3209      if (r1 == 15) {
3210         return_from_function(get_gpr_dw0(r2));
3211      } else {
3212         assign(cond, s390_call_calculate_cond(r1));
3213         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3214                                    get_gpr_dw0(r2));
3215      }
3216   }
3217   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3218      s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3219
3220   return "bcr";
3221}
3222
3223static HChar *
3224s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3225{
3226   IRTemp cond = newTemp(Ity_I32);
3227
3228   if (r1 == 0) {
3229   } else {
3230      if (r1 == 15) {
3231         always_goto(mkexpr(op2addr));
3232      } else {
3233         assign(cond, s390_call_calculate_cond(r1));
3234         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3235                                    mkexpr(op2addr));
3236      }
3237   }
3238   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3239      s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3240
3241   return "bc";
3242}
3243
3244static HChar *
3245s390_irgen_BCTR(UChar r1, UChar r2)
3246{
3247   put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3248   if (r2 != 0) {
3249      if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3250                                 get_gpr_dw0(r2));
3251   }
3252
3253   return "bctr";
3254}
3255
3256static HChar *
3257s390_irgen_BCTGR(UChar r1, UChar r2)
3258{
3259   put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3260   if (r2 != 0) {
3261      if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3262                                 get_gpr_dw0(r2));
3263   }
3264
3265   return "bctgr";
3266}
3267
3268static HChar *
3269s390_irgen_BCT(UChar r1, IRTemp op2addr)
3270{
3271   put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3272   if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3273                              mkexpr(op2addr));
3274
3275   return "bct";
3276}
3277
3278static HChar *
3279s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3280{
3281   put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3282   if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3283                              mkexpr(op2addr));
3284
3285   return "bctg";
3286}
3287
3288static HChar *
3289s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3290{
3291   IRTemp value = newTemp(Ity_I32);
3292
3293   assign(value, get_gpr_w1(r3 | 1));
3294   put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3295   if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3296                                    get_gpr_w1(r1)), mkexpr(op2addr));
3297
3298   return "bxh";
3299}
3300
3301static HChar *
3302s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3303{
3304   IRTemp value = newTemp(Ity_I64);
3305
3306   assign(value, get_gpr_dw0(r3 | 1));
3307   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3308   if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3309                                    get_gpr_dw0(r1)), mkexpr(op2addr));
3310
3311   return "bxhg";
3312}
3313
3314static HChar *
3315s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3316{
3317   IRTemp value = newTemp(Ity_I32);
3318
3319   assign(value, get_gpr_w1(r3 | 1));
3320   put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3321   if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3322                                    mkexpr(value)), mkexpr(op2addr));
3323
3324   return "bxle";
3325}
3326
3327static HChar *
3328s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3329{
3330   IRTemp value = newTemp(Ity_I64);
3331
3332   assign(value, get_gpr_dw0(r3 | 1));
3333   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3334   if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3335                                    mkexpr(value)), mkexpr(op2addr));
3336
3337   return "bxleg";
3338}
3339
3340static HChar *
3341s390_irgen_BRAS(UChar r1, UShort i2)
3342{
3343   put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3344   call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3345
3346   return "bras";
3347}
3348
3349static HChar *
3350s390_irgen_BRASL(UChar r1, UInt i2)
3351{
3352   put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
3353   call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3354
3355   return "brasl";
3356}
3357
3358static HChar *
3359s390_irgen_BRC(UChar r1, UShort i2)
3360{
3361   IRTemp cond = newTemp(Ity_I32);
3362
3363   if (r1 == 0) {
3364   } else {
3365      if (r1 == 15) {
3366         always_goto_and_chase(
3367               guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3368      } else {
3369         assign(cond, s390_call_calculate_cond(r1));
3370         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3371                           guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3372
3373      }
3374   }
3375   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3376      s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3377
3378   return "brc";
3379}
3380
3381static HChar *
3382s390_irgen_BRCL(UChar r1, UInt i2)
3383{
3384   IRTemp cond = newTemp(Ity_I32);
3385
3386   if (r1 == 0) {
3387   } else {
3388      if (r1 == 15) {
3389         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3390      } else {
3391         assign(cond, s390_call_calculate_cond(r1));
3392         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3393                           guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3394      }
3395   }
3396   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3397      s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3398
3399   return "brcl";
3400}
3401
3402static HChar *
3403s390_irgen_BRCT(UChar r1, UShort i2)
3404{
3405   put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3406   if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3407                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3408
3409   return "brct";
3410}
3411
3412static HChar *
3413s390_irgen_BRCTG(UChar r1, UShort i2)
3414{
3415   put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3416   if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3417                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3418
3419   return "brctg";
3420}
3421
3422static HChar *
3423s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3424{
3425   IRTemp value = newTemp(Ity_I32);
3426
3427   assign(value, get_gpr_w1(r3 | 1));
3428   put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3429   if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3430                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3431
3432   return "brxh";
3433}
3434
3435static HChar *
3436s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3437{
3438   IRTemp value = newTemp(Ity_I64);
3439
3440   assign(value, get_gpr_dw0(r3 | 1));
3441   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3442   if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3443                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3444
3445   return "brxhg";
3446}
3447
3448static HChar *
3449s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3450{
3451   IRTemp value = newTemp(Ity_I32);
3452
3453   assign(value, get_gpr_w1(r3 | 1));
3454   put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3455   if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3456                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3457
3458   return "brxle";
3459}
3460
3461static HChar *
3462s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3463{
3464   IRTemp value = newTemp(Ity_I64);
3465
3466   assign(value, get_gpr_dw0(r3 | 1));
3467   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3468   if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3469                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3470
3471   return "brxlg";
3472}
3473
3474static HChar *
3475s390_irgen_CR(UChar r1, UChar r2)
3476{
3477   IRTemp op1 = newTemp(Ity_I32);
3478   IRTemp op2 = newTemp(Ity_I32);
3479
3480   assign(op1, get_gpr_w1(r1));
3481   assign(op2, get_gpr_w1(r2));
3482   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3483
3484   return "cr";
3485}
3486
3487static HChar *
3488s390_irgen_CGR(UChar r1, UChar r2)
3489{
3490   IRTemp op1 = newTemp(Ity_I64);
3491   IRTemp op2 = newTemp(Ity_I64);
3492
3493   assign(op1, get_gpr_dw0(r1));
3494   assign(op2, get_gpr_dw0(r2));
3495   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3496
3497   return "cgr";
3498}
3499
3500static HChar *
3501s390_irgen_CGFR(UChar r1, UChar r2)
3502{
3503   IRTemp op1 = newTemp(Ity_I64);
3504   IRTemp op2 = newTemp(Ity_I64);
3505
3506   assign(op1, get_gpr_dw0(r1));
3507   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3508   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3509
3510   return "cgfr";
3511}
3512
3513static HChar *
3514s390_irgen_C(UChar r1, IRTemp op2addr)
3515{
3516   IRTemp op1 = newTemp(Ity_I32);
3517   IRTemp op2 = newTemp(Ity_I32);
3518
3519   assign(op1, get_gpr_w1(r1));
3520   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3521   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3522
3523   return "c";
3524}
3525
3526static HChar *
3527s390_irgen_CY(UChar r1, IRTemp op2addr)
3528{
3529   IRTemp op1 = newTemp(Ity_I32);
3530   IRTemp op2 = newTemp(Ity_I32);
3531
3532   assign(op1, get_gpr_w1(r1));
3533   assign(op2, load(Ity_I32, mkexpr(op2addr)));
3534   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3535
3536   return "cy";
3537}
3538
3539static HChar *
3540s390_irgen_CG(UChar r1, IRTemp op2addr)
3541{
3542   IRTemp op1 = newTemp(Ity_I64);
3543   IRTemp op2 = newTemp(Ity_I64);
3544
3545   assign(op1, get_gpr_dw0(r1));
3546   assign(op2, load(Ity_I64, mkexpr(op2addr)));
3547   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3548
3549   return "cg";
3550}
3551
3552static HChar *
3553s390_irgen_CGF(UChar r1, IRTemp op2addr)
3554{
3555   IRTemp op1 = newTemp(Ity_I64);
3556   IRTemp op2 = newTemp(Ity_I64);
3557
3558   assign(op1, get_gpr_dw0(r1));
3559   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3560   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3561
3562   return "cgf";
3563}
3564
3565static HChar *
3566s390_irgen_CFI(UChar r1, UInt i2)
3567{
3568   IRTemp op1 = newTemp(Ity_I32);
3569   Int op2;
3570
3571   assign(op1, get_gpr_w1(r1));
3572   op2 = (Int)i2;
3573   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3574                       mkU32((UInt)op2)));
3575
3576   return "cfi";
3577}
3578
3579static HChar *
3580s390_irgen_CGFI(UChar r1, UInt i2)
3581{
3582   IRTemp op1 = newTemp(Ity_I64);
3583   Long op2;
3584
3585   assign(op1, get_gpr_dw0(r1));
3586   op2 = (Long)(Int)i2;
3587   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3588                       mkU64((ULong)op2)));
3589
3590   return "cgfi";
3591}
3592
3593static HChar *
3594s390_irgen_CRL(UChar r1, UInt i2)
3595{
3596   IRTemp op1 = newTemp(Ity_I32);
3597   IRTemp op2 = newTemp(Ity_I32);
3598
3599   assign(op1, get_gpr_w1(r1));
3600   assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3601          i2 << 1))));
3602   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3603
3604   return "crl";
3605}
3606
3607static HChar *
3608s390_irgen_CGRL(UChar r1, UInt i2)
3609{
3610   IRTemp op1 = newTemp(Ity_I64);
3611   IRTemp op2 = newTemp(Ity_I64);
3612
3613   assign(op1, get_gpr_dw0(r1));
3614   assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3615          i2 << 1))));
3616   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3617
3618   return "cgrl";
3619}
3620
3621static HChar *
3622s390_irgen_CGFRL(UChar r1, UInt i2)
3623{
3624   IRTemp op1 = newTemp(Ity_I64);
3625   IRTemp op2 = newTemp(Ity_I64);
3626
3627   assign(op1, get_gpr_dw0(r1));
3628   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3629          ((ULong)(Long)(Int)i2 << 1)))));
3630   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3631
3632   return "cgfrl";
3633}
3634
3635static HChar *
3636s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3637{
3638   IRTemp op1 = newTemp(Ity_I32);
3639   IRTemp op2 = newTemp(Ity_I32);
3640   IRTemp cond = newTemp(Ity_I32);
3641
3642   if (m3 == 0) {
3643   } else {
3644      if (m3 == 14) {
3645         always_goto(mkexpr(op4addr));
3646      } else {
3647         assign(op1, get_gpr_w1(r1));
3648         assign(op2, get_gpr_w1(r2));
3649         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3650                                              op1, op2));
3651         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3652                                          mkU32(0)), mkexpr(op4addr));
3653      }
3654   }
3655
3656   return "crb";
3657}
3658
3659static HChar *
3660s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3661{
3662   IRTemp op1 = newTemp(Ity_I64);
3663   IRTemp op2 = newTemp(Ity_I64);
3664   IRTemp cond = newTemp(Ity_I32);
3665
3666   if (m3 == 0) {
3667   } else {
3668      if (m3 == 14) {
3669         always_goto(mkexpr(op4addr));
3670      } else {
3671         assign(op1, get_gpr_dw0(r1));
3672         assign(op2, get_gpr_dw0(r2));
3673         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3674                                              op1, op2));
3675         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3676                                          mkU32(0)), mkexpr(op4addr));
3677      }
3678   }
3679
3680   return "cgrb";
3681}
3682
3683static HChar *
3684s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3685{
3686   IRTemp op1 = newTemp(Ity_I32);
3687   IRTemp op2 = newTemp(Ity_I32);
3688   IRTemp cond = newTemp(Ity_I32);
3689
3690   if (m3 == 0) {
3691   } else {
3692      if (m3 == 14) {
3693         always_goto_and_chase(
3694                guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3695      } else {
3696         assign(op1, get_gpr_w1(r1));
3697         assign(op2, get_gpr_w1(r2));
3698         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3699                                              op1, op2));
3700         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3701                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3702
3703      }
3704   }
3705
3706   return "crj";
3707}
3708
3709static HChar *
3710s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3711{
3712   IRTemp op1 = newTemp(Ity_I64);
3713   IRTemp op2 = newTemp(Ity_I64);
3714   IRTemp cond = newTemp(Ity_I32);
3715
3716   if (m3 == 0) {
3717   } else {
3718      if (m3 == 14) {
3719         always_goto_and_chase(
3720                guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3721      } else {
3722         assign(op1, get_gpr_dw0(r1));
3723         assign(op2, get_gpr_dw0(r2));
3724         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3725                                              op1, op2));
3726         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3727                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3728
3729      }
3730   }
3731
3732   return "cgrj";
3733}
3734
3735static HChar *
3736s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3737{
3738   IRTemp op1 = newTemp(Ity_I32);
3739   Int op2;
3740   IRTemp cond = newTemp(Ity_I32);
3741
3742   if (m3 == 0) {
3743   } else {
3744      if (m3 == 14) {
3745         always_goto(mkexpr(op4addr));
3746      } else {
3747         assign(op1, get_gpr_w1(r1));
3748         op2 = (Int)(Char)i2;
3749         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3750                                              mktemp(Ity_I32, mkU32((UInt)op2))));
3751         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3752                                    mkexpr(op4addr));
3753      }
3754   }
3755
3756   return "cib";
3757}
3758
3759static HChar *
3760s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3761{
3762   IRTemp op1 = newTemp(Ity_I64);
3763   Long op2;
3764   IRTemp cond = newTemp(Ity_I32);
3765
3766   if (m3 == 0) {
3767   } else {
3768      if (m3 == 14) {
3769         always_goto(mkexpr(op4addr));
3770      } else {
3771         assign(op1, get_gpr_dw0(r1));
3772         op2 = (Long)(Char)i2;
3773         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3774                                              mktemp(Ity_I64, mkU64((ULong)op2))));
3775         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3776                                    mkexpr(op4addr));
3777      }
3778   }
3779
3780   return "cgib";
3781}
3782
3783static HChar *
3784s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3785{
3786   IRTemp op1 = newTemp(Ity_I32);
3787   Int op2;
3788   IRTemp cond = newTemp(Ity_I32);
3789
3790   if (m3 == 0) {
3791   } else {
3792      if (m3 == 14) {
3793         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3794      } else {
3795         assign(op1, get_gpr_w1(r1));
3796         op2 = (Int)(Char)i2;
3797         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3798                                              mktemp(Ity_I32, mkU32((UInt)op2))));
3799         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3800                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3801
3802      }
3803   }
3804
3805   return "cij";
3806}
3807
3808static HChar *
3809s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3810{
3811   IRTemp op1 = newTemp(Ity_I64);
3812   Long op2;
3813   IRTemp cond = newTemp(Ity_I32);
3814
3815   if (m3 == 0) {
3816   } else {
3817      if (m3 == 14) {
3818         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3819      } else {
3820         assign(op1, get_gpr_dw0(r1));
3821         op2 = (Long)(Char)i2;
3822         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3823                                              mktemp(Ity_I64, mkU64((ULong)op2))));
3824         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3825                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3826
3827      }
3828   }
3829
3830   return "cgij";
3831}
3832
3833static HChar *
3834s390_irgen_CH(UChar r1, IRTemp op2addr)
3835{
3836   IRTemp op1 = newTemp(Ity_I32);
3837   IRTemp op2 = newTemp(Ity_I32);
3838
3839   assign(op1, get_gpr_w1(r1));
3840   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3841   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3842
3843   return "ch";
3844}
3845
3846static HChar *
3847s390_irgen_CHY(UChar r1, IRTemp op2addr)
3848{
3849   IRTemp op1 = newTemp(Ity_I32);
3850   IRTemp op2 = newTemp(Ity_I32);
3851
3852   assign(op1, get_gpr_w1(r1));
3853   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3854   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3855
3856   return "chy";
3857}
3858
3859static HChar *
3860s390_irgen_CGH(UChar r1, IRTemp op2addr)
3861{
3862   IRTemp op1 = newTemp(Ity_I64);
3863   IRTemp op2 = newTemp(Ity_I64);
3864
3865   assign(op1, get_gpr_dw0(r1));
3866   assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
3867   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3868
3869   return "cgh";
3870}
3871
3872static HChar *
3873s390_irgen_CHI(UChar r1, UShort i2)
3874{
3875   IRTemp op1 = newTemp(Ity_I32);
3876   Int op2;
3877
3878   assign(op1, get_gpr_w1(r1));
3879   op2 = (Int)(Short)i2;
3880   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3881                       mkU32((UInt)op2)));
3882
3883   return "chi";
3884}
3885
3886static HChar *
3887s390_irgen_CGHI(UChar r1, UShort i2)
3888{
3889   IRTemp op1 = newTemp(Ity_I64);
3890   Long op2;
3891
3892   assign(op1, get_gpr_dw0(r1));
3893   op2 = (Long)(Short)i2;
3894   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3895                       mkU64((ULong)op2)));
3896
3897   return "cghi";
3898}
3899
3900static HChar *
3901s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
3902{
3903   IRTemp op1 = newTemp(Ity_I16);
3904   Short op2;
3905
3906   assign(op1, load(Ity_I16, mkexpr(op1addr)));
3907   op2 = (Short)i2;
3908   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
3909                       mkU16((UShort)op2)));
3910
3911   return "chhsi";
3912}
3913
3914static HChar *
3915s390_irgen_CHSI(UShort i2, IRTemp op1addr)
3916{
3917   IRTemp op1 = newTemp(Ity_I32);
3918   Int op2;
3919
3920   assign(op1, load(Ity_I32, mkexpr(op1addr)));
3921   op2 = (Int)(Short)i2;
3922   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3923                       mkU32((UInt)op2)));
3924
3925   return "chsi";
3926}
3927
3928static HChar *
3929s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
3930{
3931   IRTemp op1 = newTemp(Ity_I64);
3932   Long op2;
3933
3934   assign(op1, load(Ity_I64, mkexpr(op1addr)));
3935   op2 = (Long)(Short)i2;
3936   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3937                       mkU64((ULong)op2)));
3938
3939   return "cghsi";
3940}
3941
3942static HChar *
3943s390_irgen_CHRL(UChar r1, UInt i2)
3944{
3945   IRTemp op1 = newTemp(Ity_I32);
3946   IRTemp op2 = newTemp(Ity_I32);
3947
3948   assign(op1, get_gpr_w1(r1));
3949   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
3950          ((ULong)(Long)(Int)i2 << 1)))));
3951   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3952
3953   return "chrl";
3954}
3955
3956static HChar *
3957s390_irgen_CGHRL(UChar r1, UInt i2)
3958{
3959   IRTemp op1 = newTemp(Ity_I64);
3960   IRTemp op2 = newTemp(Ity_I64);
3961
3962   assign(op1, get_gpr_dw0(r1));
3963   assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
3964          ((ULong)(Long)(Int)i2 << 1)))));
3965   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3966
3967   return "cghrl";
3968}
3969
3970static HChar *
3971s390_irgen_CHHR(UChar r1, UChar r2)
3972{
3973   IRTemp op1 = newTemp(Ity_I32);
3974   IRTemp op2 = newTemp(Ity_I32);
3975
3976   assign(op1, get_gpr_w0(r1));
3977   assign(op2, get_gpr_w0(r2));
3978   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3979
3980   return "chhr";
3981}
3982
3983static HChar *
3984s390_irgen_CHLR(UChar r1, UChar r2)
3985{
3986   IRTemp op1 = newTemp(Ity_I32);
3987   IRTemp op2 = newTemp(Ity_I32);
3988
3989   assign(op1, get_gpr_w0(r1));
3990   assign(op2, get_gpr_w1(r2));
3991   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3992
3993   return "chlr";
3994}
3995
3996static HChar *
3997s390_irgen_CHF(UChar r1, IRTemp op2addr)
3998{
3999   IRTemp op1 = newTemp(Ity_I32);
4000   IRTemp op2 = newTemp(Ity_I32);
4001
4002   assign(op1, get_gpr_w0(r1));
4003   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4004   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4005
4006   return "chf";
4007}
4008
4009static HChar *
4010s390_irgen_CIH(UChar r1, UInt i2)
4011{
4012   IRTemp op1 = newTemp(Ity_I32);
4013   Int op2;
4014
4015   assign(op1, get_gpr_w0(r1));
4016   op2 = (Int)i2;
4017   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4018                       mkU32((UInt)op2)));
4019
4020   return "cih";
4021}
4022
4023static HChar *
4024s390_irgen_CLR(UChar r1, UChar r2)
4025{
4026   IRTemp op1 = newTemp(Ity_I32);
4027   IRTemp op2 = newTemp(Ity_I32);
4028
4029   assign(op1, get_gpr_w1(r1));
4030   assign(op2, get_gpr_w1(r2));
4031   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4032
4033   return "clr";
4034}
4035
4036static HChar *
4037s390_irgen_CLGR(UChar r1, UChar r2)
4038{
4039   IRTemp op1 = newTemp(Ity_I64);
4040   IRTemp op2 = newTemp(Ity_I64);
4041
4042   assign(op1, get_gpr_dw0(r1));
4043   assign(op2, get_gpr_dw0(r2));
4044   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4045
4046   return "clgr";
4047}
4048
4049static HChar *
4050s390_irgen_CLGFR(UChar r1, UChar r2)
4051{
4052   IRTemp op1 = newTemp(Ity_I64);
4053   IRTemp op2 = newTemp(Ity_I64);
4054
4055   assign(op1, get_gpr_dw0(r1));
4056   assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4057   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4058
4059   return "clgfr";
4060}
4061
4062static HChar *
4063s390_irgen_CL(UChar r1, IRTemp op2addr)
4064{
4065   IRTemp op1 = newTemp(Ity_I32);
4066   IRTemp op2 = newTemp(Ity_I32);
4067
4068   assign(op1, get_gpr_w1(r1));
4069   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4070   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4071
4072   return "cl";
4073}
4074
4075static HChar *
4076s390_irgen_CLY(UChar r1, IRTemp op2addr)
4077{
4078   IRTemp op1 = newTemp(Ity_I32);
4079   IRTemp op2 = newTemp(Ity_I32);
4080
4081   assign(op1, get_gpr_w1(r1));
4082   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4083   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4084
4085   return "cly";
4086}
4087
4088static HChar *
4089s390_irgen_CLG(UChar r1, IRTemp op2addr)
4090{
4091   IRTemp op1 = newTemp(Ity_I64);
4092   IRTemp op2 = newTemp(Ity_I64);
4093
4094   assign(op1, get_gpr_dw0(r1));
4095   assign(op2, load(Ity_I64, mkexpr(op2addr)));
4096   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4097
4098   return "clg";
4099}
4100
4101static HChar *
4102s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4103{
4104   IRTemp op1 = newTemp(Ity_I64);
4105   IRTemp op2 = newTemp(Ity_I64);
4106
4107   assign(op1, get_gpr_dw0(r1));
4108   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4109   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4110
4111   return "clgf";
4112}
4113
4114static HChar *
4115s390_irgen_CLFI(UChar r1, UInt i2)
4116{
4117   IRTemp op1 = newTemp(Ity_I32);
4118   UInt op2;
4119
4120   assign(op1, get_gpr_w1(r1));
4121   op2 = i2;
4122   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4123                       mkU32(op2)));
4124
4125   return "clfi";
4126}
4127
4128static HChar *
4129s390_irgen_CLGFI(UChar r1, UInt i2)
4130{
4131   IRTemp op1 = newTemp(Ity_I64);
4132   ULong op2;
4133
4134   assign(op1, get_gpr_dw0(r1));
4135   op2 = (ULong)i2;
4136   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4137                       mkU64(op2)));
4138
4139   return "clgfi";
4140}
4141
4142static HChar *
4143s390_irgen_CLI(UChar i2, IRTemp op1addr)
4144{
4145   IRTemp op1 = newTemp(Ity_I8);
4146   UChar op2;
4147
4148   assign(op1, load(Ity_I8, mkexpr(op1addr)));
4149   op2 = i2;
4150   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4151                       mkU8(op2)));
4152
4153   return "cli";
4154}
4155
4156static HChar *
4157s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4158{
4159   IRTemp op1 = newTemp(Ity_I8);
4160   UChar op2;
4161
4162   assign(op1, load(Ity_I8, mkexpr(op1addr)));
4163   op2 = i2;
4164   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4165                       mkU8(op2)));
4166
4167   return "cliy";
4168}
4169
4170static HChar *
4171s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4172{
4173   IRTemp op1 = newTemp(Ity_I32);
4174   UInt op2;
4175
4176   assign(op1, load(Ity_I32, mkexpr(op1addr)));
4177   op2 = (UInt)i2;
4178   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4179                       mkU32(op2)));
4180
4181   return "clfhsi";
4182}
4183
4184static HChar *
4185s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4186{
4187   IRTemp op1 = newTemp(Ity_I64);
4188   ULong op2;
4189
4190   assign(op1, load(Ity_I64, mkexpr(op1addr)));
4191   op2 = (ULong)i2;
4192   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4193                       mkU64(op2)));
4194
4195   return "clghsi";
4196}
4197
4198static HChar *
4199s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4200{
4201   IRTemp op1 = newTemp(Ity_I16);
4202   UShort op2;
4203
4204   assign(op1, load(Ity_I16, mkexpr(op1addr)));
4205   op2 = i2;
4206   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4207                       mkU16(op2)));
4208
4209   return "clhhsi";
4210}
4211
4212static HChar *
4213s390_irgen_CLRL(UChar r1, UInt i2)
4214{
4215   IRTemp op1 = newTemp(Ity_I32);
4216   IRTemp op2 = newTemp(Ity_I32);
4217
4218   assign(op1, get_gpr_w1(r1));
4219   assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4220          i2 << 1))));
4221   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4222
4223   return "clrl";
4224}
4225
4226static HChar *
4227s390_irgen_CLGRL(UChar r1, UInt i2)
4228{
4229   IRTemp op1 = newTemp(Ity_I64);
4230   IRTemp op2 = newTemp(Ity_I64);
4231
4232   assign(op1, get_gpr_dw0(r1));
4233   assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4234          i2 << 1))));
4235   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4236
4237   return "clgrl";
4238}
4239
4240static HChar *
4241s390_irgen_CLGFRL(UChar r1, UInt i2)
4242{
4243   IRTemp op1 = newTemp(Ity_I64);
4244   IRTemp op2 = newTemp(Ity_I64);
4245
4246   assign(op1, get_gpr_dw0(r1));
4247   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4248          ((ULong)(Long)(Int)i2 << 1)))));
4249   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4250
4251   return "clgfrl";
4252}
4253
4254static HChar *
4255s390_irgen_CLHRL(UChar r1, UInt i2)
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_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4262          ((ULong)(Long)(Int)i2 << 1)))));
4263   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4264
4265   return "clhrl";
4266}
4267
4268static HChar *
4269s390_irgen_CLGHRL(UChar r1, UInt i2)
4270{
4271   IRTemp op1 = newTemp(Ity_I64);
4272   IRTemp op2 = newTemp(Ity_I64);
4273
4274   assign(op1, get_gpr_dw0(r1));
4275   assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4276          ((ULong)(Long)(Int)i2 << 1)))));
4277   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4278
4279   return "clghrl";
4280}
4281
4282static HChar *
4283s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4284{
4285   IRTemp op1 = newTemp(Ity_I32);
4286   IRTemp op2 = newTemp(Ity_I32);
4287   IRTemp cond = newTemp(Ity_I32);
4288
4289   if (m3 == 0) {
4290   } else {
4291      if (m3 == 14) {
4292         always_goto(mkexpr(op4addr));
4293      } else {
4294         assign(op1, get_gpr_w1(r1));
4295         assign(op2, get_gpr_w1(r2));
4296         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4297                                              op1, op2));
4298         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4299                                    mkexpr(op4addr));
4300      }
4301   }
4302
4303   return "clrb";
4304}
4305
4306static HChar *
4307s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4308{
4309   IRTemp op1 = newTemp(Ity_I64);
4310   IRTemp op2 = newTemp(Ity_I64);
4311   IRTemp cond = newTemp(Ity_I32);
4312
4313   if (m3 == 0) {
4314   } else {
4315      if (m3 == 14) {
4316         always_goto(mkexpr(op4addr));
4317      } else {
4318         assign(op1, get_gpr_dw0(r1));
4319         assign(op2, get_gpr_dw0(r2));
4320         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4321                                              op1, op2));
4322         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4323                                    mkexpr(op4addr));
4324      }
4325   }
4326
4327   return "clgrb";
4328}
4329
4330static HChar *
4331s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4332{
4333   IRTemp op1 = newTemp(Ity_I32);
4334   IRTemp op2 = newTemp(Ity_I32);
4335   IRTemp cond = newTemp(Ity_I32);
4336
4337   if (m3 == 0) {
4338   } else {
4339      if (m3 == 14) {
4340         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4341      } else {
4342         assign(op1, get_gpr_w1(r1));
4343         assign(op2, get_gpr_w1(r2));
4344         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4345                                              op1, op2));
4346         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4347                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4348
4349      }
4350   }
4351
4352   return "clrj";
4353}
4354
4355static HChar *
4356s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4357{
4358   IRTemp op1 = newTemp(Ity_I64);
4359   IRTemp op2 = newTemp(Ity_I64);
4360   IRTemp cond = newTemp(Ity_I32);
4361
4362   if (m3 == 0) {
4363   } else {
4364      if (m3 == 14) {
4365         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4366      } else {
4367         assign(op1, get_gpr_dw0(r1));
4368         assign(op2, get_gpr_dw0(r2));
4369         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4370                                              op1, op2));
4371         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4372                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4373
4374      }
4375   }
4376
4377   return "clgrj";
4378}
4379
4380static HChar *
4381s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4382{
4383   IRTemp op1 = newTemp(Ity_I32);
4384   UInt op2;
4385   IRTemp cond = newTemp(Ity_I32);
4386
4387   if (m3 == 0) {
4388   } else {
4389      if (m3 == 14) {
4390         always_goto(mkexpr(op4addr));
4391      } else {
4392         assign(op1, get_gpr_w1(r1));
4393         op2 = (UInt)i2;
4394         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4395                                              mktemp(Ity_I32, mkU32(op2))));
4396         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4397                                    mkexpr(op4addr));
4398      }
4399   }
4400
4401   return "clib";
4402}
4403
4404static HChar *
4405s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4406{
4407   IRTemp op1 = newTemp(Ity_I64);
4408   ULong op2;
4409   IRTemp cond = newTemp(Ity_I32);
4410
4411   if (m3 == 0) {
4412   } else {
4413      if (m3 == 14) {
4414         always_goto(mkexpr(op4addr));
4415      } else {
4416         assign(op1, get_gpr_dw0(r1));
4417         op2 = (ULong)i2;
4418         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4419                                              mktemp(Ity_I64, mkU64(op2))));
4420         if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4421                                    mkexpr(op4addr));
4422      }
4423   }
4424
4425   return "clgib";
4426}
4427
4428static HChar *
4429s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4430{
4431   IRTemp op1 = newTemp(Ity_I32);
4432   UInt op2;
4433   IRTemp cond = newTemp(Ity_I32);
4434
4435   if (m3 == 0) {
4436   } else {
4437      if (m3 == 14) {
4438         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4439      } else {
4440         assign(op1, get_gpr_w1(r1));
4441         op2 = (UInt)i2;
4442         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4443                                              mktemp(Ity_I32, mkU32(op2))));
4444         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4445                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4446
4447      }
4448   }
4449
4450   return "clij";
4451}
4452
4453static HChar *
4454s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4455{
4456   IRTemp op1 = newTemp(Ity_I64);
4457   ULong op2;
4458   IRTemp cond = newTemp(Ity_I32);
4459
4460   if (m3 == 0) {
4461   } else {
4462      if (m3 == 14) {
4463         always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4464      } else {
4465         assign(op1, get_gpr_dw0(r1));
4466         op2 = (ULong)i2;
4467         assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4468                                              mktemp(Ity_I64, mkU64(op2))));
4469         if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4470                           guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4471
4472      }
4473   }
4474
4475   return "clgij";
4476}
4477
4478static HChar *
4479s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4480{
4481   IRTemp op1 = newTemp(Ity_I32);
4482   IRTemp op2 = newTemp(Ity_I32);
4483   IRTemp b0 = newTemp(Ity_I32);
4484   IRTemp b1 = newTemp(Ity_I32);
4485   IRTemp b2 = newTemp(Ity_I32);
4486   IRTemp b3 = newTemp(Ity_I32);
4487   IRTemp c0 = newTemp(Ity_I32);
4488   IRTemp c1 = newTemp(Ity_I32);
4489   IRTemp c2 = newTemp(Ity_I32);
4490   IRTemp c3 = newTemp(Ity_I32);
4491   UChar n;
4492
4493   n = 0;
4494   if ((r3 & 8) != 0) {
4495      assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4496      assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4497      n = n + 1;
4498   } else {
4499      assign(b0, mkU32(0));
4500      assign(c0, mkU32(0));
4501   }
4502   if ((r3 & 4) != 0) {
4503      assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4504      assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4505             mkU64(n)))));
4506      n = n + 1;
4507   } else {
4508      assign(b1, mkU32(0));
4509      assign(c1, mkU32(0));
4510   }
4511   if ((r3 & 2) != 0) {
4512      assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4513      assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4514             mkU64(n)))));
4515      n = n + 1;
4516   } else {
4517      assign(b2, mkU32(0));
4518      assign(c2, mkU32(0));
4519   }
4520   if ((r3 & 1) != 0) {
4521      assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4522      assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4523             mkU64(n)))));
4524      n = n + 1;
4525   } else {
4526      assign(b3, mkU32(0));
4527      assign(c3, mkU32(0));
4528   }
4529   assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4530          mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4531          binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4532   assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4533          mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4534          binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4535   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4536
4537   return "clm";
4538}
4539
4540static HChar *
4541s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4542{
4543   IRTemp op1 = newTemp(Ity_I32);
4544   IRTemp op2 = newTemp(Ity_I32);
4545   IRTemp b0 = newTemp(Ity_I32);
4546   IRTemp b1 = newTemp(Ity_I32);
4547   IRTemp b2 = newTemp(Ity_I32);
4548   IRTemp b3 = newTemp(Ity_I32);
4549   IRTemp c0 = newTemp(Ity_I32);
4550   IRTemp c1 = newTemp(Ity_I32);
4551   IRTemp c2 = newTemp(Ity_I32);
4552   IRTemp c3 = newTemp(Ity_I32);
4553   UChar n;
4554
4555   n = 0;
4556   if ((r3 & 8) != 0) {
4557      assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4558      assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4559      n = n + 1;
4560   } else {
4561      assign(b0, mkU32(0));
4562      assign(c0, mkU32(0));
4563   }
4564   if ((r3 & 4) != 0) {
4565      assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4566      assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4567             mkU64(n)))));
4568      n = n + 1;
4569   } else {
4570      assign(b1, mkU32(0));
4571      assign(c1, mkU32(0));
4572   }
4573   if ((r3 & 2) != 0) {
4574      assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4575      assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4576             mkU64(n)))));
4577      n = n + 1;
4578   } else {
4579      assign(b2, mkU32(0));
4580      assign(c2, mkU32(0));
4581   }
4582   if ((r3 & 1) != 0) {
4583      assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4584      assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4585             mkU64(n)))));
4586      n = n + 1;
4587   } else {
4588      assign(b3, mkU32(0));
4589      assign(c3, mkU32(0));
4590   }
4591   assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4592          mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4593          binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4594   assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4595          mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4596          binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4597   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4598
4599   return "clmy";
4600}
4601
4602static HChar *
4603s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4604{
4605   IRTemp op1 = newTemp(Ity_I32);
4606   IRTemp op2 = newTemp(Ity_I32);
4607   IRTemp b0 = newTemp(Ity_I32);
4608   IRTemp b1 = newTemp(Ity_I32);
4609   IRTemp b2 = newTemp(Ity_I32);
4610   IRTemp b3 = newTemp(Ity_I32);
4611   IRTemp c0 = newTemp(Ity_I32);
4612   IRTemp c1 = newTemp(Ity_I32);
4613   IRTemp c2 = newTemp(Ity_I32);
4614   IRTemp c3 = newTemp(Ity_I32);
4615   UChar n;
4616
4617   n = 0;
4618   if ((r3 & 8) != 0) {
4619      assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4620      assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4621      n = n + 1;
4622   } else {
4623      assign(b0, mkU32(0));
4624      assign(c0, mkU32(0));
4625   }
4626   if ((r3 & 4) != 0) {
4627      assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4628      assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4629             mkU64(n)))));
4630      n = n + 1;
4631   } else {
4632      assign(b1, mkU32(0));
4633      assign(c1, mkU32(0));
4634   }
4635   if ((r3 & 2) != 0) {
4636      assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4637      assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4638             mkU64(n)))));
4639      n = n + 1;
4640   } else {
4641      assign(b2, mkU32(0));
4642      assign(c2, mkU32(0));
4643   }
4644   if ((r3 & 1) != 0) {
4645      assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4646      assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4647             mkU64(n)))));
4648      n = n + 1;
4649   } else {
4650      assign(b3, mkU32(0));
4651      assign(c3, mkU32(0));
4652   }
4653   assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4654          mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4655          binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4656   assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4657          mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4658          binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4659   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4660
4661   return "clmh";
4662}
4663
4664static HChar *
4665s390_irgen_CLHHR(UChar r1, UChar r2)
4666{
4667   IRTemp op1 = newTemp(Ity_I32);
4668   IRTemp op2 = newTemp(Ity_I32);
4669
4670   assign(op1, get_gpr_w0(r1));
4671   assign(op2, get_gpr_w0(r2));
4672   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4673
4674   return "clhhr";
4675}
4676
4677static HChar *
4678s390_irgen_CLHLR(UChar r1, UChar r2)
4679{
4680   IRTemp op1 = newTemp(Ity_I32);
4681   IRTemp op2 = newTemp(Ity_I32);
4682
4683   assign(op1, get_gpr_w0(r1));
4684   assign(op2, get_gpr_w1(r2));
4685   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4686
4687   return "clhlr";
4688}
4689
4690static HChar *
4691s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4692{
4693   IRTemp op1 = newTemp(Ity_I32);
4694   IRTemp op2 = newTemp(Ity_I32);
4695
4696   assign(op1, get_gpr_w0(r1));
4697   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4698   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4699
4700   return "clhf";
4701}
4702
4703static HChar *
4704s390_irgen_CLIH(UChar r1, UInt i2)
4705{
4706   IRTemp op1 = newTemp(Ity_I32);
4707   UInt op2;
4708
4709   assign(op1, get_gpr_w0(r1));
4710   op2 = i2;
4711   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4712                       mkU32(op2)));
4713
4714   return "clih";
4715}
4716
4717static HChar *
4718s390_irgen_CPYA(UChar r1, UChar r2)
4719{
4720   put_ar_w0(r1, get_ar_w0(r2));
4721   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4722      s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4723
4724   return "cpya";
4725}
4726
4727static HChar *
4728s390_irgen_XR(UChar r1, UChar r2)
4729{
4730   IRTemp op1 = newTemp(Ity_I32);
4731   IRTemp op2 = newTemp(Ity_I32);
4732   IRTemp result = newTemp(Ity_I32);
4733
4734   if (r1 == r2) {
4735      assign(result, mkU32(0));
4736   } else {
4737      assign(op1, get_gpr_w1(r1));
4738      assign(op2, get_gpr_w1(r2));
4739      assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4740   }
4741   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4742   put_gpr_w1(r1, mkexpr(result));
4743
4744   return "xr";
4745}
4746
4747static HChar *
4748s390_irgen_XGR(UChar r1, UChar r2)
4749{
4750   IRTemp op1 = newTemp(Ity_I64);
4751   IRTemp op2 = newTemp(Ity_I64);
4752   IRTemp result = newTemp(Ity_I64);
4753
4754   if (r1 == r2) {
4755      assign(result, mkU64(0));
4756   } else {
4757      assign(op1, get_gpr_dw0(r1));
4758      assign(op2, get_gpr_dw0(r2));
4759      assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4760   }
4761   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4762   put_gpr_dw0(r1, mkexpr(result));
4763
4764   return "xgr";
4765}
4766
4767static HChar *
4768s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4769{
4770   IRTemp op2 = newTemp(Ity_I32);
4771   IRTemp op3 = newTemp(Ity_I32);
4772   IRTemp result = newTemp(Ity_I32);
4773
4774   assign(op2, get_gpr_w1(r2));
4775   assign(op3, get_gpr_w1(r3));
4776   assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4777   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4778   put_gpr_w1(r1, mkexpr(result));
4779
4780   return "xrk";
4781}
4782
4783static HChar *
4784s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4785{
4786   IRTemp op2 = newTemp(Ity_I64);
4787   IRTemp op3 = newTemp(Ity_I64);
4788   IRTemp result = newTemp(Ity_I64);
4789
4790   assign(op2, get_gpr_dw0(r2));
4791   assign(op3, get_gpr_dw0(r3));
4792   assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4793   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4794   put_gpr_dw0(r1, mkexpr(result));
4795
4796   return "xgrk";
4797}
4798
4799static HChar *
4800s390_irgen_X(UChar r1, IRTemp op2addr)
4801{
4802   IRTemp op1 = newTemp(Ity_I32);
4803   IRTemp op2 = newTemp(Ity_I32);
4804   IRTemp result = newTemp(Ity_I32);
4805
4806   assign(op1, get_gpr_w1(r1));
4807   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4808   assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4809   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4810   put_gpr_w1(r1, mkexpr(result));
4811
4812   return "x";
4813}
4814
4815static HChar *
4816s390_irgen_XY(UChar r1, IRTemp op2addr)
4817{
4818   IRTemp op1 = newTemp(Ity_I32);
4819   IRTemp op2 = newTemp(Ity_I32);
4820   IRTemp result = newTemp(Ity_I32);
4821
4822   assign(op1, get_gpr_w1(r1));
4823   assign(op2, load(Ity_I32, mkexpr(op2addr)));
4824   assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4825   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4826   put_gpr_w1(r1, mkexpr(result));
4827
4828   return "xy";
4829}
4830
4831static HChar *
4832s390_irgen_XG(UChar r1, IRTemp op2addr)
4833{
4834   IRTemp op1 = newTemp(Ity_I64);
4835   IRTemp op2 = newTemp(Ity_I64);
4836   IRTemp result = newTemp(Ity_I64);
4837
4838   assign(op1, get_gpr_dw0(r1));
4839   assign(op2, load(Ity_I64, mkexpr(op2addr)));
4840   assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4841   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4842   put_gpr_dw0(r1, mkexpr(result));
4843
4844   return "xg";
4845}
4846
4847static HChar *
4848s390_irgen_XI(UChar i2, IRTemp op1addr)
4849{
4850   IRTemp op1 = newTemp(Ity_I8);
4851   UChar op2;
4852   IRTemp result = newTemp(Ity_I8);
4853
4854   assign(op1, load(Ity_I8, mkexpr(op1addr)));
4855   op2 = i2;
4856   assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4857   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4858   store(mkexpr(op1addr), mkexpr(result));
4859
4860   return "xi";
4861}
4862
4863static HChar *
4864s390_irgen_XIY(UChar i2, IRTemp op1addr)
4865{
4866   IRTemp op1 = newTemp(Ity_I8);
4867   UChar op2;
4868   IRTemp result = newTemp(Ity_I8);
4869
4870   assign(op1, load(Ity_I8, mkexpr(op1addr)));
4871   op2 = i2;
4872   assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4873   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4874   store(mkexpr(op1addr), mkexpr(result));
4875
4876   return "xiy";
4877}
4878
4879static HChar *
4880s390_irgen_XIHF(UChar r1, UInt i2)
4881{
4882   IRTemp op1 = newTemp(Ity_I32);
4883   UInt op2;
4884   IRTemp result = newTemp(Ity_I32);
4885
4886   assign(op1, get_gpr_w0(r1));
4887   op2 = i2;
4888   assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4889   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4890   put_gpr_w0(r1, mkexpr(result));
4891
4892   return "xihf";
4893}
4894
4895static HChar *
4896s390_irgen_XILF(UChar r1, UInt i2)
4897{
4898   IRTemp op1 = newTemp(Ity_I32);
4899   UInt op2;
4900   IRTemp result = newTemp(Ity_I32);
4901
4902   assign(op1, get_gpr_w1(r1));
4903   op2 = i2;
4904   assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4905   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4906   put_gpr_w1(r1, mkexpr(result));
4907
4908   return "xilf";
4909}
4910
4911static HChar *
4912s390_irgen_EAR(UChar r1, UChar r2)
4913{
4914   put_gpr_w1(r1, get_ar_w0(r2));
4915   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4916      s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
4917
4918   return "ear";
4919}
4920
4921static HChar *
4922s390_irgen_IC(UChar r1, IRTemp op2addr)
4923{
4924   put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4925
4926   return "ic";
4927}
4928
4929static HChar *
4930s390_irgen_ICY(UChar r1, IRTemp op2addr)
4931{
4932   put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4933
4934   return "icy";
4935}
4936
4937static HChar *
4938s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
4939{
4940   UChar n;
4941   IRTemp result = newTemp(Ity_I32);
4942   UInt mask;
4943
4944   n = 0;
4945   mask = (UInt)r3;
4946   if ((mask & 8) != 0) {
4947      put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4948      n = n + 1;
4949   }
4950   if ((mask & 4) != 0) {
4951      put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4952
4953      n = n + 1;
4954   }
4955   if ((mask & 2) != 0) {
4956      put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4957
4958      n = n + 1;
4959   }
4960   if ((mask & 1) != 0) {
4961      put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4962
4963      n = n + 1;
4964   }
4965   assign(result, get_gpr_w1(r1));
4966   s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
4967                       mkU32(mask)));
4968
4969   return "icm";
4970}
4971
4972static HChar *
4973s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
4974{
4975   UChar n;
4976   IRTemp result = newTemp(Ity_I32);
4977   UInt mask;
4978
4979   n = 0;
4980   mask = (UInt)r3;
4981   if ((mask & 8) != 0) {
4982      put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4983      n = n + 1;
4984   }
4985   if ((mask & 4) != 0) {
4986      put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4987
4988      n = n + 1;
4989   }
4990   if ((mask & 2) != 0) {
4991      put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4992
4993      n = n + 1;
4994   }
4995   if ((mask & 1) != 0) {
4996      put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4997
4998      n = n + 1;
4999   }
5000   assign(result, get_gpr_w1(r1));
5001   s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5002                       mkU32(mask)));
5003
5004   return "icmy";
5005}
5006
5007static HChar *
5008s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5009{
5010   UChar n;
5011   IRTemp result = newTemp(Ity_I32);
5012   UInt mask;
5013
5014   n = 0;
5015   mask = (UInt)r3;
5016   if ((mask & 8) != 0) {
5017      put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5018      n = n + 1;
5019   }
5020   if ((mask & 4) != 0) {
5021      put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5022
5023      n = n + 1;
5024   }
5025   if ((mask & 2) != 0) {
5026      put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5027
5028      n = n + 1;
5029   }
5030   if ((mask & 1) != 0) {
5031      put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5032
5033      n = n + 1;
5034   }
5035   assign(result, get_gpr_w0(r1));
5036   s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5037                       mkU32(mask)));
5038
5039   return "icmh";
5040}
5041
5042static HChar *
5043s390_irgen_IIHF(UChar r1, UInt i2)
5044{
5045   put_gpr_w0(r1, mkU32(i2));
5046
5047   return "iihf";
5048}
5049
5050static HChar *
5051s390_irgen_IIHH(UChar r1, UShort i2)
5052{
5053   put_gpr_hw0(r1, mkU16(i2));
5054
5055   return "iihh";
5056}
5057
5058static HChar *
5059s390_irgen_IIHL(UChar r1, UShort i2)
5060{
5061   put_gpr_hw1(r1, mkU16(i2));
5062
5063   return "iihl";
5064}
5065
5066static HChar *
5067s390_irgen_IILF(UChar r1, UInt i2)
5068{
5069   put_gpr_w1(r1, mkU32(i2));
5070
5071   return "iilf";
5072}
5073
5074static HChar *
5075s390_irgen_IILH(UChar r1, UShort i2)
5076{
5077   put_gpr_hw2(r1, mkU16(i2));
5078
5079   return "iilh";
5080}
5081
5082static HChar *
5083s390_irgen_IILL(UChar r1, UShort i2)
5084{
5085   put_gpr_hw3(r1, mkU16(i2));
5086
5087   return "iill";
5088}
5089
5090static HChar *
5091s390_irgen_LR(UChar r1, UChar r2)
5092{
5093   put_gpr_w1(r1, get_gpr_w1(r2));
5094
5095   return "lr";
5096}
5097
5098static HChar *
5099s390_irgen_LGR(UChar r1, UChar r2)
5100{
5101   put_gpr_dw0(r1, get_gpr_dw0(r2));
5102
5103   return "lgr";
5104}
5105
5106static HChar *
5107s390_irgen_LGFR(UChar r1, UChar r2)
5108{
5109   put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5110
5111   return "lgfr";
5112}
5113
5114static HChar *
5115s390_irgen_L(UChar r1, IRTemp op2addr)
5116{
5117   put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5118
5119   return "l";
5120}
5121
5122static HChar *
5123s390_irgen_LY(UChar r1, IRTemp op2addr)
5124{
5125   put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5126
5127   return "ly";
5128}
5129
5130static HChar *
5131s390_irgen_LG(UChar r1, IRTemp op2addr)
5132{
5133   put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5134
5135   return "lg";
5136}
5137
5138static HChar *
5139s390_irgen_LGF(UChar r1, IRTemp op2addr)
5140{
5141   put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5142
5143   return "lgf";
5144}
5145
5146static HChar *
5147s390_irgen_LGFI(UChar r1, UInt i2)
5148{
5149   put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5150
5151   return "lgfi";
5152}
5153
5154static HChar *
5155s390_irgen_LRL(UChar r1, UInt i2)
5156{
5157   put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5158              i2 << 1))));
5159
5160   return "lrl";
5161}
5162
5163static HChar *
5164s390_irgen_LGRL(UChar r1, UInt i2)
5165{
5166   put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5167               i2 << 1))));
5168
5169   return "lgrl";
5170}
5171
5172static HChar *
5173s390_irgen_LGFRL(UChar r1, UInt i2)
5174{
5175   put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5176               ((ULong)(Long)(Int)i2 << 1)))));
5177
5178   return "lgfrl";
5179}
5180
5181static HChar *
5182s390_irgen_LA(UChar r1, IRTemp op2addr)
5183{
5184   put_gpr_dw0(r1, mkexpr(op2addr));
5185
5186   return "la";
5187}
5188
5189static HChar *
5190s390_irgen_LAY(UChar r1, IRTemp op2addr)
5191{
5192   put_gpr_dw0(r1, mkexpr(op2addr));
5193
5194   return "lay";
5195}
5196
5197static HChar *
5198s390_irgen_LAE(UChar r1, IRTemp op2addr)
5199{
5200   put_gpr_dw0(r1, mkexpr(op2addr));
5201
5202   return "lae";
5203}
5204
5205static HChar *
5206s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5207{
5208   put_gpr_dw0(r1, mkexpr(op2addr));
5209
5210   return "laey";
5211}
5212
5213static HChar *
5214s390_irgen_LARL(UChar r1, UInt i2)
5215{
5216   put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5217
5218   return "larl";
5219}
5220
5221static HChar *
5222s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5223{
5224   IRTemp op2 = newTemp(Ity_I32);
5225   IRTemp op3 = newTemp(Ity_I32);
5226   IRTemp result = newTemp(Ity_I32);
5227
5228   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5229   assign(op3, get_gpr_w1(r3));
5230   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5231   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5232   store(mkexpr(op2addr), mkexpr(result));
5233   put_gpr_w1(r1, mkexpr(op2));
5234
5235   return "laa";
5236}
5237
5238static HChar *
5239s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5240{
5241   IRTemp op2 = newTemp(Ity_I64);
5242   IRTemp op3 = newTemp(Ity_I64);
5243   IRTemp result = newTemp(Ity_I64);
5244
5245   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5246   assign(op3, get_gpr_dw0(r3));
5247   assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5248   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5249   store(mkexpr(op2addr), mkexpr(result));
5250   put_gpr_dw0(r1, mkexpr(op2));
5251
5252   return "laag";
5253}
5254
5255static HChar *
5256s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5257{
5258   IRTemp op2 = newTemp(Ity_I32);
5259   IRTemp op3 = newTemp(Ity_I32);
5260   IRTemp result = newTemp(Ity_I32);
5261
5262   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5263   assign(op3, get_gpr_w1(r3));
5264   assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5265   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5266   store(mkexpr(op2addr), mkexpr(result));
5267   put_gpr_w1(r1, mkexpr(op2));
5268
5269   return "laal";
5270}
5271
5272static HChar *
5273s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5274{
5275   IRTemp op2 = newTemp(Ity_I64);
5276   IRTemp op3 = newTemp(Ity_I64);
5277   IRTemp result = newTemp(Ity_I64);
5278
5279   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5280   assign(op3, get_gpr_dw0(r3));
5281   assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5282   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5283   store(mkexpr(op2addr), mkexpr(result));
5284   put_gpr_dw0(r1, mkexpr(op2));
5285
5286   return "laalg";
5287}
5288
5289static HChar *
5290s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5291{
5292   IRTemp op2 = newTemp(Ity_I32);
5293   IRTemp op3 = newTemp(Ity_I32);
5294   IRTemp result = newTemp(Ity_I32);
5295
5296   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5297   assign(op3, get_gpr_w1(r3));
5298   assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5299   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5300   store(mkexpr(op2addr), mkexpr(result));
5301   put_gpr_w1(r1, mkexpr(op2));
5302
5303   return "lan";
5304}
5305
5306static HChar *
5307s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5308{
5309   IRTemp op2 = newTemp(Ity_I64);
5310   IRTemp op3 = newTemp(Ity_I64);
5311   IRTemp result = newTemp(Ity_I64);
5312
5313   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5314   assign(op3, get_gpr_dw0(r3));
5315   assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5316   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5317   store(mkexpr(op2addr), mkexpr(result));
5318   put_gpr_dw0(r1, mkexpr(op2));
5319
5320   return "lang";
5321}
5322
5323static HChar *
5324s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5325{
5326   IRTemp op2 = newTemp(Ity_I32);
5327   IRTemp op3 = newTemp(Ity_I32);
5328   IRTemp result = newTemp(Ity_I32);
5329
5330   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5331   assign(op3, get_gpr_w1(r3));
5332   assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5333   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5334   store(mkexpr(op2addr), mkexpr(result));
5335   put_gpr_w1(r1, mkexpr(op2));
5336
5337   return "lax";
5338}
5339
5340static HChar *
5341s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5342{
5343   IRTemp op2 = newTemp(Ity_I64);
5344   IRTemp op3 = newTemp(Ity_I64);
5345   IRTemp result = newTemp(Ity_I64);
5346
5347   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5348   assign(op3, get_gpr_dw0(r3));
5349   assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5350   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5351   store(mkexpr(op2addr), mkexpr(result));
5352   put_gpr_dw0(r1, mkexpr(op2));
5353
5354   return "laxg";
5355}
5356
5357static HChar *
5358s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5359{
5360   IRTemp op2 = newTemp(Ity_I32);
5361   IRTemp op3 = newTemp(Ity_I32);
5362   IRTemp result = newTemp(Ity_I32);
5363
5364   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5365   assign(op3, get_gpr_w1(r3));
5366   assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5367   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5368   store(mkexpr(op2addr), mkexpr(result));
5369   put_gpr_w1(r1, mkexpr(op2));
5370
5371   return "lao";
5372}
5373
5374static HChar *
5375s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5376{
5377   IRTemp op2 = newTemp(Ity_I64);
5378   IRTemp op3 = newTemp(Ity_I64);
5379   IRTemp result = newTemp(Ity_I64);
5380
5381   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5382   assign(op3, get_gpr_dw0(r3));
5383   assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5384   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5385   store(mkexpr(op2addr), mkexpr(result));
5386   put_gpr_dw0(r1, mkexpr(op2));
5387
5388   return "laog";
5389}
5390
5391static HChar *
5392s390_irgen_LTR(UChar r1, UChar r2)
5393{
5394   IRTemp op2 = newTemp(Ity_I32);
5395
5396   assign(op2, get_gpr_w1(r2));
5397   put_gpr_w1(r1, mkexpr(op2));
5398   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5399
5400   return "ltr";
5401}
5402
5403static HChar *
5404s390_irgen_LTGR(UChar r1, UChar r2)
5405{
5406   IRTemp op2 = newTemp(Ity_I64);
5407
5408   assign(op2, get_gpr_dw0(r2));
5409   put_gpr_dw0(r1, mkexpr(op2));
5410   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5411
5412   return "ltgr";
5413}
5414
5415static HChar *
5416s390_irgen_LTGFR(UChar r1, UChar r2)
5417{
5418   IRTemp op2 = newTemp(Ity_I64);
5419
5420   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5421   put_gpr_dw0(r1, mkexpr(op2));
5422   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5423
5424   return "ltgfr";
5425}
5426
5427static HChar *
5428s390_irgen_LT(UChar r1, IRTemp op2addr)
5429{
5430   IRTemp op2 = newTemp(Ity_I32);
5431
5432   assign(op2, load(Ity_I32, mkexpr(op2addr)));
5433   put_gpr_w1(r1, mkexpr(op2));
5434   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5435
5436   return "lt";
5437}
5438
5439static HChar *
5440s390_irgen_LTG(UChar r1, IRTemp op2addr)
5441{
5442   IRTemp op2 = newTemp(Ity_I64);
5443
5444   assign(op2, load(Ity_I64, mkexpr(op2addr)));
5445   put_gpr_dw0(r1, mkexpr(op2));
5446   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5447
5448   return "ltg";
5449}
5450
5451static HChar *
5452s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5453{
5454   IRTemp op2 = newTemp(Ity_I64);
5455
5456   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5457   put_gpr_dw0(r1, mkexpr(op2));
5458   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5459
5460   return "ltgf";
5461}
5462
5463static HChar *
5464s390_irgen_LBR(UChar r1, UChar r2)
5465{
5466   put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5467
5468   return "lbr";
5469}
5470
5471static HChar *
5472s390_irgen_LGBR(UChar r1, UChar r2)
5473{
5474   put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5475
5476   return "lgbr";
5477}
5478
5479static HChar *
5480s390_irgen_LB(UChar r1, IRTemp op2addr)
5481{
5482   put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5483
5484   return "lb";
5485}
5486
5487static HChar *
5488s390_irgen_LGB(UChar r1, IRTemp op2addr)
5489{
5490   put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5491
5492   return "lgb";
5493}
5494
5495static HChar *
5496s390_irgen_LBH(UChar r1, IRTemp op2addr)
5497{
5498   put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5499
5500   return "lbh";
5501}
5502
5503static HChar *
5504s390_irgen_LCR(UChar r1, UChar r2)
5505{
5506   Int op1;
5507   IRTemp op2 = newTemp(Ity_I32);
5508   IRTemp result = newTemp(Ity_I32);
5509
5510   op1 = 0;
5511   assign(op2, get_gpr_w1(r2));
5512   assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5513   put_gpr_w1(r1, mkexpr(result));
5514   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5515                       op1)), op2);
5516
5517   return "lcr";
5518}
5519
5520static HChar *
5521s390_irgen_LCGR(UChar r1, UChar r2)
5522{
5523   Long op1;
5524   IRTemp op2 = newTemp(Ity_I64);
5525   IRTemp result = newTemp(Ity_I64);
5526
5527   op1 = 0ULL;
5528   assign(op2, get_gpr_dw0(r2));
5529   assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5530   put_gpr_dw0(r1, mkexpr(result));
5531   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5532                       op1)), op2);
5533
5534   return "lcgr";
5535}
5536
5537static HChar *
5538s390_irgen_LCGFR(UChar r1, UChar r2)
5539{
5540   Long op1;
5541   IRTemp op2 = newTemp(Ity_I64);
5542   IRTemp result = newTemp(Ity_I64);
5543
5544   op1 = 0ULL;
5545   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5546   assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5547   put_gpr_dw0(r1, mkexpr(result));
5548   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5549                       op1)), op2);
5550
5551   return "lcgfr";
5552}
5553
5554static HChar *
5555s390_irgen_LHR(UChar r1, UChar r2)
5556{
5557   put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5558
5559   return "lhr";
5560}
5561
5562static HChar *
5563s390_irgen_LGHR(UChar r1, UChar r2)
5564{
5565   put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5566
5567   return "lghr";
5568}
5569
5570static HChar *
5571s390_irgen_LH(UChar r1, IRTemp op2addr)
5572{
5573   put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5574
5575   return "lh";
5576}
5577
5578static HChar *
5579s390_irgen_LHY(UChar r1, IRTemp op2addr)
5580{
5581   put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5582
5583   return "lhy";
5584}
5585
5586static HChar *
5587s390_irgen_LGH(UChar r1, IRTemp op2addr)
5588{
5589   put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5590
5591   return "lgh";
5592}
5593
5594static HChar *
5595s390_irgen_LHI(UChar r1, UShort i2)
5596{
5597   put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5598
5599   return "lhi";
5600}
5601
5602static HChar *
5603s390_irgen_LGHI(UChar r1, UShort i2)
5604{
5605   put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5606
5607   return "lghi";
5608}
5609
5610static HChar *
5611s390_irgen_LHRL(UChar r1, UInt i2)
5612{
5613   put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5614              ((ULong)(Long)(Int)i2 << 1)))));
5615
5616   return "lhrl";
5617}
5618
5619static HChar *
5620s390_irgen_LGHRL(UChar r1, UInt i2)
5621{
5622   put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5623               ((ULong)(Long)(Int)i2 << 1)))));
5624
5625   return "lghrl";
5626}
5627
5628static HChar *
5629s390_irgen_LHH(UChar r1, IRTemp op2addr)
5630{
5631   put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5632
5633   return "lhh";
5634}
5635
5636static HChar *
5637s390_irgen_LFH(UChar r1, IRTemp op2addr)
5638{
5639   put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5640
5641   return "lfh";
5642}
5643
5644static HChar *
5645s390_irgen_LLGFR(UChar r1, UChar r2)
5646{
5647   put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5648
5649   return "llgfr";
5650}
5651
5652static HChar *
5653s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5654{
5655   put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5656
5657   return "llgf";
5658}
5659
5660static HChar *
5661s390_irgen_LLGFRL(UChar r1, UInt i2)
5662{
5663   put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5664               ((ULong)(Long)(Int)i2 << 1)))));
5665
5666   return "llgfrl";
5667}
5668
5669static HChar *
5670s390_irgen_LLCR(UChar r1, UChar r2)
5671{
5672   put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5673
5674   return "llcr";
5675}
5676
5677static HChar *
5678s390_irgen_LLGCR(UChar r1, UChar r2)
5679{
5680   put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5681
5682   return "llgcr";
5683}
5684
5685static HChar *
5686s390_irgen_LLC(UChar r1, IRTemp op2addr)
5687{
5688   put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5689
5690   return "llc";
5691}
5692
5693static HChar *
5694s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5695{
5696   put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5697
5698   return "llgc";
5699}
5700
5701static HChar *
5702s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5703{
5704   put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5705
5706   return "llch";
5707}
5708
5709static HChar *
5710s390_irgen_LLHR(UChar r1, UChar r2)
5711{
5712   put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5713
5714   return "llhr";
5715}
5716
5717static HChar *
5718s390_irgen_LLGHR(UChar r1, UChar r2)
5719{
5720   put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5721
5722   return "llghr";
5723}
5724
5725static HChar *
5726s390_irgen_LLH(UChar r1, IRTemp op2addr)
5727{
5728   put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5729
5730   return "llh";
5731}
5732
5733static HChar *
5734s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5735{
5736   put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5737
5738   return "llgh";
5739}
5740
5741static HChar *
5742s390_irgen_LLHRL(UChar r1, UInt i2)
5743{
5744   put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5745              ((ULong)(Long)(Int)i2 << 1)))));
5746
5747   return "llhrl";
5748}
5749
5750static HChar *
5751s390_irgen_LLGHRL(UChar r1, UInt i2)
5752{
5753   put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5754               ((ULong)(Long)(Int)i2 << 1)))));
5755
5756   return "llghrl";
5757}
5758
5759static HChar *
5760s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5761{
5762   put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5763
5764   return "llhh";
5765}
5766
5767static HChar *
5768s390_irgen_LLIHF(UChar r1, UInt i2)
5769{
5770   put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5771
5772   return "llihf";
5773}
5774
5775static HChar *
5776s390_irgen_LLIHH(UChar r1, UShort i2)
5777{
5778   put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5779
5780   return "llihh";
5781}
5782
5783static HChar *
5784s390_irgen_LLIHL(UChar r1, UShort i2)
5785{
5786   put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5787
5788   return "llihl";
5789}
5790
5791static HChar *
5792s390_irgen_LLILF(UChar r1, UInt i2)
5793{
5794   put_gpr_dw0(r1, mkU64(i2));
5795
5796   return "llilf";
5797}
5798
5799static HChar *
5800s390_irgen_LLILH(UChar r1, UShort i2)
5801{
5802   put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
5803
5804   return "llilh";
5805}
5806
5807static HChar *
5808s390_irgen_LLILL(UChar r1, UShort i2)
5809{
5810   put_gpr_dw0(r1, mkU64(i2));
5811
5812   return "llill";
5813}
5814
5815static HChar *
5816s390_irgen_LLGTR(UChar r1, UChar r2)
5817{
5818   put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
5819               mkU32(2147483647))));
5820
5821   return "llgtr";
5822}
5823
5824static HChar *
5825s390_irgen_LLGT(UChar r1, IRTemp op2addr)
5826{
5827   put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
5828               mkexpr(op2addr)), mkU32(2147483647))));
5829
5830   return "llgt";
5831}
5832
5833static HChar *
5834s390_irgen_LNR(UChar r1, UChar r2)
5835{
5836   IRTemp op2 = newTemp(Ity_I32);
5837   IRTemp result = newTemp(Ity_I32);
5838
5839   assign(op2, get_gpr_w1(r2));
5840   assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
5841          binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
5842   put_gpr_w1(r1, mkexpr(result));
5843   s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5844
5845   return "lnr";
5846}
5847
5848static HChar *
5849s390_irgen_LNGR(UChar r1, UChar r2)
5850{
5851   IRTemp op2 = newTemp(Ity_I64);
5852   IRTemp result = newTemp(Ity_I64);
5853
5854   assign(op2, get_gpr_dw0(r2));
5855   assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5856          binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5857   put_gpr_dw0(r1, mkexpr(result));
5858   s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5859
5860   return "lngr";
5861}
5862
5863static HChar *
5864s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
5865{
5866   IRTemp op2 = newTemp(Ity_I64);
5867   IRTemp result = newTemp(Ity_I64);
5868
5869   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
5870   assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5871          binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5872   put_gpr_dw0(r1, mkexpr(result));
5873   s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5874
5875   return "lngfr";
5876}
5877
5878static HChar *
5879s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
5880{
5881   next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
5882   put_gpr_w1(r1, get_gpr_w1(r2));
5883
5884   return "locr";
5885}
5886
5887static HChar *
5888s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
5889{
5890   next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
5891   put_gpr_dw0(r1, get_gpr_dw0(r2));
5892
5893   return "locgr";
5894}
5895
5896static HChar *
5897s390_irgen_LOC(UChar r1, IRTemp op2addr)
5898{
5899   /* condition is checked in format handler */
5900   put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5901
5902   return "loc";
5903}
5904
5905static HChar *
5906s390_irgen_LOCG(UChar r1, IRTemp op2addr)
5907{
5908   /* condition is checked in format handler */
5909   put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5910
5911   return "locg";
5912}
5913
5914static HChar *
5915s390_irgen_LPQ(UChar r1, IRTemp op2addr)
5916{
5917   put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5918   put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
5919               ));
5920
5921   return "lpq";
5922}
5923
5924static HChar *
5925s390_irgen_LPR(UChar r1, UChar r2)
5926{
5927   IRTemp op2 = newTemp(Ity_I32);
5928   IRTemp result = newTemp(Ity_I32);
5929
5930   assign(op2, get_gpr_w1(r2));
5931   assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
5932          binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
5933   put_gpr_w1(r1, mkexpr(result));
5934   s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
5935
5936   return "lpr";
5937}
5938
5939static HChar *
5940s390_irgen_LPGR(UChar r1, UChar r2)
5941{
5942   IRTemp op2 = newTemp(Ity_I64);
5943   IRTemp result = newTemp(Ity_I64);
5944
5945   assign(op2, get_gpr_dw0(r2));
5946   assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5947          binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5948   put_gpr_dw0(r1, mkexpr(result));
5949   s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5950
5951   return "lpgr";
5952}
5953
5954static HChar *
5955s390_irgen_LPGFR(UChar r1, UChar r2)
5956{
5957   IRTemp op2 = newTemp(Ity_I64);
5958   IRTemp result = newTemp(Ity_I64);
5959
5960   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5961   assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5962          binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5963   put_gpr_dw0(r1, mkexpr(result));
5964   s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5965
5966   return "lpgfr";
5967}
5968
5969static HChar *
5970s390_irgen_LRVR(UChar r1, UChar r2)
5971{
5972   IRTemp b0 = newTemp(Ity_I8);
5973   IRTemp b1 = newTemp(Ity_I8);
5974   IRTemp b2 = newTemp(Ity_I8);
5975   IRTemp b3 = newTemp(Ity_I8);
5976
5977   assign(b3, get_gpr_b7(r2));
5978   assign(b2, get_gpr_b6(r2));
5979   assign(b1, get_gpr_b5(r2));
5980   assign(b0, get_gpr_b4(r2));
5981   put_gpr_b4(r1, mkexpr(b3));
5982   put_gpr_b5(r1, mkexpr(b2));
5983   put_gpr_b6(r1, mkexpr(b1));
5984   put_gpr_b7(r1, mkexpr(b0));
5985
5986   return "lrvr";
5987}
5988
5989static HChar *
5990s390_irgen_LRVGR(UChar r1, UChar r2)
5991{
5992   IRTemp b0 = newTemp(Ity_I8);
5993   IRTemp b1 = newTemp(Ity_I8);
5994   IRTemp b2 = newTemp(Ity_I8);
5995   IRTemp b3 = newTemp(Ity_I8);
5996   IRTemp b4 = newTemp(Ity_I8);
5997   IRTemp b5 = newTemp(Ity_I8);
5998   IRTemp b6 = newTemp(Ity_I8);
5999   IRTemp b7 = newTemp(Ity_I8);
6000
6001   assign(b7, get_gpr_b7(r2));
6002   assign(b6, get_gpr_b6(r2));
6003   assign(b5, get_gpr_b5(r2));
6004   assign(b4, get_gpr_b4(r2));
6005   assign(b3, get_gpr_b3(r2));
6006   assign(b2, get_gpr_b2(r2));
6007   assign(b1, get_gpr_b1(r2));
6008   assign(b0, get_gpr_b0(r2));
6009   put_gpr_b0(r1, mkexpr(b7));
6010   put_gpr_b1(r1, mkexpr(b6));
6011   put_gpr_b2(r1, mkexpr(b5));
6012   put_gpr_b3(r1, mkexpr(b4));
6013   put_gpr_b4(r1, mkexpr(b3));
6014   put_gpr_b5(r1, mkexpr(b2));
6015   put_gpr_b6(r1, mkexpr(b1));
6016   put_gpr_b7(r1, mkexpr(b0));
6017
6018   return "lrvgr";
6019}
6020
6021static HChar *
6022s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6023{
6024   IRTemp op2 = newTemp(Ity_I16);
6025
6026   assign(op2, load(Ity_I16, mkexpr(op2addr)));
6027   put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6028   put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6029
6030   return "lrvh";
6031}
6032
6033static HChar *
6034s390_irgen_LRV(UChar r1, IRTemp op2addr)
6035{
6036   IRTemp op2 = newTemp(Ity_I32);
6037
6038   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6039   put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6040   put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6041              mkU8(8)), mkU32(255))));
6042   put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6043              mkU8(16)), mkU32(255))));
6044   put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6045              mkU8(24)), mkU32(255))));
6046
6047   return "lrv";
6048}
6049
6050static HChar *
6051s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6052{
6053   IRTemp op2 = newTemp(Ity_I64);
6054
6055   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6056   put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6057   put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6058              mkU8(8)), mkU64(255))));
6059   put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6060              mkU8(16)), mkU64(255))));
6061   put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6062              mkU8(24)), mkU64(255))));
6063   put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6064              mkU8(32)), mkU64(255))));
6065   put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6066              mkU8(40)), mkU64(255))));
6067   put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6068              mkU8(48)), mkU64(255))));
6069   put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6070              mkU8(56)), mkU64(255))));
6071
6072   return "lrvg";
6073}
6074
6075static HChar *
6076s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6077{
6078   store(mkexpr(op1addr), mkU16(i2));
6079
6080   return "mvhhi";
6081}
6082
6083static HChar *
6084s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6085{
6086   store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6087
6088   return "mvhi";
6089}
6090
6091static HChar *
6092s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6093{
6094   store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6095
6096   return "mvghi";
6097}
6098
6099static HChar *
6100s390_irgen_MVI(UChar i2, IRTemp op1addr)
6101{
6102   store(mkexpr(op1addr), mkU8(i2));
6103
6104   return "mvi";
6105}
6106
6107static HChar *
6108s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6109{
6110   store(mkexpr(op1addr), mkU8(i2));
6111
6112   return "mviy";
6113}
6114
6115static HChar *
6116s390_irgen_MR(UChar r1, UChar r2)
6117{
6118   IRTemp op1 = newTemp(Ity_I32);
6119   IRTemp op2 = newTemp(Ity_I32);
6120   IRTemp result = newTemp(Ity_I64);
6121
6122   assign(op1, get_gpr_w1(r1 + 1));
6123   assign(op2, get_gpr_w1(r2));
6124   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6125   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6126   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6127
6128   return "mr";
6129}
6130
6131static HChar *
6132s390_irgen_M(UChar r1, IRTemp op2addr)
6133{
6134   IRTemp op1 = newTemp(Ity_I32);
6135   IRTemp op2 = newTemp(Ity_I32);
6136   IRTemp result = newTemp(Ity_I64);
6137
6138   assign(op1, get_gpr_w1(r1 + 1));
6139   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6140   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6141   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6142   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6143
6144   return "m";
6145}
6146
6147static HChar *
6148s390_irgen_MFY(UChar r1, IRTemp op2addr)
6149{
6150   IRTemp op1 = newTemp(Ity_I32);
6151   IRTemp op2 = newTemp(Ity_I32);
6152   IRTemp result = newTemp(Ity_I64);
6153
6154   assign(op1, get_gpr_w1(r1 + 1));
6155   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6156   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6157   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6158   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6159
6160   return "mfy";
6161}
6162
6163static HChar *
6164s390_irgen_MH(UChar r1, IRTemp op2addr)
6165{
6166   IRTemp op1 = newTemp(Ity_I32);
6167   IRTemp op2 = newTemp(Ity_I16);
6168   IRTemp result = newTemp(Ity_I64);
6169
6170   assign(op1, get_gpr_w1(r1));
6171   assign(op2, load(Ity_I16, mkexpr(op2addr)));
6172   assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6173          ));
6174   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6175
6176   return "mh";
6177}
6178
6179static HChar *
6180s390_irgen_MHY(UChar r1, IRTemp op2addr)
6181{
6182   IRTemp op1 = newTemp(Ity_I32);
6183   IRTemp op2 = newTemp(Ity_I16);
6184   IRTemp result = newTemp(Ity_I64);
6185
6186   assign(op1, get_gpr_w1(r1));
6187   assign(op2, load(Ity_I16, mkexpr(op2addr)));
6188   assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6189          ));
6190   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6191
6192   return "mhy";
6193}
6194
6195static HChar *
6196s390_irgen_MHI(UChar r1, UShort i2)
6197{
6198   IRTemp op1 = newTemp(Ity_I32);
6199   Short op2;
6200   IRTemp result = newTemp(Ity_I64);
6201
6202   assign(op1, get_gpr_w1(r1));
6203   op2 = (Short)i2;
6204   assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6205          mkU16((UShort)op2))));
6206   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6207
6208   return "mhi";
6209}
6210
6211static HChar *
6212s390_irgen_MGHI(UChar r1, UShort i2)
6213{
6214   IRTemp op1 = newTemp(Ity_I64);
6215   Short op2;
6216   IRTemp result = newTemp(Ity_I128);
6217
6218   assign(op1, get_gpr_dw0(r1));
6219   op2 = (Short)i2;
6220   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6221          mkU16((UShort)op2))));
6222   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6223
6224   return "mghi";
6225}
6226
6227static HChar *
6228s390_irgen_MLR(UChar r1, UChar r2)
6229{
6230   IRTemp op1 = newTemp(Ity_I32);
6231   IRTemp op2 = newTemp(Ity_I32);
6232   IRTemp result = newTemp(Ity_I64);
6233
6234   assign(op1, get_gpr_w1(r1 + 1));
6235   assign(op2, get_gpr_w1(r2));
6236   assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6237   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6238   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6239
6240   return "mlr";
6241}
6242
6243static HChar *
6244s390_irgen_MLGR(UChar r1, UChar r2)
6245{
6246   IRTemp op1 = newTemp(Ity_I64);
6247   IRTemp op2 = newTemp(Ity_I64);
6248   IRTemp result = newTemp(Ity_I128);
6249
6250   assign(op1, get_gpr_dw0(r1 + 1));
6251   assign(op2, get_gpr_dw0(r2));
6252   assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6253   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6254   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6255
6256   return "mlgr";
6257}
6258
6259static HChar *
6260s390_irgen_ML(UChar r1, IRTemp op2addr)
6261{
6262   IRTemp op1 = newTemp(Ity_I32);
6263   IRTemp op2 = newTemp(Ity_I32);
6264   IRTemp result = newTemp(Ity_I64);
6265
6266   assign(op1, get_gpr_w1(r1 + 1));
6267   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6268   assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6269   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6270   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6271
6272   return "ml";
6273}
6274
6275static HChar *
6276s390_irgen_MLG(UChar r1, IRTemp op2addr)
6277{
6278   IRTemp op1 = newTemp(Ity_I64);
6279   IRTemp op2 = newTemp(Ity_I64);
6280   IRTemp result = newTemp(Ity_I128);
6281
6282   assign(op1, get_gpr_dw0(r1 + 1));
6283   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6284   assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6285   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6286   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6287
6288   return "mlg";
6289}
6290
6291static HChar *
6292s390_irgen_MSR(UChar r1, UChar r2)
6293{
6294   IRTemp op1 = newTemp(Ity_I32);
6295   IRTemp op2 = newTemp(Ity_I32);
6296   IRTemp result = newTemp(Ity_I64);
6297
6298   assign(op1, get_gpr_w1(r1));
6299   assign(op2, get_gpr_w1(r2));
6300   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6301   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6302
6303   return "msr";
6304}
6305
6306static HChar *
6307s390_irgen_MSGR(UChar r1, UChar r2)
6308{
6309   IRTemp op1 = newTemp(Ity_I64);
6310   IRTemp op2 = newTemp(Ity_I64);
6311   IRTemp result = newTemp(Ity_I128);
6312
6313   assign(op1, get_gpr_dw0(r1));
6314   assign(op2, get_gpr_dw0(r2));
6315   assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6316   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6317
6318   return "msgr";
6319}
6320
6321static HChar *
6322s390_irgen_MSGFR(UChar r1, UChar r2)
6323{
6324   IRTemp op1 = newTemp(Ity_I64);
6325   IRTemp op2 = newTemp(Ity_I32);
6326   IRTemp result = newTemp(Ity_I128);
6327
6328   assign(op1, get_gpr_dw0(r1));
6329   assign(op2, get_gpr_w1(r2));
6330   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6331          ));
6332   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6333
6334   return "msgfr";
6335}
6336
6337static HChar *
6338s390_irgen_MS(UChar r1, IRTemp op2addr)
6339{
6340   IRTemp op1 = newTemp(Ity_I32);
6341   IRTemp op2 = newTemp(Ity_I32);
6342   IRTemp result = newTemp(Ity_I64);
6343
6344   assign(op1, get_gpr_w1(r1));
6345   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6346   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6347   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6348
6349   return "ms";
6350}
6351
6352static HChar *
6353s390_irgen_MSY(UChar r1, IRTemp op2addr)
6354{
6355   IRTemp op1 = newTemp(Ity_I32);
6356   IRTemp op2 = newTemp(Ity_I32);
6357   IRTemp result = newTemp(Ity_I64);
6358
6359   assign(op1, get_gpr_w1(r1));
6360   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6361   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6362   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6363
6364   return "msy";
6365}
6366
6367static HChar *
6368s390_irgen_MSG(UChar r1, IRTemp op2addr)
6369{
6370   IRTemp op1 = newTemp(Ity_I64);
6371   IRTemp op2 = newTemp(Ity_I64);
6372   IRTemp result = newTemp(Ity_I128);
6373
6374   assign(op1, get_gpr_dw0(r1));
6375   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6376   assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6377   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6378
6379   return "msg";
6380}
6381
6382static HChar *
6383s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6384{
6385   IRTemp op1 = newTemp(Ity_I64);
6386   IRTemp op2 = newTemp(Ity_I32);
6387   IRTemp result = newTemp(Ity_I128);
6388
6389   assign(op1, get_gpr_dw0(r1));
6390   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6391   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6392          ));
6393   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6394
6395   return "msgf";
6396}
6397
6398static HChar *
6399s390_irgen_MSFI(UChar r1, UInt i2)
6400{
6401   IRTemp op1 = newTemp(Ity_I32);
6402   Int op2;
6403   IRTemp result = newTemp(Ity_I64);
6404
6405   assign(op1, get_gpr_w1(r1));
6406   op2 = (Int)i2;
6407   assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6408   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6409
6410   return "msfi";
6411}
6412
6413static HChar *
6414s390_irgen_MSGFI(UChar r1, UInt i2)
6415{
6416   IRTemp op1 = newTemp(Ity_I64);
6417   Int op2;
6418   IRTemp result = newTemp(Ity_I128);
6419
6420   assign(op1, get_gpr_dw0(r1));
6421   op2 = (Int)i2;
6422   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6423          op2))));
6424   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6425
6426   return "msgfi";
6427}
6428
6429static HChar *
6430s390_irgen_OR(UChar r1, UChar r2)
6431{
6432   IRTemp op1 = newTemp(Ity_I32);
6433   IRTemp op2 = newTemp(Ity_I32);
6434   IRTemp result = newTemp(Ity_I32);
6435
6436   assign(op1, get_gpr_w1(r1));
6437   assign(op2, get_gpr_w1(r2));
6438   assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6439   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6440   put_gpr_w1(r1, mkexpr(result));
6441
6442   return "or";
6443}
6444
6445static HChar *
6446s390_irgen_OGR(UChar r1, UChar r2)
6447{
6448   IRTemp op1 = newTemp(Ity_I64);
6449   IRTemp op2 = newTemp(Ity_I64);
6450   IRTemp result = newTemp(Ity_I64);
6451
6452   assign(op1, get_gpr_dw0(r1));
6453   assign(op2, get_gpr_dw0(r2));
6454   assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6455   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6456   put_gpr_dw0(r1, mkexpr(result));
6457
6458   return "ogr";
6459}
6460
6461static HChar *
6462s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6463{
6464   IRTemp op2 = newTemp(Ity_I32);
6465   IRTemp op3 = newTemp(Ity_I32);
6466   IRTemp result = newTemp(Ity_I32);
6467
6468   assign(op2, get_gpr_w1(r2));
6469   assign(op3, get_gpr_w1(r3));
6470   assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6471   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6472   put_gpr_w1(r1, mkexpr(result));
6473
6474   return "ork";
6475}
6476
6477static HChar *
6478s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6479{
6480   IRTemp op2 = newTemp(Ity_I64);
6481   IRTemp op3 = newTemp(Ity_I64);
6482   IRTemp result = newTemp(Ity_I64);
6483
6484   assign(op2, get_gpr_dw0(r2));
6485   assign(op3, get_gpr_dw0(r3));
6486   assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6487   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6488   put_gpr_dw0(r1, mkexpr(result));
6489
6490   return "ogrk";
6491}
6492
6493static HChar *
6494s390_irgen_O(UChar r1, IRTemp op2addr)
6495{
6496   IRTemp op1 = newTemp(Ity_I32);
6497   IRTemp op2 = newTemp(Ity_I32);
6498   IRTemp result = newTemp(Ity_I32);
6499
6500   assign(op1, get_gpr_w1(r1));
6501   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6502   assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6503   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6504   put_gpr_w1(r1, mkexpr(result));
6505
6506   return "o";
6507}
6508
6509static HChar *
6510s390_irgen_OY(UChar r1, IRTemp op2addr)
6511{
6512   IRTemp op1 = newTemp(Ity_I32);
6513   IRTemp op2 = newTemp(Ity_I32);
6514   IRTemp result = newTemp(Ity_I32);
6515
6516   assign(op1, get_gpr_w1(r1));
6517   assign(op2, load(Ity_I32, mkexpr(op2addr)));
6518   assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6519   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6520   put_gpr_w1(r1, mkexpr(result));
6521
6522   return "oy";
6523}
6524
6525static HChar *
6526s390_irgen_OG(UChar r1, IRTemp op2addr)
6527{
6528   IRTemp op1 = newTemp(Ity_I64);
6529   IRTemp op2 = newTemp(Ity_I64);
6530   IRTemp result = newTemp(Ity_I64);
6531
6532   assign(op1, get_gpr_dw0(r1));
6533   assign(op2, load(Ity_I64, mkexpr(op2addr)));
6534   assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6535   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6536   put_gpr_dw0(r1, mkexpr(result));
6537
6538   return "og";
6539}
6540
6541static HChar *
6542s390_irgen_OI(UChar i2, IRTemp op1addr)
6543{
6544   IRTemp op1 = newTemp(Ity_I8);
6545   UChar op2;
6546   IRTemp result = newTemp(Ity_I8);
6547
6548   assign(op1, load(Ity_I8, mkexpr(op1addr)));
6549   op2 = i2;
6550   assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6551   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6552   store(mkexpr(op1addr), mkexpr(result));
6553
6554   return "oi";
6555}
6556
6557static HChar *
6558s390_irgen_OIY(UChar i2, IRTemp op1addr)
6559{
6560   IRTemp op1 = newTemp(Ity_I8);
6561   UChar op2;
6562   IRTemp result = newTemp(Ity_I8);
6563
6564   assign(op1, load(Ity_I8, mkexpr(op1addr)));
6565   op2 = i2;
6566   assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6567   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6568   store(mkexpr(op1addr), mkexpr(result));
6569
6570   return "oiy";
6571}
6572
6573static HChar *
6574s390_irgen_OIHF(UChar r1, UInt i2)
6575{
6576   IRTemp op1 = newTemp(Ity_I32);
6577   UInt op2;
6578   IRTemp result = newTemp(Ity_I32);
6579
6580   assign(op1, get_gpr_w0(r1));
6581   op2 = i2;
6582   assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6583   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6584   put_gpr_w0(r1, mkexpr(result));
6585
6586   return "oihf";
6587}
6588
6589static HChar *
6590s390_irgen_OIHH(UChar r1, UShort i2)
6591{
6592   IRTemp op1 = newTemp(Ity_I16);
6593   UShort op2;
6594   IRTemp result = newTemp(Ity_I16);
6595
6596   assign(op1, get_gpr_hw0(r1));
6597   op2 = i2;
6598   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6599   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6600   put_gpr_hw0(r1, mkexpr(result));
6601
6602   return "oihh";
6603}
6604
6605static HChar *
6606s390_irgen_OIHL(UChar r1, UShort i2)
6607{
6608   IRTemp op1 = newTemp(Ity_I16);
6609   UShort op2;
6610   IRTemp result = newTemp(Ity_I16);
6611
6612   assign(op1, get_gpr_hw1(r1));
6613   op2 = i2;
6614   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6615   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6616   put_gpr_hw1(r1, mkexpr(result));
6617
6618   return "oihl";
6619}
6620
6621static HChar *
6622s390_irgen_OILF(UChar r1, UInt i2)
6623{
6624   IRTemp op1 = newTemp(Ity_I32);
6625   UInt op2;
6626   IRTemp result = newTemp(Ity_I32);
6627
6628   assign(op1, get_gpr_w1(r1));
6629   op2 = i2;
6630   assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6631   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6632   put_gpr_w1(r1, mkexpr(result));
6633
6634   return "oilf";
6635}
6636
6637static HChar *
6638s390_irgen_OILH(UChar r1, UShort i2)
6639{
6640   IRTemp op1 = newTemp(Ity_I16);
6641   UShort op2;
6642   IRTemp result = newTemp(Ity_I16);
6643
6644   assign(op1, get_gpr_hw2(r1));
6645   op2 = i2;
6646   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6647   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6648   put_gpr_hw2(r1, mkexpr(result));
6649
6650   return "oilh";
6651}
6652
6653static HChar *
6654s390_irgen_OILL(UChar r1, UShort i2)
6655{
6656   IRTemp op1 = newTemp(Ity_I16);
6657   UShort op2;
6658   IRTemp result = newTemp(Ity_I16);
6659
6660   assign(op1, get_gpr_hw3(r1));
6661   op2 = i2;
6662   assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6663   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6664   put_gpr_hw3(r1, mkexpr(result));
6665
6666   return "oill";
6667}
6668
6669static HChar *
6670s390_irgen_PFD(void)
6671{
6672
6673   return "pfd";
6674}
6675
6676static HChar *
6677s390_irgen_PFDRL(void)
6678{
6679
6680   return "pfdrl";
6681}
6682
6683static HChar *
6684s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6685{
6686   IRTemp amount = newTemp(Ity_I64);
6687   IRTemp op = newTemp(Ity_I32);
6688
6689   assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6690   assign(op, get_gpr_w1(r3));
6691   put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6692              mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6693              binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6694
6695   return "rll";
6696}
6697
6698static HChar *
6699s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6700{
6701   IRTemp amount = newTemp(Ity_I64);
6702   IRTemp op = newTemp(Ity_I64);
6703
6704   assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6705   assign(op, get_gpr_dw0(r3));
6706   put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6707               mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6708               binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6709
6710   return "rllg";
6711}
6712
6713static HChar *
6714s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6715{
6716   UChar from;
6717   UChar to;
6718   UChar rot;
6719   UChar t_bit;
6720   ULong mask;
6721   ULong maskc;
6722   IRTemp result = newTemp(Ity_I64);
6723   IRTemp op2 = newTemp(Ity_I64);
6724
6725   from = i3 & 63;
6726   to = i4 & 63;
6727   rot = i5 & 63;
6728   t_bit = i3 & 128;
6729   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6730          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6731          mkU8(64 - rot))));
6732   if (from <= to) {
6733      mask = ~0ULL;
6734      mask = (mask >> from) & (mask << (63 - to));
6735      maskc = ~mask;
6736   } else {
6737      maskc = ~0ULL;
6738      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6739      mask = ~maskc;
6740   }
6741   assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6742          ), mkU64(mask)));
6743   if (t_bit == 0) {
6744      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6745                  mkU64(maskc)), mkexpr(result)));
6746   }
6747   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6748
6749   return "rnsbg";
6750}
6751
6752static HChar *
6753s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6754{
6755   UChar from;
6756   UChar to;
6757   UChar rot;
6758   UChar t_bit;
6759   ULong mask;
6760   ULong maskc;
6761   IRTemp result = newTemp(Ity_I64);
6762   IRTemp op2 = newTemp(Ity_I64);
6763
6764   from = i3 & 63;
6765   to = i4 & 63;
6766   rot = i5 & 63;
6767   t_bit = i3 & 128;
6768   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6769          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6770          mkU8(64 - rot))));
6771   if (from <= to) {
6772      mask = ~0ULL;
6773      mask = (mask >> from) & (mask << (63 - to));
6774      maskc = ~mask;
6775   } else {
6776      maskc = ~0ULL;
6777      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6778      mask = ~maskc;
6779   }
6780   assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6781          ), mkU64(mask)));
6782   if (t_bit == 0) {
6783      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6784                  mkU64(maskc)), mkexpr(result)));
6785   }
6786   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6787
6788   return "rxsbg";
6789}
6790
6791static HChar *
6792s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6793{
6794   UChar from;
6795   UChar to;
6796   UChar rot;
6797   UChar t_bit;
6798   ULong mask;
6799   ULong maskc;
6800   IRTemp result = newTemp(Ity_I64);
6801   IRTemp op2 = newTemp(Ity_I64);
6802
6803   from = i3 & 63;
6804   to = i4 & 63;
6805   rot = i5 & 63;
6806   t_bit = i3 & 128;
6807   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6808          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6809          mkU8(64 - rot))));
6810   if (from <= to) {
6811      mask = ~0ULL;
6812      mask = (mask >> from) & (mask << (63 - to));
6813      maskc = ~mask;
6814   } else {
6815      maskc = ~0ULL;
6816      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6817      mask = ~maskc;
6818   }
6819   assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
6820          ), mkU64(mask)));
6821   if (t_bit == 0) {
6822      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6823                  mkU64(maskc)), mkexpr(result)));
6824   }
6825   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6826
6827   return "rosbg";
6828}
6829
6830static HChar *
6831s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6832{
6833   UChar from;
6834   UChar to;
6835   UChar rot;
6836   UChar z_bit;
6837   ULong mask;
6838   ULong maskc;
6839   IRTemp op2 = newTemp(Ity_I64);
6840   IRTemp result = newTemp(Ity_I64);
6841
6842   from = i3 & 63;
6843   to = i4 & 63;
6844   rot = i5 & 63;
6845   z_bit = i4 & 128;
6846   assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6847          get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6848          mkU8(64 - rot))));
6849   if (from <= to) {
6850      mask = ~0ULL;
6851      mask = (mask >> from) & (mask << (63 - to));
6852      maskc = ~mask;
6853   } else {
6854      maskc = ~0ULL;
6855      maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6856      mask = ~maskc;
6857   }
6858   if (z_bit == 0) {
6859      put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6860                  mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
6861   } else {
6862      put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
6863   }
6864   assign(result, get_gpr_dw0(r1));
6865   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
6866
6867   return "risbg";
6868}
6869
6870static HChar *
6871s390_irgen_SAR(UChar r1, UChar r2)
6872{
6873   put_ar_w0(r1, get_gpr_w1(r2));
6874   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
6875      s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
6876
6877   return "sar";
6878}
6879
6880static HChar *
6881s390_irgen_SLDA(UChar r1, IRTemp op2addr)
6882{
6883   IRTemp p1 = newTemp(Ity_I64);
6884   IRTemp p2 = newTemp(Ity_I64);
6885   IRTemp op = newTemp(Ity_I64);
6886   IRTemp result = newTemp(Ity_I64);
6887   ULong sign_mask;
6888   IRTemp shift_amount = newTemp(Ity_I64);
6889
6890   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6891   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6892   assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
6893          ));
6894   sign_mask = 1ULL << 63;
6895   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6896   assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
6897          unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6898          binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
6899   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6900   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6901   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6902
6903   return "slda";
6904}
6905
6906static HChar *
6907s390_irgen_SLDL(UChar r1, IRTemp op2addr)
6908{
6909   IRTemp p1 = newTemp(Ity_I64);
6910   IRTemp p2 = newTemp(Ity_I64);
6911   IRTemp result = newTemp(Ity_I64);
6912
6913   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6914   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6915   assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
6916          mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
6917          mkexpr(op2addr), mkU64(63)))));
6918   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6919   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6920
6921   return "sldl";
6922}
6923
6924static HChar *
6925s390_irgen_SLA(UChar r1, IRTemp op2addr)
6926{
6927   IRTemp uop = newTemp(Ity_I32);
6928   IRTemp result = newTemp(Ity_I32);
6929   UInt sign_mask;
6930   IRTemp shift_amount = newTemp(Ity_I64);
6931   IRTemp op = newTemp(Ity_I32);
6932
6933   assign(op, get_gpr_w1(r1));
6934   assign(uop, get_gpr_w1(r1));
6935   sign_mask = 2147483648U;
6936   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6937   assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6938          unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6939          binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6940   put_gpr_w1(r1, mkexpr(result));
6941   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6942
6943   return "sla";
6944}
6945
6946static HChar *
6947s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
6948{
6949   IRTemp uop = newTemp(Ity_I32);
6950   IRTemp result = newTemp(Ity_I32);
6951   UInt sign_mask;
6952   IRTemp shift_amount = newTemp(Ity_I64);
6953   IRTemp op = newTemp(Ity_I32);
6954
6955   assign(op, get_gpr_w1(r3));
6956   assign(uop, get_gpr_w1(r3));
6957   sign_mask = 2147483648U;
6958   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6959   assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6960          unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6961          binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6962   put_gpr_w1(r1, mkexpr(result));
6963   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6964
6965   return "slak";
6966}
6967
6968static HChar *
6969s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
6970{
6971   IRTemp uop = newTemp(Ity_I64);
6972   IRTemp result = newTemp(Ity_I64);
6973   ULong sign_mask;
6974   IRTemp shift_amount = newTemp(Ity_I64);
6975   IRTemp op = newTemp(Ity_I64);
6976
6977   assign(op, get_gpr_dw0(r3));
6978   assign(uop, get_gpr_dw0(r3));
6979   sign_mask = 9223372036854775808ULL;
6980   assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6981   assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
6982          unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6983          binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
6984   put_gpr_dw0(r1, mkexpr(result));
6985   s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6986
6987   return "slag";
6988}
6989
6990static HChar *
6991s390_irgen_SLL(UChar r1, IRTemp op2addr)
6992{
6993   put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
6994              binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
6995
6996   return "sll";
6997}
6998
6999static HChar *
7000s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7001{
7002   put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7003              binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7004
7005   return "sllk";
7006}
7007
7008static HChar *
7009s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7010{
7011   put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7012               binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7013
7014   return "sllg";
7015}
7016
7017static HChar *
7018s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7019{
7020   IRTemp p1 = newTemp(Ity_I64);
7021   IRTemp p2 = newTemp(Ity_I64);
7022   IRTemp result = newTemp(Ity_I64);
7023
7024   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7025   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7026   assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7027          mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7028          mkexpr(op2addr), mkU64(63)))));
7029   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7030   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7031   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7032
7033   return "srda";
7034}
7035
7036static HChar *
7037s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7038{
7039   IRTemp p1 = newTemp(Ity_I64);
7040   IRTemp p2 = newTemp(Ity_I64);
7041   IRTemp result = newTemp(Ity_I64);
7042
7043   assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7044   assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7045   assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7046          mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7047          mkexpr(op2addr), mkU64(63)))));
7048   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7049   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7050
7051   return "srdl";
7052}
7053
7054static HChar *
7055s390_irgen_SRA(UChar r1, IRTemp op2addr)
7056{
7057   IRTemp result = newTemp(Ity_I32);
7058   IRTemp op = newTemp(Ity_I32);
7059
7060   assign(op, get_gpr_w1(r1));
7061   assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7062          mkexpr(op2addr), mkU64(63)))));
7063   put_gpr_w1(r1, mkexpr(result));
7064   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7065
7066   return "sra";
7067}
7068
7069static HChar *
7070s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7071{
7072   IRTemp result = newTemp(Ity_I32);
7073   IRTemp op = newTemp(Ity_I32);
7074
7075   assign(op, get_gpr_w1(r3));
7076   assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7077          mkexpr(op2addr), mkU64(63)))));
7078   put_gpr_w1(r1, mkexpr(result));
7079   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7080
7081   return "srak";
7082}
7083
7084static HChar *
7085s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7086{
7087   IRTemp result = newTemp(Ity_I64);
7088   IRTemp op = newTemp(Ity_I64);
7089
7090   assign(op, get_gpr_dw0(r3));
7091   assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7092          mkexpr(op2addr), mkU64(63)))));
7093   put_gpr_dw0(r1, mkexpr(result));
7094   s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7095
7096   return "srag";
7097}
7098
7099static HChar *
7100s390_irgen_SRL(UChar r1, IRTemp op2addr)
7101{
7102   IRTemp op = newTemp(Ity_I32);
7103
7104   assign(op, get_gpr_w1(r1));
7105   put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7106              mkexpr(op2addr), mkU64(63)))));
7107
7108   return "srl";
7109}
7110
7111static HChar *
7112s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7113{
7114   IRTemp op = newTemp(Ity_I32);
7115
7116   assign(op, get_gpr_w1(r3));
7117   put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7118              mkexpr(op2addr), mkU64(63)))));
7119
7120   return "srlk";
7121}
7122
7123static HChar *
7124s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7125{
7126   IRTemp op = newTemp(Ity_I64);
7127
7128   assign(op, get_gpr_dw0(r3));
7129   put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7130               mkexpr(op2addr), mkU64(63)))));
7131
7132   return "srlg";
7133}
7134
7135static HChar *
7136s390_irgen_ST(UChar r1, IRTemp op2addr)
7137{
7138   store(mkexpr(op2addr), get_gpr_w1(r1));
7139
7140   return "st";
7141}
7142
7143static HChar *
7144s390_irgen_STY(UChar r1, IRTemp op2addr)
7145{
7146   store(mkexpr(op2addr), get_gpr_w1(r1));
7147
7148   return "sty";
7149}
7150
7151static HChar *
7152s390_irgen_STG(UChar r1, IRTemp op2addr)
7153{
7154   store(mkexpr(op2addr), get_gpr_dw0(r1));
7155
7156   return "stg";
7157}
7158
7159static HChar *
7160s390_irgen_STRL(UChar r1, UInt i2)
7161{
7162   store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7163         get_gpr_w1(r1));
7164
7165   return "strl";
7166}
7167
7168static HChar *
7169s390_irgen_STGRL(UChar r1, UInt i2)
7170{
7171   store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7172         get_gpr_dw0(r1));
7173
7174   return "stgrl";
7175}
7176
7177static HChar *
7178s390_irgen_STC(UChar r1, IRTemp op2addr)
7179{
7180   store(mkexpr(op2addr), get_gpr_b7(r1));
7181
7182   return "stc";
7183}
7184
7185static HChar *
7186s390_irgen_STCY(UChar r1, IRTemp op2addr)
7187{
7188   store(mkexpr(op2addr), get_gpr_b7(r1));
7189
7190   return "stcy";
7191}
7192
7193static HChar *
7194s390_irgen_STCH(UChar r1, IRTemp op2addr)
7195{
7196   store(mkexpr(op2addr), get_gpr_b3(r1));
7197
7198   return "stch";
7199}
7200
7201static HChar *
7202s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7203{
7204   UChar mask;
7205   UChar n;
7206
7207   mask = (UChar)r3;
7208   n = 0;
7209   if ((mask & 8) != 0) {
7210      store(mkexpr(op2addr), get_gpr_b4(r1));
7211      n = n + 1;
7212   }
7213   if ((mask & 4) != 0) {
7214      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7215      n = n + 1;
7216   }
7217   if ((mask & 2) != 0) {
7218      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7219      n = n + 1;
7220   }
7221   if ((mask & 1) != 0) {
7222      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7223   }
7224
7225   return "stcm";
7226}
7227
7228static HChar *
7229s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7230{
7231   UChar mask;
7232   UChar n;
7233
7234   mask = (UChar)r3;
7235   n = 0;
7236   if ((mask & 8) != 0) {
7237      store(mkexpr(op2addr), get_gpr_b4(r1));
7238      n = n + 1;
7239   }
7240   if ((mask & 4) != 0) {
7241      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7242      n = n + 1;
7243   }
7244   if ((mask & 2) != 0) {
7245      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7246      n = n + 1;
7247   }
7248   if ((mask & 1) != 0) {
7249      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7250   }
7251
7252   return "stcmy";
7253}
7254
7255static HChar *
7256s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7257{
7258   UChar mask;
7259   UChar n;
7260
7261   mask = (UChar)r3;
7262   n = 0;
7263   if ((mask & 8) != 0) {
7264      store(mkexpr(op2addr), get_gpr_b0(r1));
7265      n = n + 1;
7266   }
7267   if ((mask & 4) != 0) {
7268      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7269      n = n + 1;
7270   }
7271   if ((mask & 2) != 0) {
7272      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7273      n = n + 1;
7274   }
7275   if ((mask & 1) != 0) {
7276      store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7277   }
7278
7279   return "stcmh";
7280}
7281
7282static HChar *
7283s390_irgen_STH(UChar r1, IRTemp op2addr)
7284{
7285   store(mkexpr(op2addr), get_gpr_hw3(r1));
7286
7287   return "sth";
7288}
7289
7290static HChar *
7291s390_irgen_STHY(UChar r1, IRTemp op2addr)
7292{
7293   store(mkexpr(op2addr), get_gpr_hw3(r1));
7294
7295   return "sthy";
7296}
7297
7298static HChar *
7299s390_irgen_STHRL(UChar r1, UInt i2)
7300{
7301   store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7302         get_gpr_hw3(r1));
7303
7304   return "sthrl";
7305}
7306
7307static HChar *
7308s390_irgen_STHH(UChar r1, IRTemp op2addr)
7309{
7310   store(mkexpr(op2addr), get_gpr_hw1(r1));
7311
7312   return "sthh";
7313}
7314
7315static HChar *
7316s390_irgen_STFH(UChar r1, IRTemp op2addr)
7317{
7318   store(mkexpr(op2addr), get_gpr_w0(r1));
7319
7320   return "stfh";
7321}
7322
7323static HChar *
7324s390_irgen_STOC(UChar r1, IRTemp op2addr)
7325{
7326   /* condition is checked in format handler */
7327   store(mkexpr(op2addr), get_gpr_w1(r1));
7328
7329   return "stoc";
7330}
7331
7332static HChar *
7333s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7334{
7335   /* condition is checked in format handler */
7336   store(mkexpr(op2addr), get_gpr_dw0(r1));
7337
7338   return "stocg";
7339}
7340
7341static HChar *
7342s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7343{
7344   store(mkexpr(op2addr), get_gpr_dw0(r1));
7345   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7346
7347   return "stpq";
7348}
7349
7350static HChar *
7351s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7352{
7353   store(mkexpr(op2addr), get_gpr_b7(r1));
7354   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7355
7356   return "strvh";
7357}
7358
7359static HChar *
7360s390_irgen_STRV(UChar r1, IRTemp op2addr)
7361{
7362   store(mkexpr(op2addr), get_gpr_b7(r1));
7363   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7364   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7365   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7366
7367   return "strv";
7368}
7369
7370static HChar *
7371s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7372{
7373   store(mkexpr(op2addr), get_gpr_b7(r1));
7374   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7375   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7376   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7377   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7378   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7379   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7380   store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7381
7382   return "strvg";
7383}
7384
7385static HChar *
7386s390_irgen_SR(UChar r1, UChar r2)
7387{
7388   IRTemp op1 = newTemp(Ity_I32);
7389   IRTemp op2 = newTemp(Ity_I32);
7390   IRTemp result = newTemp(Ity_I32);
7391
7392   assign(op1, get_gpr_w1(r1));
7393   assign(op2, get_gpr_w1(r2));
7394   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7395   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7396   put_gpr_w1(r1, mkexpr(result));
7397
7398   return "sr";
7399}
7400
7401static HChar *
7402s390_irgen_SGR(UChar r1, UChar r2)
7403{
7404   IRTemp op1 = newTemp(Ity_I64);
7405   IRTemp op2 = newTemp(Ity_I64);
7406   IRTemp result = newTemp(Ity_I64);
7407
7408   assign(op1, get_gpr_dw0(r1));
7409   assign(op2, get_gpr_dw0(r2));
7410   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7411   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7412   put_gpr_dw0(r1, mkexpr(result));
7413
7414   return "sgr";
7415}
7416
7417static HChar *
7418s390_irgen_SGFR(UChar r1, UChar r2)
7419{
7420   IRTemp op1 = newTemp(Ity_I64);
7421   IRTemp op2 = newTemp(Ity_I64);
7422   IRTemp result = newTemp(Ity_I64);
7423
7424   assign(op1, get_gpr_dw0(r1));
7425   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7426   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7427   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7428   put_gpr_dw0(r1, mkexpr(result));
7429
7430   return "sgfr";
7431}
7432
7433static HChar *
7434s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7435{
7436   IRTemp op2 = newTemp(Ity_I32);
7437   IRTemp op3 = newTemp(Ity_I32);
7438   IRTemp result = newTemp(Ity_I32);
7439
7440   assign(op2, get_gpr_w1(r2));
7441   assign(op3, get_gpr_w1(r3));
7442   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7443   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7444   put_gpr_w1(r1, mkexpr(result));
7445
7446   return "srk";
7447}
7448
7449static HChar *
7450s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7451{
7452   IRTemp op2 = newTemp(Ity_I64);
7453   IRTemp op3 = newTemp(Ity_I64);
7454   IRTemp result = newTemp(Ity_I64);
7455
7456   assign(op2, get_gpr_dw0(r2));
7457   assign(op3, get_gpr_dw0(r3));
7458   assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7459   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7460   put_gpr_dw0(r1, mkexpr(result));
7461
7462   return "sgrk";
7463}
7464
7465static HChar *
7466s390_irgen_S(UChar r1, IRTemp op2addr)
7467{
7468   IRTemp op1 = newTemp(Ity_I32);
7469   IRTemp op2 = newTemp(Ity_I32);
7470   IRTemp result = newTemp(Ity_I32);
7471
7472   assign(op1, get_gpr_w1(r1));
7473   assign(op2, load(Ity_I32, mkexpr(op2addr)));
7474   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7475   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7476   put_gpr_w1(r1, mkexpr(result));
7477
7478   return "s";
7479}
7480
7481static HChar *
7482s390_irgen_SY(UChar r1, IRTemp op2addr)
7483{
7484   IRTemp op1 = newTemp(Ity_I32);
7485   IRTemp op2 = newTemp(Ity_I32);
7486   IRTemp result = newTemp(Ity_I32);
7487
7488   assign(op1, get_gpr_w1(r1));
7489   assign(op2, load(Ity_I32, mkexpr(op2addr)));
7490   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7491   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7492   put_gpr_w1(r1, mkexpr(result));
7493
7494   return "sy";
7495}
7496
7497static HChar *
7498s390_irgen_SG(UChar r1, IRTemp op2addr)
7499{
7500   IRTemp op1 = newTemp(Ity_I64);
7501   IRTemp op2 = newTemp(Ity_I64);
7502   IRTemp result = newTemp(Ity_I64);
7503
7504   assign(op1, get_gpr_dw0(r1));
7505   assign(op2, load(Ity_I64, mkexpr(op2addr)));
7506   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7507   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7508   put_gpr_dw0(r1, mkexpr(result));
7509
7510   return "sg";
7511}
7512
7513static HChar *
7514s390_irgen_SGF(UChar r1, IRTemp op2addr)
7515{
7516   IRTemp op1 = newTemp(Ity_I64);
7517   IRTemp op2 = newTemp(Ity_I64);
7518   IRTemp result = newTemp(Ity_I64);
7519
7520   assign(op1, get_gpr_dw0(r1));
7521   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7522   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7523   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7524   put_gpr_dw0(r1, mkexpr(result));
7525
7526   return "sgf";
7527}
7528
7529static HChar *
7530s390_irgen_SH(UChar r1, IRTemp op2addr)
7531{
7532   IRTemp op1 = newTemp(Ity_I32);
7533   IRTemp op2 = newTemp(Ity_I32);
7534   IRTemp result = newTemp(Ity_I32);
7535
7536   assign(op1, get_gpr_w1(r1));
7537   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7538   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7539   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7540   put_gpr_w1(r1, mkexpr(result));
7541
7542   return "sh";
7543}
7544
7545static HChar *
7546s390_irgen_SHY(UChar r1, IRTemp op2addr)
7547{
7548   IRTemp op1 = newTemp(Ity_I32);
7549   IRTemp op2 = newTemp(Ity_I32);
7550   IRTemp result = newTemp(Ity_I32);
7551
7552   assign(op1, get_gpr_w1(r1));
7553   assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7554   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7555   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7556   put_gpr_w1(r1, mkexpr(result));
7557
7558   return "shy";
7559}
7560
7561static HChar *
7562s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7563{
7564   IRTemp op2 = newTemp(Ity_I32);
7565   IRTemp op3 = newTemp(Ity_I32);
7566   IRTemp result = newTemp(Ity_I32);
7567
7568   assign(op2, get_gpr_w0(r1));
7569   assign(op3, get_gpr_w0(r2));
7570   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7571   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7572   put_gpr_w0(r1, mkexpr(result));
7573
7574   return "shhhr";
7575}
7576
7577static HChar *
7578s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7579{
7580   IRTemp op2 = newTemp(Ity_I32);
7581   IRTemp op3 = newTemp(Ity_I32);
7582   IRTemp result = newTemp(Ity_I32);
7583
7584   assign(op2, get_gpr_w0(r1));
7585   assign(op3, get_gpr_w1(r2));
7586   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7587   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7588   put_gpr_w0(r1, mkexpr(result));
7589
7590   return "shhlr";
7591}
7592
7593static HChar *
7594s390_irgen_SLR(UChar r1, UChar r2)
7595{
7596   IRTemp op1 = newTemp(Ity_I32);
7597   IRTemp op2 = newTemp(Ity_I32);
7598   IRTemp result = newTemp(Ity_I32);
7599
7600   assign(op1, get_gpr_w1(r1));
7601   assign(op2, get_gpr_w1(r2));
7602   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7603   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7604   put_gpr_w1(r1, mkexpr(result));
7605
7606   return "slr";
7607}
7608
7609static HChar *
7610s390_irgen_SLGR(UChar r1, UChar r2)
7611{
7612   IRTemp op1 = newTemp(Ity_I64);
7613   IRTemp op2 = newTemp(Ity_I64);
7614   IRTemp result = newTemp(Ity_I64);
7615
7616   assign(op1, get_gpr_dw0(r1));
7617   assign(op2, get_gpr_dw0(r2));
7618   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7619   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7620   put_gpr_dw0(r1, mkexpr(result));
7621
7622   return "slgr";
7623}
7624
7625static HChar *
7626s390_irgen_SLGFR(UChar r1, UChar r2)
7627{
7628   IRTemp op1 = newTemp(Ity_I64);
7629   IRTemp op2 = newTemp(Ity_I64);
7630   IRTemp result = newTemp(Ity_I64);
7631
7632   assign(op1, get_gpr_dw0(r1));
7633   assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7634   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7635   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7636   put_gpr_dw0(r1, mkexpr(result));
7637
7638   return "slgfr";
7639}
7640
7641static HChar *
7642s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7643{
7644   IRTemp op2 = newTemp(Ity_I32);
7645   IRTemp op3 = newTemp(Ity_I32);
7646   IRTemp result = newTemp(Ity_I32);
7647
7648   assign(op2, get_gpr_w1(r2));
7649   assign(op3, get_gpr_w1(r3));
7650   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7651   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7652   put_gpr_w1(r1, mkexpr(result));
7653
7654   return "slrk";
7655}
7656
7657static HChar *
7658s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7659{
7660   IRTemp op2 = newTemp(Ity_I64);
7661   IRTemp op3 = newTemp(Ity_I64);
7662   IRTemp result = newTemp(Ity_I64);
7663
7664   assign(op2, get_gpr_dw0(r2));
7665   assign(op3, get_gpr_dw0(r3));
7666   assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7667   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7668   put_gpr_dw0(r1, mkexpr(result));
7669
7670   return "slgrk";
7671}
7672
7673static HChar *
7674s390_irgen_SL(UChar r1, IRTemp op2addr)
7675{
7676   IRTemp op1 = newTemp(Ity_I32);
7677   IRTemp op2 = newTemp(Ity_I32);
7678   IRTemp result = newTemp(Ity_I32);
7679
7680   assign(op1, get_gpr_w1(r1));
7681   assign(op2, load(Ity_I32, mkexpr(op2addr)));
7682   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7683   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7684   put_gpr_w1(r1, mkexpr(result));
7685
7686   return "sl";
7687}
7688
7689static HChar *
7690s390_irgen_SLY(UChar r1, IRTemp op2addr)
7691{
7692   IRTemp op1 = newTemp(Ity_I32);
7693   IRTemp op2 = newTemp(Ity_I32);
7694   IRTemp result = newTemp(Ity_I32);
7695
7696   assign(op1, get_gpr_w1(r1));
7697   assign(op2, load(Ity_I32, mkexpr(op2addr)));
7698   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7699   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7700   put_gpr_w1(r1, mkexpr(result));
7701
7702   return "sly";
7703}
7704
7705static HChar *
7706s390_irgen_SLG(UChar r1, IRTemp op2addr)
7707{
7708   IRTemp op1 = newTemp(Ity_I64);
7709   IRTemp op2 = newTemp(Ity_I64);
7710   IRTemp result = newTemp(Ity_I64);
7711
7712   assign(op1, get_gpr_dw0(r1));
7713   assign(op2, load(Ity_I64, mkexpr(op2addr)));
7714   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7715   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7716   put_gpr_dw0(r1, mkexpr(result));
7717
7718   return "slg";
7719}
7720
7721static HChar *
7722s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7723{
7724   IRTemp op1 = newTemp(Ity_I64);
7725   IRTemp op2 = newTemp(Ity_I64);
7726   IRTemp result = newTemp(Ity_I64);
7727
7728   assign(op1, get_gpr_dw0(r1));
7729   assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7730   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7731   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7732   put_gpr_dw0(r1, mkexpr(result));
7733
7734   return "slgf";
7735}
7736
7737static HChar *
7738s390_irgen_SLFI(UChar r1, UInt i2)
7739{
7740   IRTemp op1 = newTemp(Ity_I32);
7741   UInt op2;
7742   IRTemp result = newTemp(Ity_I32);
7743
7744   assign(op1, get_gpr_w1(r1));
7745   op2 = i2;
7746   assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7747   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7748                       mkU32(op2)));
7749   put_gpr_w1(r1, mkexpr(result));
7750
7751   return "slfi";
7752}
7753
7754static HChar *
7755s390_irgen_SLGFI(UChar r1, UInt i2)
7756{
7757   IRTemp op1 = newTemp(Ity_I64);
7758   ULong op2;
7759   IRTemp result = newTemp(Ity_I64);
7760
7761   assign(op1, get_gpr_dw0(r1));
7762   op2 = (ULong)i2;
7763   assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7764   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7765                       mkU64(op2)));
7766   put_gpr_dw0(r1, mkexpr(result));
7767
7768   return "slgfi";
7769}
7770
7771static HChar *
7772s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7773{
7774   IRTemp op2 = newTemp(Ity_I32);
7775   IRTemp op3 = newTemp(Ity_I32);
7776   IRTemp result = newTemp(Ity_I32);
7777
7778   assign(op2, get_gpr_w0(r1));
7779   assign(op3, get_gpr_w0(r2));
7780   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7781   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7782   put_gpr_w0(r1, mkexpr(result));
7783
7784   return "slhhhr";
7785}
7786
7787static HChar *
7788s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7789{
7790   IRTemp op2 = newTemp(Ity_I32);
7791   IRTemp op3 = newTemp(Ity_I32);
7792   IRTemp result = newTemp(Ity_I32);
7793
7794   assign(op2, get_gpr_w0(r1));
7795   assign(op3, get_gpr_w1(r2));
7796   assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7797   s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7798   put_gpr_w0(r1, mkexpr(result));
7799
7800   return "slhhlr";
7801}
7802
7803static HChar *
7804s390_irgen_SLBR(UChar r1, UChar r2)
7805{
7806   IRTemp op1 = newTemp(Ity_I32);
7807   IRTemp op2 = newTemp(Ity_I32);
7808   IRTemp result = newTemp(Ity_I32);
7809   IRTemp borrow_in = newTemp(Ity_I32);
7810
7811   assign(op1, get_gpr_w1(r1));
7812   assign(op2, get_gpr_w1(r2));
7813   assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7814          s390_call_calculate_cc(), mkU8(1))));
7815   assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7816          mkexpr(borrow_in)));
7817   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7818   put_gpr_w1(r1, mkexpr(result));
7819
7820   return "slbr";
7821}
7822
7823static HChar *
7824s390_irgen_SLBGR(UChar r1, UChar r2)
7825{
7826   IRTemp op1 = newTemp(Ity_I64);
7827   IRTemp op2 = newTemp(Ity_I64);
7828   IRTemp result = newTemp(Ity_I64);
7829   IRTemp borrow_in = newTemp(Ity_I64);
7830
7831   assign(op1, get_gpr_dw0(r1));
7832   assign(op2, get_gpr_dw0(r2));
7833   assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7834          binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7835   assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7836          mkexpr(borrow_in)));
7837   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7838   put_gpr_dw0(r1, mkexpr(result));
7839
7840   return "slbgr";
7841}
7842
7843static HChar *
7844s390_irgen_SLB(UChar r1, IRTemp op2addr)
7845{
7846   IRTemp op1 = newTemp(Ity_I32);
7847   IRTemp op2 = newTemp(Ity_I32);
7848   IRTemp result = newTemp(Ity_I32);
7849   IRTemp borrow_in = newTemp(Ity_I32);
7850
7851   assign(op1, get_gpr_w1(r1));
7852   assign(op2, load(Ity_I32, mkexpr(op2addr)));
7853   assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7854          s390_call_calculate_cc(), mkU8(1))));
7855   assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7856          mkexpr(borrow_in)));
7857   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7858   put_gpr_w1(r1, mkexpr(result));
7859
7860   return "slb";
7861}
7862
7863static HChar *
7864s390_irgen_SLBG(UChar r1, IRTemp op2addr)
7865{
7866   IRTemp op1 = newTemp(Ity_I64);
7867   IRTemp op2 = newTemp(Ity_I64);
7868   IRTemp result = newTemp(Ity_I64);
7869   IRTemp borrow_in = newTemp(Ity_I64);
7870
7871   assign(op1, get_gpr_dw0(r1));
7872   assign(op2, load(Ity_I64, mkexpr(op2addr)));
7873   assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7874          binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7875   assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7876          mkexpr(borrow_in)));
7877   s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7878   put_gpr_dw0(r1, mkexpr(result));
7879
7880   return "slbg";
7881}
7882
7883static HChar *
7884s390_irgen_SVC(UChar i)
7885{
7886   IRTemp sysno = newTemp(Ity_I64);
7887
7888   if (i != 0) {
7889      assign(sysno, mkU64(i));
7890   } else {
7891      assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
7892   }
7893   system_call(mkexpr(sysno));
7894
7895   return "svc";
7896}
7897
7898static HChar *
7899s390_irgen_TM(UChar i2, IRTemp op1addr)
7900{
7901   UChar mask;
7902   IRTemp value = newTemp(Ity_I8);
7903
7904   mask = i2;
7905   assign(value, load(Ity_I8, mkexpr(op1addr)));
7906   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7907                       mkU8(mask)));
7908
7909   return "tm";
7910}
7911
7912static HChar *
7913s390_irgen_TMY(UChar i2, IRTemp op1addr)
7914{
7915   UChar mask;
7916   IRTemp value = newTemp(Ity_I8);
7917
7918   mask = i2;
7919   assign(value, load(Ity_I8, mkexpr(op1addr)));
7920   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7921                       mkU8(mask)));
7922
7923   return "tmy";
7924}
7925
7926static HChar *
7927s390_irgen_TMHH(UChar r1, UShort i2)
7928{
7929   UShort mask;
7930   IRTemp value = newTemp(Ity_I16);
7931
7932   mask = i2;
7933   assign(value, get_gpr_hw0(r1));
7934   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7935                       mkU16(mask)));
7936
7937   return "tmhh";
7938}
7939
7940static HChar *
7941s390_irgen_TMHL(UChar r1, UShort i2)
7942{
7943   UShort mask;
7944   IRTemp value = newTemp(Ity_I16);
7945
7946   mask = i2;
7947   assign(value, get_gpr_hw1(r1));
7948   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7949                       mkU16(mask)));
7950
7951   return "tmhl";
7952}
7953
7954static HChar *
7955s390_irgen_TMLH(UChar r1, UShort i2)
7956{
7957   UShort mask;
7958   IRTemp value = newTemp(Ity_I16);
7959
7960   mask = i2;
7961   assign(value, get_gpr_hw2(r1));
7962   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7963                       mkU16(mask)));
7964
7965   return "tmlh";
7966}
7967
7968static HChar *
7969s390_irgen_TMLL(UChar r1, UShort i2)
7970{
7971   UShort mask;
7972   IRTemp value = newTemp(Ity_I16);
7973
7974   mask = i2;
7975   assign(value, get_gpr_hw3(r1));
7976   s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7977                       mkU16(mask)));
7978
7979   return "tmll";
7980}
7981
7982static HChar *
7983s390_irgen_EFPC(UChar r1)
7984{
7985   put_gpr_w1(r1, get_fpc_w0());
7986
7987   return "efpc";
7988}
7989
7990static HChar *
7991s390_irgen_LER(UChar r1, UChar r2)
7992{
7993   put_fpr_w0(r1, get_fpr_w0(r2));
7994
7995   return "ler";
7996}
7997
7998static HChar *
7999s390_irgen_LDR(UChar r1, UChar r2)
8000{
8001   put_fpr_dw0(r1, get_fpr_dw0(r2));
8002
8003   return "ldr";
8004}
8005
8006static HChar *
8007s390_irgen_LXR(UChar r1, UChar r2)
8008{
8009   put_fpr_dw0(r1, get_fpr_dw0(r2));
8010   put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8011
8012   return "lxr";
8013}
8014
8015static HChar *
8016s390_irgen_LE(UChar r1, IRTemp op2addr)
8017{
8018   put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8019
8020   return "le";
8021}
8022
8023static HChar *
8024s390_irgen_LD(UChar r1, IRTemp op2addr)
8025{
8026   put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8027
8028   return "ld";
8029}
8030
8031static HChar *
8032s390_irgen_LEY(UChar r1, IRTemp op2addr)
8033{
8034   put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8035
8036   return "ley";
8037}
8038
8039static HChar *
8040s390_irgen_LDY(UChar r1, IRTemp op2addr)
8041{
8042   put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8043
8044   return "ldy";
8045}
8046
8047static HChar *
8048s390_irgen_LFPC(IRTemp op2addr)
8049{
8050   put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8051
8052   return "lfpc";
8053}
8054
8055static HChar *
8056s390_irgen_LZER(UChar r1)
8057{
8058   put_fpr_w0(r1, mkF32i(0x0));
8059
8060   return "lzer";
8061}
8062
8063static HChar *
8064s390_irgen_LZDR(UChar r1)
8065{
8066   put_fpr_dw0(r1, mkF64i(0x0));
8067
8068   return "lzdr";
8069}
8070
8071static HChar *
8072s390_irgen_LZXR(UChar r1)
8073{
8074   put_fpr_dw0(r1, mkF64i(0x0));
8075   put_fpr_dw0(r1 + 2, mkF64i(0x0));
8076
8077   return "lzxr";
8078}
8079
8080static HChar *
8081s390_irgen_SRNM(IRTemp op2addr)
8082{
8083   UInt mask;
8084
8085   mask = 3;
8086   put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~mask)),
8087              binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(mask)))
8088              );
8089
8090   return "srnm";
8091}
8092
8093static HChar *
8094s390_irgen_SFPC(UChar r1)
8095{
8096   put_fpc_w0(get_gpr_w1(r1));
8097
8098   return "sfpc";
8099}
8100
8101static HChar *
8102s390_irgen_STE(UChar r1, IRTemp op2addr)
8103{
8104   store(mkexpr(op2addr), get_fpr_w0(r1));
8105
8106   return "ste";
8107}
8108
8109static HChar *
8110s390_irgen_STD(UChar r1, IRTemp op2addr)
8111{
8112   store(mkexpr(op2addr), get_fpr_dw0(r1));
8113
8114   return "std";
8115}
8116
8117static HChar *
8118s390_irgen_STEY(UChar r1, IRTemp op2addr)
8119{
8120   store(mkexpr(op2addr), get_fpr_w0(r1));
8121
8122   return "stey";
8123}
8124
8125static HChar *
8126s390_irgen_STDY(UChar r1, IRTemp op2addr)
8127{
8128   store(mkexpr(op2addr), get_fpr_dw0(r1));
8129
8130   return "stdy";
8131}
8132
8133static HChar *
8134s390_irgen_STFPC(IRTemp op2addr)
8135{
8136   store(mkexpr(op2addr), get_fpc_w0());
8137
8138   return "stfpc";
8139}
8140
8141static HChar *
8142s390_irgen_AEBR(UChar r1, UChar r2)
8143{
8144   IRTemp op1 = newTemp(Ity_F32);
8145   IRTemp op2 = newTemp(Ity_F32);
8146   IRTemp result = newTemp(Ity_F32);
8147
8148   assign(op1, get_fpr_w0(r1));
8149   assign(op2, get_fpr_w0(r2));
8150   assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8151          mkexpr(op2)));
8152   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8153   put_fpr_w0(r1, mkexpr(result));
8154
8155   return "aebr";
8156}
8157
8158static HChar *
8159s390_irgen_ADBR(UChar r1, UChar r2)
8160{
8161   IRTemp op1 = newTemp(Ity_F64);
8162   IRTemp op2 = newTemp(Ity_F64);
8163   IRTemp result = newTemp(Ity_F64);
8164
8165   assign(op1, get_fpr_dw0(r1));
8166   assign(op2, get_fpr_dw0(r2));
8167   assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8168          mkexpr(op2)));
8169   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8170   put_fpr_dw0(r1, mkexpr(result));
8171
8172   return "adbr";
8173}
8174
8175static HChar *
8176s390_irgen_AEB(UChar r1, IRTemp op2addr)
8177{
8178   IRTemp op1 = newTemp(Ity_F32);
8179   IRTemp op2 = newTemp(Ity_F32);
8180   IRTemp result = newTemp(Ity_F32);
8181
8182   assign(op1, get_fpr_w0(r1));
8183   assign(op2, load(Ity_F32, mkexpr(op2addr)));
8184   assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8185          mkexpr(op2)));
8186   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8187   put_fpr_w0(r1, mkexpr(result));
8188
8189   return "aeb";
8190}
8191
8192static HChar *
8193s390_irgen_ADB(UChar r1, IRTemp op2addr)
8194{
8195   IRTemp op1 = newTemp(Ity_F64);
8196   IRTemp op2 = newTemp(Ity_F64);
8197   IRTemp result = newTemp(Ity_F64);
8198
8199   assign(op1, get_fpr_dw0(r1));
8200   assign(op2, load(Ity_F64, mkexpr(op2addr)));
8201   assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8202          mkexpr(op2)));
8203   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8204   put_fpr_dw0(r1, mkexpr(result));
8205
8206   return "adb";
8207}
8208
8209static HChar *
8210s390_irgen_CEFBR(UChar r1, UChar r2)
8211{
8212   IRTemp op2 = newTemp(Ity_I32);
8213
8214   assign(op2, get_gpr_w1(r2));
8215   put_fpr_w0(r1, binop(Iop_I32StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8216
8217   return "cefbr";
8218}
8219
8220static HChar *
8221s390_irgen_CDFBR(UChar r1, UChar r2)
8222{
8223   IRTemp op2 = newTemp(Ity_I32);
8224
8225   assign(op2, get_gpr_w1(r2));
8226   put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8227
8228   return "cdfbr";
8229}
8230
8231static HChar *
8232s390_irgen_CEGBR(UChar r1, UChar r2)
8233{
8234   IRTemp op2 = newTemp(Ity_I64);
8235
8236   assign(op2, get_gpr_dw0(r2));
8237   put_fpr_w0(r1, binop(Iop_I64StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8238
8239   return "cegbr";
8240}
8241
8242static HChar *
8243s390_irgen_CDGBR(UChar r1, UChar r2)
8244{
8245   IRTemp op2 = newTemp(Ity_I64);
8246
8247   assign(op2, get_gpr_dw0(r2));
8248   put_fpr_dw0(r1, binop(Iop_I64StoF64, mkU32(Irrm_NEAREST), mkexpr(op2)));
8249
8250   return "cdgbr";
8251}
8252
8253static HChar *
8254s390_irgen_CFEBR(UChar r3, UChar r1, UChar r2)
8255{
8256   IRTemp op = newTemp(Ity_F32);
8257   IRTemp result = newTemp(Ity_I32);
8258
8259   assign(op, get_fpr_w0(r2));
8260   assign(result, binop(Iop_F32toI32S, mkU32(encode_rounding_mode(r3)),
8261          mkexpr(op)));
8262   put_gpr_w1(r1, mkexpr(result));
8263   s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_32, op);
8264
8265   return "cfebr";
8266}
8267
8268static HChar *
8269s390_irgen_CFDBR(UChar r3, UChar r1, UChar r2)
8270{
8271   IRTemp op = newTemp(Ity_F64);
8272   IRTemp result = newTemp(Ity_I32);
8273
8274   assign(op, get_fpr_dw0(r2));
8275   assign(result, binop(Iop_F64toI32S, mkU32(encode_rounding_mode(r3)),
8276          mkexpr(op)));
8277   put_gpr_w1(r1, mkexpr(result));
8278   s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_32, op);
8279
8280   return "cfdbr";
8281}
8282
8283static HChar *
8284s390_irgen_CGEBR(UChar r3, UChar r1, UChar r2)
8285{
8286   IRTemp op = newTemp(Ity_F32);
8287   IRTemp result = newTemp(Ity_I64);
8288
8289   assign(op, get_fpr_w0(r2));
8290   assign(result, binop(Iop_F32toI64S, mkU32(encode_rounding_mode(r3)),
8291          mkexpr(op)));
8292   put_gpr_dw0(r1, mkexpr(result));
8293   s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_64, op);
8294
8295   return "cgebr";
8296}
8297
8298static HChar *
8299s390_irgen_CGDBR(UChar r3, UChar r1, UChar r2)
8300{
8301   IRTemp op = newTemp(Ity_F64);
8302   IRTemp result = newTemp(Ity_I64);
8303
8304   assign(op, get_fpr_dw0(r2));
8305   assign(result, binop(Iop_F64toI64S, mkU32(encode_rounding_mode(r3)),
8306          mkexpr(op)));
8307   put_gpr_dw0(r1, mkexpr(result));
8308   s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_64, op);
8309
8310   return "cgdbr";
8311}
8312
8313static HChar *
8314s390_irgen_DEBR(UChar r1, UChar r2)
8315{
8316   IRTemp op1 = newTemp(Ity_F32);
8317   IRTemp op2 = newTemp(Ity_F32);
8318   IRTemp result = newTemp(Ity_F32);
8319
8320   assign(op1, get_fpr_w0(r1));
8321   assign(op2, get_fpr_w0(r2));
8322   assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8323          mkexpr(op2)));
8324   put_fpr_w0(r1, mkexpr(result));
8325
8326   return "debr";
8327}
8328
8329static HChar *
8330s390_irgen_DDBR(UChar r1, UChar r2)
8331{
8332   IRTemp op1 = newTemp(Ity_F64);
8333   IRTemp op2 = newTemp(Ity_F64);
8334   IRTemp result = newTemp(Ity_F64);
8335
8336   assign(op1, get_fpr_dw0(r1));
8337   assign(op2, get_fpr_dw0(r2));
8338   assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8339          mkexpr(op2)));
8340   put_fpr_dw0(r1, mkexpr(result));
8341
8342   return "ddbr";
8343}
8344
8345static HChar *
8346s390_irgen_DEB(UChar r1, IRTemp op2addr)
8347{
8348   IRTemp op1 = newTemp(Ity_F32);
8349   IRTemp op2 = newTemp(Ity_F32);
8350   IRTemp result = newTemp(Ity_F32);
8351
8352   assign(op1, get_fpr_w0(r1));
8353   assign(op2, load(Ity_F32, mkexpr(op2addr)));
8354   assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8355          mkexpr(op2)));
8356   put_fpr_w0(r1, mkexpr(result));
8357
8358   return "deb";
8359}
8360
8361static HChar *
8362s390_irgen_DDB(UChar r1, IRTemp op2addr)
8363{
8364   IRTemp op1 = newTemp(Ity_F64);
8365   IRTemp op2 = newTemp(Ity_F64);
8366   IRTemp result = newTemp(Ity_F64);
8367
8368   assign(op1, get_fpr_dw0(r1));
8369   assign(op2, load(Ity_F64, mkexpr(op2addr)));
8370   assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8371          mkexpr(op2)));
8372   put_fpr_dw0(r1, mkexpr(result));
8373
8374   return "ddb";
8375}
8376
8377static HChar *
8378s390_irgen_LTEBR(UChar r1, UChar r2)
8379{
8380   IRTemp result = newTemp(Ity_F32);
8381
8382   assign(result, get_fpr_w0(r2));
8383   put_fpr_w0(r1, mkexpr(result));
8384   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8385
8386   return "ltebr";
8387}
8388
8389static HChar *
8390s390_irgen_LTDBR(UChar r1, UChar r2)
8391{
8392   IRTemp result = newTemp(Ity_F64);
8393
8394   assign(result, get_fpr_dw0(r2));
8395   put_fpr_dw0(r1, mkexpr(result));
8396   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8397
8398   return "ltdbr";
8399}
8400
8401static HChar *
8402s390_irgen_LCEBR(UChar r1, UChar r2)
8403{
8404   IRTemp result = newTemp(Ity_F32);
8405
8406   assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8407   put_fpr_w0(r1, mkexpr(result));
8408   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8409
8410   return "lcebr";
8411}
8412
8413static HChar *
8414s390_irgen_LCDBR(UChar r1, UChar r2)
8415{
8416   IRTemp result = newTemp(Ity_F64);
8417
8418   assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8419   put_fpr_dw0(r1, mkexpr(result));
8420   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8421
8422   return "lcdbr";
8423}
8424
8425static HChar *
8426s390_irgen_LDEBR(UChar r1, UChar r2)
8427{
8428   IRTemp op = newTemp(Ity_F32);
8429
8430   assign(op, get_fpr_w0(r2));
8431   put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8432
8433   return "ldebr";
8434}
8435
8436static HChar *
8437s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8438{
8439   IRTemp op = newTemp(Ity_F32);
8440
8441   assign(op, load(Ity_F32, mkexpr(op2addr)));
8442   put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8443
8444   return "ldeb";
8445}
8446
8447static HChar *
8448s390_irgen_LEDBR(UChar r1, UChar r2)
8449{
8450   IRTemp op = newTemp(Ity_F64);
8451
8452   assign(op, get_fpr_dw0(r2));
8453   put_fpr_w0(r1, binop(Iop_F64toF32, mkU32(Irrm_NEAREST), mkexpr(op)));
8454
8455   return "ledbr";
8456}
8457
8458static HChar *
8459s390_irgen_MEEBR(UChar r1, UChar r2)
8460{
8461   IRTemp op1 = newTemp(Ity_F32);
8462   IRTemp op2 = newTemp(Ity_F32);
8463   IRTemp result = newTemp(Ity_F32);
8464
8465   assign(op1, get_fpr_w0(r1));
8466   assign(op2, get_fpr_w0(r2));
8467   assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8468          mkexpr(op2)));
8469   put_fpr_w0(r1, mkexpr(result));
8470
8471   return "meebr";
8472}
8473
8474static HChar *
8475s390_irgen_MDBR(UChar r1, UChar r2)
8476{
8477   IRTemp op1 = newTemp(Ity_F64);
8478   IRTemp op2 = newTemp(Ity_F64);
8479   IRTemp result = newTemp(Ity_F64);
8480
8481   assign(op1, get_fpr_dw0(r1));
8482   assign(op2, get_fpr_dw0(r2));
8483   assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8484          mkexpr(op2)));
8485   put_fpr_dw0(r1, mkexpr(result));
8486
8487   return "mdbr";
8488}
8489
8490static HChar *
8491s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8492{
8493   IRTemp op1 = newTemp(Ity_F32);
8494   IRTemp op2 = newTemp(Ity_F32);
8495   IRTemp result = newTemp(Ity_F32);
8496
8497   assign(op1, get_fpr_w0(r1));
8498   assign(op2, load(Ity_F32, mkexpr(op2addr)));
8499   assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8500          mkexpr(op2)));
8501   put_fpr_w0(r1, mkexpr(result));
8502
8503   return "meeb";
8504}
8505
8506static HChar *
8507s390_irgen_MDB(UChar r1, IRTemp op2addr)
8508{
8509   IRTemp op1 = newTemp(Ity_F64);
8510   IRTemp op2 = newTemp(Ity_F64);
8511   IRTemp result = newTemp(Ity_F64);
8512
8513   assign(op1, get_fpr_dw0(r1));
8514   assign(op2, load(Ity_F64, mkexpr(op2addr)));
8515   assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8516          mkexpr(op2)));
8517   put_fpr_dw0(r1, mkexpr(result));
8518
8519   return "mdb";
8520}
8521
8522static HChar *
8523s390_irgen_SEBR(UChar r1, UChar r2)
8524{
8525   IRTemp op1 = newTemp(Ity_F32);
8526   IRTemp op2 = newTemp(Ity_F32);
8527   IRTemp result = newTemp(Ity_F32);
8528
8529   assign(op1, get_fpr_w0(r1));
8530   assign(op2, get_fpr_w0(r2));
8531   assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8532          mkexpr(op2)));
8533   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8534   put_fpr_w0(r1, mkexpr(result));
8535
8536   return "sebr";
8537}
8538
8539static HChar *
8540s390_irgen_SDBR(UChar r1, UChar r2)
8541{
8542   IRTemp op1 = newTemp(Ity_F64);
8543   IRTemp op2 = newTemp(Ity_F64);
8544   IRTemp result = newTemp(Ity_F64);
8545
8546   assign(op1, get_fpr_dw0(r1));
8547   assign(op2, get_fpr_dw0(r2));
8548   assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8549          mkexpr(op2)));
8550   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8551   put_fpr_dw0(r1, mkexpr(result));
8552
8553   return "sdbr";
8554}
8555
8556static HChar *
8557s390_irgen_SEB(UChar r1, IRTemp op2addr)
8558{
8559   IRTemp op1 = newTemp(Ity_F32);
8560   IRTemp op2 = newTemp(Ity_F32);
8561   IRTemp result = newTemp(Ity_F32);
8562
8563   assign(op1, get_fpr_w0(r1));
8564   assign(op2, load(Ity_F32, mkexpr(op2addr)));
8565   assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8566          mkexpr(op2)));
8567   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8568   put_fpr_w0(r1, mkexpr(result));
8569
8570   return "seb";
8571}
8572
8573static HChar *
8574s390_irgen_SDB(UChar r1, IRTemp op2addr)
8575{
8576   IRTemp op1 = newTemp(Ity_F64);
8577   IRTemp op2 = newTemp(Ity_F64);
8578   IRTemp result = newTemp(Ity_F64);
8579
8580   assign(op1, get_fpr_dw0(r1));
8581   assign(op2, load(Ity_F64, mkexpr(op2addr)));
8582   assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8583          mkexpr(op2)));
8584   s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8585   put_fpr_dw0(r1, mkexpr(result));
8586
8587   return "sdb";
8588}
8589
8590
8591static HChar *
8592s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8593{
8594   IRTemp len = newTemp(Ity_I64);
8595
8596   assign(len, mkU64(length));
8597   s390_irgen_CLC_EX(len, start1, start2);
8598
8599   return "clc";
8600}
8601
8602static HChar *
8603s390_irgen_CLCL(UChar r1, UChar r2)
8604{
8605   IRTemp addr1 = newTemp(Ity_I64);
8606   IRTemp addr2 = newTemp(Ity_I64);
8607   IRTemp addr1_load = newTemp(Ity_I64);
8608   IRTemp addr2_load = newTemp(Ity_I64);
8609   IRTemp len1 = newTemp(Ity_I32);
8610   IRTemp len2 = newTemp(Ity_I32);
8611   IRTemp r1p1 = newTemp(Ity_I32);   /* contents of r1 + 1 */
8612   IRTemp r2p1 = newTemp(Ity_I32);   /* contents of r2 + 1 */
8613   IRTemp single1 = newTemp(Ity_I8);
8614   IRTemp single2 = newTemp(Ity_I8);
8615   IRTemp pad = newTemp(Ity_I8);
8616
8617   assign(addr1, get_gpr_dw0(r1));
8618   assign(r1p1, get_gpr_w1(r1 + 1));
8619   assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8620   assign(addr2, get_gpr_dw0(r2));
8621   assign(r2p1, get_gpr_w1(r2 + 1));
8622   assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8623   assign(pad, get_gpr_b4(r2 + 1));
8624
8625   /* len1 == 0 and len2 == 0? Exit */
8626   s390_cc_set(0);
8627   next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8628                                         mkexpr(len2)), mkU32(0)));
8629
8630   /* Because mkite evaluates both the then-clause and the else-clause
8631      we cannot load directly from addr1 here. If len1 is 0, then adddr1
8632      may be NULL and loading from there would segfault. So we provide a
8633      valid dummy address in that case. Loading from there does no harm and
8634      the value will be discarded at runtime. */
8635   assign(addr1_load,
8636          mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8637                mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8638   assign(single1,
8639          mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8640                mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8641
8642   assign(addr2_load,
8643          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8644                mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8645   assign(single2,
8646          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8647                mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8648
8649   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8650   /* Fields differ ? */
8651   next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
8652
8653   /* Update len1 and addr1, unless len1 == 0. */
8654   put_gpr_dw0(r1,
8655               mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8656                     mkexpr(addr1),
8657                     binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8658
8659   /* When updating len1 we must not modify bits (r1+1)[0:39] */
8660   put_gpr_w1(r1 + 1,
8661              mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8662                    binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8663                    binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8664
8665   /* Update len2 and addr2, unless len2 == 0. */
8666   put_gpr_dw0(r2,
8667               mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8668                     mkexpr(addr2),
8669                     binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8670
8671   /* When updating len2 we must not modify bits (r2+1)[0:39] */
8672   put_gpr_w1(r2 + 1,
8673              mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8674                    binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
8675                    binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
8676
8677   iterate();
8678
8679   return "clcl";
8680}
8681
8682static HChar *
8683s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
8684{
8685   IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
8686
8687   addr1 = newTemp(Ity_I64);
8688   addr3 = newTemp(Ity_I64);
8689   addr1_load = newTemp(Ity_I64);
8690   addr3_load = newTemp(Ity_I64);
8691   len1 = newTemp(Ity_I64);
8692   len3 = newTemp(Ity_I64);
8693   single1 = newTemp(Ity_I8);
8694   single3 = newTemp(Ity_I8);
8695
8696   assign(addr1, get_gpr_dw0(r1));
8697   assign(len1, get_gpr_dw0(r1 + 1));
8698   assign(addr3, get_gpr_dw0(r3));
8699   assign(len3, get_gpr_dw0(r3 + 1));
8700
8701   /* len1 == 0 and len3 == 0? Exit */
8702   s390_cc_set(0);
8703   next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
8704                                        mkexpr(len3)), mkU64(0)));
8705
8706   /* A mux requires both ways to be possible. This is a way to prevent clcle
8707      from reading from addr1 if it should read from the pad. Since the pad
8708      has no address, just read from the instruction, we discard that anyway */
8709   assign(addr1_load,
8710          mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8711                mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8712
8713   /* same for addr3 */
8714   assign(addr3_load,
8715          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8716                mkU64(guest_IA_curr_instr), mkexpr(addr3)));
8717
8718   assign(single1,
8719          mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8720                unop(Iop_64to8, mkexpr(pad2)),
8721                load(Ity_I8, mkexpr(addr1_load))));
8722
8723   assign(single3,
8724          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8725                unop(Iop_64to8, mkexpr(pad2)),
8726                load(Ity_I8, mkexpr(addr3_load))));
8727
8728   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
8729   /* Both fields differ ? */
8730   next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
8731
8732   /* If a length in 0 we must not change this length and the address */
8733   put_gpr_dw0(r1,
8734               mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8735                     mkexpr(addr1),
8736                     binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8737
8738   put_gpr_dw0(r1 + 1,
8739               mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8740                     mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
8741
8742   put_gpr_dw0(r3,
8743               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8744                     mkexpr(addr3),
8745                     binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
8746
8747   put_gpr_dw0(r3 + 1,
8748               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8749                     mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
8750
8751   iterate();
8752
8753   return "clcle";
8754}
8755
8756
8757static void
8758s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8759{
8760   s390_irgen_xonc(Iop_Xor8, length, start1, start2);
8761}
8762
8763
8764static void
8765s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8766{
8767   s390_irgen_xonc(Iop_And8, length, start1, start2);
8768}
8769
8770
8771static void
8772s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8773{
8774   s390_irgen_xonc(Iop_Or8, length, start1, start2);
8775}
8776
8777
8778static void
8779s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8780{
8781   IRTemp current1 = newTemp(Ity_I8);
8782   IRTemp current2 = newTemp(Ity_I8);
8783   IRTemp counter = newTemp(Ity_I64);
8784
8785   assign(counter, get_counter_dw0());
8786   put_counter_dw0(mkU64(0));
8787
8788   assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
8789                                       mkexpr(counter))));
8790   assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
8791                                       mkexpr(counter))));
8792   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
8793                      False);
8794
8795   /* Both fields differ ? */
8796   next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
8797
8798   /* Check for end of field */
8799   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
8800   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
8801   put_counter_dw0(mkU64(0));
8802}
8803
8804static void
8805s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8806{
8807   IRTemp counter = newTemp(Ity_I64);
8808
8809   assign(counter, get_counter_dw0());
8810
8811   store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
8812         load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
8813
8814   /* Check for end of field */
8815   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
8816   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
8817   put_counter_dw0(mkU64(0));
8818}
8819
8820static void
8821s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
8822{
8823   IRTemp op = newTemp(Ity_I8);
8824   IRTemp op1 = newTemp(Ity_I8);
8825   IRTemp result = newTemp(Ity_I64);
8826   IRTemp counter = newTemp(Ity_I64);
8827
8828   assign(counter, get_counter_dw0());
8829
8830   assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
8831
8832   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
8833
8834   assign(op1, load(Ity_I8, mkexpr(result)));
8835   store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
8836
8837   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
8838   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
8839   put_counter_dw0(mkU64(0));
8840}
8841
8842
8843static void
8844s390_irgen_EX_SS(UChar r, IRTemp addr2,
8845                 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
8846                 int lensize)
8847{
8848   struct SS {
8849      unsigned int op :  8;
8850      unsigned int l  :  8;
8851      unsigned int b1 :  4;
8852      unsigned int d1 : 12;
8853      unsigned int b2 :  4;
8854      unsigned int d2 : 12;
8855   };
8856   union {
8857      struct SS dec;
8858      unsigned long bytes;
8859   } ss;
8860   IRTemp cond;
8861   IRDirty *d;
8862   IRTemp torun;
8863
8864   IRTemp start1 = newTemp(Ity_I64);
8865   IRTemp start2 = newTemp(Ity_I64);
8866   IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
8867   cond = newTemp(Ity_I1);
8868   torun = newTemp(Ity_I64);
8869
8870   assign(torun, load(Ity_I64, mkexpr(addr2)));
8871   /* Start with a check that the saved code is still correct */
8872   assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
8873   /* If not, save the new value */
8874   d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8875                          mkIRExprVec_1(mkexpr(torun)));
8876   d->guard = mkexpr(cond);
8877   stmt(IRStmt_Dirty(d));
8878
8879   /* and restart */
8880   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
8881                   mkU64(guest_IA_curr_instr)));
8882   stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
8883   restart_if(mkexpr(cond));
8884
8885   ss.bytes = last_execute_target;
8886   assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
8887          ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
8888   assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
8889          ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
8890   assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
8891          r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
8892   irgen(len, start1, start2);
8893
8894   last_execute_target = 0;
8895}
8896
8897static HChar *
8898s390_irgen_EX(UChar r1, IRTemp addr2)
8899{
8900   switch(last_execute_target & 0xff00000000000000ULL) {
8901   case 0:
8902   {
8903      /* no code information yet */
8904      IRDirty *d;
8905
8906      /* so safe the code... */
8907      d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8908                             mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
8909      stmt(IRStmt_Dirty(d));
8910      /* and restart */
8911      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
8912                      mkU64(guest_IA_curr_instr)));
8913      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
8914      restart_if(IRExpr_Const(IRConst_U1(True)));
8915
8916      /* we know that this will be invalidated */
8917      put_IA(mkaddr_expr(guest_IA_next_instr));
8918      dis_res->whatNext = Dis_StopHere;
8919      dis_res->jk_StopHere = Ijk_TInval;
8920      break;
8921   }
8922
8923   case 0xd200000000000000ULL:
8924      /* special case MVC */
8925      s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
8926      return "mvc via ex";
8927
8928   case 0xd500000000000000ULL:
8929      /* special case CLC */
8930      s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
8931      return "clc via ex";
8932
8933   case 0xd700000000000000ULL:
8934      /* special case XC */
8935      s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
8936      return "xc via ex";
8937
8938   case 0xd600000000000000ULL:
8939      /* special case OC */
8940      s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
8941      return "oc via ex";
8942
8943   case 0xd400000000000000ULL:
8944      /* special case NC */
8945      s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
8946      return "nc via ex";
8947
8948   case 0xdc00000000000000ULL:
8949      /* special case TR */
8950      s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
8951      return "tr via ex";
8952
8953   default:
8954   {
8955      /* everything else will get a self checking prefix that also checks the
8956         register content */
8957      IRDirty *d;
8958      UChar *bytes;
8959      IRTemp cond;
8960      IRTemp orperand;
8961      IRTemp torun;
8962
8963      cond = newTemp(Ity_I1);
8964      orperand = newTemp(Ity_I64);
8965      torun = newTemp(Ity_I64);
8966
8967      if (r1 == 0)
8968         assign(orperand, mkU64(0));
8969      else
8970         assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
8971      /* This code is going to be translated */
8972      assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
8973             binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
8974
8975      /* Start with a check that saved code is still correct */
8976      assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
8977             mkU64(last_execute_target)));
8978      /* If not, save the new value */
8979      d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8980                             mkIRExprVec_1(mkexpr(torun)));
8981      d->guard = mkexpr(cond);
8982      stmt(IRStmt_Dirty(d));
8983
8984      /* and restart */
8985      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
8986      stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
8987      restart_if(mkexpr(cond));
8988
8989      /* Now comes the actual translation */
8990      bytes = (UChar *) &last_execute_target;
8991      s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
8992                            dis_res);
8993      if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
8994         vex_printf("    which was executed by\n");
8995      /* dont make useless translations in the next execute */
8996      last_execute_target = 0;
8997   }
8998   }
8999   return "ex";
9000}
9001
9002static HChar *
9003s390_irgen_EXRL(UChar r1, UInt offset)
9004{
9005   IRTemp addr = newTemp(Ity_I64);
9006   /* we might save one round trip because we know the target */
9007   if (!last_execute_target)
9008      last_execute_target = *(ULong *)(HWord)
9009                             (guest_IA_curr_instr + offset * 2UL);
9010   assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9011   s390_irgen_EX(r1, addr);
9012   return "exrl";
9013}
9014
9015static HChar *
9016s390_irgen_IPM(UChar r1)
9017{
9018   // As long as we dont support SPM, lets just assume 0 as program mask
9019   put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9020                       binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9021
9022   return "ipm";
9023}
9024
9025
9026static HChar *
9027s390_irgen_SRST(UChar r1, UChar r2)
9028{
9029   IRTemp address = newTemp(Ity_I64);
9030   IRTemp next = newTemp(Ity_I64);
9031   IRTemp delim = newTemp(Ity_I8);
9032   IRTemp counter = newTemp(Ity_I64);
9033   IRTemp byte = newTemp(Ity_I8);
9034
9035   assign(address, get_gpr_dw0(r2));
9036   assign(next, get_gpr_dw0(r1));
9037
9038   assign(counter, get_counter_dw0());
9039   put_counter_dw0(mkU64(0));
9040
9041   // start = next?  CC=2 and out r1 and r2 unchanged
9042   s390_cc_set(2);
9043   put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
9044   next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
9045
9046   assign(byte, load(Ity_I8, mkexpr(address)));
9047   assign(delim, get_gpr_b7(0));
9048
9049   // byte = delim? CC=1, R1=address
9050   s390_cc_set(1);
9051   put_gpr_dw0(r1,  mkexpr(address));
9052   next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
9053
9054   // else: all equal, no end yet, loop
9055   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9056   put_gpr_dw0(r1, mkexpr(next));
9057   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
9058
9059   iterate();
9060
9061   return "srst";
9062}
9063
9064static HChar *
9065s390_irgen_CLST(UChar r1, UChar r2)
9066{
9067   IRTemp address1 = newTemp(Ity_I64);
9068   IRTemp address2 = newTemp(Ity_I64);
9069   IRTemp end = newTemp(Ity_I8);
9070   IRTemp counter = newTemp(Ity_I64);
9071   IRTemp byte1 = newTemp(Ity_I8);
9072   IRTemp byte2 = newTemp(Ity_I8);
9073
9074   assign(address1, get_gpr_dw0(r1));
9075   assign(address2, get_gpr_dw0(r2));
9076   assign(end, get_gpr_b7(0));
9077   assign(counter, get_counter_dw0());
9078   put_counter_dw0(mkU64(0));
9079   assign(byte1, load(Ity_I8, mkexpr(address1)));
9080   assign(byte2, load(Ity_I8, mkexpr(address2)));
9081
9082   // end in both? all equal, reset r1 and r2 to start values
9083   s390_cc_set(0);
9084   put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9085   put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
9086   next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9087                      binop(Iop_Or8,
9088                            binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9089                            binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
9090
9091   put_gpr_dw0(r1, mkexpr(address1));
9092   put_gpr_dw0(r2, mkexpr(address2));
9093
9094   // End found in string1
9095   s390_cc_set(1);
9096   next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
9097
9098   // End found in string2
9099   s390_cc_set(2);
9100   next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
9101
9102   // string1 < string2
9103   s390_cc_set(1);
9104   next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9105                      unop(Iop_8Uto32, mkexpr(byte2))));
9106
9107   // string2 < string1
9108   s390_cc_set(2);
9109   next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9110                      unop(Iop_8Uto32, mkexpr(byte1))));
9111
9112   // else: all equal, no end yet, loop
9113   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9114   put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9115   put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
9116
9117   iterate();
9118
9119   return "clst";
9120}
9121
9122static void
9123s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9124{
9125   UChar reg;
9126   IRTemp addr = newTemp(Ity_I64);
9127
9128   assign(addr, mkexpr(op2addr));
9129   reg = r1;
9130   do {
9131      IRTemp old = addr;
9132
9133      reg %= 16;
9134      put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9135      addr = newTemp(Ity_I64);
9136      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9137      reg++;
9138   } while (reg != (r3 + 1));
9139}
9140
9141static HChar *
9142s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9143{
9144   s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9145
9146   return "lm";
9147}
9148
9149static HChar *
9150s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9151{
9152   s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9153
9154   return "lmy";
9155}
9156
9157static HChar *
9158s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9159{
9160   UChar reg;
9161   IRTemp addr = newTemp(Ity_I64);
9162
9163   assign(addr, mkexpr(op2addr));
9164   reg = r1;
9165   do {
9166      IRTemp old = addr;
9167
9168      reg %= 16;
9169      put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9170      addr = newTemp(Ity_I64);
9171      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9172      reg++;
9173   } while (reg != (r3 + 1));
9174
9175   return "lmh";
9176}
9177
9178static HChar *
9179s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9180{
9181   UChar reg;
9182   IRTemp addr = newTemp(Ity_I64);
9183
9184   assign(addr, mkexpr(op2addr));
9185   reg = r1;
9186   do {
9187      IRTemp old = addr;
9188
9189      reg %= 16;
9190      put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9191      addr = newTemp(Ity_I64);
9192      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9193      reg++;
9194   } while (reg != (r3 + 1));
9195
9196   return "lmg";
9197}
9198
9199static void
9200s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9201{
9202   UChar reg;
9203   IRTemp addr = newTemp(Ity_I64);
9204
9205   assign(addr, mkexpr(op2addr));
9206   reg = r1;
9207   do {
9208      IRTemp old = addr;
9209
9210      reg %= 16;
9211      store(mkexpr(addr), get_gpr_w1(reg));
9212      addr = newTemp(Ity_I64);
9213      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9214      reg++;
9215   } while( reg != (r3 + 1));
9216}
9217
9218static HChar *
9219s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9220{
9221   s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9222
9223   return "stm";
9224}
9225
9226static HChar *
9227s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9228{
9229   s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9230
9231   return "stmy";
9232}
9233
9234static HChar *
9235s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9236{
9237   UChar reg;
9238   IRTemp addr = newTemp(Ity_I64);
9239
9240   assign(addr, mkexpr(op2addr));
9241   reg = r1;
9242   do {
9243      IRTemp old = addr;
9244
9245      reg %= 16;
9246      store(mkexpr(addr), get_gpr_w0(reg));
9247      addr = newTemp(Ity_I64);
9248      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9249      reg++;
9250   } while( reg != (r3 + 1));
9251
9252   return "stmh";
9253}
9254
9255static HChar *
9256s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9257{
9258   UChar reg;
9259   IRTemp addr = newTemp(Ity_I64);
9260
9261   assign(addr, mkexpr(op2addr));
9262   reg = r1;
9263   do {
9264      IRTemp old = addr;
9265
9266      reg %= 16;
9267      store(mkexpr(addr), get_gpr_dw0(reg));
9268      addr = newTemp(Ity_I64);
9269      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9270      reg++;
9271   } while( reg != (r3 + 1));
9272
9273   return "stmg";
9274}
9275
9276static void
9277s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
9278{
9279   IRTemp old1 = newTemp(Ity_I8);
9280   IRTemp old2 = newTemp(Ity_I8);
9281   IRTemp new1 = newTemp(Ity_I8);
9282   IRTemp counter = newTemp(Ity_I32);
9283   IRTemp addr1 = newTemp(Ity_I64);
9284
9285   assign(counter, get_counter_w0());
9286
9287   assign(addr1, binop(Iop_Add64, mkexpr(start1),
9288                       unop(Iop_32Uto64, mkexpr(counter))));
9289
9290   assign(old1, load(Ity_I8, mkexpr(addr1)));
9291   assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9292                                   unop(Iop_32Uto64,mkexpr(counter)))));
9293   assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9294
9295   /* Special case: xc is used to zero memory */
9296   if (op == Iop_Xor8) {
9297      store(mkexpr(addr1),
9298            mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9299                  mkU8(0), mkexpr(new1)));
9300   } else
9301      store(mkexpr(addr1), mkexpr(new1));
9302   put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9303                        get_counter_w1()));
9304
9305   /* Check for end of field */
9306   put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
9307   iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
9308   s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9309                      False);
9310   put_counter_dw0(mkU64(0));
9311}
9312
9313static HChar *
9314s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9315{
9316   IRTemp len = newTemp(Ity_I32);
9317
9318   assign(len, mkU32(length));
9319   s390_irgen_xonc(Iop_Xor8, len, start1, start2);
9320
9321   return "xc";
9322}
9323
9324static void
9325s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9326{
9327   IRTemp counter = newTemp(Ity_I32);
9328   IRTemp start = newTemp(Ity_I64);
9329   IRTemp addr  = newTemp(Ity_I64);
9330
9331   assign(start,
9332          binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9333
9334   if (length < 8) {
9335      UInt i;
9336
9337      for (i = 0; i <= length; ++i) {
9338         store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9339      }
9340   } else {
9341     assign(counter, get_counter_w0());
9342
9343     assign(addr, binop(Iop_Add64, mkexpr(start),
9344                        unop(Iop_32Uto64, mkexpr(counter))));
9345
9346     store(mkexpr(addr), mkU8(0));
9347
9348     /* Check for end of field */
9349     put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
9350     iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
9351
9352     /* Reset counter */
9353     put_counter_dw0(mkU64(0));
9354   }
9355
9356   s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9357
9358   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
9359      s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9360}
9361
9362static HChar *
9363s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9364{
9365   IRTemp len = newTemp(Ity_I32);
9366
9367   assign(len, mkU32(length));
9368   s390_irgen_xonc(Iop_And8, len, start1, start2);
9369
9370   return "nc";
9371}
9372
9373static HChar *
9374s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9375{
9376   IRTemp len = newTemp(Ity_I32);
9377
9378   assign(len, mkU32(length));
9379   s390_irgen_xonc(Iop_Or8, len, start1, start2);
9380
9381   return "oc";
9382}
9383
9384
9385static HChar *
9386s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9387{
9388   IRTemp len = newTemp(Ity_I64);
9389
9390   assign(len, mkU64(length));
9391   s390_irgen_MVC_EX(len, start1, start2);
9392
9393   return "mvc";
9394}
9395
9396static HChar *
9397s390_irgen_MVCL(UChar r1, UChar r2)
9398{
9399   IRTemp addr1 = newTemp(Ity_I64);
9400   IRTemp addr2 = newTemp(Ity_I64);
9401   IRTemp addr2_load = newTemp(Ity_I64);
9402   IRTemp r1p1 = newTemp(Ity_I32);   /* contents of r1 + 1 */
9403   IRTemp r2p1 = newTemp(Ity_I32);   /* contents of r2 + 1 */
9404   IRTemp len1 = newTemp(Ity_I32);
9405   IRTemp len2 = newTemp(Ity_I32);
9406   IRTemp pad = newTemp(Ity_I8);
9407   IRTemp single = newTemp(Ity_I8);
9408
9409   assign(addr1, get_gpr_dw0(r1));
9410   assign(r1p1, get_gpr_w1(r1 + 1));
9411   assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9412   assign(addr2, get_gpr_dw0(r2));
9413   assign(r2p1, get_gpr_w1(r2 + 1));
9414   assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9415   assign(pad, get_gpr_b4(r2 + 1));
9416
9417   /* len1 == 0 ? */
9418   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
9419   next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
9420
9421   /* Check for destructive overlap:
9422      addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9423   s390_cc_set(3);
9424   IRTemp cond1 = newTemp(Ity_I32);
9425   assign(cond1, unop(Iop_1Uto32,
9426                      binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9427   IRTemp cond2 = newTemp(Ity_I32);
9428   assign(cond2, unop(Iop_1Uto32,
9429                      binop(Iop_CmpLT64U, mkexpr(addr1),
9430                            binop(Iop_Add64, mkexpr(addr2),
9431                                  unop(Iop_32Uto64, mkexpr(len1))))));
9432   IRTemp cond3 = newTemp(Ity_I32);
9433   assign(cond3, unop(Iop_1Uto32,
9434                      binop(Iop_CmpLT64U,
9435                            mkexpr(addr1),
9436                            binop(Iop_Add64, mkexpr(addr2),
9437                                  unop(Iop_32Uto64, mkexpr(len2))))));
9438
9439   next_insn_if(binop(Iop_CmpEQ32,
9440                      binop(Iop_And32,
9441                            binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9442                            mkexpr(cond3)),
9443                      mkU32(1)));
9444
9445   /* See s390_irgen_CLCL for explanation why we cannot load directly
9446      and need two steps. */
9447   assign(addr2_load,
9448          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9449                mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9450   assign(single,
9451          mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9452                mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9453
9454   store(mkexpr(addr1), mkexpr(single));
9455
9456   /* Update addr1 and len1 */
9457   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9458   put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9459
9460   /* Update addr2 and len2 */
9461   put_gpr_dw0(r2,
9462               mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9463                     mkexpr(addr2),
9464                     binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9465
9466   /* When updating len2 we must not modify bits (r2+1)[0:39] */
9467   put_gpr_w1(r2 + 1,
9468              mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9469                    binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9470                    binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9471
9472   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
9473   iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
9474
9475   return "mvcl";
9476}
9477
9478
9479static HChar *
9480s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9481{
9482   IRTemp addr1, addr3, addr3_load, len1, len3, single;
9483
9484   addr1 = newTemp(Ity_I64);
9485   addr3 = newTemp(Ity_I64);
9486   addr3_load = newTemp(Ity_I64);
9487   len1 = newTemp(Ity_I64);
9488   len3 = newTemp(Ity_I64);
9489   single = newTemp(Ity_I8);
9490
9491   assign(addr1, get_gpr_dw0(r1));
9492   assign(len1, get_gpr_dw0(r1 + 1));
9493   assign(addr3, get_gpr_dw0(r3));
9494   assign(len3, get_gpr_dw0(r3 + 1));
9495
9496   // len1 == 0 ?
9497   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
9498   next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
9499
9500   /* This is a hack to prevent mvcle from reading from addr3 if it
9501      should read from the pad. Since the pad has no address, just
9502      read from the instruction, we discard that anyway */
9503   assign(addr3_load,
9504          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9505                mkU64(guest_IA_curr_instr), mkexpr(addr3)));
9506
9507   assign(single,
9508          mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9509                unop(Iop_64to8, mkexpr(pad2)),
9510                load(Ity_I8, mkexpr(addr3_load))));
9511   store(mkexpr(addr1), mkexpr(single));
9512
9513   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9514
9515   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9516
9517   put_gpr_dw0(r3,
9518               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9519                     mkexpr(addr3),
9520                     binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
9521
9522   put_gpr_dw0(r3 + 1,
9523               mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9524                     mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
9525
9526   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
9527   iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
9528
9529   return "mvcle";
9530}
9531
9532static HChar *
9533s390_irgen_MVST(UChar r1, UChar r2)
9534{
9535   IRTemp addr1 = newTemp(Ity_I64);
9536   IRTemp addr2 = newTemp(Ity_I64);
9537   IRTemp end = newTemp(Ity_I8);
9538   IRTemp byte = newTemp(Ity_I8);
9539   IRTemp counter = newTemp(Ity_I64);
9540
9541   assign(addr1, get_gpr_dw0(r1));
9542   assign(addr2, get_gpr_dw0(r2));
9543   assign(counter, get_counter_dw0());
9544   assign(end, get_gpr_b7(0));
9545   assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9546   store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9547
9548   // We use unlimited as cpu-determined number
9549   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9550   iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
9551
9552   // and always set cc=1 at the end + update r1
9553   s390_cc_set(1);
9554   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9555   put_counter_dw0(mkU64(0));
9556
9557   return "mvst";
9558}
9559
9560static void
9561s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9562{
9563   IRTemp op1 = newTemp(Ity_I64);
9564   IRTemp result = newTemp(Ity_I64);
9565
9566   assign(op1, binop(Iop_32HLto64,
9567                     get_gpr_w1(r1),         // high 32 bits
9568                     get_gpr_w1(r1 + 1)));   // low  32 bits
9569   assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9570   put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));   // remainder
9571   put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9572}
9573
9574static void
9575s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9576{
9577   IRTemp op1 = newTemp(Ity_I128);
9578   IRTemp result = newTemp(Ity_I128);
9579
9580   assign(op1, binop(Iop_64HLto128,
9581                     get_gpr_dw0(r1),         // high 64 bits
9582                     get_gpr_dw0(r1 + 1)));   // low  64 bits
9583   assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9584   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));   // remainder
9585   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9586}
9587
9588static void
9589s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9590{
9591   IRTemp op1 = newTemp(Ity_I64);
9592   IRTemp result = newTemp(Ity_I128);
9593
9594   assign(op1, get_gpr_dw0(r1 + 1));
9595   assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9596   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));   // remainder
9597   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9598}
9599
9600static HChar *
9601s390_irgen_DR(UChar r1, UChar r2)
9602{
9603   IRTemp op2 = newTemp(Ity_I32);
9604
9605   assign(op2, get_gpr_w1(r2));
9606
9607   s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9608
9609   return "dr";
9610}
9611
9612static HChar *
9613s390_irgen_D(UChar r1, IRTemp op2addr)
9614{
9615   IRTemp op2 = newTemp(Ity_I32);
9616
9617   assign(op2, load(Ity_I32, mkexpr(op2addr)));
9618
9619   s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9620
9621   return "d";
9622}
9623
9624static HChar *
9625s390_irgen_DLR(UChar r1, UChar r2)
9626{
9627   IRTemp op2 = newTemp(Ity_I32);
9628
9629   assign(op2, get_gpr_w1(r2));
9630
9631   s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9632
9633   return "dr";
9634}
9635
9636static HChar *
9637s390_irgen_DL(UChar r1, IRTemp op2addr)
9638{
9639   IRTemp op2 = newTemp(Ity_I32);
9640
9641   assign(op2, load(Ity_I32, mkexpr(op2addr)));
9642
9643   s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9644
9645   return "dl";
9646}
9647
9648static HChar *
9649s390_irgen_DLG(UChar r1, IRTemp op2addr)
9650{
9651   IRTemp op2 = newTemp(Ity_I64);
9652
9653   assign(op2, load(Ity_I64, mkexpr(op2addr)));
9654
9655   s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9656
9657   return "dlg";
9658}
9659
9660static HChar *
9661s390_irgen_DLGR(UChar r1, UChar r2)
9662{
9663   IRTemp op2 = newTemp(Ity_I64);
9664
9665   assign(op2, get_gpr_dw0(r2));
9666
9667   s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9668
9669   return "dlgr";
9670}
9671
9672static HChar *
9673s390_irgen_DSGR(UChar r1, UChar r2)
9674{
9675   IRTemp op2 = newTemp(Ity_I64);
9676
9677   assign(op2, get_gpr_dw0(r2));
9678
9679   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9680
9681   return "dsgr";
9682}
9683
9684static HChar *
9685s390_irgen_DSG(UChar r1, IRTemp op2addr)
9686{
9687   IRTemp op2 = newTemp(Ity_I64);
9688
9689   assign(op2, load(Ity_I64, mkexpr(op2addr)));
9690
9691   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9692
9693   return "dsg";
9694}
9695
9696static HChar *
9697s390_irgen_DSGFR(UChar r1, UChar r2)
9698{
9699   IRTemp op2 = newTemp(Ity_I64);
9700
9701   assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
9702
9703   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9704
9705   return "dsgfr";
9706}
9707
9708static HChar *
9709s390_irgen_DSGF(UChar r1, IRTemp op2addr)
9710{
9711   IRTemp op2 = newTemp(Ity_I64);
9712
9713   assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
9714
9715   s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9716
9717   return "dsgf";
9718}
9719
9720static void
9721s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9722{
9723   UChar reg;
9724   IRTemp addr = newTemp(Ity_I64);
9725
9726   assign(addr, mkexpr(op2addr));
9727   reg = r1;
9728   do {
9729      IRTemp old = addr;
9730
9731      reg %= 16;
9732      put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
9733      addr = newTemp(Ity_I64);
9734      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9735      reg++;
9736   } while (reg != (r3 + 1));
9737}
9738
9739static HChar *
9740s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
9741{
9742   s390_irgen_load_ar_multiple(r1, r3, op2addr);
9743
9744   return "lam";
9745}
9746
9747static HChar *
9748s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
9749{
9750   s390_irgen_load_ar_multiple(r1, r3, op2addr);
9751
9752   return "lamy";
9753}
9754
9755static void
9756s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9757{
9758   UChar reg;
9759   IRTemp addr = newTemp(Ity_I64);
9760
9761   assign(addr, mkexpr(op2addr));
9762   reg = r1;
9763   do {
9764      IRTemp old = addr;
9765
9766      reg %= 16;
9767      store(mkexpr(addr), get_ar_w0(reg));
9768      addr = newTemp(Ity_I64);
9769      assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9770      reg++;
9771   } while (reg != (r3 + 1));
9772}
9773
9774static HChar *
9775s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
9776{
9777   s390_irgen_store_ar_multiple(r1, r3, op2addr);
9778
9779   return "stam";
9780}
9781
9782static HChar *
9783s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
9784{
9785   s390_irgen_store_ar_multiple(r1, r3, op2addr);
9786
9787   return "stamy";
9788}
9789
9790
9791/* Implementation for 32-bit compare-and-swap */
9792static void
9793s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
9794{
9795   IRCAS *cas;
9796   IRTemp op1 = newTemp(Ity_I32);
9797   IRTemp old_mem = newTemp(Ity_I32);
9798   IRTemp op3 = newTemp(Ity_I32);
9799   IRTemp result = newTemp(Ity_I32);
9800   IRTemp nequal = newTemp(Ity_I1);
9801
9802   assign(op1, get_gpr_w1(r1));
9803   assign(op3, get_gpr_w1(r3));
9804
9805   /* The first and second operands are compared. If they are equal,
9806      the third operand is stored at the second- operand location. */
9807   cas = mkIRCAS(IRTemp_INVALID, old_mem,
9808                 Iend_BE, mkexpr(op2addr),
9809                 NULL, mkexpr(op1), /* expected value */
9810                 NULL, mkexpr(op3)  /* new value */);
9811   stmt(IRStmt_CAS(cas));
9812
9813   /* Set CC. Operands compared equal -> 0, else 1. */
9814   assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
9815   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9816
9817   /* If operands were equal (cc == 0) just store the old value op1 in r1.
9818      Otherwise, store the old_value from memory in r1 and yield. */
9819   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9820   put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
9821   yield_if(mkexpr(nequal));
9822}
9823
9824static HChar *
9825s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
9826{
9827   s390_irgen_cas_32(r1, r3, op2addr);
9828
9829   return "cs";
9830}
9831
9832static HChar *
9833s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
9834{
9835   s390_irgen_cas_32(r1, r3, op2addr);
9836
9837   return "csy";
9838}
9839
9840static HChar *
9841s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
9842{
9843   IRCAS *cas;
9844   IRTemp op1 = newTemp(Ity_I64);
9845   IRTemp old_mem = newTemp(Ity_I64);
9846   IRTemp op3 = newTemp(Ity_I64);
9847   IRTemp result = newTemp(Ity_I64);
9848   IRTemp nequal = newTemp(Ity_I1);
9849
9850   assign(op1, get_gpr_dw0(r1));
9851   assign(op3, get_gpr_dw0(r3));
9852
9853   /* The first and second operands are compared. If they are equal,
9854      the third operand is stored at the second- operand location. */
9855   cas = mkIRCAS(IRTemp_INVALID, old_mem,
9856                 Iend_BE, mkexpr(op2addr),
9857                 NULL, mkexpr(op1), /* expected value */
9858                 NULL, mkexpr(op3)  /* new value */);
9859   stmt(IRStmt_CAS(cas));
9860
9861   /* Set CC. Operands compared equal -> 0, else 1. */
9862   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
9863   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9864
9865   /* If operands were equal (cc == 0) just store the old value op1 in r1.
9866      Otherwise, store the old_value from memory in r1 and yield. */
9867   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9868   put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
9869   yield_if(mkexpr(nequal));
9870
9871   return "csg";
9872}
9873
9874/* Implementation for 32-bit compare-double-and-swap */
9875static void
9876s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
9877{
9878   IRCAS *cas;
9879   IRTemp op1_high = newTemp(Ity_I32);
9880   IRTemp op1_low  = newTemp(Ity_I32);
9881   IRTemp old_mem_high = newTemp(Ity_I32);
9882   IRTemp old_mem_low  = newTemp(Ity_I32);
9883   IRTemp op3_high = newTemp(Ity_I32);
9884   IRTemp op3_low  = newTemp(Ity_I32);
9885   IRTemp result = newTemp(Ity_I32);
9886   IRTemp nequal = newTemp(Ity_I1);
9887
9888   assign(op1_high, get_gpr_w1(r1));
9889   assign(op1_low,  get_gpr_w1(r1+1));
9890   assign(op3_high, get_gpr_w1(r3));
9891   assign(op3_low,  get_gpr_w1(r3+1));
9892
9893   /* The first and second operands are compared. If they are equal,
9894      the third operand is stored at the second-operand location. */
9895   cas = mkIRCAS(old_mem_high, old_mem_low,
9896                 Iend_BE, mkexpr(op2addr),
9897                 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
9898                 mkexpr(op3_high), mkexpr(op3_low)  /* new value */);
9899   stmt(IRStmt_CAS(cas));
9900
9901   /* Set CC. Operands compared equal -> 0, else 1. */
9902   assign(result, unop(Iop_1Uto32,
9903          binop(Iop_CmpNE32,
9904                binop(Iop_Or32,
9905                      binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
9906                      binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
9907                mkU32(0))));
9908
9909   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9910
9911   /* If operands were equal (cc == 0) just store the old value op1 in r1.
9912      Otherwise, store the old_value from memory in r1 and yield. */
9913   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9914   put_gpr_w1(r1,   mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
9915   put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low),  mkexpr(op1_low)));
9916   yield_if(mkexpr(nequal));
9917}
9918
9919static HChar *
9920s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
9921{
9922   s390_irgen_cdas_32(r1, r3, op2addr);
9923
9924   return "cds";
9925}
9926
9927static HChar *
9928s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
9929{
9930   s390_irgen_cdas_32(r1, r3, op2addr);
9931
9932   return "cdsy";
9933}
9934
9935static HChar *
9936s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
9937{
9938   IRCAS *cas;
9939   IRTemp op1_high = newTemp(Ity_I64);
9940   IRTemp op1_low  = newTemp(Ity_I64);
9941   IRTemp old_mem_high = newTemp(Ity_I64);
9942   IRTemp old_mem_low  = newTemp(Ity_I64);
9943   IRTemp op3_high = newTemp(Ity_I64);
9944   IRTemp op3_low  = newTemp(Ity_I64);
9945   IRTemp result = newTemp(Ity_I64);
9946   IRTemp nequal = newTemp(Ity_I1);
9947
9948   assign(op1_high, get_gpr_dw0(r1));
9949   assign(op1_low,  get_gpr_dw0(r1+1));
9950   assign(op3_high, get_gpr_dw0(r3));
9951   assign(op3_low,  get_gpr_dw0(r3+1));
9952
9953   /* The first and second operands are compared. If they are equal,
9954      the third operand is stored at the second-operand location. */
9955   cas = mkIRCAS(old_mem_high, old_mem_low,
9956                 Iend_BE, mkexpr(op2addr),
9957                 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
9958                 mkexpr(op3_high), mkexpr(op3_low)  /* new value */);
9959   stmt(IRStmt_CAS(cas));
9960
9961   /* Set CC. Operands compared equal -> 0, else 1. */
9962   assign(result, unop(Iop_1Uto64,
9963          binop(Iop_CmpNE64,
9964                binop(Iop_Or64,
9965                      binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
9966                      binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
9967                mkU64(0))));
9968
9969   s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9970
9971   /* If operands were equal (cc == 0) just store the old value op1 in r1.
9972      Otherwise, store the old_value from memory in r1 and yield. */
9973   assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9974   put_gpr_dw0(r1,   mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
9975   put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low),  mkexpr(op1_low)));
9976   yield_if(mkexpr(nequal));
9977
9978   return "cdsg";
9979}
9980
9981
9982/* Binary floating point */
9983
9984static HChar *
9985s390_irgen_AXBR(UChar r1, UChar r2)
9986{
9987   IRTemp op1 = newTemp(Ity_F128);
9988   IRTemp op2 = newTemp(Ity_F128);
9989   IRTemp result = newTemp(Ity_F128);
9990
9991   assign(op1, get_fpr_pair(r1));
9992   assign(op2, get_fpr_pair(r2));
9993   assign(result, triop(Iop_AddF128, mkU32(Irrm_NEAREST), mkexpr(op1),
9994                        mkexpr(op2)));
9995   put_fpr_pair(r1, mkexpr(result));
9996
9997   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
9998
9999   return "axbr";
10000}
10001
10002/* The result of a Iop_CmdFxx operation is a condition code. It is
10003   encoded using the values defined in type IRCmpFxxResult.
10004   Before we can store the condition code into the guest state (or do
10005   anything else with it for that matter) we need to convert it to
10006   the encoding that s390 uses. This is what this function does.
10007
10008   s390     VEX                b6 b2 b0   cc.1  cc.0
10009   0      0x40 EQ             1  0  0     0     0
10010   1      0x01 LT             0  0  1     0     1
10011   2      0x00 GT             0  0  0     1     0
10012   3      0x45 Unordered      1  1  1     1     1
10013
10014   The following bits from the VEX encoding are interesting:
10015   b0, b2, b6  with b0 being the LSB. We observe:
10016
10017   cc.0 = b0;
10018   cc.1 = b2 | (~b0 & ~b6)
10019
10020   with cc being the s390 condition code.
10021*/
10022static IRExpr *
10023convert_vex_fpcc_to_s390(IRTemp vex_cc)
10024{
10025   IRTemp cc0  = newTemp(Ity_I32);
10026   IRTemp cc1  = newTemp(Ity_I32);
10027   IRTemp b0   = newTemp(Ity_I32);
10028   IRTemp b2   = newTemp(Ity_I32);
10029   IRTemp b6   = newTemp(Ity_I32);
10030
10031   assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10032   assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10033                    mkU32(1)));
10034   assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10035                    mkU32(1)));
10036
10037   assign(cc0, mkexpr(b0));
10038   assign(cc1, binop(Iop_Or32, mkexpr(b2),
10039                     binop(Iop_And32,
10040                           binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10041                           binop(Iop_Sub32, mkU32(1), mkexpr(b6))  /* ~b6 */
10042                           )));
10043
10044   return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10045}
10046
10047static HChar *
10048s390_irgen_CEBR(UChar r1, UChar r2)
10049{
10050   IRTemp op1 = newTemp(Ity_F32);
10051   IRTemp op2 = newTemp(Ity_F32);
10052   IRTemp cc_vex  = newTemp(Ity_I32);
10053   IRTemp cc_s390 = newTemp(Ity_I32);
10054
10055   assign(op1, get_fpr_w0(r1));
10056   assign(op2, get_fpr_w0(r2));
10057   assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10058
10059   assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10060   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10061
10062   return "cebr";
10063}
10064
10065static HChar *
10066s390_irgen_CDBR(UChar r1, UChar r2)
10067{
10068   IRTemp op1 = newTemp(Ity_F64);
10069   IRTemp op2 = newTemp(Ity_F64);
10070   IRTemp cc_vex  = newTemp(Ity_I32);
10071   IRTemp cc_s390 = newTemp(Ity_I32);
10072
10073   assign(op1, get_fpr_dw0(r1));
10074   assign(op2, get_fpr_dw0(r2));
10075   assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10076
10077   assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10078   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10079
10080   return "cdbr";
10081}
10082
10083static HChar *
10084s390_irgen_CXBR(UChar r1, UChar r2)
10085{
10086   IRTemp op1 = newTemp(Ity_F128);
10087   IRTemp op2 = newTemp(Ity_F128);
10088   IRTemp cc_vex  = newTemp(Ity_I32);
10089   IRTemp cc_s390 = newTemp(Ity_I32);
10090
10091   assign(op1, get_fpr_pair(r1));
10092   assign(op2, get_fpr_pair(r2));
10093   assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10094
10095   assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10096   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10097
10098   return "cxbr";
10099}
10100
10101static HChar *
10102s390_irgen_CEB(UChar r1, IRTemp op2addr)
10103{
10104   IRTemp op1 = newTemp(Ity_F32);
10105   IRTemp op2 = newTemp(Ity_F32);
10106   IRTemp cc_vex  = newTemp(Ity_I32);
10107   IRTemp cc_s390 = newTemp(Ity_I32);
10108
10109   assign(op1, get_fpr_w0(r1));
10110   assign(op2, load(Ity_F32, mkexpr(op2addr)));
10111   assign(cc_vex,  binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10112
10113   assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10114   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10115
10116   return "ceb";
10117}
10118
10119static HChar *
10120s390_irgen_CDB(UChar r1, IRTemp op2addr)
10121{
10122   IRTemp op1 = newTemp(Ity_F64);
10123   IRTemp op2 = newTemp(Ity_F64);
10124   IRTemp cc_vex  = newTemp(Ity_I32);
10125   IRTemp cc_s390 = newTemp(Ity_I32);
10126
10127   assign(op1, get_fpr_dw0(r1));
10128   assign(op2, load(Ity_F64, mkexpr(op2addr)));
10129   assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10130
10131   assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10132   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10133
10134   return "cdb";
10135}
10136
10137static HChar *
10138s390_irgen_CXFBR(UChar r1, UChar r2)
10139{
10140   IRTemp op2 = newTemp(Ity_I32);
10141
10142   assign(op2, get_gpr_w1(r2));
10143   put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10144
10145   return "cxfbr";
10146}
10147
10148static HChar *
10149s390_irgen_CXGBR(UChar r1, UChar r2)
10150{
10151   IRTemp op2 = newTemp(Ity_I64);
10152
10153   assign(op2, get_gpr_dw0(r2));
10154   put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10155
10156   return "cxgbr";
10157}
10158
10159static HChar *
10160s390_irgen_CFXBR(UChar r3, UChar r1, UChar r2)
10161{
10162   IRTemp op = newTemp(Ity_F128);
10163   IRTemp result = newTemp(Ity_I32);
10164
10165   assign(op, get_fpr_pair(r2));
10166   assign(result, binop(Iop_F128toI32S, mkU32(encode_rounding_mode(r3)),
10167                        mkexpr(op)));
10168   put_gpr_w1(r1, mkexpr(result));
10169   s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_32, op);
10170
10171   return "cfxbr";
10172}
10173
10174static HChar *
10175s390_irgen_CGXBR(UChar r3, UChar r1, UChar r2)
10176{
10177   IRTemp op = newTemp(Ity_F128);
10178   IRTemp result = newTemp(Ity_I64);
10179
10180   assign(op, get_fpr_pair(r2));
10181   assign(result, binop(Iop_F128toI64S, mkU32(encode_rounding_mode(r3)),
10182                        mkexpr(op)));
10183   put_gpr_dw0(r1, mkexpr(result));
10184   s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_64, op);
10185
10186   return "cgxbr";
10187}
10188
10189static HChar *
10190s390_irgen_DXBR(UChar r1, UChar r2)
10191{
10192   IRTemp op1 = newTemp(Ity_F128);
10193   IRTemp op2 = newTemp(Ity_F128);
10194   IRTemp result = newTemp(Ity_F128);
10195
10196   assign(op1, get_fpr_pair(r1));
10197   assign(op2, get_fpr_pair(r2));
10198   assign(result, triop(Iop_DivF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10199                        mkexpr(op2)));
10200   put_fpr_pair(r1, mkexpr(result));
10201
10202   return "dxbr";
10203}
10204
10205static HChar *
10206s390_irgen_LTXBR(UChar r1, UChar r2)
10207{
10208   IRTemp result = newTemp(Ity_F128);
10209
10210   assign(result, get_fpr_pair(r2));
10211   put_fpr_pair(r1, mkexpr(result));
10212   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10213
10214   return "ltxbr";
10215}
10216
10217static HChar *
10218s390_irgen_LCXBR(UChar r1, UChar r2)
10219{
10220   IRTemp result = newTemp(Ity_F128);
10221
10222   assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10223   put_fpr_pair(r1, mkexpr(result));
10224   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10225
10226   return "lcxbr";
10227}
10228
10229static HChar *
10230s390_irgen_LXDBR(UChar r1, UChar r2)
10231{
10232   IRTemp op = newTemp(Ity_F64);
10233
10234   assign(op, get_fpr_dw0(r2));
10235   put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10236
10237   return "lxdbr";
10238}
10239
10240static HChar *
10241s390_irgen_LXEBR(UChar r1, UChar r2)
10242{
10243   IRTemp op = newTemp(Ity_F32);
10244
10245   assign(op, get_fpr_w0(r2));
10246   put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10247
10248   return "lxebr";
10249}
10250
10251static HChar *
10252s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10253{
10254   IRTemp op = newTemp(Ity_F64);
10255
10256   assign(op, load(Ity_F64, mkexpr(op2addr)));
10257   put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10258
10259   return "lxdb";
10260}
10261
10262static HChar *
10263s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10264{
10265   IRTemp op = newTemp(Ity_F32);
10266
10267   assign(op, load(Ity_F32, mkexpr(op2addr)));
10268   put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10269
10270   return "lxeb";
10271}
10272
10273static HChar *
10274s390_irgen_LNEBR(UChar r1, UChar r2)
10275{
10276   IRTemp result = newTemp(Ity_F32);
10277
10278   assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10279   put_fpr_w0(r1, mkexpr(result));
10280   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10281
10282   return "lnebr";
10283}
10284
10285static HChar *
10286s390_irgen_LNDBR(UChar r1, UChar r2)
10287{
10288   IRTemp result = newTemp(Ity_F64);
10289
10290   assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10291   put_fpr_dw0(r1, mkexpr(result));
10292   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10293
10294   return "lndbr";
10295}
10296
10297static HChar *
10298s390_irgen_LNXBR(UChar r1, UChar r2)
10299{
10300   IRTemp result = newTemp(Ity_F128);
10301
10302   assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10303   put_fpr_pair(r1, mkexpr(result));
10304   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10305
10306   return "lnxbr";
10307}
10308
10309static HChar *
10310s390_irgen_LPEBR(UChar r1, UChar r2)
10311{
10312   IRTemp result = newTemp(Ity_F32);
10313
10314   assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10315   put_fpr_w0(r1, mkexpr(result));
10316   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10317
10318   return "lpebr";
10319}
10320
10321static HChar *
10322s390_irgen_LPDBR(UChar r1, UChar r2)
10323{
10324   IRTemp result = newTemp(Ity_F64);
10325
10326   assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10327   put_fpr_dw0(r1, mkexpr(result));
10328   s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10329
10330   return "lpdbr";
10331}
10332
10333static HChar *
10334s390_irgen_LPXBR(UChar r1, UChar r2)
10335{
10336   IRTemp result = newTemp(Ity_F128);
10337
10338   assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10339   put_fpr_pair(r1, mkexpr(result));
10340   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10341
10342   return "lpxbr";
10343}
10344
10345static HChar *
10346s390_irgen_LDXBR(UChar r1, UChar r2)
10347{
10348   IRTemp result = newTemp(Ity_F64);
10349
10350   assign(result, binop(Iop_F128toF64, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10351   put_fpr_dw0(r1, mkexpr(result));
10352
10353   return "ldxbr";
10354}
10355
10356static HChar *
10357s390_irgen_LEXBR(UChar r1, UChar r2)
10358{
10359   IRTemp result = newTemp(Ity_F32);
10360
10361   assign(result, binop(Iop_F128toF32, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10362   put_fpr_w0(r1, mkexpr(result));
10363
10364   return "lexbr";
10365}
10366
10367static HChar *
10368s390_irgen_MXBR(UChar r1, UChar r2)
10369{
10370   IRTemp op1 = newTemp(Ity_F128);
10371   IRTemp op2 = newTemp(Ity_F128);
10372   IRTemp result = newTemp(Ity_F128);
10373
10374   assign(op1, get_fpr_pair(r1));
10375   assign(op2, get_fpr_pair(r2));
10376   assign(result, triop(Iop_MulF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10377                        mkexpr(op2)));
10378   put_fpr_pair(r1, mkexpr(result));
10379
10380   return "mxbr";
10381}
10382
10383static HChar *
10384s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10385{
10386   put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10387                      get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10388
10389   return "maebr";
10390}
10391
10392static HChar *
10393s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10394{
10395   put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10396                       get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10397
10398   return "madbr";
10399}
10400
10401static HChar *
10402s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10403{
10404   IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10405
10406   put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10407                      get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10408
10409   return "maeb";
10410}
10411
10412static HChar *
10413s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10414{
10415   IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10416
10417   put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10418                       get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10419
10420   return "madb";
10421}
10422
10423static HChar *
10424s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10425{
10426   put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10427                      get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10428
10429   return "msebr";
10430}
10431
10432static HChar *
10433s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10434{
10435   put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10436                       get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10437
10438   return "msdbr";
10439}
10440
10441static HChar *
10442s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10443{
10444   IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10445
10446   put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10447                      get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10448
10449   return "mseb";
10450}
10451
10452static HChar *
10453s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10454{
10455   IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10456
10457   put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10458                       get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10459
10460   return "msdb";
10461}
10462
10463static HChar *
10464s390_irgen_SQEBR(UChar r1, UChar r2)
10465{
10466   IRTemp result = newTemp(Ity_F32);
10467
10468   assign(result, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), get_fpr_w0(r2)));
10469   put_fpr_w0(r1, mkexpr(result));
10470
10471   return "sqebr";
10472}
10473
10474static HChar *
10475s390_irgen_SQDBR(UChar r1, UChar r2)
10476{
10477   IRTemp result = newTemp(Ity_F64);
10478
10479   assign(result, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), get_fpr_dw0(r2)));
10480   put_fpr_dw0(r1, mkexpr(result));
10481
10482   return "sqdbr";
10483}
10484
10485static HChar *
10486s390_irgen_SQXBR(UChar r1, UChar r2)
10487{
10488   IRTemp result = newTemp(Ity_F128);
10489
10490   assign(result, binop(Iop_SqrtF128, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10491   put_fpr_pair(r1, mkexpr(result));
10492
10493   return "sqxbr";
10494}
10495
10496static HChar *
10497s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10498{
10499   IRTemp op = newTemp(Ity_F32);
10500
10501   assign(op, load(Ity_F32, mkexpr(op2addr)));
10502   put_fpr_w0(r1, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), mkexpr(op)));
10503
10504   return "sqeb";
10505}
10506
10507static HChar *
10508s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10509{
10510   IRTemp op = newTemp(Ity_F64);
10511
10512   assign(op, load(Ity_F64, mkexpr(op2addr)));
10513   put_fpr_dw0(r1, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), mkexpr(op)));
10514
10515   return "sqdb";
10516}
10517
10518static HChar *
10519s390_irgen_SXBR(UChar r1, UChar r2)
10520{
10521   IRTemp op1 = newTemp(Ity_F128);
10522   IRTemp op2 = newTemp(Ity_F128);
10523   IRTemp result = newTemp(Ity_F128);
10524
10525   assign(op1, get_fpr_pair(r1));
10526   assign(op2, get_fpr_pair(r2));
10527   assign(result, triop(Iop_SubF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10528                        mkexpr(op2)));
10529   put_fpr_pair(r1, mkexpr(result));
10530   s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10531
10532   return "sxbr";
10533}
10534
10535static HChar *
10536s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10537{
10538   IRTemp value = newTemp(Ity_F32);
10539
10540   assign(value, get_fpr_w0(r1));
10541
10542   s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10543
10544   return "tceb";
10545}
10546
10547static HChar *
10548s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10549{
10550   IRTemp value = newTemp(Ity_F64);
10551
10552   assign(value, get_fpr_dw0(r1));
10553
10554   s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10555
10556   return "tcdb";
10557}
10558
10559static HChar *
10560s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10561{
10562   IRTemp value = newTemp(Ity_F128);
10563
10564   assign(value, get_fpr_pair(r1));
10565
10566   s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
10567
10568   return "tcxb";
10569}
10570
10571static HChar *
10572s390_irgen_LCDFR(UChar r1, UChar r2)
10573{
10574   IRTemp result = newTemp(Ity_F64);
10575
10576   assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
10577   put_fpr_dw0(r1, mkexpr(result));
10578
10579   return "lcdfr";
10580}
10581
10582static HChar *
10583s390_irgen_LNDFR(UChar r1, UChar r2)
10584{
10585   IRTemp result = newTemp(Ity_F64);
10586
10587   assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10588   put_fpr_dw0(r1, mkexpr(result));
10589
10590   return "lndfr";
10591}
10592
10593static HChar *
10594s390_irgen_LPDFR(UChar r1, UChar r2)
10595{
10596   IRTemp result = newTemp(Ity_F64);
10597
10598   assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10599   put_fpr_dw0(r1, mkexpr(result));
10600
10601   return "lpdfr";
10602}
10603
10604static HChar *
10605s390_irgen_LDGR(UChar r1, UChar r2)
10606{
10607   put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
10608
10609   return "ldgr";
10610}
10611
10612static HChar *
10613s390_irgen_LGDR(UChar r1, UChar r2)
10614{
10615   put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
10616
10617   return "lgdr";
10618}
10619
10620
10621static HChar *
10622s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
10623{
10624   IRTemp sign  = newTemp(Ity_I64);
10625   IRTemp value = newTemp(Ity_I64);
10626
10627   assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
10628                      mkU64(1ULL << 63)));
10629   assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
10630                       mkU64((1ULL << 63) - 1)));
10631   put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
10632                                                    mkexpr(sign))));
10633
10634   return "cpsdr";
10635}
10636
10637
10638static IRExpr *
10639s390_call_cvb(IRExpr *in)
10640{
10641   IRExpr **args, *call;
10642
10643   args = mkIRExprVec_1(in);
10644   call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
10645                        "s390_do_cvb", &s390_do_cvb, args);
10646
10647   /* Nothing is excluded from definedness checking. */
10648   call->Iex.CCall.cee->mcx_mask = 0;
10649
10650   return call;
10651}
10652
10653static HChar *
10654s390_irgen_CVB(UChar r1, IRTemp op2addr)
10655{
10656   put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10657
10658   return "cvb";
10659}
10660
10661static HChar *
10662s390_irgen_CVBY(UChar r1, IRTemp op2addr)
10663{
10664   put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10665
10666   return "cvby";
10667}
10668
10669
10670static IRExpr *
10671s390_call_cvd(IRExpr *in)
10672{
10673   IRExpr **args, *call;
10674
10675   args = mkIRExprVec_1(in);
10676   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
10677                        "s390_do_cvd", &s390_do_cvd, args);
10678
10679   /* Nothing is excluded from definedness checking. */
10680   call->Iex.CCall.cee->mcx_mask = 0;
10681
10682   return call;
10683}
10684
10685static HChar *
10686s390_irgen_CVD(UChar r1, IRTemp op2addr)
10687{
10688   store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
10689
10690   return "cvd";
10691}
10692
10693static HChar *
10694s390_irgen_CVDY(UChar r1, IRTemp op2addr)
10695{
10696   store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
10697
10698   return "cvdy";
10699}
10700
10701static HChar *
10702s390_irgen_FLOGR(UChar r1, UChar r2)
10703{
10704   IRTemp input    = newTemp(Ity_I64);
10705   IRTemp not_zero = newTemp(Ity_I64);
10706   IRTemp tmpnum   = newTemp(Ity_I64);
10707   IRTemp num      = newTemp(Ity_I64);
10708   IRTemp shift_amount = newTemp(Ity_I8);
10709
10710   /* We use the "count leading zeroes" operator because the number of
10711      leading zeroes is identical with the bit position of the first '1' bit.
10712      However, that operator does not work when the input value is zero.
10713      Therefore, we set the LSB of the input value to 1 and use Clz64 on
10714      the modified value. If input == 0, then the result is 64. Otherwise,
10715      the result of Clz64 is what we want. */
10716
10717   assign(input, get_gpr_dw0(r2));
10718   assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
10719   assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
10720
10721   /* num = (input == 0) ? 64 : tmpnum */
10722   assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
10723                     /* == 0 */ mkU64(64),
10724                     /* != 0 */ mkexpr(tmpnum)));
10725
10726   put_gpr_dw0(r1, mkexpr(num));
10727
10728   /* Set the leftmost '1' bit of the input value to zero. The general scheme
10729      is to first shift the input value by NUM + 1 bits to the left which
10730      causes the leftmost '1' bit to disappear. Then we shift logically to
10731      the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
10732      Iop_Shr64 are undefined if the shift-amount is greater than or equal to
10733      the width of the value-to-be-shifted, we need to special case
10734      NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
10735      For both such INPUT values the result will be 0. */
10736
10737   assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
10738                          mkU64(1))));
10739
10740   put_gpr_dw0(r1 + 1,
10741               mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
10742                     /* == 0 || == 1*/ mkU64(0),
10743                     /* otherwise */
10744                     binop(Iop_Shr64,
10745                           binop(Iop_Shl64, mkexpr(input),
10746                                 mkexpr(shift_amount)),
10747                           mkexpr(shift_amount))));
10748
10749   /* Compare the original value as an unsigned integer with 0. */
10750   s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
10751                      mktemp(Ity_I64, mkU64(0)), False);
10752
10753   return "flogr";
10754}
10755
10756static HChar *
10757s390_irgen_STCK(IRTemp op2addr)
10758{
10759   IRDirty *d;
10760   IRTemp cc = newTemp(Ity_I64);
10761
10762   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
10763                         &s390x_dirtyhelper_STCK,
10764                         mkIRExprVec_1(mkexpr(op2addr)));
10765   d->mFx   = Ifx_Write;
10766   d->mAddr = mkexpr(op2addr);
10767   d->mSize = 8;
10768   stmt(IRStmt_Dirty(d));
10769   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10770                      mkexpr(cc), mkU64(0), mkU64(0));
10771   return "stck";
10772}
10773
10774static HChar *
10775s390_irgen_STCKF(IRTemp op2addr)
10776{
10777   IRDirty *d;
10778   IRTemp cc = newTemp(Ity_I64);
10779
10780   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
10781                         &s390x_dirtyhelper_STCKF,
10782                         mkIRExprVec_1(mkexpr(op2addr)));
10783   d->mFx   = Ifx_Write;
10784   d->mAddr = mkexpr(op2addr);
10785   d->mSize = 8;
10786   stmt(IRStmt_Dirty(d));
10787   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10788                      mkexpr(cc), mkU64(0), mkU64(0));
10789   return "stckf";
10790}
10791
10792static HChar *
10793s390_irgen_STCKE(IRTemp op2addr)
10794{
10795   IRDirty *d;
10796   IRTemp cc = newTemp(Ity_I64);
10797
10798   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
10799                         &s390x_dirtyhelper_STCKE,
10800                         mkIRExprVec_1(mkexpr(op2addr)));
10801   d->mFx   = Ifx_Write;
10802   d->mAddr = mkexpr(op2addr);
10803   d->mSize = 16;
10804   stmt(IRStmt_Dirty(d));
10805   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10806                      mkexpr(cc), mkU64(0), mkU64(0));
10807   return "stcke";
10808}
10809
10810static HChar *
10811s390_irgen_STFLE(IRTemp op2addr)
10812{
10813   IRDirty *d;
10814   IRTemp cc = newTemp(Ity_I64);
10815
10816   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
10817                         &s390x_dirtyhelper_STFLE,
10818                         mkIRExprVec_1(mkexpr(op2addr)));
10819
10820   d->needsBBP = 1;  /* Need to pass pointer to guest state to helper */
10821
10822   d->nFxState = 1;
10823   vex_bzero(&d->fxState, sizeof(d->fxState));
10824
10825   d->fxState[0].fx     = Ifx_Modify;  /* read then write */
10826   d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
10827   d->fxState[0].size   = sizeof(ULong);
10828
10829   d->mAddr = mkexpr(op2addr);
10830   /* Pretend all double words are written */
10831   d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
10832   d->mFx   = Ifx_Write;
10833
10834   stmt(IRStmt_Dirty(d));
10835
10836   s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
10837
10838   return "stfle";
10839}
10840
10841static HChar *
10842s390_irgen_CKSM(UChar r1,UChar r2)
10843{
10844   IRTemp addr = newTemp(Ity_I64);
10845   IRTemp op = newTemp(Ity_I32);
10846   IRTemp len = newTemp(Ity_I64);
10847   IRTemp oldval = newTemp(Ity_I32);
10848   IRTemp mask = newTemp(Ity_I32);
10849   IRTemp newop = newTemp(Ity_I32);
10850   IRTemp result = newTemp(Ity_I32);
10851   IRTemp result1 = newTemp(Ity_I32);
10852   IRTemp inc = newTemp(Ity_I64);
10853
10854   assign(oldval, get_gpr_w1(r1));
10855   assign(addr, get_gpr_dw0(r2));
10856   assign(len, get_gpr_dw0(r2+1));
10857
10858   /* Condition code is always zero. */
10859   s390_cc_set(0);
10860
10861   /* If length is zero, there is no need to calculate the checksum */
10862   next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
10863
10864   /* Assiging the increment variable to adjust address and length
10865      later on. */
10866   assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
10867                           mkexpr(len), mkU64(4)));
10868
10869   /* If length < 4 the final 4-byte 2nd operand value is computed by
10870      appending the remaining bytes to the right with 0. This is done
10871      by AND'ing the 4 bytes loaded from memory with an appropriate
10872      mask. If length >= 4, that mask is simply 0xffffffff. */
10873
10874   assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
10875                      /* Mask computation when len < 4:
10876                         0xffffffff << (32 - (len % 4)*8) */
10877                      binop(Iop_Shl32, mkU32(0xffffffff),
10878                            unop(Iop_32to8,
10879                                 binop(Iop_Sub32, mkU32(32),
10880                                       binop(Iop_Shl32,
10881                                             unop(Iop_64to32,
10882                                                  binop(Iop_And64,
10883                                                        mkexpr(len), mkU64(3))),
10884                                             mkU8(3))))),
10885                      mkU32(0xffffffff)));
10886
10887   assign(op, load(Ity_I32, mkexpr(addr)));
10888   assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
10889   assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
10890
10891   /* Checking for carry */
10892   assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
10893                         binop(Iop_Add32, mkexpr(result), mkU32(1)),
10894                         mkexpr(result)));
10895
10896   put_gpr_w1(r1, mkexpr(result1));
10897   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
10898   put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
10899
10900   iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
10901
10902   return "cksm";
10903}
10904
10905static HChar *
10906s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
10907{
10908   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
10909   src_addr = newTemp(Ity_I64);
10910   des_addr = newTemp(Ity_I64);
10911   tab_addr = newTemp(Ity_I64);
10912   test_byte = newTemp(Ity_I8);
10913   src_len = newTemp(Ity_I64);
10914
10915   assign(src_addr, get_gpr_dw0(r2));
10916   assign(des_addr, get_gpr_dw0(r1));
10917   assign(tab_addr, get_gpr_dw0(1));
10918   assign(src_len, get_gpr_dw0(r1+1));
10919   assign(test_byte, get_gpr_b7(0));
10920
10921   IRTemp op = newTemp(Ity_I8);
10922   IRTemp op1 = newTemp(Ity_I8);
10923   IRTemp result = newTemp(Ity_I64);
10924
10925   /* End of source string? We're done; proceed to next insn */
10926   s390_cc_set(0);
10927   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
10928
10929   /* Load character from source string, index translation table and
10930      store translated character in op1. */
10931   assign(op, load(Ity_I8, mkexpr(src_addr)));
10932
10933   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
10934                        mkexpr(tab_addr)));
10935   assign(op1, load(Ity_I8, mkexpr(result)));
10936
10937   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
10938      s390_cc_set(1);
10939      next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
10940   }
10941   store(get_gpr_dw0(r1), mkexpr(op1));
10942
10943   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
10944   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
10945   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
10946
10947   iterate();
10948
10949   return "troo";
10950}
10951
10952static HChar *
10953s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
10954{
10955   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
10956   src_addr = newTemp(Ity_I64);
10957   des_addr = newTemp(Ity_I64);
10958   tab_addr = newTemp(Ity_I64);
10959   test_byte = newTemp(Ity_I8);
10960   src_len = newTemp(Ity_I64);
10961
10962   assign(src_addr, get_gpr_dw0(r2));
10963   assign(des_addr, get_gpr_dw0(r1));
10964   assign(tab_addr, get_gpr_dw0(1));
10965   assign(src_len, get_gpr_dw0(r1+1));
10966   assign(test_byte, get_gpr_b7(0));
10967
10968   IRTemp op = newTemp(Ity_I16);
10969   IRTemp op1 = newTemp(Ity_I8);
10970   IRTemp result = newTemp(Ity_I64);
10971
10972   /* End of source string? We're done; proceed to next insn */
10973   s390_cc_set(0);
10974   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
10975
10976   /* Load character from source string, index translation table and
10977      store translated character in op1. */
10978   assign(op, load(Ity_I16, mkexpr(src_addr)));
10979
10980   assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
10981                        mkexpr(tab_addr)));
10982
10983   assign(op1, load(Ity_I8, mkexpr(result)));
10984
10985   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
10986      s390_cc_set(1);
10987      next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
10988   }
10989   store(get_gpr_dw0(r1), mkexpr(op1));
10990
10991   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
10992   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
10993   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
10994
10995   iterate();
10996
10997   return "trto";
10998}
10999
11000static HChar *
11001s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11002{
11003   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11004   src_addr = newTemp(Ity_I64);
11005   des_addr = newTemp(Ity_I64);
11006   tab_addr = newTemp(Ity_I64);
11007   test_byte = newTemp(Ity_I16);
11008   src_len = newTemp(Ity_I64);
11009
11010   assign(src_addr, get_gpr_dw0(r2));
11011   assign(des_addr, get_gpr_dw0(r1));
11012   assign(tab_addr, get_gpr_dw0(1));
11013   assign(src_len, get_gpr_dw0(r1+1));
11014   assign(test_byte, get_gpr_hw3(0));
11015
11016   IRTemp op = newTemp(Ity_I8);
11017   IRTemp op1 = newTemp(Ity_I16);
11018   IRTemp result = newTemp(Ity_I64);
11019
11020   /* End of source string? We're done; proceed to next insn */
11021   s390_cc_set(0);
11022   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
11023
11024   /* Load character from source string, index translation table and
11025      store translated character in op1. */
11026   assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11027
11028   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11029                        mkexpr(tab_addr)));
11030   assign(op1, load(Ity_I16, mkexpr(result)));
11031
11032   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11033      s390_cc_set(1);
11034      next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
11035   }
11036   store(get_gpr_dw0(r1), mkexpr(op1));
11037
11038   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11039   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11040   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11041
11042   iterate();
11043
11044   return "trot";
11045}
11046
11047static HChar *
11048s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11049{
11050   IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11051   src_addr = newTemp(Ity_I64);
11052   des_addr = newTemp(Ity_I64);
11053   tab_addr = newTemp(Ity_I64);
11054   test_byte = newTemp(Ity_I16);
11055   src_len = newTemp(Ity_I64);
11056
11057   assign(src_addr, get_gpr_dw0(r2));
11058   assign(des_addr, get_gpr_dw0(r1));
11059   assign(tab_addr, get_gpr_dw0(1));
11060   assign(src_len, get_gpr_dw0(r1+1));
11061   assign(test_byte, get_gpr_hw3(0));
11062
11063   IRTemp op = newTemp(Ity_I16);
11064   IRTemp op1 = newTemp(Ity_I16);
11065   IRTemp result = newTemp(Ity_I64);
11066
11067   /* End of source string? We're done; proceed to next insn */
11068   s390_cc_set(0);
11069   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
11070
11071   /* Load character from source string, index translation table and
11072      store translated character in op1. */
11073   assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11074
11075   assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11076                        mkexpr(tab_addr)));
11077   assign(op1, load(Ity_I16, mkexpr(result)));
11078
11079   if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11080      s390_cc_set(1);
11081      next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
11082   }
11083
11084   store(get_gpr_dw0(r1), mkexpr(op1));
11085
11086   put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11087   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11088   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11089
11090   iterate();
11091
11092   return "trtt";
11093}
11094
11095static HChar *
11096s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11097{
11098   IRTemp len = newTemp(Ity_I64);
11099
11100   assign(len, mkU64(length));
11101   s390_irgen_TR_EX(len, start1, start2);
11102
11103   return "tr";
11104}
11105
11106static HChar *
11107s390_irgen_TRE(UChar r1,UChar r2)
11108{
11109   IRTemp src_addr, tab_addr, src_len, test_byte;
11110   src_addr = newTemp(Ity_I64);
11111   tab_addr = newTemp(Ity_I64);
11112   src_len = newTemp(Ity_I64);
11113   test_byte = newTemp(Ity_I8);
11114
11115   assign(src_addr, get_gpr_dw0(r1));
11116   assign(src_len, get_gpr_dw0(r1+1));
11117   assign(tab_addr, get_gpr_dw0(r2));
11118   assign(test_byte, get_gpr_b7(0));
11119
11120   IRTemp op = newTemp(Ity_I8);
11121   IRTemp op1 = newTemp(Ity_I8);
11122   IRTemp result = newTemp(Ity_I64);
11123
11124   /* End of source string? We're done; proceed to next insn */
11125   s390_cc_set(0);
11126   next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
11127
11128   /* Load character from source string and compare with test byte */
11129   assign(op, load(Ity_I8, mkexpr(src_addr)));
11130
11131   s390_cc_set(1);
11132   next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
11133
11134   assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11135			mkexpr(tab_addr)));
11136
11137   assign(op1, load(Ity_I8, mkexpr(result)));
11138
11139   store(get_gpr_dw0(r1), mkexpr(op1));
11140   put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11141   put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11142
11143   iterate();
11144
11145   return "tre";
11146}
11147
11148static IRExpr *
11149s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11150{
11151   IRExpr **args, *call;
11152   args = mkIRExprVec_2(srcval, low_surrogate);
11153   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11154                       "s390_do_cu21", &s390_do_cu21, args);
11155
11156   /* Nothing is excluded from definedness checking. */
11157   call->Iex.CCall.cee->mcx_mask = 0;
11158
11159   return call;
11160}
11161
11162static HChar *
11163s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11164{
11165   IRTemp addr1 = newTemp(Ity_I64);
11166   IRTemp addr2 = newTemp(Ity_I64);
11167   IRTemp len1 = newTemp(Ity_I64);
11168   IRTemp len2 = newTemp(Ity_I64);
11169
11170   assign(addr1, get_gpr_dw0(r1));
11171   assign(addr2, get_gpr_dw0(r2));
11172   assign(len1, get_gpr_dw0(r1 + 1));
11173   assign(len2, get_gpr_dw0(r2 + 1));
11174
11175   /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11176      there are less than 2 bytes left, then the 2nd operand is exhausted
11177      and we're done here. cc = 0 */
11178   s390_cc_set(0);
11179   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
11180
11181   /* There are at least two bytes there. Read them. */
11182   IRTemp srcval = newTemp(Ity_I32);
11183   assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11184
11185   /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11186      inside the interval [0xd800 - 0xdbff] */
11187   IRTemp  is_high_surrogate = newTemp(Ity_I32);
11188   IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11189                         mkU32(1), mkU32(0));
11190   IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11191                         mkU32(1), mkU32(0));
11192   assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11193
11194   /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11195      then the 2nd operand is exhausted and we're done here. cc = 0 */
11196   IRExpr *not_enough_bytes =
11197      mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11198
11199   next_insn_if(binop(Iop_CmpEQ32,
11200                      binop(Iop_And32, mkexpr(is_high_surrogate),
11201                            not_enough_bytes), mkU32(1)));
11202
11203   /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11204      surrogate, read the next two bytes (low surrogate). */
11205   IRTemp  low_surrogate = newTemp(Ity_I32);
11206   IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11207
11208   assign(low_surrogate,
11209          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11210                unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11211                mkU32(0)));  // any value is fine; it will not be used
11212
11213   /* Call the helper */
11214   IRTemp retval = newTemp(Ity_I64);
11215   assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11216                                 unop(Iop_32Uto64, mkexpr(low_surrogate))));
11217
11218   /* Before we can test whether the 1st operand is exhausted we need to
11219      test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11220   if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11221      IRExpr *invalid_low_surrogate =
11222         binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11223
11224      s390_cc_set(2);
11225      next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
11226   }
11227
11228   /* Now test whether the 1st operand is exhausted */
11229   IRTemp num_bytes = newTemp(Ity_I64);
11230   assign(num_bytes, binop(Iop_And64,
11231                           binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11232                           mkU64(0xff)));
11233   s390_cc_set(1);
11234   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11235
11236   /* Extract the bytes to be stored at addr1 */
11237   IRTemp data = newTemp(Ity_I64);
11238   assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11239
11240   /* To store the bytes construct 4 dirty helper calls. The helper calls
11241      are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11242      one of them will be called at runtime. */
11243   int i;
11244   for (i = 1; i <= 4; ++i) {
11245      IRDirty *d;
11246
11247      d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11248                            &s390x_dirtyhelper_CUxy,
11249                            mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11250                                          mkexpr(num_bytes)));
11251      d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11252      d->mFx   = Ifx_Write;
11253      d->mAddr = mkexpr(addr1);
11254      d->mSize = i;
11255      stmt(IRStmt_Dirty(d));
11256   }
11257
11258   /* Update source address and length */
11259   IRTemp num_src_bytes = newTemp(Ity_I64);
11260   assign(num_src_bytes,
11261          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11262                mkU64(4), mkU64(2)));
11263   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11264   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
11265
11266   /* Update destination address and length */
11267   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11268   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
11269
11270   iterate();
11271
11272   return "cu21";
11273}
11274
11275static IRExpr *
11276s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11277{
11278   IRExpr **args, *call;
11279   args = mkIRExprVec_2(srcval, low_surrogate);
11280   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11281                       "s390_do_cu24", &s390_do_cu24, args);
11282
11283   /* Nothing is excluded from definedness checking. */
11284   call->Iex.CCall.cee->mcx_mask = 0;
11285
11286   return call;
11287}
11288
11289static HChar *
11290s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11291{
11292   IRTemp addr1 = newTemp(Ity_I64);
11293   IRTemp addr2 = newTemp(Ity_I64);
11294   IRTemp len1 = newTemp(Ity_I64);
11295   IRTemp len2 = newTemp(Ity_I64);
11296
11297   assign(addr1, get_gpr_dw0(r1));
11298   assign(addr2, get_gpr_dw0(r2));
11299   assign(len1, get_gpr_dw0(r1 + 1));
11300   assign(len2, get_gpr_dw0(r2 + 1));
11301
11302   /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11303      there are less than 2 bytes left, then the 2nd operand is exhausted
11304      and we're done here. cc = 0 */
11305   s390_cc_set(0);
11306   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
11307
11308   /* There are at least two bytes there. Read them. */
11309   IRTemp srcval = newTemp(Ity_I32);
11310   assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11311
11312   /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11313      inside the interval [0xd800 - 0xdbff] */
11314   IRTemp  is_high_surrogate = newTemp(Ity_I32);
11315   IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11316                         mkU32(1), mkU32(0));
11317   IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11318                         mkU32(1), mkU32(0));
11319   assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11320
11321   /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11322      then the 2nd operand is exhausted and we're done here. cc = 0 */
11323   IRExpr *not_enough_bytes =
11324      mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11325
11326   next_insn_if(binop(Iop_CmpEQ32,
11327                      binop(Iop_And32, mkexpr(is_high_surrogate),
11328                            not_enough_bytes),
11329                      mkU32(1)));
11330
11331   /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11332      surrogate, read the next two bytes (low surrogate). */
11333   IRTemp  low_surrogate = newTemp(Ity_I32);
11334   IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11335
11336   assign(low_surrogate,
11337          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11338                unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11339                mkU32(0)));  // any value is fine; it will not be used
11340
11341   /* Call the helper */
11342   IRTemp retval = newTemp(Ity_I64);
11343   assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
11344                                 unop(Iop_32Uto64, mkexpr(low_surrogate))));
11345
11346   /* Before we can test whether the 1st operand is exhausted we need to
11347      test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11348   if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11349      IRExpr *invalid_low_surrogate =
11350         binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11351
11352      s390_cc_set(2);
11353      next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
11354   }
11355
11356   /* Now test whether the 1st operand is exhausted */
11357   s390_cc_set(1);
11358   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
11359
11360   /* Extract the bytes to be stored at addr1 */
11361   IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11362
11363   store(mkexpr(addr1), data);
11364
11365   /* Update source address and length */
11366   IRTemp num_src_bytes = newTemp(Ity_I64);
11367   assign(num_src_bytes,
11368          mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11369                mkU64(4), mkU64(2)));
11370   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11371   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
11372
11373   /* Update destination address and length */
11374   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11375   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkU64(4)));
11376
11377   iterate();
11378
11379   return "cu24";
11380}
11381
11382static IRExpr *
11383s390_call_cu42(IRExpr *srcval)
11384{
11385   IRExpr **args, *call;
11386   args = mkIRExprVec_1(srcval);
11387   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11388                       "s390_do_cu42", &s390_do_cu42, args);
11389
11390   /* Nothing is excluded from definedness checking. */
11391   call->Iex.CCall.cee->mcx_mask = 0;
11392
11393   return call;
11394}
11395
11396static HChar *
11397s390_irgen_CU42(UChar r1, UChar r2)
11398{
11399   IRTemp addr1 = newTemp(Ity_I64);
11400   IRTemp addr2 = newTemp(Ity_I64);
11401   IRTemp len1 = newTemp(Ity_I64);
11402   IRTemp len2 = newTemp(Ity_I64);
11403
11404   assign(addr1, get_gpr_dw0(r1));
11405   assign(addr2, get_gpr_dw0(r2));
11406   assign(len1, get_gpr_dw0(r1 + 1));
11407   assign(len2, get_gpr_dw0(r2 + 1));
11408
11409   /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11410      there are less than 4 bytes left, then the 2nd operand is exhausted
11411      and we're done here. cc = 0 */
11412   s390_cc_set(0);
11413   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11414
11415   /* Read the 2nd operand. */
11416   IRTemp srcval = newTemp(Ity_I32);
11417   assign(srcval, load(Ity_I32, mkexpr(addr2)));
11418
11419   /* Call the helper */
11420   IRTemp retval = newTemp(Ity_I64);
11421   assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
11422
11423   /* If the UTF-32 character was invalid, set cc=2 and we're done.
11424      cc=2 outranks cc=1 (1st operand exhausted) */
11425   IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11426
11427   s390_cc_set(2);
11428   next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11429
11430   /* Now test whether the 1st operand is exhausted */
11431   IRTemp num_bytes = newTemp(Ity_I64);
11432   assign(num_bytes, binop(Iop_And64,
11433                           binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11434                           mkU64(0xff)));
11435   s390_cc_set(1);
11436   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11437
11438   /* Extract the bytes to be stored at addr1 */
11439   IRTemp data = newTemp(Ity_I64);
11440   assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11441
11442   /* To store the bytes construct 2 dirty helper calls. The helper calls
11443      are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11444      that only one of them will be called at runtime. */
11445
11446   Int i;
11447   for (i = 2; i <= 4; ++i) {
11448      IRDirty *d;
11449
11450      if (i == 3) continue;  // skip this one
11451
11452      d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11453                            &s390x_dirtyhelper_CUxy,
11454                            mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11455                                          mkexpr(num_bytes)));
11456      d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11457      d->mFx   = Ifx_Write;
11458      d->mAddr = mkexpr(addr1);
11459      d->mSize = i;
11460      stmt(IRStmt_Dirty(d));
11461   }
11462
11463   /* Update source address and length */
11464   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11465   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkU64(4)));
11466
11467   /* Update destination address and length */
11468   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11469   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
11470
11471   iterate();
11472
11473   return "cu42";
11474}
11475
11476static IRExpr *
11477s390_call_cu41(IRExpr *srcval)
11478{
11479   IRExpr **args, *call;
11480   args = mkIRExprVec_1(srcval);
11481   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11482                       "s390_do_cu41", &s390_do_cu41, args);
11483
11484   /* Nothing is excluded from definedness checking. */
11485   call->Iex.CCall.cee->mcx_mask = 0;
11486
11487   return call;
11488}
11489
11490static HChar *
11491s390_irgen_CU41(UChar r1, UChar r2)
11492{
11493   IRTemp addr1 = newTemp(Ity_I64);
11494   IRTemp addr2 = newTemp(Ity_I64);
11495   IRTemp len1 = newTemp(Ity_I64);
11496   IRTemp len2 = newTemp(Ity_I64);
11497
11498   assign(addr1, get_gpr_dw0(r1));
11499   assign(addr2, get_gpr_dw0(r2));
11500   assign(len1, get_gpr_dw0(r1 + 1));
11501   assign(len2, get_gpr_dw0(r2 + 1));
11502
11503   /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11504      there are less than 4 bytes left, then the 2nd operand is exhausted
11505      and we're done here. cc = 0 */
11506   s390_cc_set(0);
11507   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11508
11509   /* Read the 2nd operand. */
11510   IRTemp srcval = newTemp(Ity_I32);
11511   assign(srcval, load(Ity_I32, mkexpr(addr2)));
11512
11513   /* Call the helper */
11514   IRTemp retval = newTemp(Ity_I64);
11515   assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
11516
11517   /* If the UTF-32 character was invalid, set cc=2 and we're done.
11518      cc=2 outranks cc=1 (1st operand exhausted) */
11519   IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11520
11521   s390_cc_set(2);
11522   next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11523
11524   /* Now test whether the 1st operand is exhausted */
11525   IRTemp num_bytes = newTemp(Ity_I64);
11526   assign(num_bytes, binop(Iop_And64,
11527                           binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11528                           mkU64(0xff)));
11529   s390_cc_set(1);
11530   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11531
11532   /* Extract the bytes to be stored at addr1 */
11533   IRTemp data = newTemp(Ity_I64);
11534   assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11535
11536   /* To store the bytes construct 4 dirty helper calls. The helper calls
11537      are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11538      one of them will be called at runtime. */
11539   int i;
11540   for (i = 1; i <= 4; ++i) {
11541      IRDirty *d;
11542
11543      d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11544                            &s390x_dirtyhelper_CUxy,
11545                            mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11546                                          mkexpr(num_bytes)));
11547      d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11548      d->mFx   = Ifx_Write;
11549      d->mAddr = mkexpr(addr1);
11550      d->mSize = i;
11551      stmt(IRStmt_Dirty(d));
11552   }
11553
11554   /* Update source address and length */
11555   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11556   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkU64(4)));
11557
11558   /* Update destination address and length */
11559   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11560   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
11561
11562   iterate();
11563
11564   return "cu41";
11565}
11566
11567static IRExpr *
11568s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
11569{
11570   IRExpr **args, *call;
11571   args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
11572   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
11573                        &s390_do_cu12_cu14_helper1, args);
11574
11575   /* Nothing is excluded from definedness checking. */
11576   call->Iex.CCall.cee->mcx_mask = 0;
11577
11578   return call;
11579}
11580
11581static IRExpr *
11582s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11583                       IRExpr *byte4, IRExpr *stuff)
11584{
11585   IRExpr **args, *call;
11586   args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11587   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11588                        "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
11589
11590   /* Nothing is excluded from definedness checking. */
11591   call->Iex.CCall.cee->mcx_mask = 0;
11592
11593   return call;
11594}
11595
11596static IRExpr *
11597s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11598                       IRExpr *byte4, IRExpr *stuff)
11599{
11600   IRExpr **args, *call;
11601   args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11602   call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11603                        "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
11604
11605   /* Nothing is excluded from definedness checking. */
11606   call->Iex.CCall.cee->mcx_mask = 0;
11607
11608   return call;
11609}
11610
11611static void
11612s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
11613{
11614   IRTemp addr1 = newTemp(Ity_I64);
11615   IRTemp addr2 = newTemp(Ity_I64);
11616   IRTemp len1 = newTemp(Ity_I64);
11617   IRTemp len2 = newTemp(Ity_I64);
11618
11619   assign(addr1, get_gpr_dw0(r1));
11620   assign(addr2, get_gpr_dw0(r2));
11621   assign(len1, get_gpr_dw0(r1 + 1));
11622   assign(len2, get_gpr_dw0(r2 + 1));
11623
11624   UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
11625
11626   /* We're processing the 2nd operand 1 byte at a time. Therefore, if
11627      there is less than 1 byte left, then the 2nd operand is exhausted
11628      and we're done here. cc = 0 */
11629   s390_cc_set(0);
11630   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
11631
11632   /* There is at least one byte there. Read it. */
11633   IRTemp byte1 = newTemp(Ity_I64);
11634   assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
11635
11636   /* Call the helper to get number of bytes and invalid byte indicator */
11637   IRTemp retval1 = newTemp(Ity_I64);
11638   assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
11639                                               mkU64(extended_checking)));
11640
11641   /* Check for invalid 1st byte */
11642   IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
11643   s390_cc_set(2);
11644   next_insn_if(is_invalid);
11645
11646   /* How many bytes do we have to read? */
11647   IRTemp num_src_bytes = newTemp(Ity_I64);
11648   assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
11649
11650   /* Now test whether the 2nd operand is exhausted */
11651   s390_cc_set(0);
11652   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
11653
11654   /* Read the remaining bytes */
11655   IRExpr *cond, *addr, *byte2, *byte3, *byte4;
11656
11657   cond  = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
11658   addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
11659   byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
11660   cond  = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
11661   addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11662   byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
11663   cond  = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
11664   addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
11665   byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
11666
11667   /* Call the helper to get the converted value and invalid byte indicator.
11668      We can pass at most 5 arguments; therefore some encoding is needed
11669      here */
11670   IRExpr *stuff = binop(Iop_Or64,
11671                         binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
11672                         mkU64(extended_checking));
11673   IRTemp retval2 = newTemp(Ity_I64);
11674
11675   if (is_cu12) {
11676      assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
11677                                             byte4, stuff));
11678   } else {
11679      assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
11680                                             byte4, stuff));
11681   }
11682
11683   /* Check for invalid character */
11684   s390_cc_set(2);
11685   is_invalid = unop(Iop_64to1, mkexpr(retval2));
11686   next_insn_if(is_invalid);
11687
11688   /* Now test whether the 1st operand is exhausted */
11689   IRTemp num_bytes = newTemp(Ity_I64);
11690   assign(num_bytes, binop(Iop_And64,
11691                           binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
11692                           mkU64(0xff)));
11693   s390_cc_set(1);
11694   next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11695
11696   /* Extract the bytes to be stored at addr1 */
11697   IRTemp data = newTemp(Ity_I64);
11698   assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
11699
11700   if (is_cu12) {
11701      /* To store the bytes construct 2 dirty helper calls. The helper calls
11702         are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11703         that only one of them will be called at runtime. */
11704
11705      Int i;
11706      for (i = 2; i <= 4; ++i) {
11707         IRDirty *d;
11708
11709         if (i == 3) continue;  // skip this one
11710
11711         d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11712                               &s390x_dirtyhelper_CUxy,
11713                               mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11714                                             mkexpr(num_bytes)));
11715         d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11716         d->mFx   = Ifx_Write;
11717         d->mAddr = mkexpr(addr1);
11718         d->mSize = i;
11719         stmt(IRStmt_Dirty(d));
11720      }
11721   } else {
11722      // cu14
11723      store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
11724   }
11725
11726   /* Update source address and length */
11727   put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11728   put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
11729
11730   /* Update destination address and length */
11731   put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11732   put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
11733
11734   iterate();
11735}
11736
11737static HChar *
11738s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
11739{
11740   s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
11741
11742   return "cu12";
11743}
11744
11745static HChar *
11746s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
11747{
11748   s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
11749
11750   return "cu14";
11751}
11752
11753/*------------------------------------------------------------*/
11754/*--- Build IR for special instructions                    ---*/
11755/*------------------------------------------------------------*/
11756
11757static void
11758s390_irgen_client_request(void)
11759{
11760   if (0)
11761      vex_printf("%%R3 = client_request ( %%R2 )\n");
11762
11763   Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
11764                                     + S390_SPECIAL_OP_SIZE;
11765
11766   dis_res->jk_StopHere = Ijk_ClientReq;
11767   dis_res->whatNext = Dis_StopHere;
11768
11769   put_IA(mkaddr_expr(next));
11770}
11771
11772static void
11773s390_irgen_guest_NRADDR(void)
11774{
11775   if (0)
11776      vex_printf("%%R3 = guest_NRADDR\n");
11777
11778   put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
11779}
11780
11781static void
11782s390_irgen_call_noredir(void)
11783{
11784   Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
11785                                     + S390_SPECIAL_OP_SIZE;
11786
11787   /* Continue after special op */
11788   put_gpr_dw0(14, mkaddr_expr(next));
11789
11790   /* The address is in REG1, all parameters are in the right (guest) places */
11791   put_IA(get_gpr_dw0(1));
11792
11793   dis_res->whatNext = Dis_StopHere;
11794   dis_res->jk_StopHere = Ijk_NoRedir;
11795}
11796
11797/* Force proper alignment for the structures below. */
11798#pragma pack(1)
11799
11800
11801static s390_decode_t
11802s390_decode_2byte_and_irgen(UChar *bytes)
11803{
11804   typedef union {
11805      struct {
11806         unsigned int op : 16;
11807      } E;
11808      struct {
11809         unsigned int op :  8;
11810         unsigned int i  :  8;
11811      } I;
11812      struct {
11813         unsigned int op :  8;
11814         unsigned int r1 :  4;
11815         unsigned int r2 :  4;
11816      } RR;
11817   } formats;
11818   union {
11819      formats fmt;
11820      UShort value;
11821   } ovl;
11822
11823   vassert(sizeof(formats) == 2);
11824
11825   ((char *)(&ovl.value))[0] = bytes[0];
11826   ((char *)(&ovl.value))[1] = bytes[1];
11827
11828   switch (ovl.value & 0xffff) {
11829   case 0x0101: /* PR */ goto unimplemented;
11830   case 0x0102: /* UPT */ goto unimplemented;
11831   case 0x0104: /* PTFF */ goto unimplemented;
11832   case 0x0107: /* SCKPF */ goto unimplemented;
11833   case 0x010a: /* PFPO */ goto unimplemented;
11834   case 0x010b: /* TAM */ goto unimplemented;
11835   case 0x010c: /* SAM24 */ goto unimplemented;
11836   case 0x010d: /* SAM31 */ goto unimplemented;
11837   case 0x010e: /* SAM64 */ goto unimplemented;
11838   case 0x01ff: /* TRAP2 */ goto unimplemented;
11839   }
11840
11841   switch ((ovl.value & 0xff00) >> 8) {
11842   case 0x04: /* SPM */ goto unimplemented;
11843   case 0x05: /* BALR */ goto unimplemented;
11844   case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11845                                goto ok;
11846   case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11847                             goto ok;
11848   case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i);  goto ok;
11849   case 0x0b: /* BSM */ goto unimplemented;
11850   case 0x0c: /* BASSM */ goto unimplemented;
11851   case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11852                                goto ok;
11853   case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11854                             goto ok;
11855   case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11856                             goto ok;
11857   case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11858                                goto ok;
11859   case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11860                                goto ok;
11861   case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11862                                goto ok;
11863   case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11864                                goto ok;
11865   case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11866                                goto ok;
11867   case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11868                                goto ok;
11869   case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11870                                goto ok;
11871   case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11872                                goto ok;
11873   case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11874                                goto ok;
11875   case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11876                                goto ok;
11877   case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11878                                goto ok;
11879   case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11880                                goto ok;
11881   case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11882                                goto ok;
11883   case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11884                                goto ok;
11885   case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11886                                goto ok;
11887   case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11888                                goto ok;
11889   case 0x20: /* LPDR */ goto unimplemented;
11890   case 0x21: /* LNDR */ goto unimplemented;
11891   case 0x22: /* LTDR */ goto unimplemented;
11892   case 0x23: /* LCDR */ goto unimplemented;
11893   case 0x24: /* HDR */ goto unimplemented;
11894   case 0x25: /* LDXR */ goto unimplemented;
11895   case 0x26: /* MXR */ goto unimplemented;
11896   case 0x27: /* MXDR */ goto unimplemented;
11897   case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11898                                goto ok;
11899   case 0x29: /* CDR */ goto unimplemented;
11900   case 0x2a: /* ADR */ goto unimplemented;
11901   case 0x2b: /* SDR */ goto unimplemented;
11902   case 0x2c: /* MDR */ goto unimplemented;
11903   case 0x2d: /* DDR */ goto unimplemented;
11904   case 0x2e: /* AWR */ goto unimplemented;
11905   case 0x2f: /* SWR */ goto unimplemented;
11906   case 0x30: /* LPER */ goto unimplemented;
11907   case 0x31: /* LNER */ goto unimplemented;
11908   case 0x32: /* LTER */ goto unimplemented;
11909   case 0x33: /* LCER */ goto unimplemented;
11910   case 0x34: /* HER */ goto unimplemented;
11911   case 0x35: /* LEDR */ goto unimplemented;
11912   case 0x36: /* AXR */ goto unimplemented;
11913   case 0x37: /* SXR */ goto unimplemented;
11914   case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11915                                goto ok;
11916   case 0x39: /* CER */ goto unimplemented;
11917   case 0x3a: /* AER */ goto unimplemented;
11918   case 0x3b: /* SER */ goto unimplemented;
11919   case 0x3c: /* MDER */ goto unimplemented;
11920   case 0x3d: /* DER */ goto unimplemented;
11921   case 0x3e: /* AUR */ goto unimplemented;
11922   case 0x3f: /* SUR */ goto unimplemented;
11923   }
11924
11925   return S390_DECODE_UNKNOWN_INSN;
11926
11927ok:
11928   return S390_DECODE_OK;
11929
11930unimplemented:
11931   return S390_DECODE_UNIMPLEMENTED_INSN;
11932}
11933
11934static s390_decode_t
11935s390_decode_4byte_and_irgen(UChar *bytes)
11936{
11937   typedef union {
11938      struct {
11939         unsigned int op1 :  8;
11940         unsigned int r1  :  4;
11941         unsigned int op2 :  4;
11942         unsigned int i2  : 16;
11943      } RI;
11944      struct {
11945         unsigned int op : 16;
11946         unsigned int    :  8;
11947         unsigned int r1 :  4;
11948         unsigned int r2 :  4;
11949      } RRE;
11950      struct {
11951         unsigned int op : 16;
11952         unsigned int r1 :  4;
11953         unsigned int    :  4;
11954         unsigned int r3 :  4;
11955         unsigned int r2 :  4;
11956      } RRF;
11957      struct {
11958         unsigned int op : 16;
11959         unsigned int r3 :  4;
11960         unsigned int m4 :  4;
11961         unsigned int r1 :  4;
11962         unsigned int r2 :  4;
11963      } RRF2;
11964      struct {
11965         unsigned int op : 16;
11966         unsigned int r3 :  4;
11967         unsigned int    :  4;
11968         unsigned int r1 :  4;
11969         unsigned int r2 :  4;
11970      } RRF3;
11971      struct {
11972         unsigned int op : 16;
11973         unsigned int r3 :  4;
11974         unsigned int    :  4;
11975         unsigned int r1 :  4;
11976         unsigned int r2 :  4;
11977      } RRR;
11978      struct {
11979         unsigned int op : 16;
11980         unsigned int r3 :  4;
11981         unsigned int    :  4;
11982         unsigned int r1 :  4;
11983         unsigned int r2 :  4;
11984      } RRF4;
11985      struct {
11986         unsigned int op :  8;
11987         unsigned int r1 :  4;
11988         unsigned int r3 :  4;
11989         unsigned int b2 :  4;
11990         unsigned int d2 : 12;
11991      } RS;
11992      struct {
11993         unsigned int op :  8;
11994         unsigned int r1 :  4;
11995         unsigned int r3 :  4;
11996         unsigned int i2 : 16;
11997      } RSI;
11998      struct {
11999         unsigned int op :  8;
12000         unsigned int r1 :  4;
12001         unsigned int x2 :  4;
12002         unsigned int b2 :  4;
12003         unsigned int d2 : 12;
12004      } RX;
12005      struct {
12006         unsigned int op : 16;
12007         unsigned int b2 :  4;
12008         unsigned int d2 : 12;
12009      } S;
12010      struct {
12011         unsigned int op :  8;
12012         unsigned int i2 :  8;
12013         unsigned int b1 :  4;
12014         unsigned int d1 : 12;
12015      } SI;
12016   } formats;
12017   union {
12018      formats fmt;
12019      UInt value;
12020   } ovl;
12021
12022   vassert(sizeof(formats) == 4);
12023
12024   ((char *)(&ovl.value))[0] = bytes[0];
12025   ((char *)(&ovl.value))[1] = bytes[1];
12026   ((char *)(&ovl.value))[2] = bytes[2];
12027   ((char *)(&ovl.value))[3] = bytes[3];
12028
12029   switch ((ovl.value & 0xff0f0000) >> 16) {
12030   case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12031                                  ovl.fmt.RI.i2);  goto ok;
12032   case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12033                                  ovl.fmt.RI.i2);  goto ok;
12034   case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12035                                  ovl.fmt.RI.i2);  goto ok;
12036   case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12037                                  ovl.fmt.RI.i2);  goto ok;
12038   case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12039                                  ovl.fmt.RI.i2);  goto ok;
12040   case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12041                                  ovl.fmt.RI.i2);  goto ok;
12042   case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12043                                  ovl.fmt.RI.i2);  goto ok;
12044   case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12045                                  ovl.fmt.RI.i2);  goto ok;
12046   case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12047                                  ovl.fmt.RI.i2);  goto ok;
12048   case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12049                                  ovl.fmt.RI.i2);  goto ok;
12050   case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12051                                  ovl.fmt.RI.i2);  goto ok;
12052   case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12053                                  ovl.fmt.RI.i2);  goto ok;
12054   case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12055                                  ovl.fmt.RI.i2);  goto ok;
12056   case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12057                                  ovl.fmt.RI.i2);  goto ok;
12058   case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12059                                  ovl.fmt.RI.i2);  goto ok;
12060   case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12061                                  ovl.fmt.RI.i2);  goto ok;
12062   case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12063                                  ovl.fmt.RI.i2);  goto ok;
12064   case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12065                                  ovl.fmt.RI.i2);  goto ok;
12066   case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12067                                  ovl.fmt.RI.i2);  goto ok;
12068   case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12069                                  ovl.fmt.RI.i2);  goto ok;
12070   case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12071                               goto ok;
12072   case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12073                                  ovl.fmt.RI.i2);  goto ok;
12074   case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12075                                  ovl.fmt.RI.i2);  goto ok;
12076   case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12077                                  ovl.fmt.RI.i2);  goto ok;
12078   case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12079                                  goto ok;
12080   case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12081                                  ovl.fmt.RI.i2);  goto ok;
12082   case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12083                                  goto ok;
12084   case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12085                                  ovl.fmt.RI.i2);  goto ok;
12086   case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12087                                  goto ok;
12088   case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12089                                  ovl.fmt.RI.i2);  goto ok;
12090   case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12091                                  goto ok;
12092   case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12093                                  ovl.fmt.RI.i2);  goto ok;
12094   }
12095
12096   switch ((ovl.value & 0xffff0000) >> 16) {
12097   case 0x8000: /* SSM */ goto unimplemented;
12098   case 0x8200: /* LPSW */ goto unimplemented;
12099   case 0x9300: /* TS */ goto unimplemented;
12100   case 0xb202: /* STIDP */ goto unimplemented;
12101   case 0xb204: /* SCK */ goto unimplemented;
12102   case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12103                goto ok;
12104   case 0xb206: /* SCKC */ goto unimplemented;
12105   case 0xb207: /* STCKC */ goto unimplemented;
12106   case 0xb208: /* SPT */ goto unimplemented;
12107   case 0xb209: /* STPT */ goto unimplemented;
12108   case 0xb20a: /* SPKA */ goto unimplemented;
12109   case 0xb20b: /* IPK */ goto unimplemented;
12110   case 0xb20d: /* PTLB */ goto unimplemented;
12111   case 0xb210: /* SPX */ goto unimplemented;
12112   case 0xb211: /* STPX */ goto unimplemented;
12113   case 0xb212: /* STAP */ goto unimplemented;
12114   case 0xb214: /* SIE */ goto unimplemented;
12115   case 0xb218: /* PC */ goto unimplemented;
12116   case 0xb219: /* SAC */ goto unimplemented;
12117   case 0xb21a: /* CFC */ goto unimplemented;
12118   case 0xb221: /* IPTE */ goto unimplemented;
12119   case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1);  goto ok;
12120   case 0xb223: /* IVSK */ goto unimplemented;
12121   case 0xb224: /* IAC */ goto unimplemented;
12122   case 0xb225: /* SSAR */ goto unimplemented;
12123   case 0xb226: /* EPAR */ goto unimplemented;
12124   case 0xb227: /* ESAR */ goto unimplemented;
12125   case 0xb228: /* PT */ goto unimplemented;
12126   case 0xb229: /* ISKE */ goto unimplemented;
12127   case 0xb22a: /* RRBE */ goto unimplemented;
12128   case 0xb22b: /* SSKE */ goto unimplemented;
12129   case 0xb22c: /* TB */ goto unimplemented;
12130   case 0xb22d: /* DXR */ goto unimplemented;
12131   case 0xb22e: /* PGIN */ goto unimplemented;
12132   case 0xb22f: /* PGOUT */ goto unimplemented;
12133   case 0xb230: /* CSCH */ goto unimplemented;
12134   case 0xb231: /* HSCH */ goto unimplemented;
12135   case 0xb232: /* MSCH */ goto unimplemented;
12136   case 0xb233: /* SSCH */ goto unimplemented;
12137   case 0xb234: /* STSCH */ goto unimplemented;
12138   case 0xb235: /* TSCH */ goto unimplemented;
12139   case 0xb236: /* TPI */ goto unimplemented;
12140   case 0xb237: /* SAL */ goto unimplemented;
12141   case 0xb238: /* RSCH */ goto unimplemented;
12142   case 0xb239: /* STCRW */ goto unimplemented;
12143   case 0xb23a: /* STCPS */ goto unimplemented;
12144   case 0xb23b: /* RCHP */ goto unimplemented;
12145   case 0xb23c: /* SCHM */ goto unimplemented;
12146   case 0xb240: /* BAKR */ goto unimplemented;
12147   case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12148                                ovl.fmt.RRE.r2);  goto ok;
12149   case 0xb244: /* SQDR */ goto unimplemented;
12150   case 0xb245: /* SQER */ goto unimplemented;
12151   case 0xb246: /* STURA */ goto unimplemented;
12152   case 0xb247: /* MSTA */ goto unimplemented;
12153   case 0xb248: /* PALB */ goto unimplemented;
12154   case 0xb249: /* EREG */ goto unimplemented;
12155   case 0xb24a: /* ESTA */ goto unimplemented;
12156   case 0xb24b: /* LURA */ goto unimplemented;
12157   case 0xb24c: /* TAR */ goto unimplemented;
12158   case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12159                                ovl.fmt.RRE.r2);  goto ok;
12160   case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12161                                goto ok;
12162   case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12163                                goto ok;
12164   case 0xb250: /* CSP */ goto unimplemented;
12165   case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12166                                   ovl.fmt.RRE.r2);  goto ok;
12167   case 0xb254: /* MVPG */ goto unimplemented;
12168   case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12169                                   ovl.fmt.RRE.r2);  goto ok;
12170   case 0xb257: /* CUSE */ goto unimplemented;
12171   case 0xb258: /* BSG */ goto unimplemented;
12172   case 0xb25a: /* BSA */ goto unimplemented;
12173   case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12174                                   ovl.fmt.RRE.r2);  goto ok;
12175   case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12176                                   ovl.fmt.RRE.r2);  goto ok;
12177   case 0xb263: /* CMPSC */ goto unimplemented;
12178   case 0xb274: /* SIGA */ goto unimplemented;
12179   case 0xb276: /* XSCH */ goto unimplemented;
12180   case 0xb277: /* RP */ goto unimplemented;
12181   case 0xb278: s390_format_S_RD(s390_irgen_STCKE, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
12182   case 0xb279: /* SACF */ goto unimplemented;
12183   case 0xb27c: s390_format_S_RD(s390_irgen_STCKF, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
12184   case 0xb27d: /* STSI */ goto unimplemented;
12185   case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12186                                 goto ok;
12187   case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12188                                 goto ok;
12189   case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12190                                 goto ok;
12191   case 0xb2a5: s390_format_RRE_FF(s390_irgen_TRE, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);  goto ok;
12192   case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12193                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12194      goto ok;
12195   case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12196                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12197      goto ok;
12198   case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12199                                 goto ok;
12200   case 0xb2b1: /* STFL */ goto unimplemented;
12201   case 0xb2b2: /* LPSWE */ goto unimplemented;
12202   case 0xb2b8: /* SRNMB */ goto unimplemented;
12203   case 0xb2b9: /* SRNMT */ goto unimplemented;
12204   case 0xb2bd: /* LFAS */ goto unimplemented;
12205   case 0xb2ff: /* TRAP4 */ goto unimplemented;
12206   case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12207                                   ovl.fmt.RRE.r2);  goto ok;
12208   case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12209                                   ovl.fmt.RRE.r2);  goto ok;
12210   case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12211                                   ovl.fmt.RRE.r2);  goto ok;
12212   case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12213                                   ovl.fmt.RRE.r2);  goto ok;
12214   case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12215                                   ovl.fmt.RRE.r2);  goto ok;
12216   case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12217                                   ovl.fmt.RRE.r2);  goto ok;
12218   case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12219                                   ovl.fmt.RRE.r2);  goto ok;
12220   case 0xb307: /* MXDBR */ goto unimplemented;
12221   case 0xb308: /* KEBR */ goto unimplemented;
12222   case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12223                                   ovl.fmt.RRE.r2);  goto ok;
12224   case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12225                                   ovl.fmt.RRE.r2);  goto ok;
12226   case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12227                                   ovl.fmt.RRE.r2);  goto ok;
12228   case 0xb30c: /* MDEBR */ goto unimplemented;
12229   case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12230                                   ovl.fmt.RRE.r2);  goto ok;
12231   case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12232                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
12233   case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12234                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
12235   case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12236                                   ovl.fmt.RRE.r2);  goto ok;
12237   case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12238                                   ovl.fmt.RRE.r2);  goto ok;
12239   case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12240                                   ovl.fmt.RRE.r2);  goto ok;
12241   case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12242                                   ovl.fmt.RRE.r2);  goto ok;
12243   case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12244                                   ovl.fmt.RRE.r2);  goto ok;
12245   case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12246                                   ovl.fmt.RRE.r2);  goto ok;
12247   case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12248                                   ovl.fmt.RRE.r2);  goto ok;
12249   case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12250                                   ovl.fmt.RRE.r2);  goto ok;
12251   case 0xb318: /* KDBR */ goto unimplemented;
12252   case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12253                                   ovl.fmt.RRE.r2);  goto ok;
12254   case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12255                                   ovl.fmt.RRE.r2);  goto ok;
12256   case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12257                                   ovl.fmt.RRE.r2);  goto ok;
12258   case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12259                                   ovl.fmt.RRE.r2);  goto ok;
12260   case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12261                                   ovl.fmt.RRE.r2);  goto ok;
12262   case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12263                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
12264   case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12265                                     ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
12266   case 0xb324: /* LDER */ goto unimplemented;
12267   case 0xb325: /* LXDR */ goto unimplemented;
12268   case 0xb326: /* LXER */ goto unimplemented;
12269   case 0xb32e: /* MAER */ goto unimplemented;
12270   case 0xb32f: /* MSER */ goto unimplemented;
12271   case 0xb336: /* SQXR */ goto unimplemented;
12272   case 0xb337: /* MEER */ goto unimplemented;
12273   case 0xb338: /* MAYLR */ goto unimplemented;
12274   case 0xb339: /* MYLR */ goto unimplemented;
12275   case 0xb33a: /* MAYR */ goto unimplemented;
12276   case 0xb33b: /* MYR */ goto unimplemented;
12277   case 0xb33c: /* MAYHR */ goto unimplemented;
12278   case 0xb33d: /* MYHR */ goto unimplemented;
12279   case 0xb33e: /* MADR */ goto unimplemented;
12280   case 0xb33f: /* MSDR */ goto unimplemented;
12281   case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12282                                   ovl.fmt.RRE.r2);  goto ok;
12283   case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12284                                   ovl.fmt.RRE.r2);  goto ok;
12285   case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12286                                   ovl.fmt.RRE.r2);  goto ok;
12287   case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12288                                   ovl.fmt.RRE.r2);  goto ok;
12289   case 0xb344: s390_format_RRE_FF(s390_irgen_LEDBR, ovl.fmt.RRE.r1,
12290                                   ovl.fmt.RRE.r2);  goto ok;
12291   case 0xb345: s390_format_RRE_FF(s390_irgen_LDXBR, ovl.fmt.RRE.r1,
12292                                   ovl.fmt.RRE.r2);  goto ok;
12293   case 0xb346: s390_format_RRE_FF(s390_irgen_LEXBR, ovl.fmt.RRE.r1,
12294                                   ovl.fmt.RRE.r2);  goto ok;
12295   case 0xb347: /* FIXBR */ goto unimplemented;
12296   case 0xb348: /* KXBR */ goto unimplemented;
12297   case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12298                                   ovl.fmt.RRE.r2);  goto ok;
12299   case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12300                                   ovl.fmt.RRE.r2);  goto ok;
12301   case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12302                                   ovl.fmt.RRE.r2);  goto ok;
12303   case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12304                                   ovl.fmt.RRE.r2);  goto ok;
12305   case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12306                                   ovl.fmt.RRE.r2);  goto ok;
12307   case 0xb350: /* TBEDR */ goto unimplemented;
12308   case 0xb351: /* TBDR */ goto unimplemented;
12309   case 0xb353: /* DIEBR */ goto unimplemented;
12310   case 0xb357: /* FIEBR */ goto unimplemented;
12311   case 0xb358: /* THDER */ goto unimplemented;
12312   case 0xb359: /* THDR */ goto unimplemented;
12313   case 0xb35b: /* DIDBR */ goto unimplemented;
12314   case 0xb35f: /* FIDBR */ goto unimplemented;
12315   case 0xb360: /* LPXR */ goto unimplemented;
12316   case 0xb361: /* LNXR */ goto unimplemented;
12317   case 0xb362: /* LTXR */ goto unimplemented;
12318   case 0xb363: /* LCXR */ goto unimplemented;
12319   case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12320                                   ovl.fmt.RRE.r2);  goto ok;
12321   case 0xb366: /* LEXR */ goto unimplemented;
12322   case 0xb367: /* FIXR */ goto unimplemented;
12323   case 0xb369: /* CXR */ goto unimplemented;
12324   case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12325                                   ovl.fmt.RRE.r2);  goto ok;
12326   case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12327                                   ovl.fmt.RRE.r2);  goto ok;
12328   case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12329                                      ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12330                                      goto ok;
12331   case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12332                                   ovl.fmt.RRE.r2);  goto ok;
12333   case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1);  goto ok;
12334   case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1);  goto ok;
12335   case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1);  goto ok;
12336   case 0xb377: /* FIER */ goto unimplemented;
12337   case 0xb37f: /* FIDR */ goto unimplemented;
12338   case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1);  goto ok;
12339   case 0xb385: /* SFASR */ goto unimplemented;
12340   case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1);  goto ok;
12341   case 0xb390: /* CELFBR */ goto unimplemented;
12342   case 0xb391: /* CDLFBR */ goto unimplemented;
12343   case 0xb392: /* CXLFBR */ goto unimplemented;
12344   case 0xb394: s390_format_RRE_FR(s390_irgen_CEFBR, ovl.fmt.RRE.r1,
12345                                   ovl.fmt.RRE.r2);  goto ok;
12346   case 0xb395: s390_format_RRE_FR(s390_irgen_CDFBR, ovl.fmt.RRE.r1,
12347                                   ovl.fmt.RRE.r2);  goto ok;
12348   case 0xb396: s390_format_RRE_FR(s390_irgen_CXFBR, ovl.fmt.RRE.r1,
12349                                   ovl.fmt.RRE.r2);  goto ok;
12350   case 0xb398: s390_format_RRF_U0RF(s390_irgen_CFEBR, ovl.fmt.RRF3.r3,
12351                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12352                                     goto ok;
12353   case 0xb399: s390_format_RRF_U0RF(s390_irgen_CFDBR, ovl.fmt.RRF3.r3,
12354                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12355                                     goto ok;
12356   case 0xb39a: s390_format_RRF_U0RF(s390_irgen_CFXBR, ovl.fmt.RRF3.r3,
12357                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12358                                     goto ok;
12359   case 0xb3a0: /* CELGBR */ goto unimplemented;
12360   case 0xb3a1: /* CDLGBR */ goto unimplemented;
12361   case 0xb3a2: /* CXLGBR */ goto unimplemented;
12362   case 0xb3a4: s390_format_RRE_FR(s390_irgen_CEGBR, ovl.fmt.RRE.r1,
12363                                   ovl.fmt.RRE.r2);  goto ok;
12364   case 0xb3a5: s390_format_RRE_FR(s390_irgen_CDGBR, ovl.fmt.RRE.r1,
12365                                   ovl.fmt.RRE.r2);  goto ok;
12366   case 0xb3a6: s390_format_RRE_FR(s390_irgen_CXGBR, ovl.fmt.RRE.r1,
12367                                   ovl.fmt.RRE.r2);  goto ok;
12368   case 0xb3a8: s390_format_RRF_U0RF(s390_irgen_CGEBR, ovl.fmt.RRF3.r3,
12369                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12370                                     goto ok;
12371   case 0xb3a9: s390_format_RRF_U0RF(s390_irgen_CGDBR, ovl.fmt.RRF3.r3,
12372                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12373                                     goto ok;
12374   case 0xb3aa: s390_format_RRF_U0RF(s390_irgen_CGXBR, ovl.fmt.RRF3.r3,
12375                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12376                                     goto ok;
12377   case 0xb3b4: /* CEFR */ goto unimplemented;
12378   case 0xb3b5: /* CDFR */ goto unimplemented;
12379   case 0xb3b6: /* CXFR */ goto unimplemented;
12380   case 0xb3b8: /* CFER */ goto unimplemented;
12381   case 0xb3b9: /* CFDR */ goto unimplemented;
12382   case 0xb3ba: /* CFXR */ goto unimplemented;
12383   case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12384                                   ovl.fmt.RRE.r2);  goto ok;
12385   case 0xb3c4: /* CEGR */ goto unimplemented;
12386   case 0xb3c5: /* CDGR */ goto unimplemented;
12387   case 0xb3c6: /* CXGR */ goto unimplemented;
12388   case 0xb3c8: /* CGER */ goto unimplemented;
12389   case 0xb3c9: /* CGDR */ goto unimplemented;
12390   case 0xb3ca: /* CGXR */ goto unimplemented;
12391   case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12392                                   ovl.fmt.RRE.r2);  goto ok;
12393   case 0xb3d0: /* MDTR */ goto unimplemented;
12394   case 0xb3d1: /* DDTR */ goto unimplemented;
12395   case 0xb3d2: /* ADTR */ goto unimplemented;
12396   case 0xb3d3: /* SDTR */ goto unimplemented;
12397   case 0xb3d4: /* LDETR */ goto unimplemented;
12398   case 0xb3d5: /* LEDTR */ goto unimplemented;
12399   case 0xb3d6: /* LTDTR */ goto unimplemented;
12400   case 0xb3d7: /* FIDTR */ goto unimplemented;
12401   case 0xb3d8: /* MXTR */ goto unimplemented;
12402   case 0xb3d9: /* DXTR */ goto unimplemented;
12403   case 0xb3da: /* AXTR */ goto unimplemented;
12404   case 0xb3db: /* SXTR */ goto unimplemented;
12405   case 0xb3dc: /* LXDTR */ goto unimplemented;
12406   case 0xb3dd: /* LDXTR */ goto unimplemented;
12407   case 0xb3de: /* LTXTR */ goto unimplemented;
12408   case 0xb3df: /* FIXTR */ goto unimplemented;
12409   case 0xb3e0: /* KDTR */ goto unimplemented;
12410   case 0xb3e1: /* CGDTR */ goto unimplemented;
12411   case 0xb3e2: /* CUDTR */ goto unimplemented;
12412   case 0xb3e3: /* CSDTR */ goto unimplemented;
12413   case 0xb3e4: /* CDTR */ goto unimplemented;
12414   case 0xb3e5: /* EEDTR */ goto unimplemented;
12415   case 0xb3e7: /* ESDTR */ goto unimplemented;
12416   case 0xb3e8: /* KXTR */ goto unimplemented;
12417   case 0xb3e9: /* CGXTR */ goto unimplemented;
12418   case 0xb3ea: /* CUXTR */ goto unimplemented;
12419   case 0xb3eb: /* CSXTR */ goto unimplemented;
12420   case 0xb3ec: /* CXTR */ goto unimplemented;
12421   case 0xb3ed: /* EEXTR */ goto unimplemented;
12422   case 0xb3ef: /* ESXTR */ goto unimplemented;
12423   case 0xb3f1: /* CDGTR */ goto unimplemented;
12424   case 0xb3f2: /* CDUTR */ goto unimplemented;
12425   case 0xb3f3: /* CDSTR */ goto unimplemented;
12426   case 0xb3f4: /* CEDTR */ goto unimplemented;
12427   case 0xb3f5: /* QADTR */ goto unimplemented;
12428   case 0xb3f6: /* IEDTR */ goto unimplemented;
12429   case 0xb3f7: /* RRDTR */ goto unimplemented;
12430   case 0xb3f9: /* CXGTR */ goto unimplemented;
12431   case 0xb3fa: /* CXUTR */ goto unimplemented;
12432   case 0xb3fb: /* CXSTR */ goto unimplemented;
12433   case 0xb3fc: /* CEXTR */ goto unimplemented;
12434   case 0xb3fd: /* QAXTR */ goto unimplemented;
12435   case 0xb3fe: /* IEXTR */ goto unimplemented;
12436   case 0xb3ff: /* RRXTR */ goto unimplemented;
12437   case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12438                                   ovl.fmt.RRE.r2);  goto ok;
12439   case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12440                                   ovl.fmt.RRE.r2);  goto ok;
12441   case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12442                                   ovl.fmt.RRE.r2);  goto ok;
12443   case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12444                                   ovl.fmt.RRE.r2);  goto ok;
12445   case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12446                                   ovl.fmt.RRE.r2);  goto ok;
12447   case 0xb905: /* LURAG */ goto unimplemented;
12448   case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12449                                   ovl.fmt.RRE.r2);  goto ok;
12450   case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12451                                   ovl.fmt.RRE.r2);  goto ok;
12452   case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12453                                   ovl.fmt.RRE.r2);  goto ok;
12454   case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12455                                   ovl.fmt.RRE.r2);  goto ok;
12456   case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12457                                   ovl.fmt.RRE.r2);  goto ok;
12458   case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12459                                   ovl.fmt.RRE.r2);  goto ok;
12460   case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12461                                   ovl.fmt.RRE.r2);  goto ok;
12462   case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12463                                   ovl.fmt.RRE.r2);  goto ok;
12464   case 0xb90e: /* EREGG */ goto unimplemented;
12465   case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12466                                   ovl.fmt.RRE.r2);  goto ok;
12467   case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12468                                   ovl.fmt.RRE.r2);  goto ok;
12469   case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12470                                   ovl.fmt.RRE.r2);  goto ok;
12471   case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12472                                   ovl.fmt.RRE.r2);  goto ok;
12473   case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12474                                   ovl.fmt.RRE.r2);  goto ok;
12475   case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12476                                   ovl.fmt.RRE.r2);  goto ok;
12477   case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12478                                   ovl.fmt.RRE.r2);  goto ok;
12479   case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12480                                   ovl.fmt.RRE.r2);  goto ok;
12481   case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12482                                   ovl.fmt.RRE.r2);  goto ok;
12483   case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12484                                   ovl.fmt.RRE.r2);  goto ok;
12485   case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
12486                                   ovl.fmt.RRE.r2);  goto ok;
12487   case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
12488                                   ovl.fmt.RRE.r2);  goto ok;
12489   case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
12490                                   ovl.fmt.RRE.r2);  goto ok;
12491   case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
12492                                   ovl.fmt.RRE.r2);  goto ok;
12493   case 0xb91e: /* KMAC */ goto unimplemented;
12494   case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
12495                                   ovl.fmt.RRE.r2);  goto ok;
12496   case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
12497                                   ovl.fmt.RRE.r2);  goto ok;
12498   case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
12499                                   ovl.fmt.RRE.r2);  goto ok;
12500   case 0xb925: /* STURG */ goto unimplemented;
12501   case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
12502                                   ovl.fmt.RRE.r2);  goto ok;
12503   case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
12504                                   ovl.fmt.RRE.r2);  goto ok;
12505   case 0xb928: /* PCKMO */ goto unimplemented;
12506   case 0xb92b: /* KMO */ goto unimplemented;
12507   case 0xb92c: /* PCC */ goto unimplemented;
12508   case 0xb92d: /* KMCTR */ goto unimplemented;
12509   case 0xb92e: /* KM */ goto unimplemented;
12510   case 0xb92f: /* KMC */ goto unimplemented;
12511   case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
12512                                   ovl.fmt.RRE.r2);  goto ok;
12513   case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
12514                                   ovl.fmt.RRE.r2);  goto ok;
12515   case 0xb93e: /* KIMD */ goto unimplemented;
12516   case 0xb93f: /* KLMD */ goto unimplemented;
12517   case 0xb941: /* CFDTR */ goto unimplemented;
12518   case 0xb942: /* CLGDTR */ goto unimplemented;
12519   case 0xb943: /* CLFDTR */ goto unimplemented;
12520   case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
12521                                   ovl.fmt.RRE.r2);  goto ok;
12522   case 0xb949: /* CFXTR */ goto unimplemented;
12523   case 0xb94a: /* CLGXTR */ goto unimplemented;
12524   case 0xb94b: /* CLFXTR */ goto unimplemented;
12525   case 0xb951: /* CDFTR */ goto unimplemented;
12526   case 0xb952: /* CDLGTR */ goto unimplemented;
12527   case 0xb953: /* CDLFTR */ goto unimplemented;
12528   case 0xb959: /* CXFTR */ goto unimplemented;
12529   case 0xb95a: /* CXLGTR */ goto unimplemented;
12530   case 0xb95b: /* CXLFTR */ goto unimplemented;
12531   case 0xb960: /* CGRT */ goto unimplemented;
12532   case 0xb961: /* CLGRT */ goto unimplemented;
12533   case 0xb972: /* CRT */ goto unimplemented;
12534   case 0xb973: /* CLRT */ goto unimplemented;
12535   case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
12536                                   ovl.fmt.RRE.r2);  goto ok;
12537   case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
12538                                   ovl.fmt.RRE.r2);  goto ok;
12539   case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
12540                                   ovl.fmt.RRE.r2);  goto ok;
12541   case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
12542                                   ovl.fmt.RRE.r2);  goto ok;
12543   case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
12544                                   ovl.fmt.RRE.r2);  goto ok;
12545   case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
12546                                   ovl.fmt.RRE.r2);  goto ok;
12547   case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
12548                                   ovl.fmt.RRE.r2);  goto ok;
12549   case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
12550                                   ovl.fmt.RRE.r2);  goto ok;
12551   case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
12552                                   ovl.fmt.RRE.r2);  goto ok;
12553   case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
12554                                   ovl.fmt.RRE.r2);  goto ok;
12555   case 0xb98a: /* CSPG */ goto unimplemented;
12556   case 0xb98d: /* EPSW */ goto unimplemented;
12557   case 0xb98e: /* IDTE */ goto unimplemented;
12558   case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
12559                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
12560   case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
12561                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
12562   case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
12563                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
12564   case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
12565                                   ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);  goto ok;
12566   case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
12567                                   ovl.fmt.RRE.r2);  goto ok;
12568   case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
12569                                   ovl.fmt.RRE.r2);  goto ok;
12570   case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
12571                                   ovl.fmt.RRE.r2);  goto ok;
12572   case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
12573                                   ovl.fmt.RRE.r2);  goto ok;
12574   case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
12575                                   ovl.fmt.RRE.r2);  goto ok;
12576   case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
12577                                   ovl.fmt.RRE.r2);  goto ok;
12578   case 0xb99a: /* EPAIR */ goto unimplemented;
12579   case 0xb99b: /* ESAIR */ goto unimplemented;
12580   case 0xb99d: /* ESEA */ goto unimplemented;
12581   case 0xb99e: /* PTI */ goto unimplemented;
12582   case 0xb99f: /* SSAIR */ goto unimplemented;
12583   case 0xb9a2: /* PTF */ goto unimplemented;
12584   case 0xb9aa: /* LPTEA */ goto unimplemented;
12585   case 0xb9ae: /* RRBM */ goto unimplemented;
12586   case 0xb9af: /* PFMF */ goto unimplemented;
12587   case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
12588                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12589      goto ok;
12590   case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
12591                                       ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12592      goto ok;
12593   case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
12594                                   ovl.fmt.RRE.r2);  goto ok;
12595   case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
12596                                   ovl.fmt.RRE.r2);  goto ok;
12597   case 0xb9bd: /* TRTRE */ goto unimplemented;
12598   case 0xb9be: /* SRSTU */ goto unimplemented;
12599   case 0xb9bf: /* TRTE */ goto unimplemented;
12600   case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
12601                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12602                                      goto ok;
12603   case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
12604                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12605                                      goto ok;
12606   case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
12607                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12608                                      goto ok;
12609   case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
12610                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12611                                      goto ok;
12612   case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
12613                                   ovl.fmt.RRE.r2);  goto ok;
12614   case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
12615                                   ovl.fmt.RRE.r2);  goto ok;
12616   case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
12617                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12618                                      goto ok;
12619   case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
12620                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12621                                      goto ok;
12622   case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
12623                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12624                                      goto ok;
12625   case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
12626                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12627                                      goto ok;
12628   case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
12629                                   ovl.fmt.RRE.r2);  goto ok;
12630   case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
12631                                   ovl.fmt.RRE.r2);  goto ok;
12632   case 0xb9e1: /* POPCNT */ goto unimplemented;
12633   case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
12634                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12635                                     S390_XMNM_LOCGR);  goto ok;
12636   case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
12637                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12638                                      goto ok;
12639   case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
12640                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12641                                      goto ok;
12642   case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
12643                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12644                                      goto ok;
12645   case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
12646                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12647                                      goto ok;
12648   case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
12649                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12650                                      goto ok;
12651   case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
12652                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12653                                      goto ok;
12654   case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
12655                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12656                                      goto ok;
12657   case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
12658                                     ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12659                                     S390_XMNM_LOCR);  goto ok;
12660   case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
12661                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12662                                      goto ok;
12663   case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
12664                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12665                                      goto ok;
12666   case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
12667                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12668                                      goto ok;
12669   case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
12670                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12671                                      goto ok;
12672   case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
12673                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12674                                      goto ok;
12675   case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
12676                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12677                                      goto ok;
12678   case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
12679                                      ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12680                                      goto ok;
12681   }
12682
12683   switch ((ovl.value & 0xff000000) >> 24) {
12684   case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12685                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12686   case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12687                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12688   case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12689                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12690   case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12691                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12692   case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12693                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12694   case 0x45: /* BAL */ goto unimplemented;
12695   case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12696                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12697   case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12698                             ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12699   case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12700                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12701   case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12702                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12703   case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12704                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12705   case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12706                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12707   case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12708                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12709   case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12710                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12711   case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12712                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12713   case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12714                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12715   case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12716                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12717   case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12718                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12719   case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12720                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12721   case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12722                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12723   case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12724                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12725   case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12726                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12727   case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12728                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12729   case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12730                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12731   case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12732                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12733   case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12734                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12735   case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12736                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12737   case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12738                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12739   case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12740                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12741   case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12742                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12743   case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12744                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12745   case 0x67: /* MXD */ goto unimplemented;
12746   case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12747                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12748   case 0x69: /* CD */ goto unimplemented;
12749   case 0x6a: /* AD */ goto unimplemented;
12750   case 0x6b: /* SD */ goto unimplemented;
12751   case 0x6c: /* MD */ goto unimplemented;
12752   case 0x6d: /* DD */ goto unimplemented;
12753   case 0x6e: /* AW */ goto unimplemented;
12754   case 0x6f: /* SW */ goto unimplemented;
12755   case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12756                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12757   case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12758                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12759   case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12760                                  ovl.fmt.RX.b2, ovl.fmt.RX.d2);  goto ok;
12761   case 0x79: /* CE */ goto unimplemented;
12762   case 0x7a: /* AE */ goto unimplemented;
12763   case 0x7b: /* SE */ goto unimplemented;
12764   case 0x7c: /* MDE */ goto unimplemented;
12765   case 0x7d: /* DE */ goto unimplemented;
12766   case 0x7e: /* AU */ goto unimplemented;
12767   case 0x7f: /* SU */ goto unimplemented;
12768   case 0x83: /* DIAG */ goto unimplemented;
12769   case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
12770                                  ovl.fmt.RSI.r3, ovl.fmt.RSI.i2);  goto ok;
12771   case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
12772                                  ovl.fmt.RSI.r3, ovl.fmt.RSI.i2);  goto ok;
12773   case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12774                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
12775   case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12776                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
12777   case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12778                                  ovl.fmt.RS.d2);  goto ok;
12779   case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12780                                  ovl.fmt.RS.d2);  goto ok;
12781   case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12782                                  ovl.fmt.RS.d2);  goto ok;
12783   case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12784                                  ovl.fmt.RS.d2);  goto ok;
12785   case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12786                                  ovl.fmt.RS.d2);  goto ok;
12787   case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12788                                  ovl.fmt.RS.d2);  goto ok;
12789   case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12790                                  ovl.fmt.RS.d2);  goto ok;
12791   case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12792                                  ovl.fmt.RS.d2);  goto ok;
12793   case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12794                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
12795   case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12796                                 ovl.fmt.SI.d1);  goto ok;
12797   case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12798                                 ovl.fmt.SI.d1);  goto ok;
12799   case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12800                                 ovl.fmt.SI.d1);  goto ok;
12801   case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12802                                 ovl.fmt.SI.d1);  goto ok;
12803   case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12804                                 ovl.fmt.SI.d1);  goto ok;
12805   case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12806                                 ovl.fmt.SI.d1);  goto ok;
12807   case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12808                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
12809   case 0x99: /* TRACE */ goto unimplemented;
12810   case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12811                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
12812   case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12813                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
12814   case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
12815                                  ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
12816                                  goto ok;
12817   case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
12818                                  ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
12819                                  goto ok;
12820   case 0xac: /* STNSM */ goto unimplemented;
12821   case 0xad: /* STOSM */ goto unimplemented;
12822   case 0xae: /* SIGP */ goto unimplemented;
12823   case 0xaf: /* MC */ goto unimplemented;
12824   case 0xb1: /* LRA */ goto unimplemented;
12825   case 0xb6: /* STCTL */ goto unimplemented;
12826   case 0xb7: /* LCTL */ goto unimplemented;
12827   case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12828                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
12829   case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12830                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
12831   case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12832                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
12833   case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12834                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
12835   case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12836                                  ovl.fmt.RS.b2, ovl.fmt.RS.d2);  goto ok;
12837   }
12838
12839   return S390_DECODE_UNKNOWN_INSN;
12840
12841ok:
12842   return S390_DECODE_OK;
12843
12844unimplemented:
12845   return S390_DECODE_UNIMPLEMENTED_INSN;
12846}
12847
12848static s390_decode_t
12849s390_decode_6byte_and_irgen(UChar *bytes)
12850{
12851   typedef union {
12852      struct {
12853         unsigned int op1 :  8;
12854         unsigned int r1  :  4;
12855         unsigned int r3  :  4;
12856         unsigned int i2  : 16;
12857         unsigned int     :  8;
12858         unsigned int op2 :  8;
12859      } RIE;
12860      struct {
12861         unsigned int op1 :  8;
12862         unsigned int r1  :  4;
12863         unsigned int r2  :  4;
12864         unsigned int i3  :  8;
12865         unsigned int i4  :  8;
12866         unsigned int i5  :  8;
12867         unsigned int op2 :  8;
12868      } RIE_RRUUU;
12869      struct {
12870         unsigned int op1 :  8;
12871         unsigned int r1  :  4;
12872         unsigned int     :  4;
12873         unsigned int i2  : 16;
12874         unsigned int m3  :  4;
12875         unsigned int     :  4;
12876         unsigned int op2 :  8;
12877      } RIEv1;
12878      struct {
12879         unsigned int op1 :  8;
12880         unsigned int r1  :  4;
12881         unsigned int r2  :  4;
12882         unsigned int i4  : 16;
12883         unsigned int m3  :  4;
12884         unsigned int     :  4;
12885         unsigned int op2 :  8;
12886      } RIE_RRPU;
12887      struct {
12888         unsigned int op1 :  8;
12889         unsigned int r1  :  4;
12890         unsigned int m3  :  4;
12891         unsigned int i4  : 16;
12892         unsigned int i2  :  8;
12893         unsigned int op2 :  8;
12894      } RIEv3;
12895      struct {
12896         unsigned int op1 :  8;
12897         unsigned int r1  :  4;
12898         unsigned int op2 :  4;
12899         unsigned int i2  : 32;
12900      } RIL;
12901      struct {
12902         unsigned int op1 :  8;
12903         unsigned int r1  :  4;
12904         unsigned int m3  :  4;
12905         unsigned int b4  :  4;
12906         unsigned int d4  : 12;
12907         unsigned int i2  :  8;
12908         unsigned int op2 :  8;
12909      } RIS;
12910      struct {
12911         unsigned int op1 :  8;
12912         unsigned int r1  :  4;
12913         unsigned int r2  :  4;
12914         unsigned int b4  :  4;
12915         unsigned int d4  : 12;
12916         unsigned int m3  :  4;
12917         unsigned int     :  4;
12918         unsigned int op2 :  8;
12919      } RRS;
12920      struct {
12921         unsigned int op1 :  8;
12922         unsigned int l1  :  4;
12923         unsigned int     :  4;
12924         unsigned int b1  :  4;
12925         unsigned int d1  : 12;
12926         unsigned int     :  8;
12927         unsigned int op2 :  8;
12928      } RSL;
12929      struct {
12930         unsigned int op1 :  8;
12931         unsigned int r1  :  4;
12932         unsigned int r3  :  4;
12933         unsigned int b2  :  4;
12934         unsigned int dl2 : 12;
12935         unsigned int dh2 :  8;
12936         unsigned int op2 :  8;
12937      } RSY;
12938      struct {
12939         unsigned int op1 :  8;
12940         unsigned int r1  :  4;
12941         unsigned int x2  :  4;
12942         unsigned int b2  :  4;
12943         unsigned int d2  : 12;
12944         unsigned int     :  8;
12945         unsigned int op2 :  8;
12946      } RXE;
12947      struct {
12948         unsigned int op1 :  8;
12949         unsigned int r3  :  4;
12950         unsigned int x2  :  4;
12951         unsigned int b2  :  4;
12952         unsigned int d2  : 12;
12953         unsigned int r1  :  4;
12954         unsigned int     :  4;
12955         unsigned int op2 :  8;
12956      } RXF;
12957      struct {
12958         unsigned int op1 :  8;
12959         unsigned int r1  :  4;
12960         unsigned int x2  :  4;
12961         unsigned int b2  :  4;
12962         unsigned int dl2 : 12;
12963         unsigned int dh2 :  8;
12964         unsigned int op2 :  8;
12965      } RXY;
12966      struct {
12967         unsigned int op1 :  8;
12968         unsigned int i2  :  8;
12969         unsigned int b1  :  4;
12970         unsigned int dl1 : 12;
12971         unsigned int dh1 :  8;
12972         unsigned int op2 :  8;
12973      } SIY;
12974      struct {
12975         unsigned int op :  8;
12976         unsigned int l  :  8;
12977         unsigned int b1 :  4;
12978         unsigned int d1 : 12;
12979         unsigned int b2 :  4;
12980         unsigned int d2 : 12;
12981      } SS;
12982      struct {
12983         unsigned int op :  8;
12984         unsigned int l1 :  4;
12985         unsigned int l2 :  4;
12986         unsigned int b1 :  4;
12987         unsigned int d1 : 12;
12988         unsigned int b2 :  4;
12989         unsigned int d2 : 12;
12990      } SS_LLRDRD;
12991      struct {
12992         unsigned int op :  8;
12993         unsigned int r1 :  4;
12994         unsigned int r3 :  4;
12995         unsigned int b2 :  4;
12996         unsigned int d2 : 12;
12997         unsigned int b4 :  4;
12998         unsigned int d4 : 12;
12999      } SS_RRRDRD2;
13000      struct {
13001         unsigned int op : 16;
13002         unsigned int b1 :  4;
13003         unsigned int d1 : 12;
13004         unsigned int b2 :  4;
13005         unsigned int d2 : 12;
13006      } SSE;
13007      struct {
13008         unsigned int op1 :  8;
13009         unsigned int r3  :  4;
13010         unsigned int op2 :  4;
13011         unsigned int b1  :  4;
13012         unsigned int d1  : 12;
13013         unsigned int b2  :  4;
13014         unsigned int d2  : 12;
13015      } SSF;
13016      struct {
13017         unsigned int op : 16;
13018         unsigned int b1 :  4;
13019         unsigned int d1 : 12;
13020         unsigned int i2 : 16;
13021      } SIL;
13022   } formats;
13023   union {
13024      formats fmt;
13025      ULong value;
13026   } ovl;
13027
13028   vassert(sizeof(formats) == 6);
13029
13030   ((char *)(&ovl.value))[0] = bytes[0];
13031   ((char *)(&ovl.value))[1] = bytes[1];
13032   ((char *)(&ovl.value))[2] = bytes[2];
13033   ((char *)(&ovl.value))[3] = bytes[3];
13034   ((char *)(&ovl.value))[4] = bytes[4];
13035   ((char *)(&ovl.value))[5] = bytes[5];
13036   ((char *)(&ovl.value))[6] = 0x0;
13037   ((char *)(&ovl.value))[7] = 0x0;
13038
13039   switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13040   case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13041                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13042                                                ovl.fmt.RXY.dl2,
13043                                                ovl.fmt.RXY.dh2);  goto ok;
13044   case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13045   case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13046                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13047                                                ovl.fmt.RXY.dl2,
13048                                                ovl.fmt.RXY.dh2);  goto ok;
13049   case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13050                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13051                                                ovl.fmt.RXY.dl2,
13052                                                ovl.fmt.RXY.dh2);  goto ok;
13053   case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13054                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13055                                                ovl.fmt.RXY.dl2,
13056                                                ovl.fmt.RXY.dh2);  goto ok;
13057   case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13058                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13059                                                ovl.fmt.RXY.dl2,
13060                                                ovl.fmt.RXY.dh2);  goto ok;
13061   case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13062                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13063                                                ovl.fmt.RXY.dl2,
13064                                                ovl.fmt.RXY.dh2);  goto ok;
13065   case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13066                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13067                                                ovl.fmt.RXY.dl2,
13068                                                ovl.fmt.RXY.dh2);  goto ok;
13069   case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13070                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13071                                                ovl.fmt.RXY.dl2,
13072                                                ovl.fmt.RXY.dh2);  goto ok;
13073   case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13074                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13075                                                ovl.fmt.RXY.dl2,
13076                                                ovl.fmt.RXY.dh2);  goto ok;
13077   case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13078   case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13079                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13080                                                ovl.fmt.RXY.dl2,
13081                                                ovl.fmt.RXY.dh2);  goto ok;
13082   case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13083                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13084                                                ovl.fmt.RXY.dl2,
13085                                                ovl.fmt.RXY.dh2);  goto ok;
13086   case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13087   case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13088                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13089                                                ovl.fmt.RXY.dl2,
13090                                                ovl.fmt.RXY.dh2);  goto ok;
13091   case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13092                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13093                                                ovl.fmt.RXY.dl2,
13094                                                ovl.fmt.RXY.dh2);  goto ok;
13095   case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13096                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13097                                                ovl.fmt.RXY.dl2,
13098                                                ovl.fmt.RXY.dh2);  goto ok;
13099   case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13100                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13101                                                ovl.fmt.RXY.dl2,
13102                                                ovl.fmt.RXY.dh2);  goto ok;
13103   case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13104                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13105                                                ovl.fmt.RXY.dl2,
13106                                                ovl.fmt.RXY.dh2);  goto ok;
13107   case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13108                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13109                                                ovl.fmt.RXY.dl2,
13110                                                ovl.fmt.RXY.dh2);  goto ok;
13111   case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13112                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13113                                                ovl.fmt.RXY.dl2,
13114                                                ovl.fmt.RXY.dh2);  goto ok;
13115   case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13116                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13117                                                ovl.fmt.RXY.dl2,
13118                                                ovl.fmt.RXY.dh2);  goto ok;
13119   case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13120                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13121                                                ovl.fmt.RXY.dl2,
13122                                                ovl.fmt.RXY.dh2);  goto ok;
13123   case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13124                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13125                                                ovl.fmt.RXY.dl2,
13126                                                ovl.fmt.RXY.dh2);  goto ok;
13127   case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13128                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13129                                                ovl.fmt.RXY.dl2,
13130                                                ovl.fmt.RXY.dh2);  goto ok;
13131   case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13132                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13133                                                ovl.fmt.RXY.dl2,
13134                                                ovl.fmt.RXY.dh2);  goto ok;
13135   case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13136                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13137                                                ovl.fmt.RXY.dl2,
13138                                                ovl.fmt.RXY.dh2);  goto ok;
13139   case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13140                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13141                                                ovl.fmt.RXY.dl2,
13142                                                ovl.fmt.RXY.dh2);  goto ok;
13143   case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13144                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13145                                                ovl.fmt.RXY.dl2,
13146                                                ovl.fmt.RXY.dh2);  goto ok;
13147   case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13148                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13149                                                ovl.fmt.RXY.dl2,
13150                                                ovl.fmt.RXY.dh2);  goto ok;
13151   case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13152   case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13153                                                ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13154                                                ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13155                                                ovl.fmt.RXY.dh2);  goto ok;
13156   case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13157                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13158                                                ovl.fmt.RXY.dl2,
13159                                                ovl.fmt.RXY.dh2);  goto ok;
13160   case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13161                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13162                                                ovl.fmt.RXY.dl2,
13163                                                ovl.fmt.RXY.dh2);  goto ok;
13164   case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13165                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13166                                                ovl.fmt.RXY.dl2,
13167                                                ovl.fmt.RXY.dh2);  goto ok;
13168   case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13169                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13170                                                ovl.fmt.RXY.dl2,
13171                                                ovl.fmt.RXY.dh2);  goto ok;
13172   case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13173                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13174                                                ovl.fmt.RXY.dl2,
13175                                                ovl.fmt.RXY.dh2);  goto ok;
13176   case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13177                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13178                                                ovl.fmt.RXY.dl2,
13179                                                ovl.fmt.RXY.dh2);  goto ok;
13180   case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13181                                                ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13182                                                ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13183                                                ovl.fmt.RXY.dh2);  goto ok;
13184   case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13185                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13186                                                ovl.fmt.RXY.dl2,
13187                                                ovl.fmt.RXY.dh2);  goto ok;
13188   case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13189                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13190                                                ovl.fmt.RXY.dl2,
13191                                                ovl.fmt.RXY.dh2);  goto ok;
13192   case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13193                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13194                                                ovl.fmt.RXY.dl2,
13195                                                ovl.fmt.RXY.dh2);  goto ok;
13196   case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13197                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13198                                                ovl.fmt.RXY.dl2,
13199                                                ovl.fmt.RXY.dh2);  goto ok;
13200   case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13201                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13202                                                ovl.fmt.RXY.dl2,
13203                                                ovl.fmt.RXY.dh2);  goto ok;
13204   case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13205                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13206                                                ovl.fmt.RXY.dl2,
13207                                                ovl.fmt.RXY.dh2);  goto ok;
13208   case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
13209                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13210                                                ovl.fmt.RXY.dl2,
13211                                                ovl.fmt.RXY.dh2);  goto ok;
13212   case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
13213                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13214                                                ovl.fmt.RXY.dl2,
13215                                                ovl.fmt.RXY.dh2);  goto ok;
13216   case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
13217                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13218                                                ovl.fmt.RXY.dl2,
13219                                                ovl.fmt.RXY.dh2);  goto ok;
13220   case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
13221                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13222                                                ovl.fmt.RXY.dl2,
13223                                                ovl.fmt.RXY.dh2);  goto ok;
13224   case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
13225                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13226                                                ovl.fmt.RXY.dl2,
13227                                                ovl.fmt.RXY.dh2);  goto ok;
13228   case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
13229                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13230                                                ovl.fmt.RXY.dl2,
13231                                                ovl.fmt.RXY.dh2);  goto ok;
13232   case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
13233                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13234                                                ovl.fmt.RXY.dl2,
13235                                                ovl.fmt.RXY.dh2);  goto ok;
13236   case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
13237                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13238                                                ovl.fmt.RXY.dl2,
13239                                                ovl.fmt.RXY.dh2);  goto ok;
13240   case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
13241                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13242                                                ovl.fmt.RXY.dl2,
13243                                                ovl.fmt.RXY.dh2);  goto ok;
13244   case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
13245                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13246                                                ovl.fmt.RXY.dl2,
13247                                                ovl.fmt.RXY.dh2);  goto ok;
13248   case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
13249                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13250                                                ovl.fmt.RXY.dl2,
13251                                                ovl.fmt.RXY.dh2);  goto ok;
13252   case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
13253                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13254                                                ovl.fmt.RXY.dl2,
13255                                                ovl.fmt.RXY.dh2);  goto ok;
13256   case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
13257                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13258                                                ovl.fmt.RXY.dl2,
13259                                                ovl.fmt.RXY.dh2);  goto ok;
13260   case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
13261                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13262                                                ovl.fmt.RXY.dl2,
13263                                                ovl.fmt.RXY.dh2);  goto ok;
13264   case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
13265                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13266                                                ovl.fmt.RXY.dl2,
13267                                                ovl.fmt.RXY.dh2);  goto ok;
13268   case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
13269                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13270                                                ovl.fmt.RXY.dl2,
13271                                                ovl.fmt.RXY.dh2);  goto ok;
13272   case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
13273                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13274                                                ovl.fmt.RXY.dl2,
13275                                                ovl.fmt.RXY.dh2);  goto ok;
13276   case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
13277                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13278                                                ovl.fmt.RXY.dl2,
13279                                                ovl.fmt.RXY.dh2);  goto ok;
13280   case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
13281                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13282                                                ovl.fmt.RXY.dl2,
13283                                                ovl.fmt.RXY.dh2);  goto ok;
13284   case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
13285                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13286                                                ovl.fmt.RXY.dl2,
13287                                                ovl.fmt.RXY.dh2);  goto ok;
13288   case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
13289                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13290                                                ovl.fmt.RXY.dl2,
13291                                                ovl.fmt.RXY.dh2);  goto ok;
13292   case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
13293                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13294                                                ovl.fmt.RXY.dl2,
13295                                                ovl.fmt.RXY.dh2);  goto ok;
13296   case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
13297                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13298                                                ovl.fmt.RXY.dl2,
13299                                                ovl.fmt.RXY.dh2);  goto ok;
13300   case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
13301                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13302                                                ovl.fmt.RXY.dl2,
13303                                                ovl.fmt.RXY.dh2);  goto ok;
13304   case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
13305                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13306                                                ovl.fmt.RXY.dl2,
13307                                                ovl.fmt.RXY.dh2);  goto ok;
13308   case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13309                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13310                                                ovl.fmt.RXY.dl2,
13311                                                ovl.fmt.RXY.dh2);  goto ok;
13312   case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13313                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13314                                                ovl.fmt.RXY.dl2,
13315                                                ovl.fmt.RXY.dh2);  goto ok;
13316   case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13317                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13318                                                ovl.fmt.RXY.dl2,
13319                                                ovl.fmt.RXY.dh2);  goto ok;
13320   case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13321                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13322                                                ovl.fmt.RXY.dl2,
13323                                                ovl.fmt.RXY.dh2);  goto ok;
13324   case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13325                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13326                                                ovl.fmt.RXY.dl2,
13327                                                ovl.fmt.RXY.dh2);  goto ok;
13328   case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13329                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13330                                                ovl.fmt.RXY.dl2,
13331                                                ovl.fmt.RXY.dh2);  goto ok;
13332   case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13333                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13334                                                ovl.fmt.RXY.dl2,
13335                                                ovl.fmt.RXY.dh2);  goto ok;
13336   case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13337                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13338                                                ovl.fmt.RXY.dl2,
13339                                                ovl.fmt.RXY.dh2);  goto ok;
13340   case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13341                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13342                                                ovl.fmt.RXY.dl2,
13343                                                ovl.fmt.RXY.dh2);  goto ok;
13344   case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13345                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13346                                                ovl.fmt.RXY.dl2,
13347                                                ovl.fmt.RXY.dh2);  goto ok;
13348   case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13349                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13350                                                ovl.fmt.RXY.dl2,
13351                                                ovl.fmt.RXY.dh2);  goto ok;
13352   case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13353                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13354                                                ovl.fmt.RXY.dl2,
13355                                                ovl.fmt.RXY.dh2);  goto ok;
13356   case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13357                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13358                                                ovl.fmt.RXY.dl2,
13359                                                ovl.fmt.RXY.dh2);  goto ok;
13360   case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13361                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13362                                                ovl.fmt.RXY.dl2,
13363                                                ovl.fmt.RXY.dh2);  goto ok;
13364   case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13365                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13366                                                ovl.fmt.RXY.dl2,
13367                                                ovl.fmt.RXY.dh2);  goto ok;
13368   case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13369                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13370                                                ovl.fmt.RXY.dl2,
13371                                                ovl.fmt.RXY.dh2);  goto ok;
13372   case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13373                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13374                                                ovl.fmt.RXY.dl2,
13375                                                ovl.fmt.RXY.dh2);  goto ok;
13376   case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13377                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13378                                                ovl.fmt.RXY.dl2,
13379                                                ovl.fmt.RXY.dh2);  goto ok;
13380   case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13381                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13382                                                ovl.fmt.RXY.dl2,
13383                                                ovl.fmt.RXY.dh2);  goto ok;
13384   case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13385                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13386                                                ovl.fmt.RXY.dl2,
13387                                                ovl.fmt.RXY.dh2);  goto ok;
13388   case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13389                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13390                                                ovl.fmt.RXY.dl2,
13391                                                ovl.fmt.RXY.dh2);  goto ok;
13392   case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13393                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13394                                                ovl.fmt.RXY.dl2,
13395                                                ovl.fmt.RXY.dh2);  goto ok;
13396   case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13397                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13398                                                ovl.fmt.RSY.dl2,
13399                                                ovl.fmt.RSY.dh2);  goto ok;
13400   case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13401                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13402                                                ovl.fmt.RSY.dl2,
13403                                                ovl.fmt.RSY.dh2);  goto ok;
13404   case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13405                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13406                                                ovl.fmt.RSY.dl2,
13407                                                ovl.fmt.RSY.dh2);  goto ok;
13408   case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13409                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13410                                                ovl.fmt.RSY.dl2,
13411                                                ovl.fmt.RSY.dh2);  goto ok;
13412   case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13413                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13414                                                ovl.fmt.RSY.dl2,
13415                                                ovl.fmt.RSY.dh2);  goto ok;
13416   case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13417   case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13418                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13419                                                ovl.fmt.RSY.dl2,
13420                                                ovl.fmt.RSY.dh2);  goto ok;
13421   case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
13422                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13423                                                ovl.fmt.RSY.dl2,
13424                                                ovl.fmt.RSY.dh2);  goto ok;
13425   case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
13426                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13427                                                ovl.fmt.RSY.dl2,
13428                                                ovl.fmt.RSY.dh2);  goto ok;
13429   case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
13430                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13431                                                ovl.fmt.RSY.dl2,
13432                                                ovl.fmt.RSY.dh2);  goto ok;
13433   case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
13434                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13435                                                ovl.fmt.RSY.dl2,
13436                                                ovl.fmt.RSY.dh2);  goto ok;
13437   case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
13438                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13439                                                ovl.fmt.RSY.dl2,
13440                                                ovl.fmt.RSY.dh2);  goto ok;
13441   case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13442   case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
13443                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13444                                                ovl.fmt.RSY.dl2,
13445                                                ovl.fmt.RSY.dh2);  goto ok;
13446   case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13447                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13448                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13449                                                ovl.fmt.RSY.dh2);  goto ok;
13450   case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13451                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13452                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13453                                                ovl.fmt.RSY.dh2);  goto ok;
13454   case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13455   case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13456                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13457                                                ovl.fmt.RSY.dl2,
13458                                                ovl.fmt.RSY.dh2);  goto ok;
13459   case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13460                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13461                                                ovl.fmt.RSY.dl2,
13462                                                ovl.fmt.RSY.dh2);  goto ok;
13463   case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13464                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13465                                                ovl.fmt.RSY.dl2,
13466                                                ovl.fmt.RSY.dh2);  goto ok;
13467   case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
13468                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13469                                                ovl.fmt.RSY.dl2,
13470                                                ovl.fmt.RSY.dh2);  goto ok;
13471   case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
13472                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13473                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13474                                                ovl.fmt.RSY.dh2);  goto ok;
13475   case 0xeb000000004cULL: /* ECAG */ goto unimplemented;
13476   case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13477                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13478                                               ovl.fmt.SIY.dh1);  goto ok;
13479   case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13480                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13481                                               ovl.fmt.SIY.dh1);  goto ok;
13482   case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
13483                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13484                                               ovl.fmt.SIY.dh1);  goto ok;
13485   case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
13486                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13487                                               ovl.fmt.SIY.dh1);  goto ok;
13488   case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
13489                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13490                                               ovl.fmt.SIY.dh1);  goto ok;
13491   case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
13492                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13493                                               ovl.fmt.SIY.dh1);  goto ok;
13494   case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
13495                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13496                                               ovl.fmt.SIY.dh1);  goto ok;
13497   case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
13498                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13499                                               ovl.fmt.SIY.dh1);  goto ok;
13500   case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
13501                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13502                                               ovl.fmt.SIY.dh1);  goto ok;
13503   case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
13504                                               ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13505                                               ovl.fmt.SIY.dh1);  goto ok;
13506   case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
13507                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13508                                                ovl.fmt.RSY.dl2,
13509                                                ovl.fmt.RSY.dh2);  goto ok;
13510   case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
13511                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13512                                                ovl.fmt.RSY.dl2,
13513                                                ovl.fmt.RSY.dh2);  goto ok;
13514   case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
13515   case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
13516   case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
13517                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13518                                                ovl.fmt.RSY.dl2,
13519                                                ovl.fmt.RSY.dh2);  goto ok;
13520   case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
13521                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13522                                                ovl.fmt.RSY.dl2,
13523                                                ovl.fmt.RSY.dh2);  goto ok;
13524   case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
13525                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13526                                                ovl.fmt.RSY.dl2,
13527                                                ovl.fmt.RSY.dh2);  goto ok;
13528   case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
13529                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13530                                                ovl.fmt.RSY.dl2,
13531                                                ovl.fmt.RSY.dh2);  goto ok;
13532   case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
13533                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13534                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13535                                                ovl.fmt.RSY.dh2);  goto ok;
13536   case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
13537   case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
13538                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13539                                                ovl.fmt.RSY.dl2,
13540                                                ovl.fmt.RSY.dh2);  goto ok;
13541   case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
13542                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13543                                                ovl.fmt.RSY.dl2,
13544                                                ovl.fmt.RSY.dh2);  goto ok;
13545   case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
13546                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13547                                                ovl.fmt.RSY.dl2,
13548                                                ovl.fmt.RSY.dh2);  goto ok;
13549   case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
13550                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13551                                                ovl.fmt.RSY.dl2,
13552                                                ovl.fmt.RSY.dh2);  goto ok;
13553   case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
13554                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13555                                                ovl.fmt.RSY.dl2,
13556                                                ovl.fmt.RSY.dh2,
13557                                                S390_XMNM_LOCG);  goto ok;
13558   case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
13559                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13560                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13561                                                ovl.fmt.RSY.dh2,
13562                                                S390_XMNM_STOCG);  goto ok;
13563   case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
13564                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13565                                                ovl.fmt.RSY.dl2,
13566                                                ovl.fmt.RSY.dh2);  goto ok;
13567   case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
13568                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13569                                                ovl.fmt.RSY.dl2,
13570                                                ovl.fmt.RSY.dh2);  goto ok;
13571   case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
13572                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13573                                                ovl.fmt.RSY.dl2,
13574                                                ovl.fmt.RSY.dh2);  goto ok;
13575   case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
13576                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13577                                                ovl.fmt.RSY.dl2,
13578                                                ovl.fmt.RSY.dh2);  goto ok;
13579   case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
13580                                                ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13581                                                ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13582                                                ovl.fmt.RSY.dh2);  goto ok;
13583   case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
13584                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13585                                                ovl.fmt.RSY.dl2,
13586                                                ovl.fmt.RSY.dh2, S390_XMNM_LOC);
13587                                                goto ok;
13588   case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
13589                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13590                                                ovl.fmt.RSY.dl2,
13591                                                ovl.fmt.RSY.dh2,
13592                                                S390_XMNM_STOC);  goto ok;
13593   case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
13594                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13595                                                ovl.fmt.RSY.dl2,
13596                                                ovl.fmt.RSY.dh2);  goto ok;
13597   case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
13598                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13599                                                ovl.fmt.RSY.dl2,
13600                                                ovl.fmt.RSY.dh2);  goto ok;
13601   case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
13602                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13603                                                ovl.fmt.RSY.dl2,
13604                                                ovl.fmt.RSY.dh2);  goto ok;
13605   case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
13606                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13607                                                ovl.fmt.RSY.dl2,
13608                                                ovl.fmt.RSY.dh2);  goto ok;
13609   case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
13610                                                ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13611                                                ovl.fmt.RSY.dl2,
13612                                                ovl.fmt.RSY.dh2);  goto ok;
13613   case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
13614                                               ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13615                                               goto ok;
13616   case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
13617                                               ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13618                                               goto ok;
13619   case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
13620   case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
13621                                                 ovl.fmt.RIE_RRUUU.r1,
13622                                                 ovl.fmt.RIE_RRUUU.r2,
13623                                                 ovl.fmt.RIE_RRUUU.i3,
13624                                                 ovl.fmt.RIE_RRUUU.i4,
13625                                                 ovl.fmt.RIE_RRUUU.i5);
13626                                                 goto ok;
13627   case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
13628                                                 ovl.fmt.RIE_RRUUU.r1,
13629                                                 ovl.fmt.RIE_RRUUU.r2,
13630                                                 ovl.fmt.RIE_RRUUU.i3,
13631                                                 ovl.fmt.RIE_RRUUU.i4,
13632                                                 ovl.fmt.RIE_RRUUU.i5);
13633                                                 goto ok;
13634   case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
13635                                                 ovl.fmt.RIE_RRUUU.r1,
13636                                                 ovl.fmt.RIE_RRUUU.r2,
13637                                                 ovl.fmt.RIE_RRUUU.i3,
13638                                                 ovl.fmt.RIE_RRUUU.i4,
13639                                                 ovl.fmt.RIE_RRUUU.i5);
13640                                                 goto ok;
13641   case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
13642                                                 ovl.fmt.RIE_RRUUU.r1,
13643                                                 ovl.fmt.RIE_RRUUU.r2,
13644                                                 ovl.fmt.RIE_RRUUU.i3,
13645                                                 ovl.fmt.RIE_RRUUU.i4,
13646                                                 ovl.fmt.RIE_RRUUU.i5);
13647                                                 goto ok;
13648   case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
13649   case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
13650                                                ovl.fmt.RIE_RRPU.r1,
13651                                                ovl.fmt.RIE_RRPU.r2,
13652                                                ovl.fmt.RIE_RRPU.i4,
13653                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
13654   case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
13655                                                ovl.fmt.RIE_RRPU.r1,
13656                                                ovl.fmt.RIE_RRPU.r2,
13657                                                ovl.fmt.RIE_RRPU.i4,
13658                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
13659   case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
13660   case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
13661   case 0xec0000000072ULL: /* CIT */ goto unimplemented;
13662   case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
13663   case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
13664                                                ovl.fmt.RIE_RRPU.r1,
13665                                                ovl.fmt.RIE_RRPU.r2,
13666                                                ovl.fmt.RIE_RRPU.i4,
13667                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
13668   case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
13669                                                ovl.fmt.RIE_RRPU.r1,
13670                                                ovl.fmt.RIE_RRPU.r2,
13671                                                ovl.fmt.RIE_RRPU.i4,
13672                                                ovl.fmt.RIE_RRPU.m3);  goto ok;
13673   case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
13674                                                ovl.fmt.RIEv3.r1,
13675                                                ovl.fmt.RIEv3.m3,
13676                                                ovl.fmt.RIEv3.i4,
13677                                                ovl.fmt.RIEv3.i2);  goto ok;
13678   case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
13679                                                ovl.fmt.RIEv3.r1,
13680                                                ovl.fmt.RIEv3.m3,
13681                                                ovl.fmt.RIEv3.i4,
13682                                                ovl.fmt.RIEv3.i2);  goto ok;
13683   case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
13684                                                ovl.fmt.RIEv3.r1,
13685                                                ovl.fmt.RIEv3.m3,
13686                                                ovl.fmt.RIEv3.i4,
13687                                                ovl.fmt.RIEv3.i2);  goto ok;
13688   case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
13689                                                ovl.fmt.RIEv3.r1,
13690                                                ovl.fmt.RIEv3.m3,
13691                                                ovl.fmt.RIEv3.i4,
13692                                                ovl.fmt.RIEv3.i2);  goto ok;
13693   case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
13694                                                ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13695                                                goto ok;
13696   case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
13697                                                ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13698                                                ovl.fmt.RIE.i2);  goto ok;
13699   case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
13700                                                ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13701                                                ovl.fmt.RIE.i2);  goto ok;
13702   case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
13703                                                ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13704                                                ovl.fmt.RIE.i2);  goto ok;
13705   case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
13706                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13707                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13708                                           goto ok;
13709   case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
13710                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13711                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13712                                           goto ok;
13713   case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
13714                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13715                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13716                                           goto ok;
13717   case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
13718                                           ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13719                                           ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13720                                           goto ok;
13721   case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
13722                                                 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13723                                                 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13724                                                 ovl.fmt.RIS.i2);  goto ok;
13725   case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
13726                                                 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13727                                                 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13728                                                 ovl.fmt.RIS.i2);  goto ok;
13729   case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
13730                                                 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
13731                                                 ovl.fmt.RIS.d4,
13732                                                 ovl.fmt.RIS.i2);  goto ok;
13733   case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
13734                                                 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13735                                                 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13736                                                 ovl.fmt.RIS.i2);  goto ok;
13737   case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
13738                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13739                                                ovl.fmt.RXE.d2);  goto ok;
13740   case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
13741                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13742                                                ovl.fmt.RXE.d2);  goto ok;
13743   case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
13744                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13745                                                ovl.fmt.RXE.d2);  goto ok;
13746   case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
13747   case 0xed0000000008ULL: /* KEB */ goto unimplemented;
13748   case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
13749                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13750                                                ovl.fmt.RXE.d2);  goto ok;
13751   case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
13752                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13753                                                ovl.fmt.RXE.d2);  goto ok;
13754   case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
13755                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13756                                                ovl.fmt.RXE.d2);  goto ok;
13757   case 0xed000000000cULL: /* MDEB */ goto unimplemented;
13758   case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
13759                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13760                                                ovl.fmt.RXE.d2);  goto ok;
13761   case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
13762                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13763                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13764                                                 ovl.fmt.RXF.r1);  goto ok;
13765   case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
13766                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13767                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13768                                                 ovl.fmt.RXF.r1);  goto ok;
13769   case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
13770                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13771                                                ovl.fmt.RXE.d2);  goto ok;
13772   case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
13773                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13774                                                ovl.fmt.RXE.d2);  goto ok;
13775   case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
13776                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13777                                                ovl.fmt.RXE.d2);  goto ok;
13778   case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
13779                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13780                                                ovl.fmt.RXE.d2);  goto ok;
13781   case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
13782                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13783                                                ovl.fmt.RXE.d2);  goto ok;
13784   case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
13785                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13786                                                ovl.fmt.RXE.d2);  goto ok;
13787   case 0xed0000000018ULL: /* KDB */ goto unimplemented;
13788   case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
13789                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13790                                                ovl.fmt.RXE.d2);  goto ok;
13791   case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
13792                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13793                                                ovl.fmt.RXE.d2);  goto ok;
13794   case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
13795                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13796                                                ovl.fmt.RXE.d2);  goto ok;
13797   case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
13798                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13799                                                ovl.fmt.RXE.d2);  goto ok;
13800   case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
13801                                                ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13802                                                ovl.fmt.RXE.d2);  goto ok;
13803   case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
13804                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13805                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13806                                                 ovl.fmt.RXF.r1);  goto ok;
13807   case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
13808                                                 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13809                                                 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13810                                                 ovl.fmt.RXF.r1);  goto ok;
13811   case 0xed0000000024ULL: /* LDE */ goto unimplemented;
13812   case 0xed0000000025ULL: /* LXD */ goto unimplemented;
13813   case 0xed0000000026ULL: /* LXE */ goto unimplemented;
13814   case 0xed000000002eULL: /* MAE */ goto unimplemented;
13815   case 0xed000000002fULL: /* MSE */ goto unimplemented;
13816   case 0xed0000000034ULL: /* SQE */ goto unimplemented;
13817   case 0xed0000000035ULL: /* SQD */ goto unimplemented;
13818   case 0xed0000000037ULL: /* MEE */ goto unimplemented;
13819   case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
13820   case 0xed0000000039ULL: /* MYL */ goto unimplemented;
13821   case 0xed000000003aULL: /* MAY */ goto unimplemented;
13822   case 0xed000000003bULL: /* MY */ goto unimplemented;
13823   case 0xed000000003cULL: /* MAYH */ goto unimplemented;
13824   case 0xed000000003dULL: /* MYH */ goto unimplemented;
13825   case 0xed000000003eULL: /* MAD */ goto unimplemented;
13826   case 0xed000000003fULL: /* MSD */ goto unimplemented;
13827   case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
13828   case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
13829   case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
13830   case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
13831   case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
13832   case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
13833   case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
13834   case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
13835   case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
13836   case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
13837   case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
13838                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13839                                                ovl.fmt.RXY.dl2,
13840                                                ovl.fmt.RXY.dh2);  goto ok;
13841   case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
13842                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13843                                                ovl.fmt.RXY.dl2,
13844                                                ovl.fmt.RXY.dh2);  goto ok;
13845   case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
13846                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13847                                                ovl.fmt.RXY.dl2,
13848                                                ovl.fmt.RXY.dh2);  goto ok;
13849   case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
13850                                                ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13851                                                ovl.fmt.RXY.dl2,
13852                                                ovl.fmt.RXY.dh2);  goto ok;
13853   }
13854
13855   switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
13856   case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
13857                                      ovl.fmt.RIL.i2);  goto ok;
13858   case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
13859                                      ovl.fmt.RIL.i2);  goto ok;
13860   case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
13861                                   ovl.fmt.RIL.i2);  goto ok;
13862   case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
13863                                      ovl.fmt.RIL.i2);  goto ok;
13864   case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
13865                                      ovl.fmt.RIL.i2);  goto ok;
13866   case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
13867                                      ovl.fmt.RIL.i2);  goto ok;
13868   case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
13869                                      ovl.fmt.RIL.i2);  goto ok;
13870   case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
13871                                      ovl.fmt.RIL.i2);  goto ok;
13872   case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
13873                                      ovl.fmt.RIL.i2);  goto ok;
13874   case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
13875                                      ovl.fmt.RIL.i2);  goto ok;
13876   case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
13877                                      ovl.fmt.RIL.i2);  goto ok;
13878   case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
13879                                      ovl.fmt.RIL.i2);  goto ok;
13880   case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
13881                                      ovl.fmt.RIL.i2);  goto ok;
13882   case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
13883                                      ovl.fmt.RIL.i2);  goto ok;
13884   case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
13885                                      ovl.fmt.RIL.i2);  goto ok;
13886   case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
13887                                      ovl.fmt.RIL.i2);  goto ok;
13888   case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
13889                                      ovl.fmt.RIL.i2);  goto ok;
13890   case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
13891                                      ovl.fmt.RIL.i2);  goto ok;
13892   case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
13893                                      ovl.fmt.RIL.i2);  goto ok;
13894   case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
13895                                      ovl.fmt.RIL.i2);  goto ok;
13896   case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
13897                                      ovl.fmt.RIL.i2);  goto ok;
13898   case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
13899                                      ovl.fmt.RIL.i2);  goto ok;
13900   case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
13901                                      ovl.fmt.RIL.i2);  goto ok;
13902   case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
13903                                      ovl.fmt.RIL.i2);  goto ok;
13904   case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
13905                                      ovl.fmt.RIL.i2);  goto ok;
13906   case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
13907                                      ovl.fmt.RIL.i2);  goto ok;
13908   case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
13909                                      ovl.fmt.RIL.i2);  goto ok;
13910   case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
13911                                      ovl.fmt.RIL.i2);  goto ok;
13912   case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
13913                                      ovl.fmt.RIL.i2);  goto ok;
13914   case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
13915                                      ovl.fmt.RIL.i2);  goto ok;
13916   case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
13917                                      ovl.fmt.RIL.i2);  goto ok;
13918   case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
13919                                      ovl.fmt.RIL.i2);  goto ok;
13920   case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
13921                                      ovl.fmt.RIL.i2);  goto ok;
13922   case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
13923                                      ovl.fmt.RIL.i2);  goto ok;
13924   case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
13925                                      ovl.fmt.RIL.i2);  goto ok;
13926   case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
13927                                      ovl.fmt.RIL.i2);  goto ok;
13928   case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
13929                                      ovl.fmt.RIL.i2);  goto ok;
13930   case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
13931                                      ovl.fmt.RIL.i2);  goto ok;
13932   case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
13933                                      ovl.fmt.RIL.i2);  goto ok;
13934   case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
13935                                      ovl.fmt.RIL.i2);  goto ok;
13936   case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
13937                                      ovl.fmt.RIL.i2);  goto ok;
13938   case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
13939                                      ovl.fmt.RIL.i2);  goto ok;
13940   case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
13941                                      ovl.fmt.RIL.i2);  goto ok;
13942   case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
13943                                      ovl.fmt.RIL.i2);  goto ok;
13944   case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
13945                                      ovl.fmt.RIL.i2);  goto ok;
13946   case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
13947                                      ovl.fmt.RIL.i2);  goto ok;
13948   case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
13949                                      ovl.fmt.RIL.i2);  goto ok;
13950   case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
13951                                      ovl.fmt.RIL.i2);  goto ok;
13952   case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
13953                                      ovl.fmt.RIL.i2);  goto ok;
13954   case 0xc800ULL: /* MVCOS */ goto unimplemented;
13955   case 0xc801ULL: /* ECTG */ goto unimplemented;
13956   case 0xc802ULL: /* CSST */ goto unimplemented;
13957   case 0xc804ULL: /* LPD */ goto unimplemented;
13958   case 0xc805ULL: /* LPDG */ goto unimplemented;
13959   case 0xcc06ULL: /* BRCTH */ goto unimplemented;
13960   case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
13961                                      ovl.fmt.RIL.i2);  goto ok;
13962   case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
13963                                      ovl.fmt.RIL.i2);  goto ok;
13964   case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
13965                                      ovl.fmt.RIL.i2);  goto ok;
13966   case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
13967                                      ovl.fmt.RIL.i2);  goto ok;
13968   case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
13969                                      ovl.fmt.RIL.i2);  goto ok;
13970   }
13971
13972   switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
13973   case 0xd0ULL: /* TRTR */ goto unimplemented;
13974   case 0xd1ULL: /* MVN */ goto unimplemented;
13975   case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
13976                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13977                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
13978   case 0xd3ULL: /* MVZ */ goto unimplemented;
13979   case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
13980                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13981                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
13982   case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
13983                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13984                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
13985   case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
13986                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13987                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
13988   case 0xd7ULL:
13989      if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
13990         s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
13991      else
13992        s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
13993                              ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13994                              ovl.fmt.SS.b2, ovl.fmt.SS.d2);
13995      goto ok;
13996   case 0xd9ULL: /* MVCK */ goto unimplemented;
13997   case 0xdaULL: /* MVCP */ goto unimplemented;
13998   case 0xdbULL: /* MVCS */ goto unimplemented;
13999   case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14000                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14001                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
14002   case 0xddULL: /* TRT */ goto unimplemented;
14003   case 0xdeULL: /* ED */ goto unimplemented;
14004   case 0xdfULL: /* EDMK */ goto unimplemented;
14005   case 0xe1ULL: /* PKU */ goto unimplemented;
14006   case 0xe2ULL: /* UNPKU */ goto unimplemented;
14007   case 0xe8ULL: /* MVCIN */ goto unimplemented;
14008   case 0xe9ULL: /* PKA */ goto unimplemented;
14009   case 0xeaULL: /* UNPKA */ goto unimplemented;
14010   case 0xeeULL: /* PLO */ goto unimplemented;
14011   case 0xefULL: /* LMD */ goto unimplemented;
14012   case 0xf0ULL: /* SRP */ goto unimplemented;
14013   case 0xf1ULL: /* MVO */ goto unimplemented;
14014   case 0xf2ULL: /* PACK */ goto unimplemented;
14015   case 0xf3ULL: /* UNPK */ goto unimplemented;
14016   case 0xf8ULL: /* ZAP */ goto unimplemented;
14017   case 0xf9ULL: /* CP */ goto unimplemented;
14018   case 0xfaULL: /* AP */ goto unimplemented;
14019   case 0xfbULL: /* SP */ goto unimplemented;
14020   case 0xfcULL: /* MP */ goto unimplemented;
14021   case 0xfdULL: /* DP */ goto unimplemented;
14022   }
14023
14024   switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14025   case 0xe500ULL: /* LASP */ goto unimplemented;
14026   case 0xe501ULL: /* TPROT */ goto unimplemented;
14027   case 0xe502ULL: /* STRAG */ goto unimplemented;
14028   case 0xe50eULL: /* MVCSK */ goto unimplemented;
14029   case 0xe50fULL: /* MVCDK */ goto unimplemented;
14030   case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14031                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14032                                       goto ok;
14033   case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14034                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14035                                       goto ok;
14036   case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14037                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14038                                       goto ok;
14039   case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14040                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14041                                       goto ok;
14042   case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14043                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14044                                       goto ok;
14045   case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14046                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14047                                       goto ok;
14048   case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14049                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14050                                       goto ok;
14051   case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14052                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14053                                       goto ok;
14054   case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14055                                       ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14056                                       goto ok;
14057   }
14058
14059   return S390_DECODE_UNKNOWN_INSN;
14060
14061ok:
14062   return S390_DECODE_OK;
14063
14064unimplemented:
14065   return S390_DECODE_UNIMPLEMENTED_INSN;
14066}
14067
14068/* Handle "special" instructions. */
14069static s390_decode_t
14070s390_decode_special_and_irgen(UChar *bytes)
14071{
14072   s390_decode_t status = S390_DECODE_OK;
14073
14074   /* Got a "Special" instruction preamble.  Which one is it? */
14075   if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14076      s390_irgen_client_request();
14077   } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14078      s390_irgen_guest_NRADDR();
14079   } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14080      s390_irgen_call_noredir();
14081   } else {
14082      /* We don't know what it is. */
14083      return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14084   }
14085
14086   dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14087
14088   return status;
14089}
14090
14091
14092/* Function returns # bytes that were decoded or 0 in case of failure */
14093static UInt
14094s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14095{
14096   s390_decode_t status;
14097
14098   dis_res = dres;
14099
14100   /* Spot the 8-byte preamble:   18ff lr r15,r15
14101                                  1811 lr r1,r1
14102                                  1822 lr r2,r2
14103                                  1833 lr r3,r3 */
14104   if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14105       bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14106       bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14107
14108      /* Handle special instruction that follows that preamble. */
14109      if (0) vex_printf("special function handling...\n");
14110
14111      insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14112      guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14113
14114      status =
14115         s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
14116   } else {
14117      /* Handle normal instructions. */
14118      switch (insn_length) {
14119      case 2:
14120         status = s390_decode_2byte_and_irgen(bytes);
14121         break;
14122
14123      case 4:
14124         status = s390_decode_4byte_and_irgen(bytes);
14125         break;
14126
14127      case 6:
14128         status = s390_decode_6byte_and_irgen(bytes);
14129         break;
14130
14131      default:
14132        status = S390_DECODE_ERROR;
14133        break;
14134      }
14135   }
14136   /* If next instruction is execute, stop here */
14137   if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14138      put_IA(mkaddr_expr(guest_IA_next_instr));
14139      dis_res->whatNext = Dis_StopHere;
14140      dis_res->jk_StopHere = Ijk_Boring;
14141   }
14142
14143   if (status == S390_DECODE_OK) return insn_length;  /* OK */
14144
14145   /* Decoding failed somehow */
14146   vex_printf("vex s390->IR: ");
14147   switch (status) {
14148   case S390_DECODE_UNKNOWN_INSN:
14149      vex_printf("unknown insn: ");
14150      break;
14151
14152   case S390_DECODE_UNIMPLEMENTED_INSN:
14153      vex_printf("unimplemented insn: ");
14154      break;
14155
14156   case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14157      vex_printf("unimplemented special insn: ");
14158      break;
14159
14160   default:
14161   case S390_DECODE_ERROR:
14162      vex_printf("decoding error: ");
14163      break;
14164   }
14165
14166   vex_printf("%02x%02x", bytes[0], bytes[1]);
14167   if (insn_length > 2) {
14168      vex_printf(" %02x%02x", bytes[2], bytes[3]);
14169   }
14170   if (insn_length > 4) {
14171      vex_printf(" %02x%02x", bytes[4], bytes[5]);
14172   }
14173   vex_printf("\n");
14174
14175   return 0;  /* Failed */
14176}
14177
14178
14179/* Disassemble a single instruction INSN into IR. */
14180static DisResult
14181disInstr_S390_WRK(UChar *insn)
14182{
14183   UChar byte;
14184   UInt  insn_length;
14185   DisResult dres;
14186
14187   /* ---------------------------------------------------- */
14188   /* --- Compute instruction length                    -- */
14189   /* ---------------------------------------------------- */
14190
14191   /* Get the first byte of the insn. */
14192   byte = insn[0];
14193
14194   /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14195      00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14196   insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14197
14198   guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14199
14200   /* ---------------------------------------------------- */
14201   /* --- Initialise the DisResult data                 -- */
14202   /* ---------------------------------------------------- */
14203   dres.whatNext   = Dis_Continue;
14204   dres.len        = insn_length;
14205   dres.continueAt = 0;
14206   dres.jk_StopHere = Ijk_INVALID;
14207
14208   /* fixs390: consider chasing of conditional jumps */
14209
14210   /* Normal and special instruction handling starts here. */
14211   if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14212      /* All decode failures end up here. The decoder has already issued an
14213         error message.
14214         Tell the dispatcher that this insn cannot be decoded, and so has
14215         not been executed, and (is currently) the next to be executed.
14216         The insn address in the guest state needs to be set to
14217         guest_IA_curr_instr, otherwise the complaint will report an
14218         incorrect address. */
14219      put_IA(mkaddr_expr(guest_IA_curr_instr));
14220
14221      dres.whatNext    = Dis_StopHere;
14222      dres.jk_StopHere = Ijk_NoDecode;
14223      dres.continueAt  = 0;
14224      dres.len         = 0;
14225   } else {
14226      /* Decode success */
14227      switch (dres.whatNext) {
14228      case Dis_Continue:
14229         put_IA(mkaddr_expr(guest_IA_next_instr));
14230         break;
14231      case Dis_ResteerU:
14232      case Dis_ResteerC:
14233         put_IA(mkaddr_expr(dres.continueAt));
14234         break;
14235      case Dis_StopHere:
14236         break;
14237      default:
14238         vassert(0);
14239      }
14240   }
14241
14242   return dres;
14243}
14244
14245
14246/*------------------------------------------------------------*/
14247/*--- Top-level fn                                         ---*/
14248/*------------------------------------------------------------*/
14249
14250/* Disassemble a single instruction into IR.  The instruction
14251   is located in host memory at &guest_code[delta]. */
14252
14253DisResult
14254disInstr_S390(IRSB        *irsb_IN,
14255              Bool       (*resteerOkFn)(void *, Addr64),
14256              Bool         resteerCisOk,
14257              void        *callback_opaque,
14258              UChar       *guest_code,
14259              Long         delta,
14260              Addr64       guest_IP,
14261              VexArch      guest_arch,
14262              VexArchInfo *archinfo,
14263              VexAbiInfo  *abiinfo,
14264              Bool         host_bigendian)
14265{
14266   vassert(guest_arch == VexArchS390X);
14267
14268   /* The instruction decoder requires a big-endian machine. */
14269   vassert(host_bigendian == True);
14270
14271   /* Set globals (see top of this file) */
14272   guest_IA_curr_instr = guest_IP;
14273   irsb = irsb_IN;
14274   resteer_fn = resteerOkFn;
14275   resteer_data = callback_opaque;
14276
14277   return disInstr_S390_WRK(guest_code + delta);
14278}
14279
14280/*---------------------------------------------------------------*/
14281/*--- end                                   guest_s390_toIR.c ---*/
14282/*---------------------------------------------------------------*/
14283