1 /* -*- mode: C; c-basic-offset: 3; -*- */
2 
3 /*---------------------------------------------------------------*/
4 /*--- begin                                 guest_s390_toIR.c ---*/
5 /*---------------------------------------------------------------*/
6 
7 /*
8    This file is part of Valgrind, a dynamic binary instrumentation
9    framework.
10 
11    Copyright IBM Corp. 2010-2017
12 
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
dm_test_dma_m2m(struct unit_test_state * uts)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, see <http://www.gnu.org/licenses/>.
25 
26    The GNU General Public License is contained in the file COPYING.
27 */
28 
29 /* Contributed by Florian Krohm and Christian Borntraeger */
30 
31 /* Translates s390 code to IR. */
32 
33 #include "libvex_basictypes.h"
34 #include "libvex_ir.h"
35 #include "libvex_emnote.h"
36 #include "libvex_s390x_common.h"
37 #include "main_util.h"               /* vassert */
38 #include "main_globals.h"            /* vex_traceflags */
39 #include "guest_generic_bb_to_IR.h"  /* DisResult */
40 #include "guest_s390_defs.h"         /* prototypes for this file's functions */
41 #include "s390_disasm.h"
42 #include "s390_defs.h"               /* S390_BFP_ROUND_xyzzy */
43 #include "host_s390_defs.h"          /* s390_host_has_xyzzy */
44 
45 
46 /*------------------------------------------------------------*/
47 /*--- Forward declarations                                 ---*/
48 /*------------------------------------------------------------*/
49 static UInt s390_decode_and_irgen(const UChar *, UInt, DisResult *);
50 static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
51 static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
52 static const HChar *s390_irgen_BIC(UChar r1, IRTemp op2addr);
53 
54 /*------------------------------------------------------------*/
55 /*--- Globals                                              ---*/
56 /*------------------------------------------------------------*/
57 
58 /* The IRSB* into which we're generating code. */
59 static IRSB *irsb;
60 
61 /* The guest address for the instruction currently being
62    translated. */
63 static Addr64 guest_IA_curr_instr;
64 
65 /* The guest address for the instruction following the current instruction. */
66 static Addr64 guest_IA_next_instr;
67 
68 /* Result of disassembly step. */
69 static DisResult *dis_res;
70 
71 /* Resteer function and callback data */
72 static Bool (*resteer_fn)(void *, Addr);
73 static void *resteer_data;
74 
75 /* Whether to print diagnostics for illegal instructions. */
76 static Bool sigill_diag;
77 
78 /* The last seen execute target instruction */
79 ULong last_execute_target;
dm_test_dma_rx(struct unit_test_state * uts)80 
81 /* The possible outcomes of a decoding operation */
82 typedef enum {
83    S390_DECODE_OK,
84    S390_DECODE_UNKNOWN_INSN,
85    S390_DECODE_UNIMPLEMENTED_INSN,
86    S390_DECODE_UNKNOWN_SPECIAL_INSN,
87    S390_DECODE_SPECIFICATION_EXCEPTION,
88    S390_DECODE_ERROR
89 } s390_decode_t;
90 
91 
92 /*------------------------------------------------------------*/
93 /*--- Instruction formats.                                 ---*/
94 /*------------------------------------------------------------*/
95 
96 #define I_i(insn) ((insn) & 0xff)
97 #define RR_r1(insn) (((insn) >> 4) & 0xf)
98 #define RR_r2(insn) ((insn) & 0xf)
99 #define RI_r1(insn) (((insn) >> 20) & 0xf)
100 #define RI_i2(insn) ((insn) & 0xffff)
101 #define RRE_r1(insn) (((insn) >> 4) & 0xf)
102 #define RRE_r2(insn) ((insn) & 0xf)
103 #define RRF_r1(insn) (((insn) >> 12) & 0xf)
104 #define RRF_r3(insn) (((insn) >> 4) & 0xf)
105 #define RRF_r2(insn) ((insn) & 0xf)
106 #define RRF2_m3(insn) (((insn) >> 12) & 0xf)
107 #define RRF2_m4(insn) (((insn) >> 8) & 0xf)
108 #define RRF2_r1(insn) (((insn) >> 4) & 0xf)
109 #define RRF2_r2(insn) ((insn) & 0xf)
110 #define RRF3_r3(insn) (((insn) >> 12) & 0xf)
111 #define RRF3_r1(insn) (((insn) >> 4) & 0xf)
112 #define RRF3_r2(insn) ((insn) & 0xf)
113 #define RRF4_r3(insn) (((insn) >> 12) & 0xf)
114 #define RRF4_m4(insn) (((insn) >> 8) & 0xf)
115 #define RRF4_r1(insn) (((insn) >> 4) & 0xf)
116 #define RRF4_r2(insn) ((insn) & 0xf)
117 #define RRF5_m4(insn) (((insn) >> 8) & 0xf)
118 #define RRF5_r1(insn) (((insn) >> 4) & 0xf)
119 #define RRF5_r2(insn) ((insn) & 0xf)
120 #define RS_r1(insn) (((insn) >> 20) & 0xf)
121 #define RS_r3(insn) (((insn) >> 16) & 0xf)
122 #define RS_b2(insn) (((insn) >> 12) & 0xf)
123 #define RS_d2(insn) ((insn) & 0xfff)
124 #define RSI_r1(insn) (((insn) >> 20) & 0xf)
125 #define RSI_r3(insn) (((insn) >> 16) & 0xf)
126 #define RSI_i2(insn) ((insn) & 0xffff)
127 #define RX_r1(insn) (((insn) >> 20) & 0xf)
128 #define RX_x2(insn) (((insn) >> 16) & 0xf)
129 #define RX_b2(insn) (((insn) >> 12) & 0xf)
130 #define RX_d2(insn) ((insn) & 0xfff)
131 #define S_b2(insn) (((insn) >> 12) & 0xf)
132 #define S_d2(insn) ((insn) & 0xfff)
133 #define SI_i2(insn) (((insn) >> 16) & 0xff)
134 #define SI_b1(insn) (((insn) >> 12) & 0xf)
135 #define SI_d1(insn) ((insn) & 0xfff)
136 #define RIE_r1(insn) (((insn) >> 52) & 0xf)
137 #define RIE_r3(insn) (((insn) >> 48) & 0xf)
138 #define RIE_i2(insn) (((insn) >> 32) & 0xffff)
139 #define RIE_RRUUU_r1(insn) (((insn) >> 52) & 0xf)
140 #define RIE_RRUUU_r2(insn) (((insn) >> 48) & 0xf)
141 #define RIE_RRUUU_i3(insn) (((insn) >> 40) & 0xff)
142 #define RIE_RRUUU_i4(insn) (((insn) >> 32) & 0xff)
143 #define RIE_RRUUU_i5(insn) (((insn) >> 24) & 0xff)
144 #define RIEv1_r1(insn) (((insn) >> 52) & 0xf)
145 #define RIEv1_i2(insn) (((insn) >> 32) & 0xffff)
146 #define RIEv1_m3(insn) (((insn) >> 28) & 0xf)
147 #define RIE_RRPU_r1(insn) (((insn) >> 52) & 0xf)
148 #define RIE_RRPU_r2(insn) (((insn) >> 48) & 0xf)
149 #define RIE_RRPU_i4(insn) (((insn) >> 32) & 0xffff)
150 #define RIE_RRPU_m3(insn) (((insn) >> 28) & 0xf)
151 #define RIEv3_r1(insn) (((insn) >> 52) & 0xf)
152 #define RIEv3_m3(insn) (((insn) >> 48) & 0xf)
153 #define RIEv3_i4(insn) (((insn) >> 32) & 0xffff)
154 #define RIEv3_i2(insn) (((insn) >> 24) & 0xff)
155 #define RIL_r1(insn) (((insn) >> 52) & 0xf)
156 #define RIL_i2(insn) (((insn) >> 16) & 0xffffffff)
157 #define RIS_r1(insn) (((insn) >> 52) & 0xf)
158 #define RIS_m3(insn) (((insn) >> 48) & 0xf)
159 #define RIS_b4(insn) (((insn) >> 44) & 0xf)
160 #define RIS_d4(insn) (((insn) >> 32) & 0xfff)
161 #define RIS_i2(insn) (((insn) >> 24) & 0xff)
162 #define RRS_r1(insn) (((insn) >> 52) & 0xf)
163 #define RRS_r2(insn) (((insn) >> 48) & 0xf)
164 #define RRS_b4(insn) (((insn) >> 44) & 0xf)
165 #define RRS_d4(insn) (((insn) >> 32) & 0xfff)
166 #define RRS_m3(insn) (((insn) >> 28) & 0xf)
167 #define RSY_r1(insn) (((insn) >> 52) & 0xf)
168 #define RSY_r3(insn) (((insn) >> 48) & 0xf)
169 #define RSY_b2(insn) (((insn) >> 44) & 0xf)
170 #define RSY_dl2(insn) (((insn) >> 32) & 0xfff)
171 #define RSY_dh2(insn) (((insn) >> 24) & 0xff)
172 #define RXE_r1(insn) (((insn) >> 52) & 0xf)
173 #define RXE_x2(insn) (((insn) >> 48) & 0xf)
174 #define RXE_b2(insn) (((insn) >> 44) & 0xf)
175 #define RXE_d2(insn) (((insn) >> 32) & 0xfff)
176 #define RXE_m3(insn) (((insn) >> 28) & 0xf)
177 #define RXF_r3(insn) (((insn) >> 52) & 0xf)
178 #define RXF_x2(insn) (((insn) >> 48) & 0xf)
179 #define RXF_b2(insn) (((insn) >> 44) & 0xf)
180 #define RXF_d2(insn) (((insn) >> 32) & 0xfff)
181 #define RXF_r1(insn) (((insn) >> 28) & 0xf)
182 #define RXY_r1(insn) (((insn) >> 52) & 0xf)
183 #define RXY_x2(insn) (((insn) >> 48) & 0xf)
184 #define RXY_b2(insn) (((insn) >> 44) & 0xf)
185 #define RXY_dl2(insn) (((insn) >> 32) & 0xfff)
186 #define RXY_dh2(insn) (((insn) >> 24) & 0xff)
187 #define SIY_i2(insn) (((insn) >> 48) & 0xff)
188 #define SIY_b1(insn) (((insn) >> 44) & 0xf)
189 #define SIY_dl1(insn) (((insn) >> 32) & 0xfff)
190 #define SIY_dh1(insn) (((insn) >> 24) & 0xff)
191 #define SS_l(insn) (((insn) >> 48) & 0xff)
192 #define SS_b1(insn) (((insn) >> 44) & 0xf)
193 #define SS_d1(insn) (((insn) >> 32) & 0xfff)
194 #define SS_b2(insn) (((insn) >> 28) & 0xf)
195 #define SS_d2(insn) (((insn) >> 16) & 0xfff)
196 #define SIL_b1(insn) (((insn) >> 44) & 0xf)
197 #define SIL_d1(insn) (((insn) >> 32) & 0xfff)
198 #define SIL_i2(insn) (((insn) >> 16) & 0xffff)
199 #define VRX_v1(insn) (((insn) >> 52) & 0xf)
200 #define VRX_x2(insn) (((insn) >> 48) & 0xf)
201 #define VRX_b2(insn) (((insn) >> 44) & 0xf)
202 #define VRX_d2(insn) (((insn) >> 32) & 0xfff)
203 #define VRX_m3(insn) (((insn) >> 28) & 0xf)
204 #define VRX_rxb(insn) (((insn) >> 24) & 0xf)
205 #define VRR_v1(insn) (((insn) >> 52) & 0xf)
206 #define VRR_v2(insn) (((insn) >> 48) & 0xf)
207 #define VRR_r3(insn) (((insn) >> 44) & 0xf)
208 #define VRR_m5(insn) (((insn) >> 36) & 0xf)
209 #define VRR_m4(insn) (((insn) >> 28) & 0xf)
210 #define VRR_rxb(insn) (((insn) >> 24) & 0xf)
211 #define VRRa_v1(insn) (((insn) >> 52) & 0xf)
212 #define VRRa_v2(insn) (((insn) >> 48) & 0xf)
213 #define VRRa_v3(insn) (((insn) >> 44) & 0xf)
214 #define VRRa_m5(insn) (((insn) >> 36) & 0xf)
215 #define VRRa_m4(insn) (((insn) >> 32) & 0xf)
216 #define VRRa_m3(insn) (((insn) >> 28) & 0xf)
217 #define VRRa_rxb(insn) (((insn) >> 24) & 0xf)
218 #define VRRd_v1(insn) (((insn) >> 52) & 0xf)
219 #define VRRd_v2(insn) (((insn) >> 48) & 0xf)
220 #define VRRd_v3(insn) (((insn) >> 44) & 0xf)
221 #define VRRd_m5(insn) (((insn) >> 40) & 0xf)
222 #define VRRd_m6(insn) (((insn) >> 36) & 0xf)
223 #define VRRd_v4(insn) (((insn) >> 28) & 0xf)
224 #define VRRd_rxb(insn) (((insn) >> 24) & 0xf)
225 #define VRRe_v1(insn) (((insn) >> 52) & 0xf)
226 #define VRRe_v2(insn) (((insn) >> 48) & 0xf)
227 #define VRRe_v3(insn) (((insn) >> 44) & 0xf)
228 #define VRRe_m6(insn) (((insn) >> 40) & 0xf)
229 #define VRRe_m5(insn) (((insn) >> 32) & 0xf)
230 #define VRRe_v4(insn) (((insn) >> 28) & 0xf)
231 #define VRRe_rxb(insn) (((insn) >> 24) & 0xf)
232 #define VRI_v1(insn) (((insn) >> 52) & 0xf)
233 #define VRI_v3(insn) (((insn) >> 48) & 0xf)
234 #define VRI_i2(insn) (((insn) >> 32) & 0xffff)
235 #define VRI_m3(insn) (((insn) >> 28) & 0xf)
236 #define VRI_rxb(insn) (((insn) >> 24) & 0xf)
237 #define VRId_v1(insn) (((insn) >> 52) & 0xf)
238 #define VRId_v2(insn) (((insn) >> 48) & 0xf)
239 #define VRId_v3(insn) (((insn) >> 44) & 0xf)
240 #define VRId_i4(insn) (((insn) >> 32) & 0xff)
241 #define VRId_m5(insn) (((insn) >> 28) & 0xf)
242 #define VRId_rxb(insn) (((insn) >> 24) & 0xf)
243 #define VRIe_v1(insn) (((insn) >> 52) & 0xf)
244 #define VRIe_v2(insn) (((insn) >> 48) & 0xf)
245 #define VRIe_i3(insn) (((insn) >> 36) & 0xfff)
246 #define VRIe_m5(insn) (((insn) >> 32) & 0xf)
247 #define VRIe_m4(insn) (((insn) >> 28) & 0xf)
248 #define VRIe_rxb(insn) (((insn) >> 24) & 0xf)
249 #define VRS_v1(insn) (((insn) >> 52) & 0xf)
250 #define VRS_v3(insn) (((insn) >> 48) & 0xf)
251 #define VRS_b2(insn) (((insn) >> 44) & 0xf)
252 #define VRS_d2(insn) (((insn) >> 32) & 0xfff)
253 #define VRS_m4(insn) (((insn) >> 28) & 0xf)
254 #define VRS_rxb(insn) (((insn) >> 24) & 0xf)
255 
256 
257 /*------------------------------------------------------------*/
258 /*--- Helpers for constructing IR.                         ---*/
259 /*------------------------------------------------------------*/
260 
261 /* Add a statement to the current irsb. */
262 static __inline__ void
263 stmt(IRStmt *st)
264 {
265    addStmtToIRSB(irsb, st);
266 }
267 
268 /* Allocate a new temporary of the given type. */
269 static __inline__ IRTemp
270 newTemp(IRType type)
271 {
272    vassert(isPlausibleIRType(type));
273 
274    return newIRTemp(irsb->tyenv, type);
275 }
276 
277 /* Create an expression node for a temporary */
278 static __inline__ IRExpr *
279 mkexpr(IRTemp tmp)
280 {
281    return IRExpr_RdTmp(tmp);
282 }
283 
284 /* Generate an expression node for an address. */
285 static __inline__ IRExpr *
286 mkaddr_expr(Addr64 addr)
287 {
288    return IRExpr_Const(IRConst_U64(addr));
289 }
290 
291 /* Add a statement that assigns to a temporary */
292 static __inline__ void
293 assign(IRTemp dst, IRExpr *expr)
294 {
295    stmt(IRStmt_WrTmp(dst, expr));
296 }
297 
298 /* Write an address into the guest_IA */
299 static __inline__ void
300 put_IA(IRExpr *address)
301 {
302    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
303 }
304 
305 /* Create a temporary of the given type and assign the expression to it */
306 static __inline__ IRTemp
307 mktemp(IRType type, IRExpr *expr)
308 {
309    IRTemp temp = newTemp(type);
310 
311    assign(temp, expr);
312 
313    return temp;
314 }
315 
316 /* Create a unary expression */
317 static __inline__ IRExpr *
318 unop(IROp kind, IRExpr *op)
319 {
320    return IRExpr_Unop(kind, op);
321 }
322 
323 /* Create a binary expression */
324 static __inline__ IRExpr *
325 binop(IROp kind, IRExpr *op1, IRExpr *op2)
326 {
327    return IRExpr_Binop(kind, op1, op2);
328 }
329 
330 /* Create a ternary expression */
331 static __inline__ IRExpr *
332 triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
333 {
334    return IRExpr_Triop(kind, op1, op2, op3);
335 }
336 
337 /* Create a quaternary expression */
338 static __inline__  IRExpr *
339 qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
340 {
341    return IRExpr_Qop(kind, op1, op2, op3, op4);
342 }
343 
344 /* Create an expression node for an 8-bit integer constant */
345 static __inline__ IRExpr *
346 mkU8(UInt value)
347 {
348    vassert(value < 256);
349 
350    return IRExpr_Const(IRConst_U8((UChar)value));
351 }
352 
353 /* Create an expression node for a 16-bit integer constant */
354 static __inline__ IRExpr *
355 mkU16(UInt value)
356 {
357    vassert(value < 65536);
358 
359    return IRExpr_Const(IRConst_U16((UShort)value));
360 }
361 
362 /* Create an expression node for a 32-bit integer constant */
363 static __inline__ IRExpr *
364 mkU32(UInt value)
365 {
366    return IRExpr_Const(IRConst_U32(value));
367 }
368 
369 /* Create an expression node for a 64-bit integer constant */
370 static __inline__ IRExpr *
371 mkU64(ULong value)
372 {
373    return IRExpr_Const(IRConst_U64(value));
374 }
375 
376 /* Create an expression node for a 32-bit floating point constant
377    whose value is given by a bit pattern. */
378 static __inline__ IRExpr *
379 mkF32i(UInt value)
380 {
381    return IRExpr_Const(IRConst_F32i(value));
382 }
383 
384 /* Create an expression node for a 32-bit floating point constant
385    whose value is given by a bit pattern. */
386 static __inline__ IRExpr *
387 mkF64i(ULong value)
388 {
389    return IRExpr_Const(IRConst_F64i(value));
390 }
391 
392 /* Little helper function for my sanity. ITE = if-then-else */
393 static IRExpr *
394 mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
395 {
396    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
397 
398    return IRExpr_ITE(condition, iftrue, iffalse);
399 }
400 
401 /* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
402 static __inline__ void
403 store(IRExpr *addr, IRExpr *data)
404 {
405    stmt(IRStmt_Store(Iend_BE, addr, data));
406 }
407 
408 /* Create an expression that loads a TYPE sized value from ADDR.
409    This is a big-endian machine. */
410 static __inline__ IRExpr *
411 load(IRType type, IRExpr *addr)
412 {
413    return IRExpr_Load(Iend_BE, type, addr);
414 }
415 
416 /* Function call */
417 static void
418 call_function(IRExpr *callee_address)
419 {
420    put_IA(callee_address);
421 
422    dis_res->whatNext    = Dis_StopHere;
423    dis_res->jk_StopHere = Ijk_Call;
424 }
425 
426 /* Function call with known target. */
427 static void
428 call_function_and_chase(Addr64 callee_address)
429 {
430    if (resteer_fn(resteer_data, callee_address)) {
431       dis_res->whatNext   = Dis_ResteerU;
432       dis_res->continueAt = callee_address;
433    } else {
434       put_IA(mkaddr_expr(callee_address));
435 
436       dis_res->whatNext = Dis_StopHere;
437       dis_res->jk_StopHere = Ijk_Call;
438    }
439 }
440 
441 /* Function return sequence */
442 static void
443 return_from_function(IRExpr *return_address)
444 {
445    put_IA(return_address);
446 
447    dis_res->whatNext    = Dis_StopHere;
448    dis_res->jk_StopHere = Ijk_Ret;
449 }
450 
451 /* A conditional branch whose target is not known at instrumentation time.
452 
453    if (condition) goto computed_target;
454 
455    Needs to be represented as:
456 
457    if (! condition) goto next_instruction;
458    goto computed_target;
459 */
460 static void
461 if_condition_goto_computed(IRExpr *condition, IRExpr *target)
462 {
463    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
464 
465    condition = unop(Iop_Not1, condition);
466 
467    stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
468                     S390X_GUEST_OFFSET(guest_IA)));
469 
470    put_IA(target);
471 
472    dis_res->whatNext    = Dis_StopHere;
473    dis_res->jk_StopHere = Ijk_Boring;
474 }
475 
476 /* A conditional branch whose target is known at instrumentation time. */
477 static void
478 if_condition_goto(IRExpr *condition, Addr64 target)
479 {
480    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
481 
482    stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
483                     S390X_GUEST_OFFSET(guest_IA)));
484 
485    put_IA(mkaddr_expr(guest_IA_next_instr));
486 
487    dis_res->whatNext    = Dis_StopHere;
488    dis_res->jk_StopHere = Ijk_Boring;
489 }
490 
491 /* An unconditional branch. Target may or may not be known at instrumentation
492    time. */
493 static void
494 always_goto(IRExpr *target)
495 {
496    put_IA(target);
497 
498    dis_res->whatNext    = Dis_StopHere;
499    dis_res->jk_StopHere = Ijk_Boring;
500 }
501 
502 
503 /* An unconditional branch to a known target. */
504 static void
505 always_goto_and_chase(Addr64 target)
506 {
507    if (resteer_fn(resteer_data, target)) {
508       /* Follow into the target */
509       dis_res->whatNext   = Dis_ResteerU;
510       dis_res->continueAt = target;
511    } else {
512       put_IA(mkaddr_expr(target));
513 
514       dis_res->whatNext    = Dis_StopHere;
515       dis_res->jk_StopHere = Ijk_Boring;
516    }
517 }
518 
519 /* A system call */
520 static void
521 system_call(IRExpr *sysno)
522 {
523    /* Store the system call number in the pseudo register. */
524    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
525 
526    /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
527    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
528                    mkU64(guest_IA_curr_instr)));
529 
530    put_IA(mkaddr_expr(guest_IA_next_instr));
531 
532    /* It's important that all ArchRegs carry their up-to-date value
533       at this point.  So we declare an end-of-block here, which
534       forces any TempRegs caching ArchRegs to be flushed. */
535    dis_res->whatNext    = Dis_StopHere;
536    dis_res->jk_StopHere = Ijk_Sys_syscall;
537 }
538 
539 /* A side exit that branches back to the current insn if CONDITION is
540    true. Does not set DisResult. */
541 static void
542 iterate_if(IRExpr *condition)
543 {
544    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
545 
546    stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
547                     S390X_GUEST_OFFSET(guest_IA)));
548 }
549 
550 /* A side exit that branches back to the current insn.
551    Does not set DisResult. */
552 static __inline__ void
553 iterate(void)
554 {
555    iterate_if(IRExpr_Const(IRConst_U1(True)));
556 }
557 
558 /* A side exit that branches back to the insn immediately following the
559    current insn if CONDITION is true. Does not set DisResult. */
560 static void
561 next_insn_if(IRExpr *condition)
562 {
563    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
564 
565    stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
566                     S390X_GUEST_OFFSET(guest_IA)));
567 }
568 
569 /* Convenience function to restart the current insn */
570 static void
571 restart_if(IRExpr *condition)
572 {
573    vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
574 
575    stmt(IRStmt_Exit(condition, Ijk_InvalICache,
576                     IRConst_U64(guest_IA_curr_instr),
577                     S390X_GUEST_OFFSET(guest_IA)));
578 }
579 
580 /* Convenience function to yield to thread scheduler */
581 static void
582 yield_if(IRExpr *condition)
583 {
584    stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
585                     S390X_GUEST_OFFSET(guest_IA)));
586 }
587 
588 /* Convenience macro to yield a specification exception if the given condition
589    is not met.  Used to pass this type of decoding error up through the call
590    chain. */
591 #define s390_insn_assert(mnm, cond)             \
592    do {                                         \
593       if (!(cond)) {                            \
594          dis_res->whatNext = Dis_StopHere;      \
595          dis_res->jk_StopHere = Ijk_NoDecode;   \
596          return (mnm);                          \
597       }                                         \
598    } while (0)
599 
600 /* Convenience function to check for a specification exception. */
601 static Bool
602 is_specification_exception(void)
603 {
604    return (dis_res->whatNext == Dis_StopHere &&
605            dis_res->jk_StopHere == Ijk_NoDecode);
606 }
607 
608 static __inline__ IRExpr *get_fpr_dw0(UInt);
609 static __inline__ void    put_fpr_dw0(UInt, IRExpr *);
610 static __inline__ IRExpr *get_dpr_dw0(UInt);
611 static __inline__ void    put_dpr_dw0(UInt, IRExpr *);
612 
613 /* Read a floating point register pair and combine their contents into a
614    128-bit value */
615 static IRExpr *
616 get_fpr_pair(UInt archreg)
617 {
618    IRExpr *high = get_fpr_dw0(archreg);
619    IRExpr *low  = get_fpr_dw0(archreg + 2);
620 
621    return binop(Iop_F64HLtoF128, high, low);
622 }
623 
624 /* Write a 128-bit floating point value into a register pair. */
625 static void
626 put_fpr_pair(UInt archreg, IRExpr *expr)
627 {
628    IRExpr *high = unop(Iop_F128HItoF64, expr);
629    IRExpr *low  = unop(Iop_F128LOtoF64, expr);
630 
631    put_fpr_dw0(archreg,     high);
632    put_fpr_dw0(archreg + 2, low);
633 }
634 
635 /* Read a floating point register pair cointaining DFP value
636    and combine their contents into a 128-bit value */
637 
638 static IRExpr *
639 get_dpr_pair(UInt archreg)
640 {
641    IRExpr *high = get_dpr_dw0(archreg);
642    IRExpr *low  = get_dpr_dw0(archreg + 2);
643 
644    return binop(Iop_D64HLtoD128, high, low);
645 }
646 
647 /* Write a 128-bit decimal floating point value into a register pair. */
648 static void
649 put_dpr_pair(UInt archreg, IRExpr *expr)
650 {
651    IRExpr *high = unop(Iop_D128HItoD64, expr);
652    IRExpr *low  = unop(Iop_D128LOtoD64, expr);
653 
654    put_dpr_dw0(archreg,     high);
655    put_dpr_dw0(archreg + 2, low);
656 }
657 
658 /* Terminate the current IRSB with an emulation failure. */
659 static void
660 emulation_failure_with_expr(IRExpr *emfailure)
661 {
662    vassert(typeOfIRExpr(irsb->tyenv, emfailure) == Ity_I32);
663 
664    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emfailure));
665    dis_res->whatNext = Dis_StopHere;
666    dis_res->jk_StopHere = Ijk_EmFail;
667 }
668 
669 static void
670 emulation_failure(VexEmNote fail_kind)
671 {
672    emulation_failure_with_expr(mkU32(fail_kind));
673 }
674 
675 /* Terminate the current IRSB with an emulation warning. */
676 static void
677 emulation_warning_with_expr(IRExpr *emwarning)
678 {
679    vassert(typeOfIRExpr(irsb->tyenv, emwarning) == Ity_I32);
680 
681    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emwarning));
682    dis_res->whatNext = Dis_StopHere;
683    dis_res->jk_StopHere = Ijk_EmWarn;
684 }
685 
686 static void
687 emulation_warning(VexEmNote warn_kind)
688 {
689    emulation_warning_with_expr(mkU32(warn_kind));
690 }
691 
692 /*------------------------------------------------------------*/
693 /*--- IR Debugging aids.                                   ---*/
694 /*------------------------------------------------------------*/
695 #if 0
696 
697 static ULong
698 s390_do_print(HChar *text, ULong value)
699 {
700    vex_printf("%s %llu\n", text, value);
701    return 0;
702 }
703 
704 static void
705 s390_print(HChar *text, IRExpr *value)
706 {
707    IRDirty *d;
708 
709    d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
710                          mkIRExprVec_2(mkU64((ULong)text), value));
711    stmt(IRStmt_Dirty(d));
712 }
713 #endif
714 
715 
716 /*------------------------------------------------------------*/
717 /*--- Build the flags thunk.                               ---*/
718 /*------------------------------------------------------------*/
719 
720 /* Completely fill the flags thunk. We're always filling all fields.
721    Apparently, that is better for redundant PUT elimination. */
722 static void
723 s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
724 {
725    UInt op_off, dep1_off, dep2_off, ndep_off;
726 
727    op_off   = S390X_GUEST_OFFSET(guest_CC_OP);
728    dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
729    dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
730    ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
731 
732    stmt(IRStmt_Put(op_off,   op));
733    stmt(IRStmt_Put(dep1_off, dep1));
734    stmt(IRStmt_Put(dep2_off, dep2));
735    stmt(IRStmt_Put(ndep_off, ndep));
736 }
737 
738 
739 /* Create an expression for V and widen the result to 64 bit. */
740 static IRExpr *
741 s390_cc_widen(IRTemp v, Bool sign_extend)
742 {
743    IRExpr *expr;
744 
745    expr = mkexpr(v);
746 
747    switch (typeOfIRTemp(irsb->tyenv, v)) {
748    case Ity_I64:
749       break;
750    case Ity_I32:
751       expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
752       break;
753    case Ity_I16:
754       expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
755       break;
756    case Ity_I8:
757       expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
758       break;
759    default:
760       vpanic("s390_cc_widen");
761    }
762 
763    return expr;
764 }
765 
766 static void
767 s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
768 {
769    IRExpr *op, *dep1, *dep2, *ndep;
770 
771    op   = mkU64(opc);
772    dep1 = s390_cc_widen(d1, sign_extend);
773    dep2 = mkU64(0);
774    ndep = mkU64(0);
775 
776    s390_cc_thunk_fill(op, dep1, dep2, ndep);
777 }
778 
779 
780 static void
781 s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
782 {
783    IRExpr *op, *dep1, *dep2, *ndep;
784 
785    op   = mkU64(opc);
786    dep1 = s390_cc_widen(d1, sign_extend);
787    dep2 = s390_cc_widen(d2, sign_extend);
788    ndep = mkU64(0);
789 
790    s390_cc_thunk_fill(op, dep1, dep2, ndep);
791 }
792 
793 
794 /* memcheck believes that the NDEP field in the flags thunk is always
795    defined. But for some flag computations (e.g. add with carry) that is
796    just not true. We therefore need to convey to memcheck that the value
797    of the ndep field does matter and therefore we make the DEP2 field
798    depend on it:
799 
800    DEP2 = original_DEP2 ^ NDEP
801 
802    In s390_calculate_cc we exploit that  (a^b)^b == a
803    I.e. we xor the DEP2 value with the NDEP value to recover the
804    original_DEP2 value. */
805 static void
806 s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
807 {
808    IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
809 
810    op   = mkU64(opc);
811    dep1 = s390_cc_widen(d1, sign_extend);
812    dep2 = s390_cc_widen(d2, sign_extend);
813    ndep = s390_cc_widen(nd, sign_extend);
814 
815    dep2x = binop(Iop_Xor64, dep2, ndep);
816 
817    s390_cc_thunk_fill(op, dep1, dep2x, ndep);
818 }
819 
820 
821 /* Write one floating point value into the flags thunk */
822 static void
823 s390_cc_thunk_put1f(UInt opc, IRTemp d1)
824 {
825    IRExpr *op, *dep1, *dep2, *ndep;
826 
827    /* Make the CC_DEP1 slot appear completely defined.
828       Otherwise, assigning a 32-bit value will cause memcheck
829       to trigger an undefinedness error.
830    */
831    if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
832       UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
833       stmt(IRStmt_Put(dep1_off, mkU64(0)));
834    }
835    op   = mkU64(opc);
836    dep1 = mkexpr(d1);
837    dep2 = mkU64(0);
838    ndep = mkU64(0);
839 
840    s390_cc_thunk_fill(op, dep1, dep2, ndep);
841 }
842 
843 
844 /* Write a floating point value and an integer into the flags thunk. The
845    integer value is zero-extended first. */
846 static void
847 s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
848 {
849    IRExpr *op, *dep1, *dep2, *ndep;
850 
851    /* Make the CC_DEP1 slot appear completely defined.
852       Otherwise, assigning a 32-bit value will cause memcheck
853       to trigger an undefinedness error.
854    */
855    if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
856       UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
857       stmt(IRStmt_Put(dep1_off, mkU64(0)));
858    }
859    op   = mkU64(opc);
860    dep1 = mkexpr(d1);
861    dep2 = s390_cc_widen(d2, False);
862    ndep = mkU64(0);
863 
864    s390_cc_thunk_fill(op, dep1, dep2, ndep);
865 }
866 
867 
868 /* Write a 128-bit floating point value into the flags thunk. This is
869    done by splitting the value into two 64-bits values. */
870 static void
871 s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
872 {
873    IRExpr *op, *hi, *lo, *ndep;
874 
875    op   = mkU64(opc);
876    hi   = unop(Iop_F128HItoF64, mkexpr(d1));
877    lo   = unop(Iop_F128LOtoF64, mkexpr(d1));
878    ndep = mkU64(0);
879 
880    s390_cc_thunk_fill(op, hi, lo, ndep);
881 }
882 
883 
884 /* Write a 128-bit floating point value and an integer into the flags thunk.
885    The integer value is zero-extended first. */
886 static void
887 s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
888 {
889    IRExpr *op, *hi, *lo, *lox, *ndep;
890 
891    op   = mkU64(opc);
892    hi   = unop(Iop_F128HItoF64, mkexpr(d1));
893    lo   = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
894    ndep = s390_cc_widen(nd, False);
895 
896    lox = binop(Iop_Xor64, lo, ndep);  /* convey dependency */
897 
898    s390_cc_thunk_fill(op, hi, lox, ndep);
899 }
900 
901 
902 /* Write a 128-bit decimal floating point value into the flags thunk.
903    This is done by splitting the value into two 64-bits values. */
904 static void
905 s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
906 {
907    IRExpr *op, *hi, *lo, *ndep;
908 
909    op   = mkU64(opc);
910    hi   = unop(Iop_D128HItoD64, mkexpr(d1));
911    lo   = unop(Iop_D128LOtoD64, mkexpr(d1));
912    ndep = mkU64(0);
913 
914    s390_cc_thunk_fill(op, hi, lo, ndep);
915 }
916 
917 
918 /* Write a 128-bit decimal floating point value and an integer into the flags
919    thunk. The integer value is zero-extended first. */
920 static void
921 s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
922 {
923    IRExpr *op, *hi, *lo, *lox, *ndep;
924 
925    op   = mkU64(opc);
926    hi   = unop(Iop_D128HItoD64, mkexpr(d1));
927    lo   = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
928    ndep = s390_cc_widen(nd, False);
929 
930    lox = binop(Iop_Xor64, lo, ndep);  /* convey dependency */
931 
932    s390_cc_thunk_fill(op, hi, lox, ndep);
933 }
934 
935 static void
936 s390_cc_set(IRTemp cc)
937 {
938    vassert(typeOfIRTemp(irsb->tyenv, cc) == Ity_I64);
939 
940    s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
941 }
942 
943 static void
944 s390_cc_set_val(UInt val)
945 {
946    s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkU64(val), mkU64(0), mkU64(0));
947 }
948 
949 /* Build IR to calculate the condition code from flags thunk.
950    Returns an expression of type Ity_I32 */
951 static IRExpr *
952 s390_call_calculate_cc(void)
953 {
954    IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
955 
956    op   = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP),   Ity_I64);
957    dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
958    dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
959    ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
960 
961    args = mkIRExprVec_4(op, dep1, dep2, ndep);
962    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
963                         "s390_calculate_cc", &s390_calculate_cc, args);
964 
965    /* Exclude OP and NDEP from definedness checking.  We're only
966       interested in DEP1 and DEP2. */
967    call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
968 
969    return call;
970 }
971 
972 /* Build IR to calculate the internal condition code for a "compare and branch"
973    insn. Returns an expression of type Ity_I32 */
974 static IRExpr *
975 s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
976 {
977    IRExpr **args, *call, *op, *dep1, *dep2, *mask;
978 
979    switch (opc) {
980    case S390_CC_OP_SIGNED_COMPARE:
981       dep1 = s390_cc_widen(op1, True);
982       dep2 = s390_cc_widen(op2, True);
983       break;
984 
985    case S390_CC_OP_UNSIGNED_COMPARE:
986       dep1 = s390_cc_widen(op1, False);
987       dep2 = s390_cc_widen(op2, False);
988       break;
989 
990    default:
991       vpanic("s390_call_calculate_icc");
992    }
993 
994    mask = mkU64(m);
995    op   = mkU64(opc);
996 
997    args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
998    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
999                         "s390_calculate_cond", &s390_calculate_cond, args);
1000 
1001    /* Exclude the requested condition, OP and NDEP from definedness
1002       checking.  We're only interested in DEP1 and DEP2. */
1003    call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
1004 
1005    return call;
1006 }
1007 
1008 /* Build IR to calculate the condition code from flags thunk.
1009    Returns an expression of type Ity_I32 */
1010 static IRExpr *
1011 s390_call_calculate_cond(UInt m)
1012 {
1013    IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
1014 
1015    mask = mkU64(m);
1016    op   = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP),   Ity_I64);
1017    dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
1018    dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
1019    ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
1020 
1021    args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
1022    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
1023                         "s390_calculate_cond", &s390_calculate_cond, args);
1024 
1025    /* Exclude the requested condition, OP and NDEP from definedness
1026       checking.  We're only interested in DEP1 and DEP2. */
1027    call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
1028 
1029    return call;
1030 }
1031 
1032 #define s390_cc_thunk_putZ(op,dep1)  s390_cc_thunk_put1(op,dep1,False)
1033 #define s390_cc_thunk_putS(op,dep1)  s390_cc_thunk_put1(op,dep1,True)
1034 #define s390_cc_thunk_putF(op,dep1)  s390_cc_thunk_put1f(op,dep1)
1035 #define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
1036 #define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
1037 #define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
1038 #define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
1039         s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
1040 #define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
1041         s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
1042 
1043 
1044 
1045 
1046 /*------------------------------------------------------------*/
1047 /*--- Guest register access                                ---*/
1048 /*------------------------------------------------------------*/
1049 
1050 
1051 /*------------------------------------------------------------*/
1052 /*--- ar registers                                         ---*/
1053 /*------------------------------------------------------------*/
1054 
1055 /* Return the guest state offset of a ar register. */
1056 static UInt
1057 ar_offset(UInt archreg)
1058 {
1059    static const UInt offset[16] = {
1060       S390X_GUEST_OFFSET(guest_a0),
1061       S390X_GUEST_OFFSET(guest_a1),
1062       S390X_GUEST_OFFSET(guest_a2),
1063       S390X_GUEST_OFFSET(guest_a3),
1064       S390X_GUEST_OFFSET(guest_a4),
1065       S390X_GUEST_OFFSET(guest_a5),
1066       S390X_GUEST_OFFSET(guest_a6),
1067       S390X_GUEST_OFFSET(guest_a7),
1068       S390X_GUEST_OFFSET(guest_a8),
1069       S390X_GUEST_OFFSET(guest_a9),
1070       S390X_GUEST_OFFSET(guest_a10),
1071       S390X_GUEST_OFFSET(guest_a11),
1072       S390X_GUEST_OFFSET(guest_a12),
1073       S390X_GUEST_OFFSET(guest_a13),
1074       S390X_GUEST_OFFSET(guest_a14),
1075       S390X_GUEST_OFFSET(guest_a15),
1076    };
1077 
1078    vassert(archreg < 16);
1079 
1080    return offset[archreg];
1081 }
1082 
1083 
1084 /* Return the guest state offset of word #0 of a ar register. */
1085 static __inline__ UInt
1086 ar_w0_offset(UInt archreg)
1087 {
1088    return ar_offset(archreg) + 0;
1089 }
1090 
1091 /* Write word #0 of a ar to the guest state. */
1092 static __inline__ void
1093 put_ar_w0(UInt archreg, IRExpr *expr)
1094 {
1095    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1096 
1097    stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
1098 }
1099 
1100 /* Read word #0 of a ar register. */
1101 static __inline__ IRExpr *
1102 get_ar_w0(UInt archreg)
1103 {
1104    return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
1105 }
1106 
1107 
1108 /*------------------------------------------------------------*/
1109 /*--- fpr registers                                        ---*/
1110 /*------------------------------------------------------------*/
1111 
1112 /* Return the guest state offset of a fpr register.
1113    FPRs are maped to first doubleword of VRs.
1114 */
1115 static UInt
1116 fpr_offset(UInt archreg)
1117 {
1118    static const UInt offset[16] = {
1119       S390X_GUEST_OFFSET(guest_v0),
1120       S390X_GUEST_OFFSET(guest_v1),
1121       S390X_GUEST_OFFSET(guest_v2),
1122       S390X_GUEST_OFFSET(guest_v3),
1123       S390X_GUEST_OFFSET(guest_v4),
1124       S390X_GUEST_OFFSET(guest_v5),
1125       S390X_GUEST_OFFSET(guest_v6),
1126       S390X_GUEST_OFFSET(guest_v7),
1127       S390X_GUEST_OFFSET(guest_v8),
1128       S390X_GUEST_OFFSET(guest_v9),
1129       S390X_GUEST_OFFSET(guest_v10),
1130       S390X_GUEST_OFFSET(guest_v11),
1131       S390X_GUEST_OFFSET(guest_v12),
1132       S390X_GUEST_OFFSET(guest_v13),
1133       S390X_GUEST_OFFSET(guest_v14),
1134       S390X_GUEST_OFFSET(guest_v15),
1135    };
1136 
1137    vassert(archreg < 16);
1138 
1139    return offset[archreg];
1140 }
1141 
1142 
1143 /* Return the guest state offset of word #0 of a fpr register. */
1144 static __inline__ UInt
1145 fpr_w0_offset(UInt archreg)
1146 {
1147    return fpr_offset(archreg) + 0;
1148 }
1149 
1150 /* Write word #0 of a fpr to the guest state. */
1151 static __inline__ void
1152 put_fpr_w0(UInt archreg, IRExpr *expr)
1153 {
1154    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
1155 
1156    stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
1157 }
1158 
1159 /* Read word #0 of a fpr register. */
1160 static __inline__ IRExpr *
1161 get_fpr_w0(UInt archreg)
1162 {
1163    return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
1164 }
1165 
1166 /* Return the guest state offset of double word #0 of a fpr register. */
1167 static __inline__ UInt
1168 fpr_dw0_offset(UInt archreg)
1169 {
1170    return fpr_offset(archreg) + 0;
1171 }
1172 
1173 /* Write double word #0 of a fpr to the guest state. */
1174 static __inline__ void
1175 put_fpr_dw0(UInt archreg, IRExpr *expr)
1176 {
1177    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
1178 
1179    stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1180 }
1181 
1182 /* Read double word #0 of a fpr register. */
1183 static __inline__ IRExpr *
1184 get_fpr_dw0(UInt archreg)
1185 {
1186    return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
1187 }
1188 
1189 /* Write word #0 of a dpr to the guest state. */
1190 static __inline__ void
1191 put_dpr_w0(UInt archreg, IRExpr *expr)
1192 {
1193    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
1194 
1195    stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
1196 }
1197 
1198 /* Read word #0 of a dpr register. */
1199 static __inline__ IRExpr *
1200 get_dpr_w0(UInt archreg)
1201 {
1202    return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
1203 }
1204 
1205 /* Write double word #0 of a fpr containg DFP value to the guest state. */
1206 static __inline__ void
1207 put_dpr_dw0(UInt archreg, IRExpr *expr)
1208 {
1209    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
1210 
1211    stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1212 }
1213 
1214 /* Read double word #0 of a fpr register containing DFP value. */
1215 static __inline__ IRExpr *
1216 get_dpr_dw0(UInt archreg)
1217 {
1218    return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1219 }
1220 
1221 /*------------------------------------------------------------*/
1222 /*--- gpr registers                                        ---*/
1223 /*------------------------------------------------------------*/
1224 
1225 /* Return the guest state offset of a gpr register. */
1226 static UInt
1227 gpr_offset(UInt archreg)
1228 {
1229    static const UInt offset[16] = {
1230       S390X_GUEST_OFFSET(guest_r0),
1231       S390X_GUEST_OFFSET(guest_r1),
1232       S390X_GUEST_OFFSET(guest_r2),
1233       S390X_GUEST_OFFSET(guest_r3),
1234       S390X_GUEST_OFFSET(guest_r4),
1235       S390X_GUEST_OFFSET(guest_r5),
1236       S390X_GUEST_OFFSET(guest_r6),
1237       S390X_GUEST_OFFSET(guest_r7),
1238       S390X_GUEST_OFFSET(guest_r8),
1239       S390X_GUEST_OFFSET(guest_r9),
1240       S390X_GUEST_OFFSET(guest_r10),
1241       S390X_GUEST_OFFSET(guest_r11),
1242       S390X_GUEST_OFFSET(guest_r12),
1243       S390X_GUEST_OFFSET(guest_r13),
1244       S390X_GUEST_OFFSET(guest_r14),
1245       S390X_GUEST_OFFSET(guest_r15),
1246    };
1247 
1248    vassert(archreg < 16);
1249 
1250    return offset[archreg];
1251 }
1252 
1253 
1254 /* Return the guest state offset of word #0 of a gpr register. */
1255 static __inline__ UInt
1256 gpr_w0_offset(UInt archreg)
1257 {
1258    return gpr_offset(archreg) + 0;
1259 }
1260 
1261 /* Read an integer of given type from a gpr. */
1262 static __inline__ IRExpr *
1263 get_gpr_int(UInt archreg, IRType ty)
1264 {
1265    return IRExpr_Get(gpr_offset(archreg) + 8 - sizeofIRType(ty), ty);
1266 }
1267 
1268 /* Write word #0 of a gpr to the guest state. */
1269 static __inline__ void
1270 put_gpr_w0(UInt archreg, IRExpr *expr)
1271 {
1272    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1273 
1274    stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1275 }
1276 
1277 /* Read word #0 of a gpr register. */
1278 static __inline__ IRExpr *
1279 get_gpr_w0(UInt archreg)
1280 {
1281    return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1282 }
1283 
1284 /* Return the guest state offset of double word #0 of a gpr register. */
1285 static __inline__ UInt
1286 gpr_dw0_offset(UInt archreg)
1287 {
1288    return gpr_offset(archreg) + 0;
1289 }
1290 
1291 /* Write double word #0 of a gpr to the guest state. */
1292 static __inline__ void
1293 put_gpr_dw0(UInt archreg, IRExpr *expr)
1294 {
1295    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1296 
1297    stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1298 }
1299 
1300 /* Read double word #0 of a gpr register. */
1301 static __inline__ IRExpr *
1302 get_gpr_dw0(UInt archreg)
1303 {
1304    return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1305 }
1306 
1307 /* Return the guest state offset of half word #1 of a gpr register. */
1308 static __inline__ UInt
1309 gpr_hw1_offset(UInt archreg)
1310 {
1311    return gpr_offset(archreg) + 2;
1312 }
1313 
1314 /* Write half word #1 of a gpr to the guest state. */
1315 static __inline__ void
1316 put_gpr_hw1(UInt archreg, IRExpr *expr)
1317 {
1318    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1319 
1320    stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1321 }
1322 
1323 /* Read half word #1 of a gpr register. */
1324 static __inline__ IRExpr *
1325 get_gpr_hw1(UInt archreg)
1326 {
1327    return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1328 }
1329 
1330 /* Return the guest state offset of byte #6 of a gpr register. */
1331 static __inline__ UInt
1332 gpr_b6_offset(UInt archreg)
1333 {
1334    return gpr_offset(archreg) + 6;
1335 }
1336 
1337 /* Write byte #6 of a gpr to the guest state. */
1338 static __inline__ void
1339 put_gpr_b6(UInt archreg, IRExpr *expr)
1340 {
1341    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1342 
1343    stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1344 }
1345 
1346 /* Read byte #6 of a gpr register. */
1347 static __inline__ IRExpr *
1348 get_gpr_b6(UInt archreg)
1349 {
1350    return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1351 }
1352 
1353 /* Return the guest state offset of byte #3 of a gpr register. */
1354 static __inline__ UInt
1355 gpr_b3_offset(UInt archreg)
1356 {
1357    return gpr_offset(archreg) + 3;
1358 }
1359 
1360 /* Write byte #3 of a gpr to the guest state. */
1361 static __inline__ void
1362 put_gpr_b3(UInt archreg, IRExpr *expr)
1363 {
1364    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1365 
1366    stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1367 }
1368 
1369 /* Read byte #3 of a gpr register. */
1370 static __inline__ IRExpr *
1371 get_gpr_b3(UInt archreg)
1372 {
1373    return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1374 }
1375 
1376 /* Return the guest state offset of byte #0 of a gpr register. */
1377 static __inline__ UInt
1378 gpr_b0_offset(UInt archreg)
1379 {
1380    return gpr_offset(archreg) + 0;
1381 }
1382 
1383 /* Write byte #0 of a gpr to the guest state. */
1384 static __inline__ void
1385 put_gpr_b0(UInt archreg, IRExpr *expr)
1386 {
1387    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1388 
1389    stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1390 }
1391 
1392 /* Read byte #0 of a gpr register. */
1393 static __inline__ IRExpr *
1394 get_gpr_b0(UInt archreg)
1395 {
1396    return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1397 }
1398 
1399 /* Return the guest state offset of word #1 of a gpr register. */
1400 static __inline__ UInt
1401 gpr_w1_offset(UInt archreg)
1402 {
1403    return gpr_offset(archreg) + 4;
1404 }
1405 
1406 /* Write word #1 of a gpr to the guest state. */
1407 static __inline__ void
1408 put_gpr_w1(UInt archreg, IRExpr *expr)
1409 {
1410    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1411 
1412    stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1413 }
1414 
1415 /* Read word #1 of a gpr register. */
1416 static __inline__ IRExpr *
1417 get_gpr_w1(UInt archreg)
1418 {
1419    return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1420 }
1421 
1422 /* Return the guest state offset of half word #3 of a gpr register. */
1423 static __inline__ UInt
1424 gpr_hw3_offset(UInt archreg)
1425 {
1426    return gpr_offset(archreg) + 6;
1427 }
1428 
1429 /* Write half word #3 of a gpr to the guest state. */
1430 static __inline__ void
1431 put_gpr_hw3(UInt archreg, IRExpr *expr)
1432 {
1433    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1434 
1435    stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1436 }
1437 
1438 /* Read half word #3 of a gpr register. */
1439 static __inline__ IRExpr *
1440 get_gpr_hw3(UInt archreg)
1441 {
1442    return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1443 }
1444 
1445 /* Return the guest state offset of byte #7 of a gpr register. */
1446 static __inline__ UInt
1447 gpr_b7_offset(UInt archreg)
1448 {
1449    return gpr_offset(archreg) + 7;
1450 }
1451 
1452 /* Write byte #7 of a gpr to the guest state. */
1453 static __inline__ void
1454 put_gpr_b7(UInt archreg, IRExpr *expr)
1455 {
1456    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1457 
1458    stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1459 }
1460 
1461 /* Read byte #7 of a gpr register. */
1462 static __inline__ IRExpr *
1463 get_gpr_b7(UInt archreg)
1464 {
1465    return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1466 }
1467 
1468 /* Return the guest state offset of half word #0 of a gpr register. */
1469 static __inline__ UInt
1470 gpr_hw0_offset(UInt archreg)
1471 {
1472    return gpr_offset(archreg) + 0;
1473 }
1474 
1475 /* Write half word #0 of a gpr to the guest state. */
1476 static __inline__ void
1477 put_gpr_hw0(UInt archreg, IRExpr *expr)
1478 {
1479    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1480 
1481    stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1482 }
1483 
1484 /* Read half word #0 of a gpr register. */
1485 static __inline__ IRExpr *
1486 get_gpr_hw0(UInt archreg)
1487 {
1488    return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1489 }
1490 
1491 /* Return the guest state offset of byte #4 of a gpr register. */
1492 static __inline__ UInt
1493 gpr_b4_offset(UInt archreg)
1494 {
1495    return gpr_offset(archreg) + 4;
1496 }
1497 
1498 /* Write byte #4 of a gpr to the guest state. */
1499 static __inline__ void
1500 put_gpr_b4(UInt archreg, IRExpr *expr)
1501 {
1502    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1503 
1504    stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1505 }
1506 
1507 /* Read byte #4 of a gpr register. */
1508 static __inline__ IRExpr *
1509 get_gpr_b4(UInt archreg)
1510 {
1511    return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1512 }
1513 
1514 /* Return the guest state offset of byte #1 of a gpr register. */
1515 static __inline__ UInt
1516 gpr_b1_offset(UInt archreg)
1517 {
1518    return gpr_offset(archreg) + 1;
1519 }
1520 
1521 /* Write byte #1 of a gpr to the guest state. */
1522 static __inline__ void
1523 put_gpr_b1(UInt archreg, IRExpr *expr)
1524 {
1525    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1526 
1527    stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1528 }
1529 
1530 /* Read byte #1 of a gpr register. */
1531 static __inline__ IRExpr *
1532 get_gpr_b1(UInt archreg)
1533 {
1534    return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1535 }
1536 
1537 /* Return the guest state offset of half word #2 of a gpr register. */
1538 static __inline__ UInt
1539 gpr_hw2_offset(UInt archreg)
1540 {
1541    return gpr_offset(archreg) + 4;
1542 }
1543 
1544 /* Write half word #2 of a gpr to the guest state. */
1545 static __inline__ void
1546 put_gpr_hw2(UInt archreg, IRExpr *expr)
1547 {
1548    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1549 
1550    stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1551 }
1552 
1553 /* Read half word #2 of a gpr register. */
1554 static __inline__ IRExpr *
1555 get_gpr_hw2(UInt archreg)
1556 {
1557    return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1558 }
1559 
1560 /* Return the guest state offset of byte #5 of a gpr register. */
1561 static __inline__ UInt
1562 gpr_b5_offset(UInt archreg)
1563 {
1564    return gpr_offset(archreg) + 5;
1565 }
1566 
1567 /* Write byte #5 of a gpr to the guest state. */
1568 static __inline__ void
1569 put_gpr_b5(UInt archreg, IRExpr *expr)
1570 {
1571    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1572 
1573    stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1574 }
1575 
1576 /* Read byte #5 of a gpr register. */
1577 static __inline__ IRExpr *
1578 get_gpr_b5(UInt archreg)
1579 {
1580    return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1581 }
1582 
1583 /* Return the guest state offset of byte #2 of a gpr register. */
1584 static __inline__ UInt
1585 gpr_b2_offset(UInt archreg)
1586 {
1587    return gpr_offset(archreg) + 2;
1588 }
1589 
1590 /* Write byte #2 of a gpr to the guest state. */
1591 static __inline__ void
1592 put_gpr_b2(UInt archreg, IRExpr *expr)
1593 {
1594    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1595 
1596    stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1597 }
1598 
1599 /* Read byte #2 of a gpr register. */
1600 static __inline__ IRExpr *
1601 get_gpr_b2(UInt archreg)
1602 {
1603    return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1604 }
1605 
1606 /* Return the guest state offset of the counter register. */
1607 static UInt
1608 counter_offset(void)
1609 {
1610    return S390X_GUEST_OFFSET(guest_counter);
1611 }
1612 
1613 /* Return the guest state offset of double word #0 of the counter register. */
1614 static __inline__ UInt
1615 counter_dw0_offset(void)
1616 {
1617    return counter_offset() + 0;
1618 }
1619 
1620 /* Write double word #0 of the counter to the guest state. */
1621 static __inline__ void
1622 put_counter_dw0(IRExpr *expr)
1623 {
1624    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1625 
1626    stmt(IRStmt_Put(counter_dw0_offset(), expr));
1627 }
1628 
1629 /* Read double word #0 of the counter register. */
1630 static __inline__ IRExpr *
1631 get_counter_dw0(void)
1632 {
1633    return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1634 }
1635 
1636 /* Return the guest state offset of word #0 of the counter register. */
1637 static __inline__ UInt
1638 counter_w0_offset(void)
1639 {
1640    return counter_offset() + 0;
1641 }
1642 
1643 /* Return the guest state offset of word #1 of the counter register. */
1644 static __inline__ UInt
1645 counter_w1_offset(void)
1646 {
1647    return counter_offset() + 4;
1648 }
1649 
1650 /* Write word #0 of the counter to the guest state. */
1651 static __inline__ void
1652 put_counter_w0(IRExpr *expr)
1653 {
1654    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1655 
1656    stmt(IRStmt_Put(counter_w0_offset(), expr));
1657 }
1658 
1659 /* Read word #0 of the counter register. */
1660 static __inline__ IRExpr *
1661 get_counter_w0(void)
1662 {
1663    return IRExpr_Get(counter_w0_offset(), Ity_I32);
1664 }
1665 
1666 /* Write word #1 of the counter to the guest state. */
1667 static __inline__ void
1668 put_counter_w1(IRExpr *expr)
1669 {
1670    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1671 
1672    stmt(IRStmt_Put(counter_w1_offset(), expr));
1673 }
1674 
1675 /* Read word #1 of the counter register. */
1676 static __inline__ IRExpr *
1677 get_counter_w1(void)
1678 {
1679    return IRExpr_Get(counter_w1_offset(), Ity_I32);
1680 }
1681 
1682 /* Return the guest state offset of the fpc register. */
1683 static UInt
1684 fpc_offset(void)
1685 {
1686    return S390X_GUEST_OFFSET(guest_fpc);
1687 }
1688 
1689 /* Return the guest state offset of word #0 of the fpc register. */
1690 static __inline__ UInt
1691 fpc_w0_offset(void)
1692 {
1693    return fpc_offset() + 0;
1694 }
1695 
1696 /* Write word #0 of the fpc to the guest state. */
1697 static __inline__ void
1698 put_fpc_w0(IRExpr *expr)
1699 {
1700    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1701 
1702    stmt(IRStmt_Put(fpc_w0_offset(), expr));
1703 }
1704 
1705 /* Read word #0 of the fpc register. */
1706 static __inline__ IRExpr *
1707 get_fpc_w0(void)
1708 {
1709    return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1710 }
1711 
1712 
1713 /*------------------------------------------------------------*/
1714 /*--- vr registers                                        ---*/
1715 /*------------------------------------------------------------*/
1716 
1717 /* Return the guest state offset of a vr register. */
1718 static UInt
1719 vr_offset(const UInt archreg)
1720 {
1721    static const UInt offset[32] = {
1722       S390X_GUEST_OFFSET(guest_v0),
1723       S390X_GUEST_OFFSET(guest_v1),
1724       S390X_GUEST_OFFSET(guest_v2),
1725       S390X_GUEST_OFFSET(guest_v3),
1726       S390X_GUEST_OFFSET(guest_v4),
1727       S390X_GUEST_OFFSET(guest_v5),
1728       S390X_GUEST_OFFSET(guest_v6),
1729       S390X_GUEST_OFFSET(guest_v7),
1730       S390X_GUEST_OFFSET(guest_v8),
1731       S390X_GUEST_OFFSET(guest_v9),
1732       S390X_GUEST_OFFSET(guest_v10),
1733       S390X_GUEST_OFFSET(guest_v11),
1734       S390X_GUEST_OFFSET(guest_v12),
1735       S390X_GUEST_OFFSET(guest_v13),
1736       S390X_GUEST_OFFSET(guest_v14),
1737       S390X_GUEST_OFFSET(guest_v15),
1738       S390X_GUEST_OFFSET(guest_v16),
1739       S390X_GUEST_OFFSET(guest_v17),
1740       S390X_GUEST_OFFSET(guest_v18),
1741       S390X_GUEST_OFFSET(guest_v19),
1742       S390X_GUEST_OFFSET(guest_v20),
1743       S390X_GUEST_OFFSET(guest_v21),
1744       S390X_GUEST_OFFSET(guest_v22),
1745       S390X_GUEST_OFFSET(guest_v23),
1746       S390X_GUEST_OFFSET(guest_v24),
1747       S390X_GUEST_OFFSET(guest_v25),
1748       S390X_GUEST_OFFSET(guest_v26),
1749       S390X_GUEST_OFFSET(guest_v27),
1750       S390X_GUEST_OFFSET(guest_v28),
1751       S390X_GUEST_OFFSET(guest_v29),
1752       S390X_GUEST_OFFSET(guest_v30),
1753       S390X_GUEST_OFFSET(guest_v31),
1754    };
1755 
1756    vassert(archreg < 32);
1757 
1758    return offset[archreg];
1759 }
1760 
1761 /* Return the guest state offset of quadword of a vr register. */
1762 static UInt
1763 vr_qw_offset(const UInt archreg)
1764 {
1765    return vr_offset(archreg) + 0;
1766 }
1767 
1768 /* Write quadword of a vr to the guest state. */
1769 static void
1770 put_vr_qw(const UInt archreg, IRExpr *expr)
1771 {
1772    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_V128);
1773 
1774    stmt(IRStmt_Put(vr_qw_offset(archreg), expr));
1775 }
1776 
1777 /* Read quadword of a vr register. */
1778 static IRExpr *
1779 get_vr_qw(const UInt archreg)
1780 {
1781    return IRExpr_Get(vr_qw_offset(archreg), Ity_V128);
1782 }
1783 
1784 /* Return the guest state offset of double word #0 of a gpr register. */
1785 static UInt
1786 vr_dw0_offset(UInt archreg)
1787 {
1788    return vr_offset(archreg) + 0;
1789 }
1790 
1791 /* Read doubleword #0 of a vr register. */
1792 static IRExpr *
1793 get_vr_dw0(UInt archreg)
1794 {
1795    return IRExpr_Get(vr_dw0_offset(archreg), Ity_I64);
1796 }
1797 
1798 /* Write double word #0 of a vr to the guest state. */
1799 static void
1800 put_vr_dw0(UInt archreg, IRExpr *expr)
1801 {
1802    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1803 
1804    stmt(IRStmt_Put(vr_dw0_offset(archreg), expr));
1805 }
1806 
1807 /* Return the guest state offset of double word #1 of a gpr register. */
1808 static UInt
1809 vr_dw1_offset(UInt archreg)
1810 {
1811    return vr_offset(archreg) + 8;
1812 }
1813 
1814 /* Read doubleword #1 of a vr register. */
1815 static IRExpr *
1816 get_vr_dw1(UInt archreg)
1817 {
1818    return IRExpr_Get(vr_dw1_offset(archreg), Ity_I64);
1819 }
1820 
1821 /* Write double word #0 of a vr to the guest state. */
1822 static void
1823 put_vr_dw1(UInt archreg, IRExpr *expr)
1824 {
1825    vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1826 
1827    stmt(IRStmt_Put(vr_dw1_offset(archreg), expr));
1828 }
1829 
1830 /* Return the guest state offset of word #1 of a gpr register. */
1831 static UInt
1832 vr_w1_offset(UInt archreg)
1833 {
1834    return vr_offset(archreg) + 4;
1835 }
1836 
1837 /* Return the guest state offset of word #3 of a gpr register. */
1838 static UInt
1839 vr_w3_offset(UInt archreg)
1840 {
1841    return vr_offset(archreg) + 12;
1842 }
1843 
1844 /* Read word #0 of a vr register. */
1845 static IRExpr *
1846 get_vr_w0(UInt archreg)
1847 {
1848    return IRExpr_Get(vr_dw0_offset(archreg), Ity_I32);
1849 }
1850 
1851 /* Read word #1 of a vr register. */
1852 static IRExpr *
1853 get_vr_w1(UInt archreg)
1854 {
1855    return IRExpr_Get(vr_w1_offset(archreg), Ity_I32);
1856 }
1857 
1858 /* Read word #2 of a vr register. */
1859 static IRExpr *
1860 get_vr_w2(UInt archreg)
1861 {
1862    return IRExpr_Get(vr_dw1_offset(archreg), Ity_I32);
1863 }
1864 
1865 /* Read word #3 of a vr register. */
1866 static IRExpr *
1867 get_vr_w3(UInt archreg)
1868 {
1869    return IRExpr_Get(vr_w3_offset(archreg), Ity_I32);
1870 }
1871 
1872 /* Return the guest state offset of halfword #3 of a gpr register. */
1873 static UInt
1874 vr_hw3_offset(UInt archreg)
1875 {
1876    return vr_offset(archreg) + 6;
1877 }
1878 
1879 /* Read halfword #3 of a vr register. */
1880 static IRExpr *
1881 get_vr_hw3(UInt archreg)
1882 {
1883    return IRExpr_Get(vr_hw3_offset(archreg), Ity_I16);
1884 }
1885 
1886 /* Return the guest state offset of halfword #7 of a gpr register. */
1887 static UInt
1888 vr_hw7_offset(UInt archreg)
1889 {
1890    return vr_offset(archreg) + 14;
1891 }
1892 
1893 /* Read halfword #7 of a vr register. */
1894 static IRExpr *
1895 get_vr_hw7(UInt archreg)
1896 {
1897    return IRExpr_Get(vr_hw7_offset(archreg), Ity_I16);
1898 }
1899 
1900 /* Return the guest state offset of byte #7 of a vr register. */
1901 static UInt
1902 vr_b7_offset(UInt archreg)
1903 {
1904    return vr_offset(archreg) + 7;
1905 }
1906 
1907 /* Read byte #7 of a vr register. */
1908 static IRExpr *
1909 get_vr_b7(UInt archreg)
1910 {
1911    return IRExpr_Get(vr_b7_offset(archreg), Ity_I8);
1912 }
1913 
1914 /* Return the guest state offset of byte #15 of a vr register. */
1915 static UInt
1916 vr_b15_offset(UInt archreg)
1917 {
1918    return vr_offset(archreg) + 15;
1919 }
1920 
1921 /* Read byte #15 of a vr register. */
1922 static IRExpr *
1923 get_vr_b15(UInt archreg)
1924 {
1925    return IRExpr_Get(vr_b15_offset(archreg), Ity_I8);
1926 }
1927 
1928 /* Determine IRType by instruction's m3 field */
1929 static IRType
1930 s390_vr_get_type(const UChar m)
1931 {
1932    static const IRType results[] = {Ity_I8, Ity_I16, Ity_I32, Ity_I64, Ity_V128};
1933    if (m > 4) {
1934       vex_printf("s390_vr_get_type: m=%x\n", m);
1935       vpanic("s390_vr_get_type: reserved m value");
1936    }
1937 
1938    return results[m];
1939 }
1940 
1941 /* Determine if Condition Code Set (CS) flag is set in m field */
1942 #define s390_vr_is_cs_set(m) (((m) & 0x1) != 0)
1943 
1944 /* Determine if Zero Search (ZS) flag is set in m field */
1945 #define s390_vr_is_zs_set(m) (((m) & 0b0010) != 0)
1946 
1947 /* Check if the "Single-Element-Control" bit is set.
1948    Used in vector FP instructions.
1949  */
1950 #define s390_vr_is_single_element_control_set(m) (((m) & 0x8) != 0)
1951 
1952 /* Generates arg1 < arg2 (or arg1 <= arg2 if allow_equal == True) expression.
1953    Arguments must have V128 type and are treated as unsigned 128-bit numbers.
1954 */
1955 static IRExpr*
1956 s390_V128_compareLT128x1(IRExpr* arg1, IRExpr* arg2, Bool allow_equal)
1957 {
1958    /* If high halves are equal
1959       then we compare lower ones
1960       otherwise we compare high halves.
1961     */
1962    IRExpr* result;
1963    result = mkite(binop(Iop_CmpEQ64,
1964                         unop(Iop_V128HIto64, arg1),
1965                         unop(Iop_V128HIto64, arg2)
1966                         ),
1967                   unop(Iop_1Uto64,
1968                        binop(allow_equal ? Iop_CmpLE64U : Iop_CmpLT64U,
1969                              unop(Iop_V128to64, arg1),
1970                              unop(Iop_V128to64, arg2)
1971                             )
1972                       ),
1973                   unop(Iop_1Uto64,
1974                        binop(Iop_CmpLT64U,
1975                              unop(Iop_V128HIto64, arg1),
1976                              unop(Iop_V128HIto64, arg2)
1977                             )
1978                       )
1979                   );
1980 
1981    return result;
1982 }
1983 
1984 /* Generates arg1 == 0 expression.
1985    Argument must have V128 type and is treated as unsigned 128-bit number.
1986 */
1987 static IRExpr*
1988 s390_V128_isZero(IRExpr* arg)
1989 {
1990    IRExpr* high_or_low = binop(Iop_Or64,
1991                                unop(Iop_V128to64, arg),
1992                                unop(Iop_V128HIto64, arg)
1993                               );
1994 
1995    return unop(Iop_1Uto64, binop(Iop_CmpEQ64, high_or_low, mkU64(0ULL)));
1996 }
1997 
1998 /* Generate the two's complement for arg.
1999    Arg should be V128.
2000 */
2001 static IRExpr*
2002 s390_V128_get_complement(IRExpr* arg, IRType type)
2003 {
2004    IRExpr* notArg = unop(Iop_NotV128, arg);
2005    IRExpr* ones;
2006    IRExpr* result;
2007    switch(type) {
2008    case Ity_I8:
2009       ones = unop(Iop_Dup8x16, mkU8(0x01));
2010       result = binop(Iop_Add8x16, notArg, ones);
2011       break;
2012    case Ity_I16:
2013       ones = unop(Iop_Dup16x8, mkU16(0x0001));
2014       result = binop(Iop_Add16x8, notArg, ones);
2015       break;
2016    case Ity_I32:
2017       ones = unop(Iop_Dup32x4, mkU32(0x00000001));
2018       result = binop(Iop_Add32x4, notArg, ones);
2019       break;
2020    case Ity_I64:
2021       ones = binop(Iop_64HLtoV128, mkU64(0x1ULL), mkU64(0x1ULL));
2022       result = binop(Iop_Add64x2, notArg, ones);
2023       break;
2024    case Ity_V128:
2025       ones = binop(Iop_64HLtoV128, mkU64(0x0ULL), mkU64(0x1ULL));
2026       result = binop(Iop_Add128x1, notArg, ones);
2027       break;
2028    default:
2029       vpanic("s390_V128_get_complement: unknown type");
2030    }
2031 
2032    return result;
2033 }
2034 
2035 /* # Elements are treated as 128-bit unsigned integers
2036    For i = 0; i < elemCount; i++ do:
2037       sum = arg1[i] + arg2[i]
2038       result[i] = carry_out_bit(sum)
2039    end
2040    return result
2041  */
2042 static IRExpr*
2043 s390_V128_calculate_carry_out(IRExpr* arg1, IRExpr* arg2, IRType type,
2044                               Bool allow_equal)
2045 {
2046    IRTemp sum = newTemp(Ity_V128);
2047    IRExpr* mask;
2048    IRExpr* comparison;
2049    IRExpr* result;
2050    switch(type){
2051    case Ity_I8:
2052       assign(sum, binop(Iop_Add8x16, arg1, arg2));
2053       mask = unop(Iop_Dup8x16, mkU8(0x1));
2054       comparison = binop(Iop_CmpGT8Ux16, arg1, mkexpr(sum));
2055       if(allow_equal) {
2056          comparison = binop(Iop_OrV128, binop(Iop_CmpEQ8x16, arg1, mkexpr(sum)),
2057                             comparison);
2058       }
2059       result = binop(Iop_AndV128, comparison, mask);
2060       break;
2061    case Ity_I16:
2062       assign(sum, binop(Iop_Add16x8, arg1, arg2));
2063       mask = unop(Iop_Dup16x8, mkU16(0x1));
2064       comparison = binop(Iop_CmpGT16Ux8, arg1, mkexpr(sum));
2065       if(allow_equal) {
2066          comparison = binop(Iop_OrV128, binop(Iop_CmpEQ16x8, arg1, mkexpr(sum)),
2067                             comparison);
2068       }
2069       result = binop(Iop_AndV128, comparison, mask);
2070       break;
2071    case Ity_I32:
2072       assign(sum, binop(Iop_Add32x4, arg1, arg2));
2073       mask = unop(Iop_Dup32x4, mkU32(0x1));
2074       comparison = binop(Iop_CmpGT32Ux4, arg1, mkexpr(sum));
2075       if(allow_equal) {
2076          comparison = binop(Iop_OrV128, binop(Iop_CmpEQ32x4, arg1, mkexpr(sum)),
2077                             comparison);
2078       }
2079       result = binop(Iop_AndV128, comparison, mask);
2080       break;
2081    case Ity_I64:
2082       assign(sum, binop(Iop_Add64x2, arg1, arg2));
2083       mask = binop(Iop_64HLtoV128, mkU64(0x1), mkU64(0x1));
2084       comparison = binop(Iop_CmpGT64Ux2, arg1, mkexpr(sum));
2085       if(allow_equal) {
2086          comparison = binop(Iop_OrV128, binop(Iop_CmpEQ64x2, arg1, mkexpr(sum)),
2087                             comparison);
2088       }
2089       result = binop(Iop_AndV128, comparison, mask);
2090       break;
2091    case Ity_V128:
2092       assign(sum, binop(Iop_Add128x1, arg1, arg2));
2093       comparison = s390_V128_compareLT128x1(mkexpr(sum), arg1, allow_equal);
2094       result = binop(Iop_64HLtoV128, mkU64(0x0), comparison);
2095       break;
2096    default:
2097       ppIRType(type);
2098       vpanic("s390_V128_calculate_carry_out: unknown type");
2099    }
2100 
2101    return result;
2102 }
2103 
2104 /* # elemCount = 1 for now (elements are 128-bit unsigned integers)
2105    For i = 0; i < elemCount; i++ do:
2106       sum = arg1[i] + arg2[i] + arg3[i] & 0x1
2107       result[i] = carry_out_bit(sum)
2108    end
2109    return result
2110  */
2111 static IRExpr*
2112 s390_V128_calculate_carry_out_with_carry(IRExpr* arg1, IRExpr* arg2, IRExpr* arg3)
2113 {
2114    IRTemp sum = newTemp(Ity_V128);
2115    assign(sum, binop(Iop_Add128x1, arg1, arg2));
2116 
2117    IRTemp overflow_before = newTemp(Ity_I64);
2118    assign(overflow_before, s390_V128_compareLT128x1(mkexpr(sum), arg1, False));
2119 
2120    IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0), mkU64(1));
2121    IRTemp carry_in = newTemp(Ity_V128);
2122    assign(carry_in, binop(Iop_AndV128, arg3, mask));
2123 
2124    IRExpr* carry_is_not_zero = unop(Iop_1Uto64,
2125                                     binop(Iop_CmpNE64,
2126                                           unop(Iop_V128to64, mkexpr(carry_in)),
2127                                           mkU64(0ULL)
2128                                          )
2129                                     );
2130 
2131    IRTemp sum_plus_carry = newTemp(Ity_V128);
2132    assign(sum_plus_carry, binop(Iop_Add128x1, mkexpr(sum), mkexpr(carry_in)));
2133 
2134    IRExpr* overflow_after = binop(Iop_And64,
2135                                   carry_is_not_zero,
2136                                   s390_V128_isZero(mkexpr(sum_plus_carry))
2137                                   );
2138 
2139    IRExpr* result = binop(Iop_Or64, mkexpr(overflow_before), overflow_after);
2140    result = binop(Iop_64HLtoV128, mkU64(0Ull), result);
2141    return result;
2142 }
2143 
2144 /* Performs "arg1 + arg2 + carry_out_bit(arg1 + arg2)".
2145    Arguments and result are Ity_I32.
2146 */
2147 static IRTemp
2148 s390_checksum_add(IRExpr* arg1, IRExpr* arg2)
2149 {
2150    IRTemp sum = newTemp(Ity_I32);
2151    IRTemp res = newTemp(Ity_I32);
2152 
2153    assign(sum, binop(Iop_Add32, arg1, arg2));
2154    assign(res,
2155           mkite(binop(Iop_CmpLT32U, mkexpr(sum), arg1),
2156                 binop(Iop_Add32, mkexpr(sum), mkU32(1)),
2157                 mkexpr(sum))
2158                );
2159 
2160    return res;
2161 }
2162 
2163 /* Return the guest state offset of element with type's size and given index
2164    of a vr register.
2165 */
2166 static UInt
2167 s390_vr_offset_by_index(UInt archreg,IRType type, UChar index)
2168 {
2169    switch (type) {
2170    case Ity_I8:
2171       if(index > 15) {
2172          goto invalidIndex;
2173       }
2174       return vr_offset(archreg) + sizeof(UChar) * index;
2175 
2176    case Ity_I16:
2177       if(index > 7) {
2178          goto invalidIndex;
2179       }
2180       return vr_offset(archreg) + sizeof(UShort) * index;
2181 
2182    case Ity_I32:
2183    case Ity_F32:
2184       if(index > 3) {
2185          goto invalidIndex;
2186       }
2187       return vr_offset(archreg) + sizeof(UInt) * index;
2188 
2189    case Ity_I64:
2190    case Ity_F64:
2191       if(index > 1) {
2192          goto invalidIndex;
2193       }
2194       return vr_offset(archreg) + sizeof(ULong) * index;
2195    case Ity_V128:
2196       if(index == 0) {
2197          return vr_qw_offset(archreg);
2198       } else {
2199          goto invalidIndex;
2200       }
2201    default:
2202       vpanic("s390_vr_offset_by_index: unknown type");
2203    }
2204 
2205    invalidIndex:
2206       vex_printf("s390_vr_offset_by_index: index = %d ; type = ", index);
2207       ppIRType(type);
2208       vpanic("s390_vr_offset_by_index: invalid index for given type");
2209 }
2210 
2211 /* Write type sized element to indexed part of vr to the guest state. */
2212 static void
2213 put_vr(UInt archreg, IRType type, UChar index, IRExpr *expr)
2214 {
2215    UInt offset = s390_vr_offset_by_index(archreg, type, index);
2216    vassert(typeOfIRExpr(irsb->tyenv, expr) == type);
2217 
2218    stmt(IRStmt_Put(offset, expr));
2219 }
2220 
2221 /* Read type sized part specified by index of a vr register. */
2222 static IRExpr *
2223 get_vr(UInt archreg, IRType type, UChar index)
2224 {
2225    UInt offset = s390_vr_offset_by_index(archreg, type, index);
2226    return IRExpr_Get(offset, type);
2227 }
2228 
2229 /* Calculates vr index according to instruction's rxb field
2230    and position of vr in instruction.
2231    Index of first argument must be 1 (not zero) */
2232 static UChar
2233 s390_vr_getVRindex(UChar v,UChar argNumber, UChar rxb)
2234 {
2235    vassert(argNumber > 0 && argNumber <= 4);
2236    vassert(rxb < 16);
2237    return v | (((rxb) << argNumber) & 0b00010000);
2238 }
2239 
2240 static void
2241 s390_vr_fill(UChar v1, IRExpr *o2)
2242 {
2243    IRType o2type = typeOfIRExpr(irsb->tyenv, o2);
2244    switch (o2type) {
2245    case Ity_I8:
2246       put_vr_qw(v1, unop(Iop_Dup8x16, o2));
2247       break;
2248    case Ity_I16:
2249       put_vr_qw(v1, unop(Iop_Dup16x8, o2));
2250       break;
2251    case Ity_I32:
2252       put_vr_qw(v1, unop(Iop_Dup32x4, o2));
2253       break;
2254    case Ity_I64:
2255       put_vr_qw(v1, binop(Iop_64HLtoV128, o2, o2));
2256       break;
2257    default:
2258       ppIRType(o2type);
2259       vpanic("s390_vr_fill: invalid IRType");
2260    }
2261 }
2262 
2263 /* Returns Ity_I32 number of bytes till block boundary specified by m */
2264 static IRExpr*
2265 s390_getCountToBlockBoundary(IRTemp op2addr, UChar m)
2266 {
2267    IRTemp boundary = newTemp(Ity_I32);
2268    IRTemp sixteen = newTemp(Ity_I32);
2269    IRTemp divisionResult = newTemp(Ity_I64);
2270    IRTemp mod_result = newTemp(Ity_I32);
2271    IRTemp output = newTemp(Ity_I32);
2272 
2273    switch (m) {
2274    case 0: assign(boundary, mkU32(64)); break;
2275    case 1: assign(boundary, mkU32(128)); break;
2276    case 2: assign(boundary, mkU32(256)); break;
2277    case 3: assign(boundary, mkU32(512)); break;
2278    case 4: assign(boundary, mkU32(1024)); break;
2279    case 5: assign(boundary, mkU32(2048)); break;
2280    case 6: assign(boundary, mkU32(4096)); break;
2281    default:
2282       vex_printf("m = %d\n", m);
2283       vpanic("s390_getCountToBlockBoundary: invalid m");
2284    }
2285    assign(sixteen, mkU32(16));
2286    assign(divisionResult,
2287           binop(Iop_DivModU64to32, mkexpr(op2addr), mkexpr(boundary)));
2288    assign(mod_result,
2289           binop(Iop_Sub32,mkexpr(boundary),
2290                 unop(Iop_64HIto32, mkexpr(divisionResult))));
2291 
2292    assign(output,
2293           mkite(binop(Iop_CmpLE32U, mkexpr(sixteen), mkexpr(mod_result)),
2294           mkexpr(sixteen),
2295           mkexpr(mod_result)
2296          ));
2297 
2298    return mkexpr(output);
2299 }
2300 
2301 /* Load bytes into v1.
2302    maxIndex specifies max index to load and must be Ity_I32.
2303    If maxIndex >= 15, all 16 bytes are loaded.
2304    All bytes after maxIndex are zeroed. */
2305 static void s390_vr_loadWithLength(UChar v1, IRTemp addr, IRExpr *maxIndex)
2306 {
2307    IRTemp maxIdx = newTemp(Ity_I32);
2308    IRTemp cappedMax = newTemp(Ity_I64);
2309    IRTemp offset = newTemp(Ity_I64);
2310    IRTemp zeroed = newTemp(Ity_I64);
2311    IRTemp back = newTemp(Ity_I64);
2312 
2313    /* Implement the insn with a single 16-byte load, to allow memcheck's
2314       "partial-loads-OK" heuristic to apply.  Ensure that a page boundary is
2315       crossed if and only if the real insn would have crossed it as well.
2316       Thus, if the bytes to load are fully contained in an aligned 16-byte
2317       chunk, load the whole 16-byte aligned chunk, and otherwise load 16 bytes
2318       from the unaligned address.  Then shift the loaded data left-aligned
2319       into the target vector register. */
2320 
2321    assign(maxIdx, maxIndex);
2322    assign(cappedMax, mkite(binop(Iop_CmpLT32U, mkexpr(maxIdx), mkU32(15)),
2323                            unop(Iop_32Uto64, mkexpr(maxIdx)), mkU64(15)));
2324    /* 'offset': addr's offset from last 16-byte aligned address
2325       'zeroed': number of bytes to be zeroed in the target vector
2326       'back': how much to subtract from addr before loading 16 bytes */
2327    assign(offset, binop(Iop_And64, mkexpr(addr), mkU64(15)));
2328    assign(zeroed, binop(Iop_Sub64, mkU64(15), mkexpr(cappedMax)));
2329    assign(back, mkite(binop(Iop_CmpLE64U, mkexpr(offset), mkexpr(zeroed)),
2330                       mkexpr(offset), mkU64(0)));
2331 
2332    /* How much to shift the loaded 16-byte vector to the right, and then to
2333       the left.  Since both 'zeroed' and 'back' range from 0 to 15, the shift
2334       amounts range from 0 to 120. */
2335    IRExpr *shrAmount = binop(Iop_Shl64,
2336                              binop(Iop_Sub64, mkexpr(zeroed), mkexpr(back)),
2337                              mkU8(3));
2338    IRExpr *shlAmount = binop(Iop_Shl64, mkexpr(zeroed), mkU8(3));
2339 
2340    put_vr_qw(v1, binop(Iop_ShlV128,
2341                        binop(Iop_ShrV128,
2342                              load(Ity_V128,
2343                                   binop(Iop_Sub64, mkexpr(addr), mkexpr(back))),
2344                              unop(Iop_64to8, shrAmount)),
2345                        unop(Iop_64to8, shlAmount)));
2346 }
2347 
2348 /* Bitwise vCond ? v1 : v2
2349    All args are V128.
2350  */
2351 static IRExpr*
2352 s390_V128_bitwiseITE(IRExpr* vCond, IRExpr* v1, IRExpr* v2)
2353 {
2354    IRTemp vc = newTemp(Ity_V128);
2355    assign(vc, vCond);
2356    /* result = (v1 & vCond) | (v2 & ~vCond) */
2357    return binop(Iop_OrV128,
2358                 binop(Iop_AndV128, v1, mkexpr(vc)),
2359                 binop(Iop_AndV128, v2, unop(Iop_NotV128, mkexpr(vc))));
2360 }
2361 
2362 /*------------------------------------------------------------*/
2363 /*--- Rounding modes                                       ---*/
2364 /*------------------------------------------------------------*/
2365 
2366 /* Extract the bfp rounding mode from the guest FPC reg and encode it as an
2367    IRRoundingMode:
2368 
2369    rounding mode | s390 | IR
2370    -------------------------
2371    to nearest    |  00  | 00
2372    to zero       |  01  | 11
2373    to +infinity  |  10  | 10
2374    to -infinity  |  11  | 01
2375 
2376    So:  IR = (4 - s390) & 3
2377 */
2378 static IRExpr *
2379 get_bfp_rounding_mode_from_fpc(void)
2380 {
2381    IRTemp fpc_bits = newTemp(Ity_I32);
2382 
2383    /* For z196 and later the bfp rounding mode is stored in bits [29:31].
2384       Prior to that bits [30:31] contained the bfp rounding mode with
2385       bit 29 being unused and having a value of 0. So we can always
2386       extract the least significant 3 bits. */
2387    assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
2388 
2389    /* fixs390:
2390 
2391 
2392       if (! s390_host_has_fpext && rounding_mode > 3) {
2393          emulation warning @ runtime and
2394          set fpc to round nearest
2395       }
2396    */
2397 
2398    /* For now silently adjust an unsupported rounding mode to "nearest" */
2399    IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
2400                            mkexpr(fpc_bits),
2401                            mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
2402 
2403    // rm_IR = (4 - rm_s390) & 3;
2404    return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
2405 }
2406 
2407 /* Encode the s390 rounding mode as it appears in the m3 field of certain
2408    instructions to VEX's IRRoundingMode. Rounding modes that cannot be
2409    represented in VEX are converted to Irrm_NEAREST. The rationale is, that
2410    Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
2411    considers the default rounding mode (4.3.3). */
2412 static IRTemp
2413 encode_bfp_rounding_mode(UChar mode)
2414 {
2415    IRExpr *rm;
2416 
2417    switch (mode) {
2418    case S390_BFP_ROUND_PER_FPC:
2419       rm = get_bfp_rounding_mode_from_fpc();
2420       break;
2421    case S390_BFP_ROUND_NEAREST_AWAY:  rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
2422    case S390_BFP_ROUND_PREPARE_SHORT: rm = mkU32(Irrm_PREPARE_SHORTER); break;
2423    case S390_BFP_ROUND_NEAREST_EVEN:  rm = mkU32(Irrm_NEAREST); break;
2424    case S390_BFP_ROUND_ZERO:          rm = mkU32(Irrm_ZERO);    break;
2425    case S390_BFP_ROUND_POSINF:        rm = mkU32(Irrm_PosINF);  break;
2426    case S390_BFP_ROUND_NEGINF:        rm = mkU32(Irrm_NegINF);  break;
2427    default:
2428       vpanic("encode_bfp_rounding_mode");
2429    }
2430 
2431    return mktemp(Ity_I32, rm);
2432 }
2433 
2434 /* Extract the DFP rounding mode from the guest FPC reg and encode it as an
2435    IRRoundingMode:
2436 
2437    rounding mode                     | s390  | IR
2438    ------------------------------------------------
2439    to nearest, ties to even          |  000  | 000
2440    to zero                           |  001  | 011
2441    to +infinity                      |  010  | 010
2442    to -infinity                      |  011  | 001
2443    to nearest, ties away from 0      |  100  | 100
2444    to nearest, ties toward 0         |  101  | 111
2445    to away from 0                    |  110  | 110
2446    to prepare for shorter precision  |  111  | 101
2447 
2448    So:  IR = (s390 ^ ((s390 << 1) & 2))
2449 */
2450 static IRExpr *
2451 get_dfp_rounding_mode_from_fpc(void)
2452 {
2453    IRTemp fpc_bits = newTemp(Ity_I32);
2454 
2455    /* The dfp rounding mode is stored in bits [25:27].
2456       extract the bits at 25:27 and right shift 4 times. */
2457    assign(fpc_bits, binop(Iop_Shr32,
2458                           binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
2459                           mkU8(4)));
2460 
2461    IRExpr *rm_s390 = mkexpr(fpc_bits);
2462    // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
2463 
2464    return binop(Iop_Xor32, rm_s390,
2465                 binop( Iop_And32,
2466                        binop(Iop_Shl32, rm_s390, mkU8(1)),
2467                        mkU32(2)));
2468 }
2469 
2470 /* Encode the s390 rounding mode as it appears in the m3 field of certain
2471    instructions to VEX's IRRoundingMode. */
2472 static IRTemp
2473 encode_dfp_rounding_mode(UChar mode)
2474 {
2475    IRExpr *rm;
2476 
2477    switch (mode) {
2478    case S390_DFP_ROUND_PER_FPC_0:
2479    case S390_DFP_ROUND_PER_FPC_2:
2480       rm = get_dfp_rounding_mode_from_fpc(); break;
2481    case S390_DFP_ROUND_NEAREST_EVEN_4:
2482    case S390_DFP_ROUND_NEAREST_EVEN_8:
2483       rm = mkU32(Irrm_NEAREST); break;
2484    case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
2485    case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
2486       rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
2487    case S390_DFP_ROUND_PREPARE_SHORT_3:
2488    case S390_DFP_ROUND_PREPARE_SHORT_15:
2489       rm = mkU32(Irrm_PREPARE_SHORTER); break;
2490    case S390_DFP_ROUND_ZERO_5:
2491    case S390_DFP_ROUND_ZERO_9:
2492       rm = mkU32(Irrm_ZERO ); break;
2493    case S390_DFP_ROUND_POSINF_6:
2494    case S390_DFP_ROUND_POSINF_10:
2495       rm = mkU32(Irrm_PosINF); break;
2496    case S390_DFP_ROUND_NEGINF_7:
2497    case S390_DFP_ROUND_NEGINF_11:
2498       rm = mkU32(Irrm_NegINF); break;
2499    case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
2500       rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
2501    case S390_DFP_ROUND_AWAY_0:
2502       rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
2503    default:
2504       vpanic("encode_dfp_rounding_mode");
2505    }
2506 
2507    return mktemp(Ity_I32, rm);
2508 }
2509 
2510 
2511 /*------------------------------------------------------------*/
2512 /*--- Condition code helpers                               ---*/
2513 /*------------------------------------------------------------*/
2514 
2515 /* The result of a Iop_CmpFxx operation is a condition code. It is
2516    encoded using the values defined in type IRCmpFxxResult.
2517    Before we can store the condition code into the guest state (or do
2518    anything else with it for that matter) we need to convert it to
2519    the encoding that s390 uses. This is what this function does.
2520 
2521    s390     VEX                b6 b2 b0   cc.1  cc.0
2522    0      0x40 EQ             1  0  0     0     0
2523    1      0x01 LT             0  0  1     0     1
2524    2      0x00 GT             0  0  0     1     0
2525    3      0x45 Unordered      1  1  1     1     1
2526 
2527    The following bits from the VEX encoding are interesting:
2528    b0, b2, b6  with b0 being the LSB. We observe:
2529 
2530    cc.0 = b0;
2531    cc.1 = b2 | (~b0 & ~b6)
2532 
2533    with cc being the s390 condition code.
2534 */
2535 static IRExpr *
2536 convert_vex_bfpcc_to_s390(IRTemp vex_cc)
2537 {
2538    IRTemp cc0  = newTemp(Ity_I32);
2539    IRTemp cc1  = newTemp(Ity_I32);
2540    IRTemp b0   = newTemp(Ity_I32);
2541    IRTemp b2   = newTemp(Ity_I32);
2542    IRTemp b6   = newTemp(Ity_I32);
2543 
2544    assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
2545    assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
2546                     mkU32(1)));
2547    assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
2548                     mkU32(1)));
2549 
2550    assign(cc0, mkexpr(b0));
2551    assign(cc1, binop(Iop_Or32, mkexpr(b2),
2552                      binop(Iop_And32,
2553                            binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
2554                            binop(Iop_Sub32, mkU32(1), mkexpr(b6))  /* ~b6 */
2555                            )));
2556 
2557    return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
2558 }
2559 
2560 
2561 /* The result of a Iop_CmpDxx operation is a condition code. It is
2562    encoded using the values defined in type IRCmpDxxResult.
2563    Before we can store the condition code into the guest state (or do
2564    anything else with it for that matter) we need to convert it to
2565    the encoding that s390 uses. This is what this function does. */
2566 static IRExpr *
2567 convert_vex_dfpcc_to_s390(IRTemp vex_cc)
2568 {
2569    /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
2570       same. currently. */
2571    return convert_vex_bfpcc_to_s390(vex_cc);
2572 }
2573 
2574 
2575 /*------------------------------------------------------------*/
2576 /*--- Build IR for formats                                 ---*/
2577 /*------------------------------------------------------------*/
2578 static void
2579 s390_format_I(const HChar *(*irgen)(UChar i),
2580               UChar i)
2581 {
2582    const HChar *mnm = irgen(i);
2583 
2584    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2585       s390_disasm(ENC2(MNM, UINT), mnm, i);
2586 }
2587 
2588 static void
2589 s390_format_E(const HChar *(*irgen)(void))
2590 {
2591    const HChar *mnm = irgen();
2592 
2593    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2594       s390_disasm(ENC1(MNM), mnm);
2595 }
2596 
2597 static void
2598 s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
2599                UChar r1, UShort i2)
2600 {
2601    irgen(r1, i2);
2602 }
2603 
2604 static void
2605 s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
2606                   UChar r1, UShort i2)
2607 {
2608    const HChar *mnm = irgen(r1, i2);
2609 
2610    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2611       s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
2612 }
2613 
2614 static void
2615 s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
2616                   UChar r1, UShort i2)
2617 {
2618    const HChar *mnm = irgen(r1, i2);
2619 
2620    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2621       s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
2622 }
2623 
2624 static void
2625 s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
2626                   UChar r1, UShort i2)
2627 {
2628    const HChar *mnm = irgen(r1, i2);
2629 
2630    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2631       s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
2632 }
2633 
2634 static void
2635 s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
2636                     UChar r1, UChar r3, UShort i2)
2637 {
2638    const HChar *mnm = irgen(r1, r3, i2);
2639 
2640    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2641       s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2642 }
2643 
2644 static void
2645 s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
2646                      UChar r1, UChar r3, UShort i2)
2647 {
2648    const HChar *mnm = irgen(r1, r3, i2);
2649 
2650    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2651       s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
2652 }
2653 
2654 static void
2655 s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
2656                                             UChar i4, UChar i5),
2657                       UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
2658 {
2659    const HChar *mnm = irgen(r1, r2, i3, i4, i5);
2660 
2661    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2662       s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
2663                   i5);
2664 }
2665 
2666 static void
2667 s390_format_RIEv1(const HChar *(*irgen)(UChar r1, UShort i2, UChar m3),
2668                   UChar r1, UShort i2, UChar m3)
2669 {
2670    const HChar *mnm = irgen(r1, i2, m3);
2671 
2672    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2673       s390_disasm(ENC4(MNM, GPR, UINT, UINT), mnm, r1, i2, m3);
2674 }
2675 
2676 static void
2677 s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
2678                                            UChar m3),
2679                      UChar r1, UChar r2, UShort i4, UChar m3)
2680 {
2681    const HChar *mnm = irgen(r1, r2, i4, m3);
2682 
2683    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2684       s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
2685                   r2, m3, (Int)(Short)i4);
2686 }
2687 
2688 static void
2689 s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
2690                                            UChar i2),
2691                      UChar r1, UChar m3, UShort i4, UChar i2)
2692 {
2693    const HChar *mnm = irgen(r1, m3, i4, i2);
2694 
2695    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2696       s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
2697                   r1, i2, m3, (Int)(Short)i4);
2698 }
2699 
2700 static void
2701 s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
2702                                            UChar i2),
2703                      UChar r1, UChar m3, UShort i4, UChar i2)
2704 {
2705    const HChar *mnm = irgen(r1, m3, i4, i2);
2706 
2707    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2708       s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
2709                   (Int)(Char)i2, m3, (Int)(Short)i4);
2710 }
2711 
2712 static void
2713 s390_format_RIE_RUPIX(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
2714                                            UChar i2),
2715                      UChar r1, UChar m3, UShort i4, UChar i2, Int xmnm_kind)
2716 {
2717    const HChar *mnm = irgen(r1, m3, i4, i2);
2718 
2719    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2720       s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), xmnm_kind, mnm, m3, r1,
2721                   (Int)(Char)i2, m3, (Int)(Short)i4);
2722 }
2723 
2724 static void
2725 s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
2726                 UChar r1, UInt i2)
2727 {
2728    irgen(r1, i2);
2729 }
2730 
2731 static void
2732 s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
2733                    UChar r1, UInt i2)
2734 {
2735    const HChar *mnm = irgen(r1, i2);
2736 
2737    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2738       s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
2739 }
2740 
2741 static void
2742 s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
2743                    UChar r1, UInt i2)
2744 {
2745    const HChar *mnm = irgen(r1, i2);
2746 
2747    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2748       s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
2749 }
2750 
2751 static void
2752 s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
2753                    UChar r1, UInt i2)
2754 {
2755    const HChar *mnm = irgen(r1, i2);
2756 
2757    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2758       s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
2759 }
2760 
2761 static void
2762 s390_format_RIL_UP(const HChar *(*irgen)(void),
2763                    UChar r1, UInt i2)
2764 {
2765    const HChar *mnm = irgen();
2766 
2767    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2768       s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
2769 }
2770 
2771 static void
2772 s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
2773                       IRTemp op4addr),
2774                       UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
2775 {
2776    const HChar *mnm;
2777    IRTemp op4addr = newTemp(Ity_I64);
2778 
2779    assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2780           mkU64(0)));
2781 
2782    mnm = irgen(r1, m3, i2, op4addr);
2783 
2784    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2785       s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2786                   (Int)(Char)i2, m3, d4, 0, b4);
2787 }
2788 
2789 static void
2790 s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
2791                       IRTemp op4addr),
2792                       UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
2793 {
2794    const HChar *mnm;
2795    IRTemp op4addr = newTemp(Ity_I64);
2796 
2797    assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2798           mkU64(0)));
2799 
2800    mnm = irgen(r1, m3, i2, op4addr);
2801 
2802    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2803       s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2804                   i2, m3, d4, 0, b4);
2805 }
2806 
2807 static void
2808 s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
2809                UChar r1, UChar r2)
2810 {
2811    irgen(r1, r2);
2812 }
2813 
2814 static void
2815 s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
2816                   UChar r1, UChar r2)
2817 {
2818    const HChar *mnm = irgen(r1, r2);
2819 
2820    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2821       s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
2822 }
2823 
2824 static void
2825 s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
2826                   UChar r1, UChar r2)
2827 {
2828    const HChar *mnm = irgen(r1, r2);
2829 
2830    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2831       s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
2832 }
2833 
2834 static void
2835 s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
2836                 UChar r1, UChar r2)
2837 {
2838    irgen(r1, r2);
2839 }
2840 
2841 static void
2842 s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
2843                    UChar r1, UChar r2)
2844 {
2845    const HChar *mnm = irgen(r1, r2);
2846 
2847    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2848       s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
2849 }
2850 
2851 static void
2852 s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
2853                    UChar r1, UChar r2)
2854 {
2855    const HChar *mnm = irgen(r1, r2);
2856 
2857    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2858       s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
2859 }
2860 
2861 static void
2862 s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
2863                    UChar r1, UChar r2)
2864 {
2865    const HChar *mnm = irgen(r1, r2);
2866 
2867    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2868       s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
2869 }
2870 
2871 static void
2872 s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
2873                    UChar r1, UChar r2)
2874 {
2875    const HChar *mnm = irgen(r1, r2);
2876 
2877    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2878       s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
2879 }
2880 
2881 static void
2882 s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
2883                    UChar r1)
2884 {
2885    const HChar *mnm = irgen(r1);
2886 
2887    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2888       s390_disasm(ENC2(MNM, GPR), mnm, r1);
2889 }
2890 
2891 static void
2892 s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
2893                    UChar r1)
2894 {
2895    const HChar *mnm = irgen(r1);
2896 
2897    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2898       s390_disasm(ENC2(MNM, FPR), mnm, r1);
2899 }
2900 
2901 static void
2902 s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
2903                        UChar m3, UChar r1, UChar r2)
2904 {
2905    const HChar *mnm = irgen(m3, r1, r2);
2906 
2907    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2908       s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
2909 }
2910 
2911 static void
2912 s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
2913                      UChar r1, UChar r3, UChar r2)
2914 {
2915    const HChar *mnm = irgen(r1, r3, r2);
2916 
2917    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2918       s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2919 }
2920 
2921 static void
2922 s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2923                      UChar r3, UChar r1, UChar r2)
2924 {
2925    const HChar *mnm = irgen(r3, r1, r2);
2926 
2927    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2928       s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2929 }
2930 
2931 static void
2932 s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2933                                            UChar r2),
2934                      UChar m3, UChar m4, UChar r1, UChar r2)
2935 {
2936    const HChar *mnm = irgen(m3, m4, r1, r2);
2937 
2938    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2939       s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2940 }
2941 
2942 static void
2943 s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2944                      UChar m4, UChar r1, UChar r2)
2945 {
2946    const HChar *mnm = irgen(m4, r1, r2);
2947 
2948    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2949       s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2950 }
2951 
2952 static void
2953 s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2954                                            UChar r2),
2955                      UChar m3, UChar m4, UChar r1, UChar r2)
2956 {
2957    const HChar *mnm = irgen(m3, m4, r1, r2);
2958 
2959    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2960       s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2961 }
2962 
2963 static void
2964 s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2965                                            UChar r2),
2966                      UChar m3, UChar m4, UChar r1, UChar r2)
2967 {
2968    const HChar *mnm = irgen(m3, m4, r1, r2);
2969 
2970    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2971       s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2972 }
2973 
2974 
2975 static void
2976 s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
2977                      UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2978 {
2979    irgen(m3, r1, r2);
2980 
2981    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2982       s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2983 }
2984 
2985 static void
2986 s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
2987                       UChar r3, UChar r1, UChar r2)
2988 {
2989    const HChar *mnm = irgen(r3, r1, r2);
2990 
2991    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2992       s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2993 }
2994 
2995 static void
2996 s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2997                      UChar r3, UChar m4, UChar r1, UChar r2)
2998 {
2999    const HChar *mnm = irgen(r3, m4, r1, r2);
3000 
3001    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3002       s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
3003 }
3004 
3005 static void
3006 s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
3007                      UChar r3, UChar m4, UChar r1, UChar r2)
3008 {
3009    const HChar *mnm = irgen(r3, m4, r1, r2);
3010 
3011    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3012       s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
3013 }
3014 
3015 static void
3016 s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
3017                       UChar r3, UChar m4, UChar r1, UChar r2)
3018 {
3019    const HChar *mnm = irgen(r3, m4, r1, r2);
3020 
3021    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3022       s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
3023 }
3024 
3025 static void
3026 s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
3027                       UChar r3, UChar r1, UChar r2)
3028 {
3029    const HChar *mnm = irgen(r3, r1, r2);
3030 
3031    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3032       s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
3033 }
3034 
3035 static void
3036 s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
3037                                       IRTemp op4addr),
3038                 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
3039 {
3040    const HChar *mnm;
3041    IRTemp op4addr = newTemp(Ity_I64);
3042 
3043    assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
3044           mkU64(0)));
3045 
3046    mnm = irgen(r1, r2, m3, op4addr);
3047 
3048    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3049       s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
3050                   r2, m3, d4, 0, b4);
3051 }
3052 
3053 static void
3054 s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3055                     UChar r1, UChar b2, UShort d2)
3056 {
3057    const HChar *mnm;
3058    IRTemp op2addr = newTemp(Ity_I64);
3059 
3060    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3061           mkU64(0)));
3062 
3063    mnm = irgen(r1, op2addr);
3064 
3065    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3066       s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
3067 }
3068 
3069 static void
3070 s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
3071                     UChar r1, UChar r3, UChar b2, UShort d2)
3072 {
3073    const HChar *mnm;
3074    IRTemp op2addr = newTemp(Ity_I64);
3075 
3076    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3077           mkU64(0)));
3078 
3079    mnm = irgen(r1, r3, op2addr);
3080 
3081    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3082       s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
3083 }
3084 
3085 static void
3086 s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
3087                     UChar r1, UChar r3, UChar b2, UShort d2)
3088 {
3089    const HChar *mnm;
3090    IRTemp op2addr = newTemp(Ity_I64);
3091 
3092    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3093           mkU64(0)));
3094 
3095    mnm = irgen(r1, r3, op2addr);
3096 
3097    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3098       s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
3099 }
3100 
3101 static void
3102 s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
3103                     UChar r1, UChar r3, UChar b2, UShort d2)
3104 {
3105    const HChar *mnm;
3106    IRTemp op2addr = newTemp(Ity_I64);
3107 
3108    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3109           mkU64(0)));
3110 
3111    mnm = irgen(r1, r3, op2addr);
3112 
3113    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3114       s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
3115 }
3116 
3117 static void
3118 s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
3119                     UChar r1, UChar r3, UShort i2)
3120 {
3121    const HChar *mnm = irgen(r1, r3, i2);
3122 
3123    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3124       s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
3125 }
3126 
3127 static void
3128 s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
3129                      UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
3130 {
3131    const HChar *mnm;
3132    IRTemp op2addr = newTemp(Ity_I64);
3133    IRTemp d2 = newTemp(Ity_I64);
3134 
3135    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3136    assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
3137           mkU64(0)));
3138 
3139    mnm = irgen(r1, r3, op2addr);
3140 
3141    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3142       s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
3143 }
3144 
3145 static void
3146 s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
3147                      UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
3148 {
3149    const HChar *mnm;
3150    IRTemp op2addr = newTemp(Ity_I64);
3151    IRTemp d2 = newTemp(Ity_I64);
3152 
3153    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3154    assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
3155           mkU64(0)));
3156 
3157    mnm = irgen(r1, r3, op2addr);
3158 
3159    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3160       s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
3161 }
3162 
3163 static void
3164 s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
3165                      UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
3166 {
3167    const HChar *mnm;
3168    IRTemp op2addr = newTemp(Ity_I64);
3169    IRTemp d2 = newTemp(Ity_I64);
3170 
3171    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3172    assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
3173           mkU64(0)));
3174 
3175    mnm = irgen(r1, r3, op2addr);
3176 
3177    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3178       s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
3179 }
3180 
3181 static void
3182 s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3183                      UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
3184                      Int xmnm_kind)
3185 {
3186    IRTemp op2addr = newTemp(Ity_I64);
3187    IRTemp d2 = newTemp(Ity_I64);
3188 
3189    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
3190 
3191    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3192    assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
3193           mkU64(0)));
3194 
3195    irgen(r1, op2addr);
3196 
3197    vassert(dis_res->whatNext == Dis_Continue);
3198 
3199    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3200       s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
3201 }
3202 
3203 static void
3204 s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
3205                IRTemp op2addr),
3206                UChar r1, UChar x2, UChar b2, UShort d2)
3207 {
3208    IRTemp op2addr = newTemp(Ity_I64);
3209 
3210    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3211           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3212           mkU64(0)));
3213 
3214    irgen(r1, x2, b2, d2, op2addr);
3215 }
3216 
3217 static void
3218 s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3219                     UChar r1, UChar x2, UChar b2, UShort d2)
3220 {
3221    const HChar *mnm;
3222    IRTemp op2addr = newTemp(Ity_I64);
3223 
3224    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3225           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3226           mkU64(0)));
3227 
3228    mnm = irgen(r1, op2addr);
3229 
3230    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3231       s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
3232 }
3233 
3234 static void
3235 s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3236                     UChar r1, UChar x2, UChar b2, UShort d2)
3237 {
3238    const HChar *mnm;
3239    IRTemp op2addr = newTemp(Ity_I64);
3240 
3241    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3242           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3243           mkU64(0)));
3244 
3245    mnm = irgen(r1, op2addr);
3246 
3247    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3248       s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
3249 }
3250 
3251 static void
3252 s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3253                      UChar r1, UChar x2, UChar b2, UShort d2)
3254 {
3255    const HChar *mnm;
3256    IRTemp op2addr = newTemp(Ity_I64);
3257 
3258    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3259           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3260           mkU64(0)));
3261 
3262    mnm = irgen(r1, op2addr);
3263 
3264    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3265       s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
3266 }
3267 
3268 static void
3269 s390_format_RXE_RRRDR(const HChar *(*irgen)(UChar r1, IRTemp op2addr, UChar m3),
3270                      UChar r1, UChar x2, UChar b2, UShort d2, UChar m3)
3271 {
3272    const HChar *mnm;
3273    IRTemp op2addr = newTemp(Ity_I64);
3274 
3275    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3276           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3277           mkU64(0)));
3278 
3279    mnm = irgen(r1, op2addr, m3);
3280 
3281    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3282       s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
3283 }
3284 
3285 static void
3286 s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
3287                       UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
3288 {
3289    const HChar *mnm;
3290    IRTemp op2addr = newTemp(Ity_I64);
3291 
3292    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3293           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3294           mkU64(0)));
3295 
3296    mnm = irgen(r3, op2addr, r1);
3297 
3298    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3299       s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
3300 }
3301 
3302 static void
3303 s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3304                      UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3305 {
3306    const HChar *mnm;
3307    IRTemp op2addr = newTemp(Ity_I64);
3308    IRTemp d2 = newTemp(Ity_I64);
3309 
3310    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3311    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
3312           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3313           mkU64(0)));
3314 
3315    mnm = irgen(r1, op2addr);
3316 
3317    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) {
3318       if (irgen == s390_irgen_BIC)
3319          s390_disasm(ENC2(XMNM, SDXB), S390_XMNM_BIC, r1, dh2, dl2, x2, b2);
3320       else
3321          s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
3322    }
3323 }
3324 
3325 static void
3326 s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3327                      UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3328 {
3329    const HChar *mnm;
3330    IRTemp op2addr = newTemp(Ity_I64);
3331    IRTemp d2 = newTemp(Ity_I64);
3332 
3333    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3334    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
3335           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3336           mkU64(0)));
3337 
3338    mnm = irgen(r1, op2addr);
3339 
3340    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3341       s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
3342 }
3343 
3344 static void
3345 s390_format_RXY_URRD(const HChar *(*irgen)(void),
3346                      UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3347 {
3348    const HChar *mnm;
3349    IRTemp op2addr = newTemp(Ity_I64);
3350    IRTemp d2 = newTemp(Ity_I64);
3351 
3352    assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3353    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
3354           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3355           mkU64(0)));
3356 
3357    mnm = irgen();
3358 
3359    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3360       s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
3361 }
3362 
3363 static void
3364 s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
3365                  UChar b2, UShort d2)
3366 {
3367    const HChar *mnm;
3368    IRTemp op2addr = newTemp(Ity_I64);
3369 
3370    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3371           mkU64(0)));
3372 
3373    mnm = irgen(op2addr);
3374 
3375    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3376       s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
3377 }
3378 
3379 static void
3380 s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
3381                    UChar i2, UChar b1, UShort d1)
3382 {
3383    const HChar *mnm;
3384    IRTemp op1addr = newTemp(Ity_I64);
3385 
3386    assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3387           mkU64(0)));
3388 
3389    mnm = irgen(i2, op1addr);
3390 
3391    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3392       s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
3393 }
3394 
3395 static void
3396 s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
3397                     UChar i2, UChar b1, UShort dl1, UChar dh1)
3398 {
3399    const HChar *mnm;
3400    IRTemp op1addr = newTemp(Ity_I64);
3401    IRTemp d1 = newTemp(Ity_I64);
3402 
3403    assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
3404    assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
3405           mkU64(0)));
3406 
3407    mnm = irgen(i2, op1addr);
3408 
3409    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3410       s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
3411 }
3412 
3413 static void
3414 s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
3415                     UChar i2, UChar b1, UShort dl1, UChar dh1)
3416 {
3417    const HChar *mnm;
3418    IRTemp op1addr = newTemp(Ity_I64);
3419    IRTemp d1 = newTemp(Ity_I64);
3420 
3421    assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
3422    assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
3423           mkU64(0)));
3424 
3425    mnm = irgen(i2, op1addr);
3426 
3427    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3428       s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
3429 }
3430 
3431 static void
3432 s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
3433                       UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
3434 {
3435    const HChar *mnm;
3436    IRTemp op1addr = newTemp(Ity_I64);
3437    IRTemp op2addr = newTemp(Ity_I64);
3438 
3439    assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3440           mkU64(0)));
3441    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3442           mkU64(0)));
3443 
3444    mnm = irgen(l, op1addr, op2addr);
3445 
3446    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3447       s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
3448 }
3449 
3450 static void
3451 s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
3452                     UChar b1, UShort d1, UShort i2)
3453 {
3454    const HChar *mnm;
3455    IRTemp op1addr = newTemp(Ity_I64);
3456 
3457    assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3458           mkU64(0)));
3459 
3460    mnm = irgen(i2, op1addr);
3461 
3462    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3463       s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
3464 }
3465 
3466 static void
3467 s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
3468                     UChar b1, UShort d1, UShort i2)
3469 {
3470    const HChar *mnm;
3471    IRTemp op1addr = newTemp(Ity_I64);
3472 
3473    assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3474           mkU64(0)));
3475 
3476    mnm = irgen(i2, op1addr);
3477 
3478    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3479       s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
3480 }
3481 
3482 static void
3483 s390_format_VRX_VRRD(const HChar *(*irgen)(UChar v1, IRTemp op2addr),
3484                     UChar v1, UChar x2, UChar b2, UShort d2, UChar rxb)
3485 {
3486    const HChar *mnm;
3487    IRTemp op2addr = newTemp(Ity_I64);
3488 
3489    if (! s390_host_has_vx) {
3490       emulation_failure(EmFail_S390X_vx);
3491       return;
3492    }
3493 
3494    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3495           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3496           mkU64(0)));
3497 
3498    v1  = s390_vr_getVRindex(v1, 1, rxb);
3499    mnm = irgen(v1, op2addr);
3500 
3501    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3502       s390_disasm(ENC3(MNM, VR, UDXB), mnm, v1, d2, x2, b2);
3503 }
3504 
3505 
3506 static void
3507 s390_format_VRX_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3),
3508                     UChar v1, UChar x2, UChar b2, UShort d2, UChar m3, UChar rxb)
3509 {
3510    const HChar *mnm;
3511    IRTemp op2addr = newTemp(Ity_I64);
3512 
3513    if (! s390_host_has_vx) {
3514       emulation_failure(EmFail_S390X_vx);
3515       return;
3516    }
3517 
3518    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3519           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3520           mkU64(0)));
3521 
3522    v1  = s390_vr_getVRindex(v1, 1, rxb);
3523    mnm = irgen(v1, op2addr, m3);
3524 
3525    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3526       s390_disasm(ENC3(MNM, VR, UDXB), mnm, v1, d2, x2, b2);
3527 }
3528 
3529 
3530 static void
3531 s390_format_VRR_VV(const HChar *(*irgen)(UChar v1, UChar v2),
3532                     UChar v1, UChar v2, UChar rxb)
3533 {
3534    const HChar *mnm;
3535 
3536    if (! s390_host_has_vx) {
3537       emulation_failure(EmFail_S390X_vx);
3538       return;
3539    }
3540 
3541    v1  = s390_vr_getVRindex(v1, 1, rxb);
3542    v2  = s390_vr_getVRindex(v2, 2, rxb);
3543    mnm = irgen(v1, v2);
3544 
3545    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3546       s390_disasm(ENC3(MNM, VR, VR), mnm, v1, v2);
3547 }
3548 
3549 
3550 static void
3551 s390_format_VRR_VVV(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3),
3552                     UChar v1, UChar v2, UChar v3, UChar rxb)
3553 {
3554    const HChar *mnm;
3555 
3556    if (! s390_host_has_vx) {
3557       emulation_failure(EmFail_S390X_vx);
3558       return;
3559    }
3560 
3561    v1  = s390_vr_getVRindex(v1, 1, rxb);
3562    v2  = s390_vr_getVRindex(v2, 2, rxb);
3563    v3  = s390_vr_getVRindex(v3, 3, rxb);
3564    mnm = irgen(v1, v2, v3);
3565 
3566    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3567       s390_disasm(ENC4(MNM, VR, VR, VR), mnm, v1, v2, v3);
3568 }
3569 
3570 
3571 static void
3572 s390_format_VRR_VVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m4),
3573                     UChar v1, UChar v2, UChar v3, UChar m4, UChar rxb)
3574 {
3575    const HChar *mnm;
3576 
3577    if (! s390_host_has_vx) {
3578       emulation_failure(EmFail_S390X_vx);
3579       return;
3580    }
3581 
3582    v1  = s390_vr_getVRindex(v1, 1, rxb);
3583    v2  = s390_vr_getVRindex(v2, 2, rxb);
3584    v3  = s390_vr_getVRindex(v3, 3, rxb);
3585    mnm = irgen(v1, v2, v3, m4);
3586 
3587    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3588       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), mnm, v1, v2, v3, m4);
3589 }
3590 
3591 
3592 static void
3593 s390_format_VRR_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5),
3594                     UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar rxb)
3595 {
3596    const HChar *mnm;
3597 
3598    if (! s390_host_has_vx) {
3599       emulation_failure(EmFail_S390X_vx);
3600       return;
3601    }
3602 
3603    v1  = s390_vr_getVRindex(v1, 1, rxb);
3604    v2  = s390_vr_getVRindex(v2, 2, rxb);
3605    v3  = s390_vr_getVRindex(v3, 3, rxb);
3606    mnm = irgen(v1, v2, v3, m4, m5);
3607 
3608    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3609       s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), mnm, v1, v2, v3, m4, m5);
3610 }
3611 
3612 
3613 static void
3614 s390_format_VRR_VVVV(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar v4),
3615                     UChar v1, UChar v2, UChar v3, UChar v4, UChar rxb)
3616 {
3617    const HChar *mnm;
3618 
3619    if (! s390_host_has_vx) {
3620       emulation_failure(EmFail_S390X_vx);
3621       return;
3622    }
3623 
3624    v1  = s390_vr_getVRindex(v1, 1, rxb);
3625    v2  = s390_vr_getVRindex(v2, 2, rxb);
3626    v3  = s390_vr_getVRindex(v3, 3, rxb);
3627    v4  = s390_vr_getVRindex(v4, 4, rxb);
3628    mnm = irgen(v1, v2, v3, v4);
3629 
3630    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3631       s390_disasm(ENC5(MNM, VR, VR, VR, VR), mnm, v1, v2, v3, v4);
3632 }
3633 
3634 
3635 static void
3636 s390_format_VRR_VRR(const HChar *(*irgen)(UChar v1, UChar r2, UChar r3),
3637                     UChar v1, UChar r2, UChar r3, UChar rxb)
3638 {
3639    const HChar *mnm;
3640 
3641    if (! s390_host_has_vx) {
3642       emulation_failure(EmFail_S390X_vx);
3643       return;
3644    }
3645 
3646    v1  = s390_vr_getVRindex(v1, 1, rxb);
3647    mnm = irgen(v1, r2, r3);
3648 
3649    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3650       s390_disasm(ENC4(MNM, VR, GPR, GPR), mnm, v1, r2, r3);
3651 }
3652 
3653 
3654 static void
3655 s390_format_VRR_VVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3),
3656                     UChar v1, UChar v2, UChar m3, UChar rxb)
3657 {
3658    const HChar *mnm;
3659 
3660    if (! s390_host_has_vx) {
3661       emulation_failure(EmFail_S390X_vx);
3662       return;
3663    }
3664 
3665    v1  = s390_vr_getVRindex(v1, 1, rxb);
3666    v2  = s390_vr_getVRindex(v2, 2, rxb);
3667    mnm = irgen(v1, v2, m3);
3668 
3669    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3670       s390_disasm(ENC4(MNM, VR, VR, UINT), mnm, v1, v2, m3);
3671 }
3672 
3673 
3674 static void
3675 s390_format_VRI_VIM(const HChar *(*irgen)(UChar v1, UShort i2, UChar m3),
3676                     UChar v1, UShort i2, UChar m3, UChar rxb)
3677 {
3678    const HChar *mnm;
3679 
3680    if (! s390_host_has_vx) {
3681       emulation_failure(EmFail_S390X_vx);
3682       return;
3683    }
3684 
3685    v1  = s390_vr_getVRindex(v1, 1, rxb);
3686    mnm = irgen(v1, i2, m3);
3687 
3688    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3689       s390_disasm(ENC4(MNM, VR, UINT, UINT), mnm, v1, i2, m3);
3690 }
3691 
3692 
3693 static void
3694 s390_format_VRI_VVIM(const HChar *(*irgen)(UChar v1, UChar v3, UShort i2, UChar m4),
3695                     UChar v1, UChar v3, UShort i2, UChar m4, UChar rxb)
3696 {
3697    const HChar *mnm;
3698 
3699    if (! s390_host_has_vx) {
3700       emulation_failure(EmFail_S390X_vx);
3701       return;
3702    }
3703 
3704    v1  = s390_vr_getVRindex(v1, 1, rxb);
3705    v3  = s390_vr_getVRindex(v3, 2, rxb);
3706    mnm = irgen(v1, v3, i2, m4);
3707 
3708    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3709       s390_disasm(ENC5(MNM, VR, VR, UINT, UINT), mnm, v1, v3, i2, m4);
3710 }
3711 
3712 static void
3713 s390_format_VRI_VVIMM(const HChar *(*irgen)(UChar v1, UChar v2, UShort i3,
3714                                             UChar m4, UChar m5),
3715                       UChar v1, UChar v2, UShort i3, UChar m4, UChar m5,
3716                       UChar rxb)
3717 {
3718    const HChar *mnm;
3719 
3720    if (!s390_host_has_vx) {
3721       emulation_failure(EmFail_S390X_vx);
3722       return;
3723    }
3724 
3725    v1 = s390_vr_getVRindex(v1, 1, rxb);
3726    v2 = s390_vr_getVRindex(v2, 2, rxb);
3727    mnm = irgen(v1, v2, i3, m4, m5);
3728 
3729    if (vex_traceflags & VEX_TRACE_FE)
3730       s390_disasm(ENC6(MNM, VR, VR, UINT, UINT, UINT), mnm, v1, v2, i3, m4, m5);
3731 }
3732 
3733 static void
3734 s390_format_VRS_RRDVM(const HChar *(*irgen)(UChar r1, IRTemp op2addr, UChar v3,
3735                       UChar m4), UChar r1, UChar b2, UShort d2, UChar v3,
3736                       UChar m4, UChar rxb)
3737 {
3738    const HChar *mnm;
3739    IRTemp op2addr = newTemp(Ity_I64);
3740 
3741    if (! s390_host_has_vx) {
3742       emulation_failure(EmFail_S390X_vx);
3743       return;
3744    }
3745 
3746    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3747           mkU64(0)));
3748 
3749    v3  = s390_vr_getVRindex(v3, 2, rxb);
3750    mnm = irgen(r1, op2addr, v3, m4);
3751 
3752    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3753       s390_disasm(ENC5(MNM, GPR, UDXB, VR, UINT), mnm, r1, d2, 0, b2, v3, m4);
3754 }
3755 
3756 
3757 static void
3758 s390_format_VRS_VRDVM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3,
3759                       UChar m4), UChar v1, UChar b2, UShort d2, UChar v3,
3760                       UChar m4, UChar rxb)
3761 {
3762    const HChar *mnm;
3763    IRTemp op2addr = newTemp(Ity_I64);
3764 
3765    if (! s390_host_has_vx) {
3766       emulation_failure(EmFail_S390X_vx);
3767       return;
3768    }
3769 
3770    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3771           mkU64(0)));
3772 
3773    v1  = s390_vr_getVRindex(v1, 1, rxb);
3774    v3  = s390_vr_getVRindex(v3, 2, rxb);
3775    mnm = irgen(v1, op2addr, v3, m4);
3776 
3777    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3778       s390_disasm(ENC5(MNM, VR, UDXB, VR, UINT), mnm, v1, d2, 0, b2, v3, m4);
3779 }
3780 
3781 
3782 static void
3783 s390_format_VRS_VRDV(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3),
3784                      UChar v1, UChar b2, UShort d2, UChar v3, UChar rxb)
3785 {
3786    const HChar *mnm;
3787    IRTemp op2addr = newTemp(Ity_I64);
3788 
3789    if (! s390_host_has_vx) {
3790       emulation_failure(EmFail_S390X_vx);
3791       return;
3792    }
3793 
3794    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3795           mkU64(0)));
3796 
3797    v1  = s390_vr_getVRindex(v1, 1, rxb);
3798    v3  = s390_vr_getVRindex(v3, 2, rxb);
3799    mnm = irgen(v1, op2addr, v3);
3800 
3801    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3802       s390_disasm(ENC4(MNM, VR, UDXB, VR), mnm, v1, d2, 0, b2, v3);
3803 }
3804 
3805 
3806 static void
3807 s390_format_VRS_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar r3,
3808                      UChar m4),
3809                      UChar v1, UChar b2, UShort d2, UChar r3, UChar m4, UChar rxb)
3810 {
3811    const HChar *mnm;
3812    IRTemp op2addr = newTemp(Ity_I64);
3813 
3814    if (! s390_host_has_vx) {
3815       emulation_failure(EmFail_S390X_vx);
3816       return;
3817    }
3818 
3819    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3820           mkU64(0)));
3821 
3822    v1  = s390_vr_getVRindex(v1, 1, rxb);
3823    mnm = irgen(v1, op2addr, r3, m4);
3824 
3825    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3826       s390_disasm(ENC5(MNM, VR, GPR, UDXB, UINT), mnm, v1, r3, d2, 0, b2, m4);
3827 }
3828 
3829 
3830 static void
3831 s390_format_VRS_VRRD(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar r3),
3832                      UChar v1, UChar b2, UShort d2, UChar r3, UChar rxb)
3833 {
3834    const HChar *mnm;
3835    IRTemp op2addr = newTemp(Ity_I64);
3836 
3837    if (! s390_host_has_vx) {
3838       emulation_failure(EmFail_S390X_vx);
3839       return;
3840    }
3841 
3842    assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3843           mkU64(0)));
3844 
3845    v1  = s390_vr_getVRindex(v1, 1, rxb);
3846    mnm = irgen(v1, op2addr, r3);
3847 
3848    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3849       s390_disasm(ENC4(MNM, VR, GPR, UDXB), mnm, v1, r3, d2, 0, b2);
3850 }
3851 
3852 
3853 static void
3854 s390_format_VRV_VVRDMT(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3),
3855                        UChar v1, UChar v2, UChar b2, UShort d2, UChar m3, UChar rxb,
3856                        IRType type)
3857 {
3858    const HChar *mnm;
3859    IRTemp op2addr = newTemp(Ity_I64);
3860 
3861    if (! s390_host_has_vx) {
3862       emulation_failure(EmFail_S390X_vx);
3863       return;
3864    }
3865 
3866    v1  = s390_vr_getVRindex(v1, 1, rxb);
3867    v2  = s390_vr_getVRindex(v2, 2, rxb);
3868 
3869    vassert(type == Ity_I32 || type == Ity_I64);
3870    IRExpr *x2;
3871    if(type == Ity_I32) {
3872       x2 = unop(Iop_32Uto64, get_vr(v2, type, m3));
3873    } else {
3874       x2 = get_vr(v2, type, m3);
3875    }
3876 
3877    assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3878           b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2));
3879 
3880    mnm = irgen(v1, op2addr, m3);
3881 
3882    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3883       s390_disasm(ENC4(MNM, VR, UDVB, UINT), mnm, v1, d2, v2, b2, m3);
3884 }
3885 
3886 
3887 static void
3888 s390_format_VRR_VVVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
3889                                               UChar v4, UChar m5, UChar m6),
3890                         UChar v1, UChar v2, UChar v3, UChar v4, UChar m5,
3891                         UChar m6, UChar rxb)
3892 {
3893    const HChar *mnm;
3894 
3895    if (! s390_host_has_vx) {
3896       emulation_failure(EmFail_S390X_vx);
3897       return;
3898    }
3899 
3900    v1  = s390_vr_getVRindex(v1, 1, rxb);
3901    v2  = s390_vr_getVRindex(v2, 2, rxb);
3902    v3  = s390_vr_getVRindex(v3, 3, rxb);
3903    v4  = s390_vr_getVRindex(v4, 4, rxb);
3904    mnm = irgen(v1, v2, v3, v4, m5, m6);
3905 
3906    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3907       s390_disasm(ENC7(MNM, VR, VR, VR, VR, UINT, UINT),
3908                   mnm, v1, v2, v3, v4, m5, m6);
3909 }
3910 
3911 
3912 static void
3913 s390_format_VRR_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3,
3914                                            UChar m5),
3915                      UChar v1, UChar v2, UChar m3, UChar m5, UChar rxb)
3916 {
3917    const HChar *mnm;
3918 
3919    if (! s390_host_has_vx) {
3920       emulation_failure(EmFail_S390X_vx);
3921       return;
3922    }
3923 
3924    v1  = s390_vr_getVRindex(v1, 1, rxb);
3925    v2  = s390_vr_getVRindex(v2, 2, rxb);
3926    mnm = irgen(v1, v2, m3, m5);
3927 
3928    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3929       s390_disasm(ENC5(MNM, VR, VR, UINT, UINT), mnm, v1, v2, m3, m5);
3930 }
3931 
3932 
3933 static void
3934 s390_format_VRId_VVVIM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
3935                                              UChar i4, UChar m5),
3936                        UChar v1, UChar v2, UChar v3, UChar i4, UChar m5,
3937                        UChar rxb)
3938 {
3939    const HChar *mnm;
3940 
3941    if (! s390_host_has_vx) {
3942       emulation_failure(EmFail_S390X_vx);
3943       return;
3944    }
3945 
3946    v1  = s390_vr_getVRindex(v1, 1, rxb);
3947    v2  = s390_vr_getVRindex(v2, 2, rxb);
3948    v3  = s390_vr_getVRindex(v3, 3, rxb);
3949    mnm = irgen(v1, v2, v3, i4, m5);
3950 
3951    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3952       s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), mnm, v1, v2, v3, i4, m5);
3953 }
3954 
3955 
3956 static void
3957 s390_format_VRId_VVVI(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
3958                                             UChar i4),
3959                       UChar v1, UChar v2, UChar v3, UChar i4, UChar rxb)
3960 {
3961    const HChar *mnm;
3962 
3963    if (! s390_host_has_vx) {
3964       emulation_failure(EmFail_S390X_vx);
3965       return;
3966    }
3967 
3968    v1  = s390_vr_getVRindex(v1, 1, rxb);
3969    v2  = s390_vr_getVRindex(v2, 2, rxb);
3970    v3  = s390_vr_getVRindex(v3, 3, rxb);
3971    mnm = irgen(v1, v2, v3, i4);
3972 
3973    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3974       s390_disasm(ENC5(MNM, VR, VR, VR, UINT), mnm, v1, v2, v3, i4);
3975 }
3976 
3977 
3978 static void
3979 s390_format_VRRd_VVVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
3980                                              UChar v4, UChar m5),
3981                        UChar v1, UChar v2, UChar v3, UChar v4, UChar m5,
3982                        UChar rxb)
3983 {
3984    const HChar *mnm;
3985 
3986    if (! s390_host_has_vx) {
3987       emulation_failure(EmFail_S390X_vx);
3988       return;
3989    }
3990 
3991    v1  = s390_vr_getVRindex(v1, 1, rxb);
3992    v2  = s390_vr_getVRindex(v2, 2, rxb);
3993    v3  = s390_vr_getVRindex(v3, 3, rxb);
3994    v4  = s390_vr_getVRindex(v4, 4, rxb);
3995    mnm = irgen(v1, v2, v3, v4, m5);
3996 
3997    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3998       s390_disasm(ENC6(MNM, VR, VR, VR, VR, UINT), mnm, v1, v2, v3, v4, m5);
3999 }
4000 
4001 
4002 static void
4003 s390_format_VRRa_VVMMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3,
4004                                              UChar m4, UChar m5),
4005                        UChar v1, UChar v2, UChar m3, UChar m4, UChar m5,
4006                        UChar rxb)
4007 {
4008    const HChar *mnm;
4009 
4010    if (!s390_host_has_vx) {
4011       emulation_failure(EmFail_S390X_vx);
4012       return;
4013    }
4014 
4015    v1 = s390_vr_getVRindex(v1, 1, rxb);
4016    v2 = s390_vr_getVRindex(v2, 2, rxb);
4017    mnm = irgen(v1, v2, m3, m4, m5);
4018 
4019    if (vex_traceflags & VEX_TRACE_FE)
4020       s390_disasm(ENC6(MNM, VR, VR, UINT, UINT, UINT), mnm, v1, v2, m3, m4, m5);
4021 }
4022 
4023 static void
4024 s390_format_VRRa_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
4025                                              UChar m4, UChar m5),
4026                        UChar v1, UChar v2, UChar v3, UChar m4, UChar m5,
4027                        UChar rxb)
4028 {
4029    const HChar *mnm;
4030 
4031    if (!s390_host_has_vx) {
4032       emulation_failure(EmFail_S390X_vx);
4033       return;
4034    }
4035 
4036    v1 = s390_vr_getVRindex(v1, 1, rxb);
4037    v2 = s390_vr_getVRindex(v2, 2, rxb);
4038    v3 = s390_vr_getVRindex(v3, 3, rxb);
4039    mnm = irgen(v1, v2, v3, m4, m5);
4040 
4041    if (vex_traceflags & VEX_TRACE_FE)
4042       s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), mnm, v1, v2, v3, m4, m5);
4043 }
4044 
4045 static void
4046 s390_format_VRRa_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3,
4047                                             UChar m4),
4048                        UChar v1, UChar v2, UChar m3, UChar m4, UChar rxb)
4049 {
4050    const HChar *mnm;
4051 
4052    if (!s390_host_has_vx) {
4053       emulation_failure(EmFail_S390X_vx);
4054       return;
4055    }
4056 
4057    v1 = s390_vr_getVRindex(v1, 1, rxb);
4058    v2 = s390_vr_getVRindex(v2, 2, rxb);
4059    mnm = irgen(v1, v2, m3, m4);
4060 
4061    if (vex_traceflags & VEX_TRACE_FE)
4062       s390_disasm(ENC5(MNM, VR, VR, UINT, UINT), mnm, v1, v2, m3, m4);
4063 }
4064 
4065 static void
4066 s390_format_VRRa_VVVMMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
4067                                               UChar m4, UChar m5, UChar m6),
4068                         UChar v1, UChar v2, UChar v3, UChar m4, UChar m5,
4069                         UChar m6, UChar rxb)
4070 {
4071    const HChar *mnm;
4072 
4073    if (!s390_host_has_vx) {
4074       emulation_failure(EmFail_S390X_vx);
4075       return;
4076    }
4077 
4078    v1 = s390_vr_getVRindex(v1, 1, rxb);
4079    v2 = s390_vr_getVRindex(v2, 2, rxb);
4080    v3 = s390_vr_getVRindex(v3, 3, rxb);
4081    mnm = irgen(v1, v2, v3, m4, m5, m6);
4082 
4083    if (vex_traceflags & VEX_TRACE_FE)
4084       s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT),
4085                   mnm, v1, v2, v3, m4, m5, m6);
4086 }
4087 
4088 /*------------------------------------------------------------*/
4089 /*--- Build IR for opcodes                                 ---*/
4090 /*------------------------------------------------------------*/
4091 
4092 static const HChar *
4093 s390_irgen_AR(UChar r1, UChar r2)
4094 {
4095    IRTemp op1 = newTemp(Ity_I32);
4096    IRTemp op2 = newTemp(Ity_I32);
4097    IRTemp result = newTemp(Ity_I32);
4098 
4099    assign(op1, get_gpr_w1(r1));
4100    assign(op2, get_gpr_w1(r2));
4101    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4102    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4103    put_gpr_w1(r1, mkexpr(result));
4104 
4105    return "ar";
4106 }
4107 
4108 static const HChar *
4109 s390_irgen_AGR(UChar r1, UChar r2)
4110 {
4111    IRTemp op1 = newTemp(Ity_I64);
4112    IRTemp op2 = newTemp(Ity_I64);
4113    IRTemp result = newTemp(Ity_I64);
4114 
4115    assign(op1, get_gpr_dw0(r1));
4116    assign(op2, get_gpr_dw0(r2));
4117    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4118    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
4119    put_gpr_dw0(r1, mkexpr(result));
4120 
4121    return "agr";
4122 }
4123 
4124 static const HChar *
4125 s390_irgen_AGFR(UChar r1, UChar r2)
4126 {
4127    IRTemp op1 = newTemp(Ity_I64);
4128    IRTemp op2 = newTemp(Ity_I64);
4129    IRTemp result = newTemp(Ity_I64);
4130 
4131    assign(op1, get_gpr_dw0(r1));
4132    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
4133    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4134    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
4135    put_gpr_dw0(r1, mkexpr(result));
4136 
4137    return "agfr";
4138 }
4139 
4140 static const HChar *
4141 s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
4142 {
4143    IRTemp op2 = newTemp(Ity_I32);
4144    IRTemp op3 = newTemp(Ity_I32);
4145    IRTemp result = newTemp(Ity_I32);
4146 
4147    assign(op2, get_gpr_w1(r2));
4148    assign(op3, get_gpr_w1(r3));
4149    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4150    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
4151    put_gpr_w1(r1, mkexpr(result));
4152 
4153    return "ark";
4154 }
4155 
4156 static const HChar *
4157 s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
4158 {
4159    IRTemp op2 = newTemp(Ity_I64);
4160    IRTemp op3 = newTemp(Ity_I64);
4161    IRTemp result = newTemp(Ity_I64);
4162 
4163    assign(op2, get_gpr_dw0(r2));
4164    assign(op3, get_gpr_dw0(r3));
4165    assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
4166    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
4167    put_gpr_dw0(r1, mkexpr(result));
4168 
4169    return "agrk";
4170 }
4171 
4172 static const HChar *
4173 s390_irgen_A(UChar r1, IRTemp op2addr)
4174 {
4175    IRTemp op1 = newTemp(Ity_I32);
4176    IRTemp op2 = newTemp(Ity_I32);
4177    IRTemp result = newTemp(Ity_I32);
4178 
4179    assign(op1, get_gpr_w1(r1));
4180    assign(op2, load(Ity_I32, mkexpr(op2addr)));
4181    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4182    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4183    put_gpr_w1(r1, mkexpr(result));
4184 
4185    return "a";
4186 }
4187 
4188 static const HChar *
4189 s390_irgen_AY(UChar r1, IRTemp op2addr)
4190 {
4191    IRTemp op1 = newTemp(Ity_I32);
4192    IRTemp op2 = newTemp(Ity_I32);
4193    IRTemp result = newTemp(Ity_I32);
4194 
4195    assign(op1, get_gpr_w1(r1));
4196    assign(op2, load(Ity_I32, mkexpr(op2addr)));
4197    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4198    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4199    put_gpr_w1(r1, mkexpr(result));
4200 
4201    return "ay";
4202 }
4203 
4204 static const HChar *
4205 s390_irgen_AG(UChar r1, IRTemp op2addr)
4206 {
4207    IRTemp op1 = newTemp(Ity_I64);
4208    IRTemp op2 = newTemp(Ity_I64);
4209    IRTemp result = newTemp(Ity_I64);
4210 
4211    assign(op1, get_gpr_dw0(r1));
4212    assign(op2, load(Ity_I64, mkexpr(op2addr)));
4213    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4214    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
4215    put_gpr_dw0(r1, mkexpr(result));
4216 
4217    return "ag";
4218 }
4219 
4220 static const HChar *
4221 s390_irgen_AGF(UChar r1, IRTemp op2addr)
4222 {
4223    IRTemp op1 = newTemp(Ity_I64);
4224    IRTemp op2 = newTemp(Ity_I64);
4225    IRTemp result = newTemp(Ity_I64);
4226 
4227    assign(op1, get_gpr_dw0(r1));
4228    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
4229    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4230    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
4231    put_gpr_dw0(r1, mkexpr(result));
4232 
4233    return "agf";
4234 }
4235 
4236 static const HChar *
4237 s390_irgen_AFI(UChar r1, UInt i2)
4238 {
4239    IRTemp op1 = newTemp(Ity_I32);
4240    Int op2;
4241    IRTemp result = newTemp(Ity_I32);
4242 
4243    assign(op1, get_gpr_w1(r1));
4244    op2 = (Int)i2;
4245    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
4246    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
4247                        mkU32((UInt)op2)));
4248    put_gpr_w1(r1, mkexpr(result));
4249 
4250    return "afi";
4251 }
4252 
4253 static const HChar *
4254 s390_irgen_AGFI(UChar r1, UInt i2)
4255 {
4256    IRTemp op1 = newTemp(Ity_I64);
4257    Long op2;
4258    IRTemp result = newTemp(Ity_I64);
4259 
4260    assign(op1, get_gpr_dw0(r1));
4261    op2 = (Long)(Int)i2;
4262    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
4263    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
4264                        mkU64((ULong)op2)));
4265    put_gpr_dw0(r1, mkexpr(result));
4266 
4267    return "agfi";
4268 }
4269 
4270 static const HChar *
4271 s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
4272 {
4273    Int op2;
4274    IRTemp op3 = newTemp(Ity_I32);
4275    IRTemp result = newTemp(Ity_I32);
4276 
4277    op2 = (Int)(Short)i2;
4278    assign(op3, get_gpr_w1(r3));
4279    assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
4280    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
4281                        op2)), op3);
4282    put_gpr_w1(r1, mkexpr(result));
4283 
4284    return "ahik";
4285 }
4286 
4287 static const HChar *
4288 s390_irgen_AGH(UChar r1, IRTemp op2addr)
4289 {
4290    IRTemp op1 = newTemp(Ity_I64);
4291    IRTemp op2 = newTemp(Ity_I64);
4292    IRTemp result = newTemp(Ity_I64);
4293 
4294    assign(op1, get_gpr_dw0(r1));
4295    assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4296    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4297    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
4298    put_gpr_dw0(r1, mkexpr(result));
4299 
4300    return "agh";
4301 }
4302 
4303 static const HChar *
4304 s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
4305 {
4306    Long op2;
4307    IRTemp op3 = newTemp(Ity_I64);
4308    IRTemp result = newTemp(Ity_I64);
4309 
4310    op2 = (Long)(Short)i2;
4311    assign(op3, get_gpr_dw0(r3));
4312    assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
4313    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
4314                        op2)), op3);
4315    put_gpr_dw0(r1, mkexpr(result));
4316 
4317    return "aghik";
4318 }
4319 
4320 static const HChar *
4321 s390_irgen_ASI(UChar i2, IRTemp op1addr)
4322 {
4323    IRTemp op1 = newTemp(Ity_I32);
4324    Int op2;
4325    IRTemp result = newTemp(Ity_I32);
4326 
4327    assign(op1, load(Ity_I32, mkexpr(op1addr)));
4328    op2 = (Int)(Char)i2;
4329    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
4330    store(mkexpr(op1addr), mkexpr(result));
4331    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
4332                        mkU32((UInt)op2)));
4333 
4334    return "asi";
4335 }
4336 
4337 static const HChar *
4338 s390_irgen_AGSI(UChar i2, IRTemp op1addr)
4339 {
4340    IRTemp op1 = newTemp(Ity_I64);
4341    Long op2;
4342    IRTemp result = newTemp(Ity_I64);
4343 
4344    assign(op1, load(Ity_I64, mkexpr(op1addr)));
4345    op2 = (Long)(Char)i2;
4346    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
4347    store(mkexpr(op1addr), mkexpr(result));
4348    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
4349                        mkU64((ULong)op2)));
4350 
4351    return "agsi";
4352 }
4353 
4354 static const HChar *
4355 s390_irgen_AH(UChar r1, IRTemp op2addr)
4356 {
4357    IRTemp op1 = newTemp(Ity_I32);
4358    IRTemp op2 = newTemp(Ity_I32);
4359    IRTemp result = newTemp(Ity_I32);
4360 
4361    assign(op1, get_gpr_w1(r1));
4362    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4363    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4364    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4365    put_gpr_w1(r1, mkexpr(result));
4366 
4367    return "ah";
4368 }
4369 
4370 static const HChar *
4371 s390_irgen_AHY(UChar r1, IRTemp op2addr)
4372 {
4373    IRTemp op1 = newTemp(Ity_I32);
4374    IRTemp op2 = newTemp(Ity_I32);
4375    IRTemp result = newTemp(Ity_I32);
4376 
4377    assign(op1, get_gpr_w1(r1));
4378    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4379    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4380    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4381    put_gpr_w1(r1, mkexpr(result));
4382 
4383    return "ahy";
4384 }
4385 
4386 static const HChar *
4387 s390_irgen_AHI(UChar r1, UShort i2)
4388 {
4389    IRTemp op1 = newTemp(Ity_I32);
4390    Int op2;
4391    IRTemp result = newTemp(Ity_I32);
4392 
4393    assign(op1, get_gpr_w1(r1));
4394    op2 = (Int)(Short)i2;
4395    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
4396    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
4397                        mkU32((UInt)op2)));
4398    put_gpr_w1(r1, mkexpr(result));
4399 
4400    return "ahi";
4401 }
4402 
4403 static const HChar *
4404 s390_irgen_AGHI(UChar r1, UShort i2)
4405 {
4406    IRTemp op1 = newTemp(Ity_I64);
4407    Long op2;
4408    IRTemp result = newTemp(Ity_I64);
4409 
4410    assign(op1, get_gpr_dw0(r1));
4411    op2 = (Long)(Short)i2;
4412    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
4413    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
4414                        mkU64((ULong)op2)));
4415    put_gpr_dw0(r1, mkexpr(result));
4416 
4417    return "aghi";
4418 }
4419 
4420 static const HChar *
4421 s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
4422 {
4423    IRTemp op2 = newTemp(Ity_I32);
4424    IRTemp op3 = newTemp(Ity_I32);
4425    IRTemp result = newTemp(Ity_I32);
4426 
4427    assign(op2, get_gpr_w0(r2));
4428    assign(op3, get_gpr_w0(r3));
4429    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4430    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
4431    put_gpr_w0(r1, mkexpr(result));
4432 
4433    return "ahhhr";
4434 }
4435 
4436 static const HChar *
4437 s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
4438 {
4439    IRTemp op2 = newTemp(Ity_I32);
4440    IRTemp op3 = newTemp(Ity_I32);
4441    IRTemp result = newTemp(Ity_I32);
4442 
4443    assign(op2, get_gpr_w0(r2));
4444    assign(op3, get_gpr_w1(r3));
4445    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4446    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
4447    put_gpr_w0(r1, mkexpr(result));
4448 
4449    return "ahhlr";
4450 }
4451 
4452 static const HChar *
4453 s390_irgen_AIH(UChar r1, UInt i2)
4454 {
4455    IRTemp op1 = newTemp(Ity_I32);
4456    Int op2;
4457    IRTemp result = newTemp(Ity_I32);
4458 
4459    assign(op1, get_gpr_w0(r1));
4460    op2 = (Int)i2;
4461    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
4462    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
4463                        mkU32((UInt)op2)));
4464    put_gpr_w0(r1, mkexpr(result));
4465 
4466    return "aih";
4467 }
4468 
4469 static const HChar *
4470 s390_irgen_ALR(UChar r1, UChar r2)
4471 {
4472    IRTemp op1 = newTemp(Ity_I32);
4473    IRTemp op2 = newTemp(Ity_I32);
4474    IRTemp result = newTemp(Ity_I32);
4475 
4476    assign(op1, get_gpr_w1(r1));
4477    assign(op2, get_gpr_w1(r2));
4478    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4479    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
4480    put_gpr_w1(r1, mkexpr(result));
4481 
4482    return "alr";
4483 }
4484 
4485 static const HChar *
4486 s390_irgen_ALGR(UChar r1, UChar r2)
4487 {
4488    IRTemp op1 = newTemp(Ity_I64);
4489    IRTemp op2 = newTemp(Ity_I64);
4490    IRTemp result = newTemp(Ity_I64);
4491 
4492    assign(op1, get_gpr_dw0(r1));
4493    assign(op2, get_gpr_dw0(r2));
4494    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4495    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
4496    put_gpr_dw0(r1, mkexpr(result));
4497 
4498    return "algr";
4499 }
4500 
4501 static const HChar *
4502 s390_irgen_ALGFR(UChar r1, UChar r2)
4503 {
4504    IRTemp op1 = newTemp(Ity_I64);
4505    IRTemp op2 = newTemp(Ity_I64);
4506    IRTemp result = newTemp(Ity_I64);
4507 
4508    assign(op1, get_gpr_dw0(r1));
4509    assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4510    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4511    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
4512    put_gpr_dw0(r1, mkexpr(result));
4513 
4514    return "algfr";
4515 }
4516 
4517 static const HChar *
4518 s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
4519 {
4520    IRTemp op2 = newTemp(Ity_I32);
4521    IRTemp op3 = newTemp(Ity_I32);
4522    IRTemp result = newTemp(Ity_I32);
4523 
4524    assign(op2, get_gpr_w1(r2));
4525    assign(op3, get_gpr_w1(r3));
4526    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4527    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
4528    put_gpr_w1(r1, mkexpr(result));
4529 
4530    return "alrk";
4531 }
4532 
4533 static const HChar *
4534 s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
4535 {
4536    IRTemp op2 = newTemp(Ity_I64);
4537    IRTemp op3 = newTemp(Ity_I64);
4538    IRTemp result = newTemp(Ity_I64);
4539 
4540    assign(op2, get_gpr_dw0(r2));
4541    assign(op3, get_gpr_dw0(r3));
4542    assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
4543    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
4544    put_gpr_dw0(r1, mkexpr(result));
4545 
4546    return "algrk";
4547 }
4548 
4549 static const HChar *
4550 s390_irgen_AL(UChar r1, IRTemp op2addr)
4551 {
4552    IRTemp op1 = newTemp(Ity_I32);
4553    IRTemp op2 = newTemp(Ity_I32);
4554    IRTemp result = newTemp(Ity_I32);
4555 
4556    assign(op1, get_gpr_w1(r1));
4557    assign(op2, load(Ity_I32, mkexpr(op2addr)));
4558    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4559    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
4560    put_gpr_w1(r1, mkexpr(result));
4561 
4562    return "al";
4563 }
4564 
4565 static const HChar *
4566 s390_irgen_ALY(UChar r1, IRTemp op2addr)
4567 {
4568    IRTemp op1 = newTemp(Ity_I32);
4569    IRTemp op2 = newTemp(Ity_I32);
4570    IRTemp result = newTemp(Ity_I32);
4571 
4572    assign(op1, get_gpr_w1(r1));
4573    assign(op2, load(Ity_I32, mkexpr(op2addr)));
4574    assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4575    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
4576    put_gpr_w1(r1, mkexpr(result));
4577 
4578    return "aly";
4579 }
4580 
4581 static const HChar *
4582 s390_irgen_ALG(UChar r1, IRTemp op2addr)
4583 {
4584    IRTemp op1 = newTemp(Ity_I64);
4585    IRTemp op2 = newTemp(Ity_I64);
4586    IRTemp result = newTemp(Ity_I64);
4587 
4588    assign(op1, get_gpr_dw0(r1));
4589    assign(op2, load(Ity_I64, mkexpr(op2addr)));
4590    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4591    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
4592    put_gpr_dw0(r1, mkexpr(result));
4593 
4594    return "alg";
4595 }
4596 
4597 static const HChar *
4598 s390_irgen_ALGF(UChar r1, IRTemp op2addr)
4599 {
4600    IRTemp op1 = newTemp(Ity_I64);
4601    IRTemp op2 = newTemp(Ity_I64);
4602    IRTemp result = newTemp(Ity_I64);
4603 
4604    assign(op1, get_gpr_dw0(r1));
4605    assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4606    assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4607    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
4608    put_gpr_dw0(r1, mkexpr(result));
4609 
4610    return "algf";
4611 }
4612 
4613 static const HChar *
4614 s390_irgen_ALFI(UChar r1, UInt i2)
4615 {
4616    IRTemp op1 = newTemp(Ity_I32);
4617    UInt op2;
4618    IRTemp result = newTemp(Ity_I32);
4619 
4620    assign(op1, get_gpr_w1(r1));
4621    op2 = i2;
4622    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
4623    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
4624                        mkU32(op2)));
4625    put_gpr_w1(r1, mkexpr(result));
4626 
4627    return "alfi";
4628 }
4629 
4630 static const HChar *
4631 s390_irgen_ALGFI(UChar r1, UInt i2)
4632 {
4633    IRTemp op1 = newTemp(Ity_I64);
4634    ULong op2;
4635    IRTemp result = newTemp(Ity_I64);
4636 
4637    assign(op1, get_gpr_dw0(r1));
4638    op2 = (ULong)i2;
4639    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
4640    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
4641                        mkU64(op2)));
4642    put_gpr_dw0(r1, mkexpr(result));
4643 
4644    return "algfi";
4645 }
4646 
4647 static const HChar *
4648 s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
4649 {
4650    IRTemp op2 = newTemp(Ity_I32);
4651    IRTemp op3 = newTemp(Ity_I32);
4652    IRTemp result = newTemp(Ity_I32);
4653 
4654    assign(op2, get_gpr_w0(r2));
4655    assign(op3, get_gpr_w0(r3));
4656    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4657    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
4658    put_gpr_w0(r1, mkexpr(result));
4659 
4660    return "alhhhr";
4661 }
4662 
4663 static const HChar *
4664 s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
4665 {
4666    IRTemp op2 = newTemp(Ity_I32);
4667    IRTemp op3 = newTemp(Ity_I32);
4668    IRTemp result = newTemp(Ity_I32);
4669 
4670    assign(op2, get_gpr_w0(r2));
4671    assign(op3, get_gpr_w1(r3));
4672    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4673    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
4674    put_gpr_w0(r1, mkexpr(result));
4675 
4676    return "alhhlr";
4677 }
4678 
4679 static const HChar *
4680 s390_irgen_ALCR(UChar r1, UChar r2)
4681 {
4682    IRTemp op1 = newTemp(Ity_I32);
4683    IRTemp op2 = newTemp(Ity_I32);
4684    IRTemp result = newTemp(Ity_I32);
4685    IRTemp carry_in = newTemp(Ity_I32);
4686 
4687    assign(op1, get_gpr_w1(r1));
4688    assign(op2, get_gpr_w1(r2));
4689    assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
4690    assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
4691           mkexpr(carry_in)));
4692    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
4693    put_gpr_w1(r1, mkexpr(result));
4694 
4695    return "alcr";
4696 }
4697 
4698 static const HChar *
4699 s390_irgen_ALCGR(UChar r1, UChar r2)
4700 {
4701    IRTemp op1 = newTemp(Ity_I64);
4702    IRTemp op2 = newTemp(Ity_I64);
4703    IRTemp result = newTemp(Ity_I64);
4704    IRTemp carry_in = newTemp(Ity_I64);
4705 
4706    assign(op1, get_gpr_dw0(r1));
4707    assign(op2, get_gpr_dw0(r2));
4708    assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
4709           mkU8(1))));
4710    assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
4711           mkexpr(carry_in)));
4712    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
4713    put_gpr_dw0(r1, mkexpr(result));
4714 
4715    return "alcgr";
4716 }
4717 
4718 static const HChar *
4719 s390_irgen_ALC(UChar r1, IRTemp op2addr)
4720 {
4721    IRTemp op1 = newTemp(Ity_I32);
4722    IRTemp op2 = newTemp(Ity_I32);
4723    IRTemp result = newTemp(Ity_I32);
4724    IRTemp carry_in = newTemp(Ity_I32);
4725 
4726    assign(op1, get_gpr_w1(r1));
4727    assign(op2, load(Ity_I32, mkexpr(op2addr)));
4728    assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
4729    assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
4730           mkexpr(carry_in)));
4731    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
4732    put_gpr_w1(r1, mkexpr(result));
4733 
4734    return "alc";
4735 }
4736 
4737 static const HChar *
4738 s390_irgen_ALCG(UChar r1, IRTemp op2addr)
4739 {
4740    IRTemp op1 = newTemp(Ity_I64);
4741    IRTemp op2 = newTemp(Ity_I64);
4742    IRTemp result = newTemp(Ity_I64);
4743    IRTemp carry_in = newTemp(Ity_I64);
4744 
4745    assign(op1, get_gpr_dw0(r1));
4746    assign(op2, load(Ity_I64, mkexpr(op2addr)));
4747    assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
4748           mkU8(1))));
4749    assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
4750           mkexpr(carry_in)));
4751    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
4752    put_gpr_dw0(r1, mkexpr(result));
4753 
4754    return "alcg";
4755 }
4756 
4757 static const HChar *
4758 s390_irgen_ALSI(UChar i2, IRTemp op1addr)
4759 {
4760    IRTemp op1 = newTemp(Ity_I32);
4761    UInt op2;
4762    IRTemp result = newTemp(Ity_I32);
4763 
4764    assign(op1, load(Ity_I32, mkexpr(op1addr)));
4765    op2 = (UInt)(Int)(Char)i2;
4766    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
4767    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
4768                        mkU32(op2)));
4769    store(mkexpr(op1addr), mkexpr(result));
4770 
4771    return "alsi";
4772 }
4773 
4774 static const HChar *
4775 s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
4776 {
4777    IRTemp op1 = newTemp(Ity_I64);
4778    ULong op2;
4779    IRTemp result = newTemp(Ity_I64);
4780 
4781    assign(op1, load(Ity_I64, mkexpr(op1addr)));
4782    op2 = (ULong)(Long)(Char)i2;
4783    assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
4784    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
4785                        mkU64(op2)));
4786    store(mkexpr(op1addr), mkexpr(result));
4787 
4788    return "algsi";
4789 }
4790 
4791 static const HChar *
4792 s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
4793 {
4794    UInt op2;
4795    IRTemp op3 = newTemp(Ity_I32);
4796    IRTemp result = newTemp(Ity_I32);
4797 
4798    op2 = (UInt)(Int)(Short)i2;
4799    assign(op3, get_gpr_w1(r3));
4800    assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
4801    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
4802                        op3);
4803    put_gpr_w1(r1, mkexpr(result));
4804 
4805    return "alhsik";
4806 }
4807 
4808 static const HChar *
4809 s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
4810 {
4811    ULong op2;
4812    IRTemp op3 = newTemp(Ity_I64);
4813    IRTemp result = newTemp(Ity_I64);
4814 
4815    op2 = (ULong)(Long)(Short)i2;
4816    assign(op3, get_gpr_dw0(r3));
4817    assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
4818    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
4819                        op3);
4820    put_gpr_dw0(r1, mkexpr(result));
4821 
4822    return "alghsik";
4823 }
4824 
4825 static const HChar *
4826 s390_irgen_ALSIH(UChar r1, UInt i2)
4827 {
4828    IRTemp op1 = newTemp(Ity_I32);
4829    UInt op2;
4830    IRTemp result = newTemp(Ity_I32);
4831 
4832    assign(op1, get_gpr_w0(r1));
4833    op2 = i2;
4834    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
4835    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
4836                        mkU32(op2)));
4837    put_gpr_w0(r1, mkexpr(result));
4838 
4839    return "alsih";
4840 }
4841 
4842 static const HChar *
4843 s390_irgen_ALSIHN(UChar r1, UInt i2)
4844 {
4845    IRTemp op1 = newTemp(Ity_I32);
4846    UInt op2;
4847    IRTemp result = newTemp(Ity_I32);
4848 
4849    assign(op1, get_gpr_w0(r1));
4850    op2 = i2;
4851    assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
4852    put_gpr_w0(r1, mkexpr(result));
4853 
4854    return "alsihn";
4855 }
4856 
4857 static const HChar *
4858 s390_irgen_NR(UChar r1, UChar r2)
4859 {
4860    IRTemp op1 = newTemp(Ity_I32);
4861    IRTemp op2 = newTemp(Ity_I32);
4862    IRTemp result = newTemp(Ity_I32);
4863 
4864    assign(op1, get_gpr_w1(r1));
4865    assign(op2, get_gpr_w1(r2));
4866    assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
4867    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4868    put_gpr_w1(r1, mkexpr(result));
4869 
4870    return "nr";
4871 }
4872 
4873 static const HChar *
4874 s390_irgen_NGR(UChar r1, UChar r2)
4875 {
4876    IRTemp op1 = newTemp(Ity_I64);
4877    IRTemp op2 = newTemp(Ity_I64);
4878    IRTemp result = newTemp(Ity_I64);
4879 
4880    assign(op1, get_gpr_dw0(r1));
4881    assign(op2, get_gpr_dw0(r2));
4882    assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
4883    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4884    put_gpr_dw0(r1, mkexpr(result));
4885 
4886    return "ngr";
4887 }
4888 
4889 static const HChar *
4890 s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
4891 {
4892    IRTemp op2 = newTemp(Ity_I32);
4893    IRTemp op3 = newTemp(Ity_I32);
4894    IRTemp result = newTemp(Ity_I32);
4895 
4896    assign(op2, get_gpr_w1(r2));
4897    assign(op3, get_gpr_w1(r3));
4898    assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
4899    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4900    put_gpr_w1(r1, mkexpr(result));
4901 
4902    return "nrk";
4903 }
4904 
4905 static const HChar *
4906 s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
4907 {
4908    IRTemp op2 = newTemp(Ity_I64);
4909    IRTemp op3 = newTemp(Ity_I64);
4910    IRTemp result = newTemp(Ity_I64);
4911 
4912    assign(op2, get_gpr_dw0(r2));
4913    assign(op3, get_gpr_dw0(r3));
4914    assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
4915    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4916    put_gpr_dw0(r1, mkexpr(result));
4917 
4918    return "ngrk";
4919 }
4920 
4921 static const HChar *
4922 s390_irgen_N(UChar r1, IRTemp op2addr)
4923 {
4924    IRTemp op1 = newTemp(Ity_I32);
4925    IRTemp op2 = newTemp(Ity_I32);
4926    IRTemp result = newTemp(Ity_I32);
4927 
4928    assign(op1, get_gpr_w1(r1));
4929    assign(op2, load(Ity_I32, mkexpr(op2addr)));
4930    assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
4931    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4932    put_gpr_w1(r1, mkexpr(result));
4933 
4934    return "n";
4935 }
4936 
4937 static const HChar *
4938 s390_irgen_NY(UChar r1, IRTemp op2addr)
4939 {
4940    IRTemp op1 = newTemp(Ity_I32);
4941    IRTemp op2 = newTemp(Ity_I32);
4942    IRTemp result = newTemp(Ity_I32);
4943 
4944    assign(op1, get_gpr_w1(r1));
4945    assign(op2, load(Ity_I32, mkexpr(op2addr)));
4946    assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
4947    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4948    put_gpr_w1(r1, mkexpr(result));
4949 
4950    return "ny";
4951 }
4952 
4953 static const HChar *
4954 s390_irgen_NG(UChar r1, IRTemp op2addr)
4955 {
4956    IRTemp op1 = newTemp(Ity_I64);
4957    IRTemp op2 = newTemp(Ity_I64);
4958    IRTemp result = newTemp(Ity_I64);
4959 
4960    assign(op1, get_gpr_dw0(r1));
4961    assign(op2, load(Ity_I64, mkexpr(op2addr)));
4962    assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
4963    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4964    put_gpr_dw0(r1, mkexpr(result));
4965 
4966    return "ng";
4967 }
4968 
4969 static const HChar *
4970 s390_irgen_NI(UChar i2, IRTemp op1addr)
4971 {
4972    IRTemp op1 = newTemp(Ity_I8);
4973    UChar op2;
4974    IRTemp result = newTemp(Ity_I8);
4975 
4976    assign(op1, load(Ity_I8, mkexpr(op1addr)));
4977    op2 = i2;
4978    assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
4979    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4980    store(mkexpr(op1addr), mkexpr(result));
4981 
4982    return "ni";
4983 }
4984 
4985 static const HChar *
4986 s390_irgen_NIY(UChar i2, IRTemp op1addr)
4987 {
4988    IRTemp op1 = newTemp(Ity_I8);
4989    UChar op2;
4990    IRTemp result = newTemp(Ity_I8);
4991 
4992    assign(op1, load(Ity_I8, mkexpr(op1addr)));
4993    op2 = i2;
4994    assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
4995    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4996    store(mkexpr(op1addr), mkexpr(result));
4997 
4998    return "niy";
4999 }
5000 
5001 static const HChar *
5002 s390_irgen_NIHF(UChar r1, UInt i2)
5003 {
5004    IRTemp op1 = newTemp(Ity_I32);
5005    UInt op2;
5006    IRTemp result = newTemp(Ity_I32);
5007 
5008    assign(op1, get_gpr_w0(r1));
5009    op2 = i2;
5010    assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
5011    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5012    put_gpr_w0(r1, mkexpr(result));
5013 
5014    return "nihf";
5015 }
5016 
5017 static const HChar *
5018 s390_irgen_NIHH(UChar r1, UShort i2)
5019 {
5020    IRTemp op1 = newTemp(Ity_I16);
5021    UShort op2;
5022    IRTemp result = newTemp(Ity_I16);
5023 
5024    assign(op1, get_gpr_hw0(r1));
5025    op2 = i2;
5026    assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
5027    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5028    put_gpr_hw0(r1, mkexpr(result));
5029 
5030    return "nihh";
5031 }
5032 
5033 static const HChar *
5034 s390_irgen_NIHL(UChar r1, UShort i2)
5035 {
5036    IRTemp op1 = newTemp(Ity_I16);
5037    UShort op2;
5038    IRTemp result = newTemp(Ity_I16);
5039 
5040    assign(op1, get_gpr_hw1(r1));
5041    op2 = i2;
5042    assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
5043    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5044    put_gpr_hw1(r1, mkexpr(result));
5045 
5046    return "nihl";
5047 }
5048 
5049 static const HChar *
5050 s390_irgen_NILF(UChar r1, UInt i2)
5051 {
5052    IRTemp op1 = newTemp(Ity_I32);
5053    UInt op2;
5054    IRTemp result = newTemp(Ity_I32);
5055 
5056    assign(op1, get_gpr_w1(r1));
5057    op2 = i2;
5058    assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
5059    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5060    put_gpr_w1(r1, mkexpr(result));
5061 
5062    return "nilf";
5063 }
5064 
5065 static const HChar *
5066 s390_irgen_NILH(UChar r1, UShort i2)
5067 {
5068    IRTemp op1 = newTemp(Ity_I16);
5069    UShort op2;
5070    IRTemp result = newTemp(Ity_I16);
5071 
5072    assign(op1, get_gpr_hw2(r1));
5073    op2 = i2;
5074    assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
5075    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5076    put_gpr_hw2(r1, mkexpr(result));
5077 
5078    return "nilh";
5079 }
5080 
5081 static const HChar *
5082 s390_irgen_NILL(UChar r1, UShort i2)
5083 {
5084    IRTemp op1 = newTemp(Ity_I16);
5085    UShort op2;
5086    IRTemp result = newTemp(Ity_I16);
5087 
5088    assign(op1, get_gpr_hw3(r1));
5089    op2 = i2;
5090    assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
5091    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5092    put_gpr_hw3(r1, mkexpr(result));
5093 
5094    return "nill";
5095 }
5096 
5097 static const HChar *
5098 s390_irgen_BASR(UChar r1, UChar r2)
5099 {
5100    IRTemp target = newTemp(Ity_I64);
5101 
5102    if (r2 == 0) {
5103       put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
5104    } else {
5105       if (r1 != r2) {
5106          put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
5107          call_function(get_gpr_dw0(r2));
5108       } else {
5109          assign(target, get_gpr_dw0(r2));
5110          put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
5111          call_function(mkexpr(target));
5112       }
5113    }
5114 
5115    return "basr";
5116 }
5117 
5118 static const HChar *
5119 s390_irgen_BAS(UChar r1, IRTemp op2addr)
5120 {
5121    IRTemp target = newTemp(Ity_I64);
5122 
5123    put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
5124    assign(target, mkexpr(op2addr));
5125    call_function(mkexpr(target));
5126 
5127    return "bas";
5128 }
5129 
5130 static const HChar *
5131 s390_irgen_BCR(UChar r1, UChar r2)
5132 {
5133    IRTemp cond = newTemp(Ity_I32);
5134 
5135    if (r2 == 0 && (r1 >= 14)) {    /* serialization */
5136       stmt(IRStmt_MBE(Imbe_Fence));
5137    }
5138 
5139    if ((r2 == 0) || (r1 == 0)) {
5140    } else {
5141       if (r1 == 15) {
5142          return_from_function(get_gpr_dw0(r2));
5143       } else {
5144          assign(cond, s390_call_calculate_cond(r1));
5145          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5146                                     get_gpr_dw0(r2));
5147       }
5148    }
5149    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5150       s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
5151 
5152    return "bcr";
5153 }
5154 
5155 static const HChar *
5156 s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
5157 {
5158    IRTemp cond = newTemp(Ity_I32);
5159 
5160    if (r1 == 0) {
5161    } else {
5162       if (r1 == 15) {
5163          always_goto(mkexpr(op2addr));
5164       } else {
5165          assign(cond, s390_call_calculate_cond(r1));
5166          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5167                                     mkexpr(op2addr));
5168       }
5169    }
5170    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5171       s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
5172 
5173    return "bc";
5174 }
5175 
5176 static const HChar *
5177 s390_irgen_BCTR(UChar r1, UChar r2)
5178 {
5179    put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
5180    if (r2 != 0) {
5181       if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
5182                                  get_gpr_dw0(r2));
5183    }
5184 
5185    return "bctr";
5186 }
5187 
5188 static const HChar *
5189 s390_irgen_BCTGR(UChar r1, UChar r2)
5190 {
5191    put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
5192    if (r2 != 0) {
5193       if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
5194                                  get_gpr_dw0(r2));
5195    }
5196 
5197    return "bctgr";
5198 }
5199 
5200 static const HChar *
5201 s390_irgen_BCT(UChar r1, IRTemp op2addr)
5202 {
5203    put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
5204    if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
5205                               mkexpr(op2addr));
5206 
5207    return "bct";
5208 }
5209 
5210 static const HChar *
5211 s390_irgen_BCTG(UChar r1, IRTemp op2addr)
5212 {
5213    put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
5214    if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
5215                               mkexpr(op2addr));
5216 
5217    return "bctg";
5218 }
5219 
5220 static const HChar *
5221 s390_irgen_BIC(UChar r1, IRTemp op2addr)
5222 {
5223    IRTemp cond = newTemp(Ity_I32);
5224 
5225    if (r1 == 0) {
5226       /* nothing */
5227    } else if (r1 == 15) {
5228       always_goto(load(Ity_I64, mkexpr(op2addr)));
5229    } else {
5230       assign(cond, s390_call_calculate_cond(r1));
5231       if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5232                                  load(Ity_I64, mkexpr(op2addr)));
5233    }
5234 
5235    return "bic";
5236 }
5237 
5238 static const HChar *
5239 s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
5240 {
5241    IRTemp value = newTemp(Ity_I32);
5242 
5243    assign(value, get_gpr_w1(r3 | 1));
5244    put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
5245    if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
5246                                     get_gpr_w1(r1)), mkexpr(op2addr));
5247 
5248    return "bxh";
5249 }
5250 
5251 static const HChar *
5252 s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
5253 {
5254    IRTemp value = newTemp(Ity_I64);
5255 
5256    assign(value, get_gpr_dw0(r3 | 1));
5257    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
5258    if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
5259                                     get_gpr_dw0(r1)), mkexpr(op2addr));
5260 
5261    return "bxhg";
5262 }
5263 
5264 static const HChar *
5265 s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
5266 {
5267    IRTemp value = newTemp(Ity_I32);
5268 
5269    assign(value, get_gpr_w1(r3 | 1));
5270    put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
5271    if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
5272                                     mkexpr(value)), mkexpr(op2addr));
5273 
5274    return "bxle";
5275 }
5276 
5277 static const HChar *
5278 s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
5279 {
5280    IRTemp value = newTemp(Ity_I64);
5281 
5282    assign(value, get_gpr_dw0(r3 | 1));
5283    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
5284    if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
5285                                     mkexpr(value)), mkexpr(op2addr));
5286 
5287    return "bxleg";
5288 }
5289 
5290 static const HChar *
5291 s390_irgen_BRAS(UChar r1, UShort i2)
5292 {
5293    put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
5294    call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5295 
5296    return "bras";
5297 }
5298 
5299 static const HChar *
5300 s390_irgen_BRASL(UChar r1, UInt i2)
5301 {
5302    put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
5303    call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
5304 
5305    return "brasl";
5306 }
5307 
5308 static const HChar *
5309 s390_irgen_BRC(UChar r1, UShort i2)
5310 {
5311    IRTemp cond = newTemp(Ity_I32);
5312 
5313    if (r1 == 0) {
5314    } else {
5315       if (r1 == 15) {
5316          always_goto_and_chase(
5317                guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5318       } else {
5319          assign(cond, s390_call_calculate_cond(r1));
5320          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5321                            guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5322 
5323       }
5324    }
5325    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5326       s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
5327 
5328    return "brc";
5329 }
5330 
5331 static const HChar *
5332 s390_irgen_BRCL(UChar r1, UInt i2)
5333 {
5334    IRTemp cond = newTemp(Ity_I32);
5335 
5336    if (r1 == 0) {
5337    } else {
5338       if (r1 == 15) {
5339          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
5340       } else {
5341          assign(cond, s390_call_calculate_cond(r1));
5342          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5343                            guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
5344       }
5345    }
5346    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5347       s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
5348 
5349    return "brcl";
5350 }
5351 
5352 static const HChar *
5353 s390_irgen_BRCT(UChar r1, UShort i2)
5354 {
5355    put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
5356    if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
5357                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5358 
5359    return "brct";
5360 }
5361 
5362 static const HChar *
5363 s390_irgen_BRCTH(UChar r1, UInt i2)
5364 {
5365    put_gpr_w0(r1, binop(Iop_Sub32, get_gpr_w0(r1), mkU32(1)));
5366    if_condition_goto(binop(Iop_CmpNE32, get_gpr_w0(r1), mkU32(0)),
5367                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5368 
5369    return "brcth";
5370 }
5371 
5372 static const HChar *
5373 s390_irgen_BRCTG(UChar r1, UShort i2)
5374 {
5375    put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
5376    if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
5377                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5378 
5379    return "brctg";
5380 }
5381 
5382 static const HChar *
5383 s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
5384 {
5385    IRTemp value = newTemp(Ity_I32);
5386 
5387    assign(value, get_gpr_w1(r3 | 1));
5388    put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
5389    if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
5390                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5391 
5392    return "brxh";
5393 }
5394 
5395 static const HChar *
5396 s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
5397 {
5398    IRTemp value = newTemp(Ity_I64);
5399 
5400    assign(value, get_gpr_dw0(r3 | 1));
5401    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
5402    if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
5403                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5404 
5405    return "brxhg";
5406 }
5407 
5408 static const HChar *
5409 s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
5410 {
5411    IRTemp value = newTemp(Ity_I32);
5412 
5413    assign(value, get_gpr_w1(r3 | 1));
5414    put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
5415    if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
5416                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5417 
5418    return "brxle";
5419 }
5420 
5421 static const HChar *
5422 s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
5423 {
5424    IRTemp value = newTemp(Ity_I64);
5425 
5426    assign(value, get_gpr_dw0(r3 | 1));
5427    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
5428    if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
5429                      guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
5430 
5431    return "brxlg";
5432 }
5433 
5434 static const HChar *
5435 s390_irgen_CR(UChar r1, UChar r2)
5436 {
5437    IRTemp op1 = newTemp(Ity_I32);
5438    IRTemp op2 = newTemp(Ity_I32);
5439 
5440    assign(op1, get_gpr_w1(r1));
5441    assign(op2, get_gpr_w1(r2));
5442    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5443 
5444    return "cr";
5445 }
5446 
5447 static const HChar *
5448 s390_irgen_CGR(UChar r1, UChar r2)
5449 {
5450    IRTemp op1 = newTemp(Ity_I64);
5451    IRTemp op2 = newTemp(Ity_I64);
5452 
5453    assign(op1, get_gpr_dw0(r1));
5454    assign(op2, get_gpr_dw0(r2));
5455    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5456 
5457    return "cgr";
5458 }
5459 
5460 static const HChar *
5461 s390_irgen_CGFR(UChar r1, UChar r2)
5462 {
5463    IRTemp op1 = newTemp(Ity_I64);
5464    IRTemp op2 = newTemp(Ity_I64);
5465 
5466    assign(op1, get_gpr_dw0(r1));
5467    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5468    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5469 
5470    return "cgfr";
5471 }
5472 
5473 static const HChar *
5474 s390_irgen_C(UChar r1, IRTemp op2addr)
5475 {
5476    IRTemp op1 = newTemp(Ity_I32);
5477    IRTemp op2 = newTemp(Ity_I32);
5478 
5479    assign(op1, get_gpr_w1(r1));
5480    assign(op2, load(Ity_I32, mkexpr(op2addr)));
5481    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5482 
5483    return "c";
5484 }
5485 
5486 static const HChar *
5487 s390_irgen_CY(UChar r1, IRTemp op2addr)
5488 {
5489    IRTemp op1 = newTemp(Ity_I32);
5490    IRTemp op2 = newTemp(Ity_I32);
5491 
5492    assign(op1, get_gpr_w1(r1));
5493    assign(op2, load(Ity_I32, mkexpr(op2addr)));
5494    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5495 
5496    return "cy";
5497 }
5498 
5499 static const HChar *
5500 s390_irgen_CG(UChar r1, IRTemp op2addr)
5501 {
5502    IRTemp op1 = newTemp(Ity_I64);
5503    IRTemp op2 = newTemp(Ity_I64);
5504 
5505    assign(op1, get_gpr_dw0(r1));
5506    assign(op2, load(Ity_I64, mkexpr(op2addr)));
5507    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5508 
5509    return "cg";
5510 }
5511 
5512 static const HChar *
5513 s390_irgen_CGF(UChar r1, IRTemp op2addr)
5514 {
5515    IRTemp op1 = newTemp(Ity_I64);
5516    IRTemp op2 = newTemp(Ity_I64);
5517 
5518    assign(op1, get_gpr_dw0(r1));
5519    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5520    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5521 
5522    return "cgf";
5523 }
5524 
5525 static const HChar *
5526 s390_irgen_CFI(UChar r1, UInt i2)
5527 {
5528    IRTemp op1 = newTemp(Ity_I32);
5529    Int op2;
5530 
5531    assign(op1, get_gpr_w1(r1));
5532    op2 = (Int)i2;
5533    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
5534                        mkU32((UInt)op2)));
5535 
5536    return "cfi";
5537 }
5538 
5539 static const HChar *
5540 s390_irgen_CGFI(UChar r1, UInt i2)
5541 {
5542    IRTemp op1 = newTemp(Ity_I64);
5543    Long op2;
5544 
5545    assign(op1, get_gpr_dw0(r1));
5546    op2 = (Long)(Int)i2;
5547    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
5548                        mkU64((ULong)op2)));
5549 
5550    return "cgfi";
5551 }
5552 
5553 static const HChar *
5554 s390_irgen_CRL(UChar r1, UInt i2)
5555 {
5556    IRTemp op1 = newTemp(Ity_I32);
5557    IRTemp op2 = newTemp(Ity_I32);
5558 
5559    assign(op1, get_gpr_w1(r1));
5560    assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5561           i2 << 1))));
5562    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5563 
5564    return "crl";
5565 }
5566 
5567 static const HChar *
5568 s390_irgen_CGRL(UChar r1, UInt i2)
5569 {
5570    IRTemp op1 = newTemp(Ity_I64);
5571    IRTemp op2 = newTemp(Ity_I64);
5572 
5573    assign(op1, get_gpr_dw0(r1));
5574    assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5575           i2 << 1))));
5576    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5577 
5578    return "cgrl";
5579 }
5580 
5581 static const HChar *
5582 s390_irgen_CGFRL(UChar r1, UInt i2)
5583 {
5584    IRTemp op1 = newTemp(Ity_I64);
5585    IRTemp op2 = newTemp(Ity_I64);
5586 
5587    assign(op1, get_gpr_dw0(r1));
5588    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5589           ((ULong)(Long)(Int)i2 << 1)))));
5590    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5591 
5592    return "cgfrl";
5593 }
5594 
5595 static const HChar *
5596 s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
5597 {
5598    IRTemp op1 = newTemp(Ity_I32);
5599    IRTemp op2 = newTemp(Ity_I32);
5600    IRTemp cond = newTemp(Ity_I32);
5601 
5602    if (m3 == 0) {
5603    } else {
5604       if (m3 == 14) {
5605          always_goto(mkexpr(op4addr));
5606       } else {
5607          assign(op1, get_gpr_w1(r1));
5608          assign(op2, get_gpr_w1(r2));
5609          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
5610                                               op1, op2));
5611          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
5612                                           mkU32(0)), mkexpr(op4addr));
5613       }
5614    }
5615 
5616    return "crb";
5617 }
5618 
5619 static const HChar *
5620 s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
5621 {
5622    IRTemp op1 = newTemp(Ity_I64);
5623    IRTemp op2 = newTemp(Ity_I64);
5624    IRTemp cond = newTemp(Ity_I32);
5625 
5626    if (m3 == 0) {
5627    } else {
5628       if (m3 == 14) {
5629          always_goto(mkexpr(op4addr));
5630       } else {
5631          assign(op1, get_gpr_dw0(r1));
5632          assign(op2, get_gpr_dw0(r2));
5633          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
5634                                               op1, op2));
5635          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
5636                                           mkU32(0)), mkexpr(op4addr));
5637       }
5638    }
5639 
5640    return "cgrb";
5641 }
5642 
5643 static const HChar *
5644 s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
5645 {
5646    IRTemp op1 = newTemp(Ity_I32);
5647    IRTemp op2 = newTemp(Ity_I32);
5648    IRTemp cond = newTemp(Ity_I32);
5649 
5650    if (m3 == 0) {
5651    } else {
5652       if (m3 == 14) {
5653          always_goto_and_chase(
5654                 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5655       } else {
5656          assign(op1, get_gpr_w1(r1));
5657          assign(op2, get_gpr_w1(r2));
5658          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
5659                                               op1, op2));
5660          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5661                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5662 
5663       }
5664    }
5665 
5666    return "crj";
5667 }
5668 
5669 static const HChar *
5670 s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
5671 {
5672    IRTemp op1 = newTemp(Ity_I64);
5673    IRTemp op2 = newTemp(Ity_I64);
5674    IRTemp cond = newTemp(Ity_I32);
5675 
5676    if (m3 == 0) {
5677    } else {
5678       if (m3 == 14) {
5679          always_goto_and_chase(
5680                 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5681       } else {
5682          assign(op1, get_gpr_dw0(r1));
5683          assign(op2, get_gpr_dw0(r2));
5684          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
5685                                               op1, op2));
5686          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5687                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5688 
5689       }
5690    }
5691 
5692    return "cgrj";
5693 }
5694 
5695 static const HChar *
5696 s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
5697 {
5698    IRTemp op1 = newTemp(Ity_I32);
5699    Int op2;
5700    IRTemp cond = newTemp(Ity_I32);
5701 
5702    if (m3 == 0) {
5703    } else {
5704       if (m3 == 14) {
5705          always_goto(mkexpr(op4addr));
5706       } else {
5707          assign(op1, get_gpr_w1(r1));
5708          op2 = (Int)(Char)i2;
5709          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
5710                                               mktemp(Ity_I32, mkU32((UInt)op2))));
5711          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5712                                     mkexpr(op4addr));
5713       }
5714    }
5715 
5716    return "cib";
5717 }
5718 
5719 static const HChar *
5720 s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
5721 {
5722    IRTemp op1 = newTemp(Ity_I64);
5723    Long op2;
5724    IRTemp cond = newTemp(Ity_I32);
5725 
5726    if (m3 == 0) {
5727    } else {
5728       if (m3 == 14) {
5729          always_goto(mkexpr(op4addr));
5730       } else {
5731          assign(op1, get_gpr_dw0(r1));
5732          op2 = (Long)(Char)i2;
5733          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
5734                                               mktemp(Ity_I64, mkU64((ULong)op2))));
5735          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5736                                     mkexpr(op4addr));
5737       }
5738    }
5739 
5740    return "cgib";
5741 }
5742 
5743 static const HChar *
5744 s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
5745 {
5746    IRTemp op1 = newTemp(Ity_I32);
5747    Int op2;
5748    IRTemp cond = newTemp(Ity_I32);
5749 
5750    if (m3 == 0) {
5751    } else {
5752       if (m3 == 14) {
5753          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5754       } else {
5755          assign(op1, get_gpr_w1(r1));
5756          op2 = (Int)(Char)i2;
5757          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
5758                                               mktemp(Ity_I32, mkU32((UInt)op2))));
5759          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5760                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5761 
5762       }
5763    }
5764 
5765    return "cij";
5766 }
5767 
5768 static const HChar *
5769 s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
5770 {
5771    IRTemp op1 = newTemp(Ity_I64);
5772    Long op2;
5773    IRTemp cond = newTemp(Ity_I32);
5774 
5775    if (m3 == 0) {
5776    } else {
5777       if (m3 == 14) {
5778          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5779       } else {
5780          assign(op1, get_gpr_dw0(r1));
5781          op2 = (Long)(Char)i2;
5782          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
5783                                               mktemp(Ity_I64, mkU64((ULong)op2))));
5784          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5785                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
5786 
5787       }
5788    }
5789 
5790    return "cgij";
5791 }
5792 
5793 static const HChar *
5794 s390_irgen_CH(UChar r1, IRTemp op2addr)
5795 {
5796    IRTemp op1 = newTemp(Ity_I32);
5797    IRTemp op2 = newTemp(Ity_I32);
5798 
5799    assign(op1, get_gpr_w1(r1));
5800    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5801    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5802 
5803    return "ch";
5804 }
5805 
5806 static const HChar *
5807 s390_irgen_CHY(UChar r1, IRTemp op2addr)
5808 {
5809    IRTemp op1 = newTemp(Ity_I32);
5810    IRTemp op2 = newTemp(Ity_I32);
5811 
5812    assign(op1, get_gpr_w1(r1));
5813    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5814    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5815 
5816    return "chy";
5817 }
5818 
5819 static const HChar *
5820 s390_irgen_CGH(UChar r1, IRTemp op2addr)
5821 {
5822    IRTemp op1 = newTemp(Ity_I64);
5823    IRTemp op2 = newTemp(Ity_I64);
5824 
5825    assign(op1, get_gpr_dw0(r1));
5826    assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5827    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5828 
5829    return "cgh";
5830 }
5831 
5832 static const HChar *
5833 s390_irgen_CHI(UChar r1, UShort i2)
5834 {
5835    IRTemp op1 = newTemp(Ity_I32);
5836    Int op2;
5837 
5838    assign(op1, get_gpr_w1(r1));
5839    op2 = (Int)(Short)i2;
5840    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
5841                        mkU32((UInt)op2)));
5842 
5843    return "chi";
5844 }
5845 
5846 static const HChar *
5847 s390_irgen_CGHI(UChar r1, UShort i2)
5848 {
5849    IRTemp op1 = newTemp(Ity_I64);
5850    Long op2;
5851 
5852    assign(op1, get_gpr_dw0(r1));
5853    op2 = (Long)(Short)i2;
5854    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
5855                        mkU64((ULong)op2)));
5856 
5857    return "cghi";
5858 }
5859 
5860 static const HChar *
5861 s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
5862 {
5863    IRTemp op1 = newTemp(Ity_I16);
5864    Short op2;
5865 
5866    assign(op1, load(Ity_I16, mkexpr(op1addr)));
5867    op2 = (Short)i2;
5868    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
5869                        mkU16((UShort)op2)));
5870 
5871    return "chhsi";
5872 }
5873 
5874 static const HChar *
5875 s390_irgen_CHSI(UShort i2, IRTemp op1addr)
5876 {
5877    IRTemp op1 = newTemp(Ity_I32);
5878    Int op2;
5879 
5880    assign(op1, load(Ity_I32, mkexpr(op1addr)));
5881    op2 = (Int)(Short)i2;
5882    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
5883                        mkU32((UInt)op2)));
5884 
5885    return "chsi";
5886 }
5887 
5888 static const HChar *
5889 s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
5890 {
5891    IRTemp op1 = newTemp(Ity_I64);
5892    Long op2;
5893 
5894    assign(op1, load(Ity_I64, mkexpr(op1addr)));
5895    op2 = (Long)(Short)i2;
5896    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
5897                        mkU64((ULong)op2)));
5898 
5899    return "cghsi";
5900 }
5901 
5902 static const HChar *
5903 s390_irgen_CHRL(UChar r1, UInt i2)
5904 {
5905    IRTemp op1 = newTemp(Ity_I32);
5906    IRTemp op2 = newTemp(Ity_I32);
5907 
5908    assign(op1, get_gpr_w1(r1));
5909    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5910           ((ULong)(Long)(Int)i2 << 1)))));
5911    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5912 
5913    return "chrl";
5914 }
5915 
5916 static const HChar *
5917 s390_irgen_CGHRL(UChar r1, UInt i2)
5918 {
5919    IRTemp op1 = newTemp(Ity_I64);
5920    IRTemp op2 = newTemp(Ity_I64);
5921 
5922    assign(op1, get_gpr_dw0(r1));
5923    assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5924           ((ULong)(Long)(Int)i2 << 1)))));
5925    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5926 
5927    return "cghrl";
5928 }
5929 
5930 static const HChar *
5931 s390_irgen_CHHR(UChar r1, UChar r2)
5932 {
5933    IRTemp op1 = newTemp(Ity_I32);
5934    IRTemp op2 = newTemp(Ity_I32);
5935 
5936    assign(op1, get_gpr_w0(r1));
5937    assign(op2, get_gpr_w0(r2));
5938    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5939 
5940    return "chhr";
5941 }
5942 
5943 static const HChar *
5944 s390_irgen_CHLR(UChar r1, UChar r2)
5945 {
5946    IRTemp op1 = newTemp(Ity_I32);
5947    IRTemp op2 = newTemp(Ity_I32);
5948 
5949    assign(op1, get_gpr_w0(r1));
5950    assign(op2, get_gpr_w1(r2));
5951    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5952 
5953    return "chlr";
5954 }
5955 
5956 static const HChar *
5957 s390_irgen_CHF(UChar r1, IRTemp op2addr)
5958 {
5959    IRTemp op1 = newTemp(Ity_I32);
5960    IRTemp op2 = newTemp(Ity_I32);
5961 
5962    assign(op1, get_gpr_w0(r1));
5963    assign(op2, load(Ity_I32, mkexpr(op2addr)));
5964    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5965 
5966    return "chf";
5967 }
5968 
5969 static const HChar *
5970 s390_irgen_CIH(UChar r1, UInt i2)
5971 {
5972    IRTemp op1 = newTemp(Ity_I32);
5973    Int op2;
5974 
5975    assign(op1, get_gpr_w0(r1));
5976    op2 = (Int)i2;
5977    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
5978                        mkU32((UInt)op2)));
5979 
5980    return "cih";
5981 }
5982 
5983 static const HChar *
5984 s390_irgen_CLR(UChar r1, UChar r2)
5985 {
5986    IRTemp op1 = newTemp(Ity_I32);
5987    IRTemp op2 = newTemp(Ity_I32);
5988 
5989    assign(op1, get_gpr_w1(r1));
5990    assign(op2, get_gpr_w1(r2));
5991    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5992 
5993    return "clr";
5994 }
5995 
5996 static const HChar *
5997 s390_irgen_CLGR(UChar r1, UChar r2)
5998 {
5999    IRTemp op1 = newTemp(Ity_I64);
6000    IRTemp op2 = newTemp(Ity_I64);
6001 
6002    assign(op1, get_gpr_dw0(r1));
6003    assign(op2, get_gpr_dw0(r2));
6004    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6005 
6006    return "clgr";
6007 }
6008 
6009 static const HChar *
6010 s390_irgen_CLGFR(UChar r1, UChar r2)
6011 {
6012    IRTemp op1 = newTemp(Ity_I64);
6013    IRTemp op2 = newTemp(Ity_I64);
6014 
6015    assign(op1, get_gpr_dw0(r1));
6016    assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
6017    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6018 
6019    return "clgfr";
6020 }
6021 
6022 static const HChar *
6023 s390_irgen_CL(UChar r1, IRTemp op2addr)
6024 {
6025    IRTemp op1 = newTemp(Ity_I32);
6026    IRTemp op2 = newTemp(Ity_I32);
6027 
6028    assign(op1, get_gpr_w1(r1));
6029    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6030    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6031 
6032    return "cl";
6033 }
6034 
6035 static const HChar *
6036 s390_irgen_CLY(UChar r1, IRTemp op2addr)
6037 {
6038    IRTemp op1 = newTemp(Ity_I32);
6039    IRTemp op2 = newTemp(Ity_I32);
6040 
6041    assign(op1, get_gpr_w1(r1));
6042    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6043    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6044 
6045    return "cly";
6046 }
6047 
6048 static const HChar *
6049 s390_irgen_CLG(UChar r1, IRTemp op2addr)
6050 {
6051    IRTemp op1 = newTemp(Ity_I64);
6052    IRTemp op2 = newTemp(Ity_I64);
6053 
6054    assign(op1, get_gpr_dw0(r1));
6055    assign(op2, load(Ity_I64, mkexpr(op2addr)));
6056    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6057 
6058    return "clg";
6059 }
6060 
6061 static const HChar *
6062 s390_irgen_CLGF(UChar r1, IRTemp op2addr)
6063 {
6064    IRTemp op1 = newTemp(Ity_I64);
6065    IRTemp op2 = newTemp(Ity_I64);
6066 
6067    assign(op1, get_gpr_dw0(r1));
6068    assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6069    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6070 
6071    return "clgf";
6072 }
6073 
6074 static const HChar *
6075 s390_irgen_CLFI(UChar r1, UInt i2)
6076 {
6077    IRTemp op1 = newTemp(Ity_I32);
6078    UInt op2;
6079 
6080    assign(op1, get_gpr_w1(r1));
6081    op2 = i2;
6082    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
6083                        mkU32(op2)));
6084 
6085    return "clfi";
6086 }
6087 
6088 static const HChar *
6089 s390_irgen_CLGFI(UChar r1, UInt i2)
6090 {
6091    IRTemp op1 = newTemp(Ity_I64);
6092    ULong op2;
6093 
6094    assign(op1, get_gpr_dw0(r1));
6095    op2 = (ULong)i2;
6096    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
6097                        mkU64(op2)));
6098 
6099    return "clgfi";
6100 }
6101 
6102 static const HChar *
6103 s390_irgen_CLI(UChar i2, IRTemp op1addr)
6104 {
6105    IRTemp op1 = newTemp(Ity_I8);
6106    UChar op2;
6107 
6108    assign(op1, load(Ity_I8, mkexpr(op1addr)));
6109    op2 = i2;
6110    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
6111                        mkU8(op2)));
6112 
6113    return "cli";
6114 }
6115 
6116 static const HChar *
6117 s390_irgen_CLIY(UChar i2, IRTemp op1addr)
6118 {
6119    IRTemp op1 = newTemp(Ity_I8);
6120    UChar op2;
6121 
6122    assign(op1, load(Ity_I8, mkexpr(op1addr)));
6123    op2 = i2;
6124    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
6125                        mkU8(op2)));
6126 
6127    return "cliy";
6128 }
6129 
6130 static const HChar *
6131 s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
6132 {
6133    IRTemp op1 = newTemp(Ity_I32);
6134    UInt op2;
6135 
6136    assign(op1, load(Ity_I32, mkexpr(op1addr)));
6137    op2 = (UInt)i2;
6138    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
6139                        mkU32(op2)));
6140 
6141    return "clfhsi";
6142 }
6143 
6144 static const HChar *
6145 s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
6146 {
6147    IRTemp op1 = newTemp(Ity_I64);
6148    ULong op2;
6149 
6150    assign(op1, load(Ity_I64, mkexpr(op1addr)));
6151    op2 = (ULong)i2;
6152    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
6153                        mkU64(op2)));
6154 
6155    return "clghsi";
6156 }
6157 
6158 static const HChar *
6159 s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
6160 {
6161    IRTemp op1 = newTemp(Ity_I16);
6162    UShort op2;
6163 
6164    assign(op1, load(Ity_I16, mkexpr(op1addr)));
6165    op2 = i2;
6166    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
6167                        mkU16(op2)));
6168 
6169    return "clhhsi";
6170 }
6171 
6172 static const HChar *
6173 s390_irgen_CLRL(UChar r1, UInt i2)
6174 {
6175    IRTemp op1 = newTemp(Ity_I32);
6176    IRTemp op2 = newTemp(Ity_I32);
6177 
6178    assign(op1, get_gpr_w1(r1));
6179    assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
6180           i2 << 1))));
6181    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6182 
6183    return "clrl";
6184 }
6185 
6186 static const HChar *
6187 s390_irgen_CLGRL(UChar r1, UInt i2)
6188 {
6189    IRTemp op1 = newTemp(Ity_I64);
6190    IRTemp op2 = newTemp(Ity_I64);
6191 
6192    assign(op1, get_gpr_dw0(r1));
6193    assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
6194           i2 << 1))));
6195    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6196 
6197    return "clgrl";
6198 }
6199 
6200 static const HChar *
6201 s390_irgen_CLGFRL(UChar r1, UInt i2)
6202 {
6203    IRTemp op1 = newTemp(Ity_I64);
6204    IRTemp op2 = newTemp(Ity_I64);
6205 
6206    assign(op1, get_gpr_dw0(r1));
6207    assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6208           ((ULong)(Long)(Int)i2 << 1)))));
6209    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6210 
6211    return "clgfrl";
6212 }
6213 
6214 static const HChar *
6215 s390_irgen_CLHRL(UChar r1, UInt i2)
6216 {
6217    IRTemp op1 = newTemp(Ity_I32);
6218    IRTemp op2 = newTemp(Ity_I32);
6219 
6220    assign(op1, get_gpr_w1(r1));
6221    assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6222           ((ULong)(Long)(Int)i2 << 1)))));
6223    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6224 
6225    return "clhrl";
6226 }
6227 
6228 static const HChar *
6229 s390_irgen_CLGHRL(UChar r1, UInt i2)
6230 {
6231    IRTemp op1 = newTemp(Ity_I64);
6232    IRTemp op2 = newTemp(Ity_I64);
6233 
6234    assign(op1, get_gpr_dw0(r1));
6235    assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6236           ((ULong)(Long)(Int)i2 << 1)))));
6237    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6238 
6239    return "clghrl";
6240 }
6241 
6242 static const HChar *
6243 s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
6244 {
6245    IRTemp op1 = newTemp(Ity_I32);
6246    IRTemp op2 = newTemp(Ity_I32);
6247    IRTemp cond = newTemp(Ity_I32);
6248 
6249    if (m3 == 0) {
6250    } else {
6251       if (m3 == 14) {
6252          always_goto(mkexpr(op4addr));
6253       } else {
6254          assign(op1, get_gpr_w1(r1));
6255          assign(op2, get_gpr_w1(r2));
6256          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
6257                                               op1, op2));
6258          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6259                                     mkexpr(op4addr));
6260       }
6261    }
6262 
6263    return "clrb";
6264 }
6265 
6266 static const HChar *
6267 s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
6268 {
6269    IRTemp op1 = newTemp(Ity_I64);
6270    IRTemp op2 = newTemp(Ity_I64);
6271    IRTemp cond = newTemp(Ity_I32);
6272 
6273    if (m3 == 0) {
6274    } else {
6275       if (m3 == 14) {
6276          always_goto(mkexpr(op4addr));
6277       } else {
6278          assign(op1, get_gpr_dw0(r1));
6279          assign(op2, get_gpr_dw0(r2));
6280          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
6281                                               op1, op2));
6282          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6283                                     mkexpr(op4addr));
6284       }
6285    }
6286 
6287    return "clgrb";
6288 }
6289 
6290 /* Raise the appropriate signal for a compare-and-trap-instruction data
6291    exception if the condition is true. */
6292 static void
6293 s390_trap_on_condition(IRExpr *cond)
6294 {
6295    stmt(IRStmt_Exit(cond, Ijk_SigFPE, IRConst_U64(guest_IA_next_instr),
6296                     S390X_GUEST_OFFSET(guest_IA)));
6297 }
6298 
6299 /* Handle the various flavors of compare (logical) and trap. */
6300 static void
6301 s390_irgen_CxRT(UChar m3, UChar r1, UChar r2, IRType type, UInt opc)
6302 {
6303    IRExpr *cond;
6304 
6305    if (m3 == 0) {
6306       /* Trap never (NOP) */
6307       return;
6308    } else if (m3 == 14) {
6309       /* Trap always */
6310       cond = IRExpr_Const(IRConst_U1 (True));
6311    } else {
6312       IRTemp op1 = newTemp(type);
6313       IRTemp op2 = newTemp(type);
6314 
6315       assign(op1, get_gpr_int(r1, type));
6316       assign(op2, get_gpr_int(r2, type));
6317       cond = binop(Iop_CmpNE32,
6318                    s390_call_calculate_icc(m3, opc, op1, op2), mkU32(0));
6319    }
6320    s390_trap_on_condition(cond);
6321 }
6322 
6323 static const HChar *
6324 s390_irgen_CGRT(UChar m3, UChar r1, UChar r2)
6325 {
6326    s390_irgen_CxRT(m3, r1, r2, Ity_I64, S390_CC_OP_SIGNED_COMPARE);
6327    return "cgrt";
6328 }
6329 
6330 static const HChar *
6331 s390_irgen_CRT(UChar m3, UChar r1, UChar r2)
6332 {
6333    s390_irgen_CxRT(m3, r1, r2, Ity_I32, S390_CC_OP_SIGNED_COMPARE);
6334    return "crt";
6335 }
6336 
6337 static const HChar *
6338 s390_irgen_CLGRT(UChar m3, UChar r1, UChar r2)
6339 {
6340    s390_irgen_CxRT(m3, r1, r2, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE);
6341    return "clgrt";
6342 }
6343 
6344 static const HChar *
6345 s390_irgen_CLRT(UChar m3, UChar r1, UChar r2)
6346 {
6347    s390_irgen_CxRT(m3, r1, r2, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE);
6348    return "clrt";
6349 }
6350 
6351 /* Handle the various flavors of compare (logical) immediate and trap. */
6352 static void
6353 s390_irgen_CxIT(UChar m3, UChar r1, UShort i2, IRType type, UInt opc)
6354 {
6355    IRExpr *cond;
6356 
6357    if (m3 == 0) {
6358       /* Trap never (NOP) */
6359       return;
6360    } else if (m3 == 14) {
6361       /* Trap always */
6362       cond = IRExpr_Const(IRConst_U1 (True));
6363    } else {
6364       IRTemp op1 = newTemp(type);
6365       IRTemp op2 = newTemp(type);
6366 
6367       assign(op1, get_gpr_int(r1, type));
6368       if (opc == S390_CC_OP_SIGNED_COMPARE) {
6369          assign(op2, type == Ity_I64 ?
6370                 mkU64((ULong)(Short)i2) : mkU32((UInt)(Short)i2));
6371       } else {
6372          assign(op2, type == Ity_I64 ?
6373                 mkU64((ULong)i2) : mkU32((UInt)i2));
6374       }
6375       cond = binop(Iop_CmpNE32,
6376                    s390_call_calculate_icc(m3, opc, op1, op2), mkU32(0));
6377    }
6378    s390_trap_on_condition(cond);
6379 }
6380 
6381 static const HChar *
6382 s390_irgen_CGIT(UChar r1, UShort i2, UChar m3)
6383 {
6384    s390_irgen_CxIT(m3, r1, i2, Ity_I64, S390_CC_OP_SIGNED_COMPARE);
6385    return "cgit";
6386 }
6387 
6388 static const HChar *
6389 s390_irgen_CIT(UChar r1, UShort i2, UChar m3)
6390 {
6391    s390_irgen_CxIT(m3, r1, i2, Ity_I32, S390_CC_OP_SIGNED_COMPARE);
6392    return "cit";
6393 }
6394 
6395 static const HChar *
6396 s390_irgen_CLGIT(UChar r1, UShort i2, UChar m3)
6397 {
6398    s390_irgen_CxIT(m3, r1, i2, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE);
6399    return "clgit";
6400 }
6401 
6402 static const HChar *
6403 s390_irgen_CLFIT(UChar r1, UShort i2, UChar m3)
6404 {
6405    s390_irgen_CxIT(m3, r1, i2, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE);
6406    return "clfit";
6407 }
6408 
6409 /* Handle the variants of compare logical and trap with memory operand. */
6410 static void
6411 s390_irgen_CLxT(UChar r1, UChar m3, IRTemp op2addr, IRType type, UInt opc)
6412 {
6413    IRExpr *cond;
6414 
6415    if (m3 == 0) {
6416       /* Trap never (NOP) */
6417       return;
6418    } else if (m3 == 14) {
6419       /* Trap always */
6420       cond = IRExpr_Const(IRConst_U1 (True));
6421    } else {
6422       IRTemp op1 = newTemp(type);
6423       IRTemp op2 = newTemp(type);
6424 
6425       assign(op1, get_gpr_int(r1, type));
6426       assign(op2, load(type, mkexpr(op2addr)));
6427       cond = binop(Iop_CmpNE32,
6428                    s390_call_calculate_icc(m3, opc, op1, op2), mkU32(0));
6429    }
6430    s390_trap_on_condition(cond);
6431 }
6432 
6433 static const HChar *
6434 s390_irgen_CLT(UChar r1, UChar m3, IRTemp op2addr)
6435 {
6436    s390_irgen_CLxT(r1, m3, op2addr, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE);
6437    return "clt";
6438 }
6439 
6440 static const HChar *
6441 s390_irgen_CLGT(UChar r1, UChar m3, IRTemp op2addr)
6442 {
6443    s390_irgen_CLxT(r1, m3, op2addr, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE);
6444    return "clgt";
6445 }
6446 
6447 static const HChar *
6448 s390_irgen_LAT(UChar r1, IRTemp op2addr)
6449 {
6450    IRTemp val = newTemp(Ity_I32);
6451    assign(val, load(Ity_I32, mkexpr(op2addr)));
6452    put_gpr_w1(r1, mkexpr(val));
6453    s390_trap_on_condition(binop(Iop_CmpEQ32, mkexpr(val), mkU32(0)));
6454    return "lat";
6455 }
6456 
6457 static const HChar *
6458 s390_irgen_LGAT(UChar r1, IRTemp op2addr)
6459 {
6460    IRTemp val = newTemp(Ity_I64);
6461    assign(val, load(Ity_I64, mkexpr(op2addr)));
6462    put_gpr_dw0(r1, mkexpr(val));
6463    s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0)));
6464    return "lgat";
6465 }
6466 
6467 static const HChar *
6468 s390_irgen_LFHAT(UChar r1, IRTemp op2addr)
6469 {
6470    IRTemp val = newTemp(Ity_I32);
6471    assign(val, load(Ity_I32, mkexpr(op2addr)));
6472    put_gpr_w0(r1, mkexpr(val));
6473    s390_trap_on_condition(binop(Iop_CmpEQ32, mkexpr(val), mkU32(0)));
6474    return "lfhat";
6475 }
6476 
6477 static const HChar *
6478 s390_irgen_LLGFAT(UChar r1, IRTemp op2addr)
6479 {
6480    IRTemp val = newTemp(Ity_I64);
6481    assign(val, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6482    put_gpr_dw0(r1, mkexpr(val));
6483    s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0)));
6484    return "llgfat";
6485 }
6486 
6487 static const HChar *
6488 s390_irgen_LLGTAT(UChar r1, IRTemp op2addr)
6489 {
6490    IRTemp val = newTemp(Ity_I64);
6491    assign(val, binop(Iop_And64, mkU64(0x7fffffff),
6492                      unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr)))));
6493    put_gpr_dw0(r1, mkexpr(val));
6494    s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0)));
6495    return "llgtat";
6496 }
6497 
6498 static const HChar *
6499 s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
6500 {
6501    IRTemp op1 = newTemp(Ity_I32);
6502    IRTemp op2 = newTemp(Ity_I32);
6503    IRTemp cond = newTemp(Ity_I32);
6504 
6505    if (m3 == 0) {
6506    } else {
6507       if (m3 == 14) {
6508          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6509       } else {
6510          assign(op1, get_gpr_w1(r1));
6511          assign(op2, get_gpr_w1(r2));
6512          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
6513                                               op1, op2));
6514          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6515                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6516 
6517       }
6518    }
6519 
6520    return "clrj";
6521 }
6522 
6523 static const HChar *
6524 s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
6525 {
6526    IRTemp op1 = newTemp(Ity_I64);
6527    IRTemp op2 = newTemp(Ity_I64);
6528    IRTemp cond = newTemp(Ity_I32);
6529 
6530    if (m3 == 0) {
6531    } else {
6532       if (m3 == 14) {
6533          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6534       } else {
6535          assign(op1, get_gpr_dw0(r1));
6536          assign(op2, get_gpr_dw0(r2));
6537          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
6538                                               op1, op2));
6539          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6540                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6541 
6542       }
6543    }
6544 
6545    return "clgrj";
6546 }
6547 
6548 static const HChar *
6549 s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
6550 {
6551    IRTemp op1 = newTemp(Ity_I32);
6552    UInt op2;
6553    IRTemp cond = newTemp(Ity_I32);
6554 
6555    if (m3 == 0) {
6556    } else {
6557       if (m3 == 14) {
6558          always_goto(mkexpr(op4addr));
6559       } else {
6560          assign(op1, get_gpr_w1(r1));
6561          op2 = (UInt)i2;
6562          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
6563                                               mktemp(Ity_I32, mkU32(op2))));
6564          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6565                                     mkexpr(op4addr));
6566       }
6567    }
6568 
6569    return "clib";
6570 }
6571 
6572 static const HChar *
6573 s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
6574 {
6575    IRTemp op1 = newTemp(Ity_I64);
6576    ULong op2;
6577    IRTemp cond = newTemp(Ity_I32);
6578 
6579    if (m3 == 0) {
6580    } else {
6581       if (m3 == 14) {
6582          always_goto(mkexpr(op4addr));
6583       } else {
6584          assign(op1, get_gpr_dw0(r1));
6585          op2 = (ULong)i2;
6586          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
6587                                               mktemp(Ity_I64, mkU64(op2))));
6588          if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6589                                     mkexpr(op4addr));
6590       }
6591    }
6592 
6593    return "clgib";
6594 }
6595 
6596 static const HChar *
6597 s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
6598 {
6599    IRTemp op1 = newTemp(Ity_I32);
6600    UInt op2;
6601    IRTemp cond = newTemp(Ity_I32);
6602 
6603    if (m3 == 0) {
6604    } else {
6605       if (m3 == 14) {
6606          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6607       } else {
6608          assign(op1, get_gpr_w1(r1));
6609          op2 = (UInt)i2;
6610          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
6611                                               mktemp(Ity_I32, mkU32(op2))));
6612          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6613                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6614 
6615       }
6616    }
6617 
6618    return "clij";
6619 }
6620 
6621 static const HChar *
6622 s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
6623 {
6624    IRTemp op1 = newTemp(Ity_I64);
6625    ULong op2;
6626    IRTemp cond = newTemp(Ity_I32);
6627 
6628    if (m3 == 0) {
6629    } else {
6630       if (m3 == 14) {
6631          always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6632       } else {
6633          assign(op1, get_gpr_dw0(r1));
6634          op2 = (ULong)i2;
6635          assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
6636                                               mktemp(Ity_I64, mkU64(op2))));
6637          if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6638                            guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
6639 
6640       }
6641    }
6642 
6643    return "clgij";
6644 }
6645 
6646 static const HChar *
6647 s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
6648 {
6649    IRTemp op1 = newTemp(Ity_I32);
6650    IRTemp op2 = newTemp(Ity_I32);
6651    IRTemp b0 = newTemp(Ity_I32);
6652    IRTemp b1 = newTemp(Ity_I32);
6653    IRTemp b2 = newTemp(Ity_I32);
6654    IRTemp b3 = newTemp(Ity_I32);
6655    IRTemp c0 = newTemp(Ity_I32);
6656    IRTemp c1 = newTemp(Ity_I32);
6657    IRTemp c2 = newTemp(Ity_I32);
6658    IRTemp c3 = newTemp(Ity_I32);
6659    UChar n;
6660 
6661    n = 0;
6662    if ((r3 & 8) != 0) {
6663       assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
6664       assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6665       n = n + 1;
6666    } else {
6667       assign(b0, mkU32(0));
6668       assign(c0, mkU32(0));
6669    }
6670    if ((r3 & 4) != 0) {
6671       assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
6672       assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6673              mkU64(n)))));
6674       n = n + 1;
6675    } else {
6676       assign(b1, mkU32(0));
6677       assign(c1, mkU32(0));
6678    }
6679    if ((r3 & 2) != 0) {
6680       assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
6681       assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6682              mkU64(n)))));
6683       n = n + 1;
6684    } else {
6685       assign(b2, mkU32(0));
6686       assign(c2, mkU32(0));
6687    }
6688    if ((r3 & 1) != 0) {
6689       assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
6690       assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6691              mkU64(n)))));
6692       n = n + 1;
6693    } else {
6694       assign(b3, mkU32(0));
6695       assign(c3, mkU32(0));
6696    }
6697    assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6698           mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
6699           binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
6700    assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6701           mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
6702           binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
6703    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6704 
6705    return "clm";
6706 }
6707 
6708 static const HChar *
6709 s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
6710 {
6711    IRTemp op1 = newTemp(Ity_I32);
6712    IRTemp op2 = newTemp(Ity_I32);
6713    IRTemp b0 = newTemp(Ity_I32);
6714    IRTemp b1 = newTemp(Ity_I32);
6715    IRTemp b2 = newTemp(Ity_I32);
6716    IRTemp b3 = newTemp(Ity_I32);
6717    IRTemp c0 = newTemp(Ity_I32);
6718    IRTemp c1 = newTemp(Ity_I32);
6719    IRTemp c2 = newTemp(Ity_I32);
6720    IRTemp c3 = newTemp(Ity_I32);
6721    UChar n;
6722 
6723    n = 0;
6724    if ((r3 & 8) != 0) {
6725       assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
6726       assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6727       n = n + 1;
6728    } else {
6729       assign(b0, mkU32(0));
6730       assign(c0, mkU32(0));
6731    }
6732    if ((r3 & 4) != 0) {
6733       assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
6734       assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6735              mkU64(n)))));
6736       n = n + 1;
6737    } else {
6738       assign(b1, mkU32(0));
6739       assign(c1, mkU32(0));
6740    }
6741    if ((r3 & 2) != 0) {
6742       assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
6743       assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6744              mkU64(n)))));
6745       n = n + 1;
6746    } else {
6747       assign(b2, mkU32(0));
6748       assign(c2, mkU32(0));
6749    }
6750    if ((r3 & 1) != 0) {
6751       assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
6752       assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6753              mkU64(n)))));
6754       n = n + 1;
6755    } else {
6756       assign(b3, mkU32(0));
6757       assign(c3, mkU32(0));
6758    }
6759    assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6760           mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
6761           binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
6762    assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6763           mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
6764           binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
6765    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6766 
6767    return "clmy";
6768 }
6769 
6770 static const HChar *
6771 s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
6772 {
6773    IRTemp op1 = newTemp(Ity_I32);
6774    IRTemp op2 = newTemp(Ity_I32);
6775    IRTemp b0 = newTemp(Ity_I32);
6776    IRTemp b1 = newTemp(Ity_I32);
6777    IRTemp b2 = newTemp(Ity_I32);
6778    IRTemp b3 = newTemp(Ity_I32);
6779    IRTemp c0 = newTemp(Ity_I32);
6780    IRTemp c1 = newTemp(Ity_I32);
6781    IRTemp c2 = newTemp(Ity_I32);
6782    IRTemp c3 = newTemp(Ity_I32);
6783    UChar n;
6784 
6785    n = 0;
6786    if ((r3 & 8) != 0) {
6787       assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
6788       assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6789       n = n + 1;
6790    } else {
6791       assign(b0, mkU32(0));
6792       assign(c0, mkU32(0));
6793    }
6794    if ((r3 & 4) != 0) {
6795       assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
6796       assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6797              mkU64(n)))));
6798       n = n + 1;
6799    } else {
6800       assign(b1, mkU32(0));
6801       assign(c1, mkU32(0));
6802    }
6803    if ((r3 & 2) != 0) {
6804       assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
6805       assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6806              mkU64(n)))));
6807       n = n + 1;
6808    } else {
6809       assign(b2, mkU32(0));
6810       assign(c2, mkU32(0));
6811    }
6812    if ((r3 & 1) != 0) {
6813       assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
6814       assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6815              mkU64(n)))));
6816       n = n + 1;
6817    } else {
6818       assign(b3, mkU32(0));
6819       assign(c3, mkU32(0));
6820    }
6821    assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6822           mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
6823           binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
6824    assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6825           mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
6826           binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
6827    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6828 
6829    return "clmh";
6830 }
6831 
6832 static const HChar *
6833 s390_irgen_CLHHR(UChar r1, UChar r2)
6834 {
6835    IRTemp op1 = newTemp(Ity_I32);
6836    IRTemp op2 = newTemp(Ity_I32);
6837 
6838    assign(op1, get_gpr_w0(r1));
6839    assign(op2, get_gpr_w0(r2));
6840    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6841 
6842    return "clhhr";
6843 }
6844 
6845 static const HChar *
6846 s390_irgen_CLHLR(UChar r1, UChar r2)
6847 {
6848    IRTemp op1 = newTemp(Ity_I32);
6849    IRTemp op2 = newTemp(Ity_I32);
6850 
6851    assign(op1, get_gpr_w0(r1));
6852    assign(op2, get_gpr_w1(r2));
6853    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6854 
6855    return "clhlr";
6856 }
6857 
6858 static const HChar *
6859 s390_irgen_CLHF(UChar r1, IRTemp op2addr)
6860 {
6861    IRTemp op1 = newTemp(Ity_I32);
6862    IRTemp op2 = newTemp(Ity_I32);
6863 
6864    assign(op1, get_gpr_w0(r1));
6865    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6866    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6867 
6868    return "clhf";
6869 }
6870 
6871 static const HChar *
6872 s390_irgen_CLIH(UChar r1, UInt i2)
6873 {
6874    IRTemp op1 = newTemp(Ity_I32);
6875    UInt op2;
6876 
6877    assign(op1, get_gpr_w0(r1));
6878    op2 = i2;
6879    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
6880                        mkU32(op2)));
6881 
6882    return "clih";
6883 }
6884 
6885 static const HChar *
6886 s390_irgen_CPYA(UChar r1, UChar r2)
6887 {
6888    put_ar_w0(r1, get_ar_w0(r2));
6889    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
6890       s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
6891 
6892    return "cpya";
6893 }
6894 
6895 static const HChar *
6896 s390_irgen_XR(UChar r1, UChar r2)
6897 {
6898    IRTemp op1 = newTemp(Ity_I32);
6899    IRTemp op2 = newTemp(Ity_I32);
6900    IRTemp result = newTemp(Ity_I32);
6901 
6902    if (r1 == r2) {
6903       assign(result, mkU32(0));
6904    } else {
6905       assign(op1, get_gpr_w1(r1));
6906       assign(op2, get_gpr_w1(r2));
6907       assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
6908    }
6909    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6910    put_gpr_w1(r1, mkexpr(result));
6911 
6912    return "xr";
6913 }
6914 
6915 static const HChar *
6916 s390_irgen_XGR(UChar r1, UChar r2)
6917 {
6918    IRTemp op1 = newTemp(Ity_I64);
6919    IRTemp op2 = newTemp(Ity_I64);
6920    IRTemp result = newTemp(Ity_I64);
6921 
6922    if (r1 == r2) {
6923       assign(result, mkU64(0));
6924    } else {
6925       assign(op1, get_gpr_dw0(r1));
6926       assign(op2, get_gpr_dw0(r2));
6927       assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
6928    }
6929    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6930    put_gpr_dw0(r1, mkexpr(result));
6931 
6932    return "xgr";
6933 }
6934 
6935 static const HChar *
6936 s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
6937 {
6938    IRTemp op2 = newTemp(Ity_I32);
6939    IRTemp op3 = newTemp(Ity_I32);
6940    IRTemp result = newTemp(Ity_I32);
6941 
6942    assign(op2, get_gpr_w1(r2));
6943    assign(op3, get_gpr_w1(r3));
6944    assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
6945    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6946    put_gpr_w1(r1, mkexpr(result));
6947 
6948    return "xrk";
6949 }
6950 
6951 static const HChar *
6952 s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
6953 {
6954    IRTemp op2 = newTemp(Ity_I64);
6955    IRTemp op3 = newTemp(Ity_I64);
6956    IRTemp result = newTemp(Ity_I64);
6957 
6958    assign(op2, get_gpr_dw0(r2));
6959    assign(op3, get_gpr_dw0(r3));
6960    assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
6961    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6962    put_gpr_dw0(r1, mkexpr(result));
6963 
6964    return "xgrk";
6965 }
6966 
6967 static const HChar *
6968 s390_irgen_X(UChar r1, IRTemp op2addr)
6969 {
6970    IRTemp op1 = newTemp(Ity_I32);
6971    IRTemp op2 = newTemp(Ity_I32);
6972    IRTemp result = newTemp(Ity_I32);
6973 
6974    assign(op1, get_gpr_w1(r1));
6975    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6976    assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
6977    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6978    put_gpr_w1(r1, mkexpr(result));
6979 
6980    return "x";
6981 }
6982 
6983 static const HChar *
6984 s390_irgen_XY(UChar r1, IRTemp op2addr)
6985 {
6986    IRTemp op1 = newTemp(Ity_I32);
6987    IRTemp op2 = newTemp(Ity_I32);
6988    IRTemp result = newTemp(Ity_I32);
6989 
6990    assign(op1, get_gpr_w1(r1));
6991    assign(op2, load(Ity_I32, mkexpr(op2addr)));
6992    assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
6993    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6994    put_gpr_w1(r1, mkexpr(result));
6995 
6996    return "xy";
6997 }
6998 
6999 static const HChar *
7000 s390_irgen_XG(UChar r1, IRTemp op2addr)
7001 {
7002    IRTemp op1 = newTemp(Ity_I64);
7003    IRTemp op2 = newTemp(Ity_I64);
7004    IRTemp result = newTemp(Ity_I64);
7005 
7006    assign(op1, get_gpr_dw0(r1));
7007    assign(op2, load(Ity_I64, mkexpr(op2addr)));
7008    assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
7009    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7010    put_gpr_dw0(r1, mkexpr(result));
7011 
7012    return "xg";
7013 }
7014 
7015 static const HChar *
7016 s390_irgen_XI(UChar i2, IRTemp op1addr)
7017 {
7018    IRTemp op1 = newTemp(Ity_I8);
7019    UChar op2;
7020    IRTemp result = newTemp(Ity_I8);
7021 
7022    assign(op1, load(Ity_I8, mkexpr(op1addr)));
7023    op2 = i2;
7024    assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
7025    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7026    store(mkexpr(op1addr), mkexpr(result));
7027 
7028    return "xi";
7029 }
7030 
7031 static const HChar *
7032 s390_irgen_XIY(UChar i2, IRTemp op1addr)
7033 {
7034    IRTemp op1 = newTemp(Ity_I8);
7035    UChar op2;
7036    IRTemp result = newTemp(Ity_I8);
7037 
7038    assign(op1, load(Ity_I8, mkexpr(op1addr)));
7039    op2 = i2;
7040    assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
7041    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7042    store(mkexpr(op1addr), mkexpr(result));
7043 
7044    return "xiy";
7045 }
7046 
7047 static const HChar *
7048 s390_irgen_XIHF(UChar r1, UInt i2)
7049 {
7050    IRTemp op1 = newTemp(Ity_I32);
7051    UInt op2;
7052    IRTemp result = newTemp(Ity_I32);
7053 
7054    assign(op1, get_gpr_w0(r1));
7055    op2 = i2;
7056    assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
7057    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7058    put_gpr_w0(r1, mkexpr(result));
7059 
7060    return "xihf";
7061 }
7062 
7063 static const HChar *
7064 s390_irgen_XILF(UChar r1, UInt i2)
7065 {
7066    IRTemp op1 = newTemp(Ity_I32);
7067    UInt op2;
7068    IRTemp result = newTemp(Ity_I32);
7069 
7070    assign(op1, get_gpr_w1(r1));
7071    op2 = i2;
7072    assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
7073    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7074    put_gpr_w1(r1, mkexpr(result));
7075 
7076    return "xilf";
7077 }
7078 
7079 static const HChar *
7080 s390_irgen_EAR(UChar r1, UChar r2)
7081 {
7082    put_gpr_w1(r1, get_ar_w0(r2));
7083    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
7084       s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
7085 
7086    return "ear";
7087 }
7088 
7089 static const HChar *
7090 s390_irgen_IC(UChar r1, IRTemp op2addr)
7091 {
7092    put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
7093 
7094    return "ic";
7095 }
7096 
7097 static const HChar *
7098 s390_irgen_ICY(UChar r1, IRTemp op2addr)
7099 {
7100    put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
7101 
7102    return "icy";
7103 }
7104 
7105 static const HChar *
7106 s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
7107 {
7108    UChar n;
7109    IRTemp result = newTemp(Ity_I32);
7110    UInt mask;
7111 
7112    n = 0;
7113    mask = (UInt)r3;
7114    if ((mask & 8) != 0) {
7115       put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
7116       n = n + 1;
7117    }
7118    if ((mask & 4) != 0) {
7119       put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7120 
7121       n = n + 1;
7122    }
7123    if ((mask & 2) != 0) {
7124       put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7125 
7126       n = n + 1;
7127    }
7128    if ((mask & 1) != 0) {
7129       put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7130 
7131       n = n + 1;
7132    }
7133    assign(result, get_gpr_w1(r1));
7134    s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
7135                        mkU32(mask)));
7136 
7137    return "icm";
7138 }
7139 
7140 static const HChar *
7141 s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
7142 {
7143    UChar n;
7144    IRTemp result = newTemp(Ity_I32);
7145    UInt mask;
7146 
7147    n = 0;
7148    mask = (UInt)r3;
7149    if ((mask & 8) != 0) {
7150       put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
7151       n = n + 1;
7152    }
7153    if ((mask & 4) != 0) {
7154       put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7155 
7156       n = n + 1;
7157    }
7158    if ((mask & 2) != 0) {
7159       put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7160 
7161       n = n + 1;
7162    }
7163    if ((mask & 1) != 0) {
7164       put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7165 
7166       n = n + 1;
7167    }
7168    assign(result, get_gpr_w1(r1));
7169    s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
7170                        mkU32(mask)));
7171 
7172    return "icmy";
7173 }
7174 
7175 static const HChar *
7176 s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
7177 {
7178    UChar n;
7179    IRTemp result = newTemp(Ity_I32);
7180    UInt mask;
7181 
7182    n = 0;
7183    mask = (UInt)r3;
7184    if ((mask & 8) != 0) {
7185       put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
7186       n = n + 1;
7187    }
7188    if ((mask & 4) != 0) {
7189       put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7190 
7191       n = n + 1;
7192    }
7193    if ((mask & 2) != 0) {
7194       put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7195 
7196       n = n + 1;
7197    }
7198    if ((mask & 1) != 0) {
7199       put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7200 
7201       n = n + 1;
7202    }
7203    assign(result, get_gpr_w0(r1));
7204    s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
7205                        mkU32(mask)));
7206 
7207    return "icmh";
7208 }
7209 
7210 static const HChar *
7211 s390_irgen_IIHF(UChar r1, UInt i2)
7212 {
7213    put_gpr_w0(r1, mkU32(i2));
7214 
7215    return "iihf";
7216 }
7217 
7218 static const HChar *
7219 s390_irgen_IIHH(UChar r1, UShort i2)
7220 {
7221    put_gpr_hw0(r1, mkU16(i2));
7222 
7223    return "iihh";
7224 }
7225 
7226 static const HChar *
7227 s390_irgen_IIHL(UChar r1, UShort i2)
7228 {
7229    put_gpr_hw1(r1, mkU16(i2));
7230 
7231    return "iihl";
7232 }
7233 
7234 static const HChar *
7235 s390_irgen_IILF(UChar r1, UInt i2)
7236 {
7237    put_gpr_w1(r1, mkU32(i2));
7238 
7239    return "iilf";
7240 }
7241 
7242 static const HChar *
7243 s390_irgen_IILH(UChar r1, UShort i2)
7244 {
7245    put_gpr_hw2(r1, mkU16(i2));
7246 
7247    return "iilh";
7248 }
7249 
7250 static const HChar *
7251 s390_irgen_IILL(UChar r1, UShort i2)
7252 {
7253    put_gpr_hw3(r1, mkU16(i2));
7254 
7255    return "iill";
7256 }
7257 
7258 static const HChar *
7259 s390_irgen_LR(UChar r1, UChar r2)
7260 {
7261    put_gpr_w1(r1, get_gpr_w1(r2));
7262 
7263    return "lr";
7264 }
7265 
7266 static const HChar *
7267 s390_irgen_LGR(UChar r1, UChar r2)
7268 {
7269    put_gpr_dw0(r1, get_gpr_dw0(r2));
7270 
7271    return "lgr";
7272 }
7273 
7274 static const HChar *
7275 s390_irgen_LGFR(UChar r1, UChar r2)
7276 {
7277    put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
7278 
7279    return "lgfr";
7280 }
7281 
7282 static const HChar *
7283 s390_irgen_L(UChar r1, IRTemp op2addr)
7284 {
7285    put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
7286 
7287    return "l";
7288 }
7289 
7290 static const HChar *
7291 s390_irgen_LY(UChar r1, IRTemp op2addr)
7292 {
7293    put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
7294 
7295    return "ly";
7296 }
7297 
7298 static const HChar *
7299 s390_irgen_LG(UChar r1, IRTemp op2addr)
7300 {
7301    put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
7302 
7303    return "lg";
7304 }
7305 
7306 static const HChar *
7307 s390_irgen_LGF(UChar r1, IRTemp op2addr)
7308 {
7309    put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7310 
7311    return "lgf";
7312 }
7313 
7314 static const HChar *
7315 s390_irgen_LGFI(UChar r1, UInt i2)
7316 {
7317    put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
7318 
7319    return "lgfi";
7320 }
7321 
7322 static const HChar *
7323 s390_irgen_LRL(UChar r1, UInt i2)
7324 {
7325    put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
7326               i2 << 1))));
7327 
7328    return "lrl";
7329 }
7330 
7331 static const HChar *
7332 s390_irgen_LGRL(UChar r1, UInt i2)
7333 {
7334    put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
7335                i2 << 1))));
7336 
7337    return "lgrl";
7338 }
7339 
7340 static const HChar *
7341 s390_irgen_LGFRL(UChar r1, UInt i2)
7342 {
7343    put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
7344                ((ULong)(Long)(Int)i2 << 1)))));
7345 
7346    return "lgfrl";
7347 }
7348 
7349 static const HChar *
7350 s390_irgen_LA(UChar r1, IRTemp op2addr)
7351 {
7352    put_gpr_dw0(r1, mkexpr(op2addr));
7353 
7354    return "la";
7355 }
7356 
7357 static const HChar *
7358 s390_irgen_LAY(UChar r1, IRTemp op2addr)
7359 {
7360    put_gpr_dw0(r1, mkexpr(op2addr));
7361 
7362    return "lay";
7363 }
7364 
7365 static const HChar *
7366 s390_irgen_LAE(UChar r1, IRTemp op2addr)
7367 {
7368    put_gpr_dw0(r1, mkexpr(op2addr));
7369 
7370    return "lae";
7371 }
7372 
7373 static const HChar *
7374 s390_irgen_LAEY(UChar r1, IRTemp op2addr)
7375 {
7376    put_gpr_dw0(r1, mkexpr(op2addr));
7377 
7378    return "laey";
7379 }
7380 
7381 static const HChar *
7382 s390_irgen_LARL(UChar r1, UInt i2)
7383 {
7384    put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
7385 
7386    return "larl";
7387 }
7388 
7389 /* The IR representation of LAA and friends is an approximation of what
7390    happens natively. Essentially a loop containing a compare-and-swap is
7391    constructed which will iterate until the CAS succeeds. As a consequence,
7392    instrumenters may see more memory accesses than happen natively. See also
7393    discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
7394 static void
7395 s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
7396 {
7397    IRCAS *cas;
7398    IRTemp old_mem = newTemp(Ity_I32);
7399    IRTemp op2 = newTemp(Ity_I32);
7400    IRTemp op3 = newTemp(Ity_I32);
7401    IRTemp result = newTemp(Ity_I32);
7402 
7403    assign(op2, load(Ity_I32, mkexpr(op2addr)));
7404    assign(op3, get_gpr_w1(r3));
7405    assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
7406 
7407    /* Place the addition of second operand and third operand at the
7408       second-operand location everytime */
7409    cas = mkIRCAS(IRTemp_INVALID, old_mem,
7410                  Iend_BE, mkexpr(op2addr),
7411                  NULL, mkexpr(op2), /* expected value */
7412                  NULL, mkexpr(result)  /* new value */);
7413    stmt(IRStmt_CAS(cas));
7414 
7415    /* Set CC according to 32-bit addition */
7416    if (is_signed) {
7417       s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
7418    } else {
7419       s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
7420    }
7421 
7422    /* If old_mem contains the expected value, then the CAS succeeded.
7423       Otherwise, it did not */
7424    yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
7425    put_gpr_w1(r1, mkexpr(old_mem));
7426 }
7427 
7428 static void
7429 s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
7430 {
7431    IRCAS *cas;
7432    IRTemp old_mem = newTemp(Ity_I64);
7433    IRTemp op2 = newTemp(Ity_I64);
7434    IRTemp op3 = newTemp(Ity_I64);
7435    IRTemp result = newTemp(Ity_I64);
7436 
7437    assign(op2, load(Ity_I64, mkexpr(op2addr)));
7438    assign(op3, get_gpr_dw0(r3));
7439    assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
7440 
7441    /* Place the addition of second operand and third operand at the
7442       second-operand location everytime */
7443    cas = mkIRCAS(IRTemp_INVALID, old_mem,
7444                  Iend_BE, mkexpr(op2addr),
7445                  NULL, mkexpr(op2), /* expected value */
7446                  NULL, mkexpr(result)  /* new value */);
7447    stmt(IRStmt_CAS(cas));
7448 
7449    /* Set CC according to 64-bit addition */
7450    if (is_signed) {
7451       s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
7452    } else {
7453       s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
7454    }
7455 
7456    /* If old_mem contains the expected value, then the CAS succeeded.
7457       Otherwise, it did not */
7458    yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
7459    put_gpr_dw0(r1, mkexpr(old_mem));
7460 }
7461 
7462 static void
7463 s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
7464 {
7465    IRCAS *cas;
7466    IRTemp old_mem = newTemp(Ity_I32);
7467    IRTemp op2 = newTemp(Ity_I32);
7468    IRTemp op3 = newTemp(Ity_I32);
7469    IRTemp result = newTemp(Ity_I32);
7470 
7471    assign(op2, load(Ity_I32, mkexpr(op2addr)));
7472    assign(op3, get_gpr_w1(r3));
7473    assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
7474 
7475    /* Place the addition of second operand and third operand at the
7476       second-operand location everytime */
7477    cas = mkIRCAS(IRTemp_INVALID, old_mem,
7478                  Iend_BE, mkexpr(op2addr),
7479                  NULL, mkexpr(op2), /* expected value */
7480                  NULL, mkexpr(result)  /* new value */);
7481    stmt(IRStmt_CAS(cas));
7482 
7483    /* Set CC according to bitwise operation */
7484    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7485 
7486    /* If old_mem contains the expected value, then the CAS succeeded.
7487       Otherwise, it did not */
7488    yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
7489    put_gpr_w1(r1, mkexpr(old_mem));
7490 }
7491 
7492 static void
7493 s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
7494 {
7495    IRCAS *cas;
7496    IRTemp old_mem = newTemp(Ity_I64);
7497    IRTemp op2 = newTemp(Ity_I64);
7498    IRTemp op3 = newTemp(Ity_I64);
7499    IRTemp result = newTemp(Ity_I64);
7500 
7501    assign(op2, load(Ity_I64, mkexpr(op2addr)));
7502    assign(op3, get_gpr_dw0(r3));
7503    assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
7504 
7505    /* Place the addition of second operand and third operand at the
7506       second-operand location everytime */
7507    cas = mkIRCAS(IRTemp_INVALID, old_mem,
7508                  Iend_BE, mkexpr(op2addr),
7509                  NULL, mkexpr(op2), /* expected value */
7510                  NULL, mkexpr(result)  /* new value */);
7511    stmt(IRStmt_CAS(cas));
7512 
7513    /* Set CC according to bitwise operation */
7514    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7515 
7516    /* If old_mem contains the expected value, then the CAS succeeded.
7517       Otherwise, it did not */
7518    yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
7519    put_gpr_dw0(r1, mkexpr(old_mem));
7520 }
7521 
7522 static const HChar *
7523 s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
7524 {
7525    s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
7526 
7527    return "laa";
7528 }
7529 
7530 static const HChar *
7531 s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
7532 {
7533    s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
7534 
7535    return "laag";
7536 }
7537 
7538 static const HChar *
7539 s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
7540 {
7541    s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
7542 
7543    return "laal";
7544 }
7545 
7546 static const HChar *
7547 s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
7548 {
7549    s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
7550 
7551    return "laalg";
7552 }
7553 
7554 static const HChar *
7555 s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
7556 {
7557    s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
7558 
7559    return "lan";
7560 }
7561 
7562 static const HChar *
7563 s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
7564 {
7565    s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
7566 
7567    return "lang";
7568 }
7569 
7570 static const HChar *
7571 s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
7572 {
7573    s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
7574 
7575    return "lax";
7576 }
7577 
7578 static const HChar *
7579 s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
7580 {
7581    s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
7582 
7583    return "laxg";
7584 }
7585 
7586 static const HChar *
7587 s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
7588 {
7589    s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
7590 
7591    return "lao";
7592 }
7593 
7594 static const HChar *
7595 s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
7596 {
7597    s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
7598 
7599    return "laog";
7600 }
7601 
7602 static const HChar *
7603 s390_irgen_LTR(UChar r1, UChar r2)
7604 {
7605    IRTemp op2 = newTemp(Ity_I32);
7606 
7607    assign(op2, get_gpr_w1(r2));
7608    put_gpr_w1(r1, mkexpr(op2));
7609    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7610 
7611    return "ltr";
7612 }
7613 
7614 static const HChar *
7615 s390_irgen_LTGR(UChar r1, UChar r2)
7616 {
7617    IRTemp op2 = newTemp(Ity_I64);
7618 
7619    assign(op2, get_gpr_dw0(r2));
7620    put_gpr_dw0(r1, mkexpr(op2));
7621    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7622 
7623    return "ltgr";
7624 }
7625 
7626 static const HChar *
7627 s390_irgen_LTGFR(UChar r1, UChar r2)
7628 {
7629    IRTemp op2 = newTemp(Ity_I64);
7630 
7631    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7632    put_gpr_dw0(r1, mkexpr(op2));
7633    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7634 
7635    return "ltgfr";
7636 }
7637 
7638 static const HChar *
7639 s390_irgen_LT(UChar r1, IRTemp op2addr)
7640 {
7641    IRTemp op2 = newTemp(Ity_I32);
7642 
7643    assign(op2, load(Ity_I32, mkexpr(op2addr)));
7644    put_gpr_w1(r1, mkexpr(op2));
7645    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7646 
7647    return "lt";
7648 }
7649 
7650 static const HChar *
7651 s390_irgen_LTG(UChar r1, IRTemp op2addr)
7652 {
7653    IRTemp op2 = newTemp(Ity_I64);
7654 
7655    assign(op2, load(Ity_I64, mkexpr(op2addr)));
7656    put_gpr_dw0(r1, mkexpr(op2));
7657    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7658 
7659    return "ltg";
7660 }
7661 
7662 static const HChar *
7663 s390_irgen_LTGF(UChar r1, IRTemp op2addr)
7664 {
7665    IRTemp op2 = newTemp(Ity_I64);
7666 
7667    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7668    put_gpr_dw0(r1, mkexpr(op2));
7669    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7670 
7671    return "ltgf";
7672 }
7673 
7674 static const HChar *
7675 s390_irgen_LBR(UChar r1, UChar r2)
7676 {
7677    put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
7678 
7679    return "lbr";
7680 }
7681 
7682 static const HChar *
7683 s390_irgen_LGBR(UChar r1, UChar r2)
7684 {
7685    put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
7686 
7687    return "lgbr";
7688 }
7689 
7690 static const HChar *
7691 s390_irgen_LB(UChar r1, IRTemp op2addr)
7692 {
7693    put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
7694 
7695    return "lb";
7696 }
7697 
7698 static const HChar *
7699 s390_irgen_LGB(UChar r1, IRTemp op2addr)
7700 {
7701    put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
7702 
7703    return "lgb";
7704 }
7705 
7706 static const HChar *
7707 s390_irgen_LBH(UChar r1, IRTemp op2addr)
7708 {
7709    put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
7710 
7711    return "lbh";
7712 }
7713 
7714 static const HChar *
7715 s390_irgen_LCR(UChar r1, UChar r2)
7716 {
7717    Int op1;
7718    IRTemp op2 = newTemp(Ity_I32);
7719    IRTemp result = newTemp(Ity_I32);
7720 
7721    op1 = 0;
7722    assign(op2, get_gpr_w1(r2));
7723    assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
7724    put_gpr_w1(r1, mkexpr(result));
7725    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
7726                        op1)), op2);
7727 
7728    return "lcr";
7729 }
7730 
7731 static const HChar *
7732 s390_irgen_LCGR(UChar r1, UChar r2)
7733 {
7734    Long op1;
7735    IRTemp op2 = newTemp(Ity_I64);
7736    IRTemp result = newTemp(Ity_I64);
7737 
7738    op1 = 0ULL;
7739    assign(op2, get_gpr_dw0(r2));
7740    assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
7741    put_gpr_dw0(r1, mkexpr(result));
7742    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
7743                        op1)), op2);
7744 
7745    return "lcgr";
7746 }
7747 
7748 static const HChar *
7749 s390_irgen_LCGFR(UChar r1, UChar r2)
7750 {
7751    Long op1;
7752    IRTemp op2 = newTemp(Ity_I64);
7753    IRTemp result = newTemp(Ity_I64);
7754 
7755    op1 = 0ULL;
7756    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7757    assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
7758    put_gpr_dw0(r1, mkexpr(result));
7759    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
7760                        op1)), op2);
7761 
7762    return "lcgfr";
7763 }
7764 
7765 static const HChar *
7766 s390_irgen_LHR(UChar r1, UChar r2)
7767 {
7768    put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
7769 
7770    return "lhr";
7771 }
7772 
7773 static const HChar *
7774 s390_irgen_LGHR(UChar r1, UChar r2)
7775 {
7776    put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
7777 
7778    return "lghr";
7779 }
7780 
7781 static const HChar *
7782 s390_irgen_LH(UChar r1, IRTemp op2addr)
7783 {
7784    put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7785 
7786    return "lh";
7787 }
7788 
7789 static const HChar *
7790 s390_irgen_LHY(UChar r1, IRTemp op2addr)
7791 {
7792    put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7793 
7794    return "lhy";
7795 }
7796 
7797 static const HChar *
7798 s390_irgen_LGH(UChar r1, IRTemp op2addr)
7799 {
7800    put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
7801 
7802    return "lgh";
7803 }
7804 
7805 static const HChar *
7806 s390_irgen_LHI(UChar r1, UShort i2)
7807 {
7808    put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
7809 
7810    return "lhi";
7811 }
7812 
7813 static const HChar *
7814 s390_irgen_LGHI(UChar r1, UShort i2)
7815 {
7816    put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
7817 
7818    return "lghi";
7819 }
7820 
7821 static const HChar *
7822 s390_irgen_LHRL(UChar r1, UInt i2)
7823 {
7824    put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
7825               ((ULong)(Long)(Int)i2 << 1)))));
7826 
7827    return "lhrl";
7828 }
7829 
7830 static const HChar *
7831 s390_irgen_LGHRL(UChar r1, UInt i2)
7832 {
7833    put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
7834                ((ULong)(Long)(Int)i2 << 1)))));
7835 
7836    return "lghrl";
7837 }
7838 
7839 static const HChar *
7840 s390_irgen_LHH(UChar r1, IRTemp op2addr)
7841 {
7842    put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7843 
7844    return "lhh";
7845 }
7846 
7847 static const HChar *
7848 s390_irgen_LFH(UChar r1, IRTemp op2addr)
7849 {
7850    put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
7851 
7852    return "lfh";
7853 }
7854 
7855 static const HChar *
7856 s390_irgen_LLGFR(UChar r1, UChar r2)
7857 {
7858    put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
7859 
7860    return "llgfr";
7861 }
7862 
7863 static const HChar *
7864 s390_irgen_LLGF(UChar r1, IRTemp op2addr)
7865 {
7866    put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7867 
7868    return "llgf";
7869 }
7870 
7871 static const HChar *
7872 s390_irgen_LLGFRL(UChar r1, UInt i2)
7873 {
7874    put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
7875                ((ULong)(Long)(Int)i2 << 1)))));
7876 
7877    return "llgfrl";
7878 }
7879 
7880 static const HChar *
7881 s390_irgen_LLCR(UChar r1, UChar r2)
7882 {
7883    put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
7884 
7885    return "llcr";
7886 }
7887 
7888 static const HChar *
7889 s390_irgen_LLGCR(UChar r1, UChar r2)
7890 {
7891    put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
7892 
7893    return "llgcr";
7894 }
7895 
7896 static const HChar *
7897 s390_irgen_LLC(UChar r1, IRTemp op2addr)
7898 {
7899    put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
7900 
7901    return "llc";
7902 }
7903 
7904 static const HChar *
7905 s390_irgen_LLGC(UChar r1, IRTemp op2addr)
7906 {
7907    put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
7908 
7909    return "llgc";
7910 }
7911 
7912 static const HChar *
7913 s390_irgen_LLCH(UChar r1, IRTemp op2addr)
7914 {
7915    put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
7916 
7917    return "llch";
7918 }
7919 
7920 static const HChar *
7921 s390_irgen_LLHR(UChar r1, UChar r2)
7922 {
7923    put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
7924 
7925    return "llhr";
7926 }
7927 
7928 static const HChar *
7929 s390_irgen_LLGHR(UChar r1, UChar r2)
7930 {
7931    put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
7932 
7933    return "llghr";
7934 }
7935 
7936 static const HChar *
7937 s390_irgen_LLH(UChar r1, IRTemp op2addr)
7938 {
7939    put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
7940 
7941    return "llh";
7942 }
7943 
7944 static const HChar *
7945 s390_irgen_LLGH(UChar r1, IRTemp op2addr)
7946 {
7947    put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
7948 
7949    return "llgh";
7950 }
7951 
7952 static const HChar *
7953 s390_irgen_LLHRL(UChar r1, UInt i2)
7954 {
7955    put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
7956               ((ULong)(Long)(Int)i2 << 1)))));
7957 
7958    return "llhrl";
7959 }
7960 
7961 static const HChar *
7962 s390_irgen_LLGHRL(UChar r1, UInt i2)
7963 {
7964    put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
7965                ((ULong)(Long)(Int)i2 << 1)))));
7966 
7967    return "llghrl";
7968 }
7969 
7970 static const HChar *
7971 s390_irgen_LLHH(UChar r1, IRTemp op2addr)
7972 {
7973    put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
7974 
7975    return "llhh";
7976 }
7977 
7978 static const HChar *
7979 s390_irgen_LLIHF(UChar r1, UInt i2)
7980 {
7981    put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
7982 
7983    return "llihf";
7984 }
7985 
7986 static const HChar *
7987 s390_irgen_LLIHH(UChar r1, UShort i2)
7988 {
7989    put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
7990 
7991    return "llihh";
7992 }
7993 
7994 static const HChar *
7995 s390_irgen_LLIHL(UChar r1, UShort i2)
7996 {
7997    put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
7998 
7999    return "llihl";
8000 }
8001 
8002 static const HChar *
8003 s390_irgen_LLILF(UChar r1, UInt i2)
8004 {
8005    put_gpr_dw0(r1, mkU64(i2));
8006 
8007    return "llilf";
8008 }
8009 
8010 static const HChar *
8011 s390_irgen_LLILH(UChar r1, UShort i2)
8012 {
8013    put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
8014 
8015    return "llilh";
8016 }
8017 
8018 static const HChar *
8019 s390_irgen_LLILL(UChar r1, UShort i2)
8020 {
8021    put_gpr_dw0(r1, mkU64(i2));
8022 
8023    return "llill";
8024 }
8025 
8026 static const HChar *
8027 s390_irgen_LLGTR(UChar r1, UChar r2)
8028 {
8029    put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
8030                mkU32(2147483647))));
8031 
8032    return "llgtr";
8033 }
8034 
8035 static const HChar *
8036 s390_irgen_LLGT(UChar r1, IRTemp op2addr)
8037 {
8038    put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
8039                mkexpr(op2addr)), mkU32(2147483647))));
8040 
8041    return "llgt";
8042 }
8043 
8044 static const HChar *
8045 s390_irgen_LNR(UChar r1, UChar r2)
8046 {
8047    IRTemp op2 = newTemp(Ity_I32);
8048    IRTemp result = newTemp(Ity_I32);
8049 
8050    assign(op2, get_gpr_w1(r2));
8051    assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
8052           binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
8053    put_gpr_w1(r1, mkexpr(result));
8054    s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
8055 
8056    return "lnr";
8057 }
8058 
8059 static const HChar *
8060 s390_irgen_LNGR(UChar r1, UChar r2)
8061 {
8062    IRTemp op2 = newTemp(Ity_I64);
8063    IRTemp result = newTemp(Ity_I64);
8064 
8065    assign(op2, get_gpr_dw0(r2));
8066    assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
8067           binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
8068    put_gpr_dw0(r1, mkexpr(result));
8069    s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
8070 
8071    return "lngr";
8072 }
8073 
8074 static const HChar *
8075 s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
8076 {
8077    IRTemp op2 = newTemp(Ity_I64);
8078    IRTemp result = newTemp(Ity_I64);
8079 
8080    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
8081    assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
8082           binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
8083    put_gpr_dw0(r1, mkexpr(result));
8084    s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
8085 
8086    return "lngfr";
8087 }
8088 
8089 static const HChar *
8090 s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
8091 {
8092    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
8093    put_gpr_w1(r1, get_gpr_w1(r2));
8094 
8095    return "locr";
8096 }
8097 
8098 static const HChar *
8099 s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
8100 {
8101    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
8102    put_gpr_dw0(r1, get_gpr_dw0(r2));
8103 
8104    return "locgr";
8105 }
8106 
8107 static const HChar *
8108 s390_irgen_LOC(UChar r1, IRTemp op2addr)
8109 {
8110    /* condition is checked in format handler */
8111    put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
8112 
8113    return "loc";
8114 }
8115 
8116 static const HChar *
8117 s390_irgen_LOCG(UChar r1, IRTemp op2addr)
8118 {
8119    /* condition is checked in format handler */
8120    put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
8121 
8122    return "locg";
8123 }
8124 
8125 static const HChar *
8126 s390_irgen_LPQ(UChar r1, IRTemp op2addr)
8127 {
8128    put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
8129    put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
8130                ));
8131 
8132    return "lpq";
8133 }
8134 
8135 static const HChar *
8136 s390_irgen_LPR(UChar r1, UChar r2)
8137 {
8138    IRTemp op2 = newTemp(Ity_I32);
8139    IRTemp result = newTemp(Ity_I32);
8140 
8141    assign(op2, get_gpr_w1(r2));
8142    assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
8143           binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
8144    put_gpr_w1(r1, mkexpr(result));
8145    s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
8146 
8147    return "lpr";
8148 }
8149 
8150 static const HChar *
8151 s390_irgen_LPGR(UChar r1, UChar r2)
8152 {
8153    IRTemp op2 = newTemp(Ity_I64);
8154    IRTemp result = newTemp(Ity_I64);
8155 
8156    assign(op2, get_gpr_dw0(r2));
8157    assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
8158           binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
8159    put_gpr_dw0(r1, mkexpr(result));
8160    s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
8161 
8162    return "lpgr";
8163 }
8164 
8165 static const HChar *
8166 s390_irgen_LPGFR(UChar r1, UChar r2)
8167 {
8168    IRTemp op2 = newTemp(Ity_I64);
8169    IRTemp result = newTemp(Ity_I64);
8170 
8171    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8172    assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
8173           binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
8174    put_gpr_dw0(r1, mkexpr(result));
8175    s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
8176 
8177    return "lpgfr";
8178 }
8179 
8180 static const HChar *
8181 s390_irgen_LRVR(UChar r1, UChar r2)
8182 {
8183    IRTemp b0 = newTemp(Ity_I8);
8184    IRTemp b1 = newTemp(Ity_I8);
8185    IRTemp b2 = newTemp(Ity_I8);
8186    IRTemp b3 = newTemp(Ity_I8);
8187 
8188    assign(b3, get_gpr_b7(r2));
8189    assign(b2, get_gpr_b6(r2));
8190    assign(b1, get_gpr_b5(r2));
8191    assign(b0, get_gpr_b4(r2));
8192    put_gpr_b4(r1, mkexpr(b3));
8193    put_gpr_b5(r1, mkexpr(b2));
8194    put_gpr_b6(r1, mkexpr(b1));
8195    put_gpr_b7(r1, mkexpr(b0));
8196 
8197    return "lrvr";
8198 }
8199 
8200 static const HChar *
8201 s390_irgen_LRVGR(UChar r1, UChar r2)
8202 {
8203    IRTemp b0 = newTemp(Ity_I8);
8204    IRTemp b1 = newTemp(Ity_I8);
8205    IRTemp b2 = newTemp(Ity_I8);
8206    IRTemp b3 = newTemp(Ity_I8);
8207    IRTemp b4 = newTemp(Ity_I8);
8208    IRTemp b5 = newTemp(Ity_I8);
8209    IRTemp b6 = newTemp(Ity_I8);
8210    IRTemp b7 = newTemp(Ity_I8);
8211 
8212    assign(b7, get_gpr_b7(r2));
8213    assign(b6, get_gpr_b6(r2));
8214    assign(b5, get_gpr_b5(r2));
8215    assign(b4, get_gpr_b4(r2));
8216    assign(b3, get_gpr_b3(r2));
8217    assign(b2, get_gpr_b2(r2));
8218    assign(b1, get_gpr_b1(r2));
8219    assign(b0, get_gpr_b0(r2));
8220    put_gpr_b0(r1, mkexpr(b7));
8221    put_gpr_b1(r1, mkexpr(b6));
8222    put_gpr_b2(r1, mkexpr(b5));
8223    put_gpr_b3(r1, mkexpr(b4));
8224    put_gpr_b4(r1, mkexpr(b3));
8225    put_gpr_b5(r1, mkexpr(b2));
8226    put_gpr_b6(r1, mkexpr(b1));
8227    put_gpr_b7(r1, mkexpr(b0));
8228 
8229    return "lrvgr";
8230 }
8231 
8232 static const HChar *
8233 s390_irgen_LRVH(UChar r1, IRTemp op2addr)
8234 {
8235    IRTemp op2 = newTemp(Ity_I16);
8236 
8237    assign(op2, load(Ity_I16, mkexpr(op2addr)));
8238    put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
8239    put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
8240 
8241    return "lrvh";
8242 }
8243 
8244 static const HChar *
8245 s390_irgen_LRV(UChar r1, IRTemp op2addr)
8246 {
8247    IRTemp op2 = newTemp(Ity_I32);
8248 
8249    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8250    put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
8251    put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
8252               mkU8(8)), mkU32(255))));
8253    put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
8254               mkU8(16)), mkU32(255))));
8255    put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
8256               mkU8(24)), mkU32(255))));
8257 
8258    return "lrv";
8259 }
8260 
8261 static const HChar *
8262 s390_irgen_LRVG(UChar r1, IRTemp op2addr)
8263 {
8264    IRTemp op2 = newTemp(Ity_I64);
8265 
8266    assign(op2, load(Ity_I64, mkexpr(op2addr)));
8267    put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
8268    put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8269               mkU8(8)), mkU64(255))));
8270    put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8271               mkU8(16)), mkU64(255))));
8272    put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8273               mkU8(24)), mkU64(255))));
8274    put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8275               mkU8(32)), mkU64(255))));
8276    put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8277               mkU8(40)), mkU64(255))));
8278    put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8279               mkU8(48)), mkU64(255))));
8280    put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8281               mkU8(56)), mkU64(255))));
8282 
8283    return "lrvg";
8284 }
8285 
8286 static const HChar *
8287 s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
8288 {
8289    store(mkexpr(op1addr), mkU16(i2));
8290 
8291    return "mvhhi";
8292 }
8293 
8294 static const HChar *
8295 s390_irgen_MVHI(UShort i2, IRTemp op1addr)
8296 {
8297    store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
8298 
8299    return "mvhi";
8300 }
8301 
8302 static const HChar *
8303 s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
8304 {
8305    store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
8306 
8307    return "mvghi";
8308 }
8309 
8310 static const HChar *
8311 s390_irgen_MVI(UChar i2, IRTemp op1addr)
8312 {
8313    store(mkexpr(op1addr), mkU8(i2));
8314 
8315    return "mvi";
8316 }
8317 
8318 static const HChar *
8319 s390_irgen_MVIY(UChar i2, IRTemp op1addr)
8320 {
8321    store(mkexpr(op1addr), mkU8(i2));
8322 
8323    return "mviy";
8324 }
8325 
8326 static const HChar *
8327 s390_irgen_MR(UChar r1, UChar r2)
8328 {
8329    IRTemp op1 = newTemp(Ity_I32);
8330    IRTemp op2 = newTemp(Ity_I32);
8331    IRTemp result = newTemp(Ity_I64);
8332 
8333    assign(op1, get_gpr_w1(r1 + 1));
8334    assign(op2, get_gpr_w1(r2));
8335    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8336    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8337    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8338 
8339    return "mr";
8340 }
8341 
8342 static const HChar *
8343 s390_irgen_M(UChar r1, IRTemp op2addr)
8344 {
8345    IRTemp op1 = newTemp(Ity_I32);
8346    IRTemp op2 = newTemp(Ity_I32);
8347    IRTemp result = newTemp(Ity_I64);
8348 
8349    assign(op1, get_gpr_w1(r1 + 1));
8350    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8351    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8352    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8353    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8354 
8355    return "m";
8356 }
8357 
8358 static const HChar *
8359 s390_irgen_MFY(UChar r1, IRTemp op2addr)
8360 {
8361    IRTemp op1 = newTemp(Ity_I32);
8362    IRTemp op2 = newTemp(Ity_I32);
8363    IRTemp result = newTemp(Ity_I64);
8364 
8365    assign(op1, get_gpr_w1(r1 + 1));
8366    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8367    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8368    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8369    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8370 
8371    return "mfy";
8372 }
8373 
8374 static const HChar *
8375 s390_irgen_MG(UChar r1, IRTemp op2addr)
8376 {
8377    IRTemp op1 = newTemp(Ity_I64);
8378    IRTemp op2 = newTemp(Ity_I64);
8379    IRTemp result = newTemp(Ity_I128);
8380 
8381    assign(op1, get_gpr_dw0(r1 + 1));
8382    assign(op2, load(Ity_I64, mkexpr(op2addr)));
8383    assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
8384    put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
8385    put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
8386 
8387    return "mg";
8388 }
8389 
8390 static const HChar *
8391 s390_irgen_MGH(UChar r1, IRTemp op2addr)
8392 {
8393    IRTemp op1 = newTemp(Ity_I64);
8394    IRTemp op2 = newTemp(Ity_I16);
8395    IRTemp result = newTemp(Ity_I128);
8396 
8397    assign(op1, get_gpr_dw0(r1));
8398    assign(op2, load(Ity_I16, mkexpr(op2addr)));
8399    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64, mkexpr(op2))
8400    ));
8401    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8402 
8403    return "mgh";
8404 }
8405 
8406 static const HChar *
8407 s390_irgen_MGRK(UChar r3, UChar r1, UChar r2)
8408 {
8409    IRTemp op2 = newTemp(Ity_I64);
8410    IRTemp op3 = newTemp(Ity_I64);
8411    IRTemp result = newTemp(Ity_I128);
8412 
8413    assign(op2, get_gpr_dw0(r2));
8414    assign(op3, get_gpr_dw0(r3));
8415    assign(result, binop(Iop_MullS64, mkexpr(op2), mkexpr(op3)));
8416    put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
8417    put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
8418 
8419    return "mgrk";
8420 }
8421 
8422 static const HChar *
8423 s390_irgen_MH(UChar r1, IRTemp op2addr)
8424 {
8425    IRTemp op1 = newTemp(Ity_I32);
8426    IRTemp op2 = newTemp(Ity_I16);
8427    IRTemp result = newTemp(Ity_I64);
8428 
8429    assign(op1, get_gpr_w1(r1));
8430    assign(op2, load(Ity_I16, mkexpr(op2addr)));
8431    assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
8432           ));
8433    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8434 
8435    return "mh";
8436 }
8437 
8438 static const HChar *
8439 s390_irgen_MHY(UChar r1, IRTemp op2addr)
8440 {
8441    IRTemp op1 = newTemp(Ity_I32);
8442    IRTemp op2 = newTemp(Ity_I16);
8443    IRTemp result = newTemp(Ity_I64);
8444 
8445    assign(op1, get_gpr_w1(r1));
8446    assign(op2, load(Ity_I16, mkexpr(op2addr)));
8447    assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
8448           ));
8449    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8450 
8451    return "mhy";
8452 }
8453 
8454 static const HChar *
8455 s390_irgen_MHI(UChar r1, UShort i2)
8456 {
8457    IRTemp op1 = newTemp(Ity_I32);
8458    Short op2;
8459    IRTemp result = newTemp(Ity_I64);
8460 
8461    assign(op1, get_gpr_w1(r1));
8462    op2 = (Short)i2;
8463    assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
8464           mkU16((UShort)op2))));
8465    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8466 
8467    return "mhi";
8468 }
8469 
8470 static const HChar *
8471 s390_irgen_MGHI(UChar r1, UShort i2)
8472 {
8473    IRTemp op1 = newTemp(Ity_I64);
8474    Short op2;
8475    IRTemp result = newTemp(Ity_I128);
8476 
8477    assign(op1, get_gpr_dw0(r1));
8478    op2 = (Short)i2;
8479    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
8480           mkU16((UShort)op2))));
8481    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8482 
8483    return "mghi";
8484 }
8485 
8486 static const HChar *
8487 s390_irgen_MLR(UChar r1, UChar r2)
8488 {
8489    IRTemp op1 = newTemp(Ity_I32);
8490    IRTemp op2 = newTemp(Ity_I32);
8491    IRTemp result = newTemp(Ity_I64);
8492 
8493    assign(op1, get_gpr_w1(r1 + 1));
8494    assign(op2, get_gpr_w1(r2));
8495    assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
8496    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8497    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8498 
8499    return "mlr";
8500 }
8501 
8502 static const HChar *
8503 s390_irgen_MLGR(UChar r1, UChar r2)
8504 {
8505    IRTemp op1 = newTemp(Ity_I64);
8506    IRTemp op2 = newTemp(Ity_I64);
8507    IRTemp result = newTemp(Ity_I128);
8508 
8509    assign(op1, get_gpr_dw0(r1 + 1));
8510    assign(op2, get_gpr_dw0(r2));
8511    assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
8512    put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
8513    put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
8514 
8515    return "mlgr";
8516 }
8517 
8518 static const HChar *
8519 s390_irgen_ML(UChar r1, IRTemp op2addr)
8520 {
8521    IRTemp op1 = newTemp(Ity_I32);
8522    IRTemp op2 = newTemp(Ity_I32);
8523    IRTemp result = newTemp(Ity_I64);
8524 
8525    assign(op1, get_gpr_w1(r1 + 1));
8526    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8527    assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
8528    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8529    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8530 
8531    return "ml";
8532 }
8533 
8534 static const HChar *
8535 s390_irgen_MLG(UChar r1, IRTemp op2addr)
8536 {
8537    IRTemp op1 = newTemp(Ity_I64);
8538    IRTemp op2 = newTemp(Ity_I64);
8539    IRTemp result = newTemp(Ity_I128);
8540 
8541    assign(op1, get_gpr_dw0(r1 + 1));
8542    assign(op2, load(Ity_I64, mkexpr(op2addr)));
8543    assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
8544    put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
8545    put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
8546 
8547    return "mlg";
8548 }
8549 
8550 static const HChar *
8551 s390_irgen_MSR(UChar r1, UChar r2)
8552 {
8553    IRTemp op1 = newTemp(Ity_I32);
8554    IRTemp op2 = newTemp(Ity_I32);
8555    IRTemp result = newTemp(Ity_I64);
8556 
8557    assign(op1, get_gpr_w1(r1));
8558    assign(op2, get_gpr_w1(r2));
8559    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8560    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8561 
8562    return "msr";
8563 }
8564 
8565 static const HChar *
8566 s390_irgen_MSGR(UChar r1, UChar r2)
8567 {
8568    IRTemp op1 = newTemp(Ity_I64);
8569    IRTemp op2 = newTemp(Ity_I64);
8570    IRTemp result = newTemp(Ity_I128);
8571 
8572    assign(op1, get_gpr_dw0(r1));
8573    assign(op2, get_gpr_dw0(r2));
8574    assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
8575    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8576 
8577    return "msgr";
8578 }
8579 
8580 static const HChar *
8581 s390_irgen_MSGFR(UChar r1, UChar r2)
8582 {
8583    IRTemp op1 = newTemp(Ity_I64);
8584    IRTemp op2 = newTemp(Ity_I32);
8585    IRTemp result = newTemp(Ity_I128);
8586 
8587    assign(op1, get_gpr_dw0(r1));
8588    assign(op2, get_gpr_w1(r2));
8589    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
8590           ));
8591    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8592 
8593    return "msgfr";
8594 }
8595 
8596 static const HChar *
8597 s390_irgen_MS(UChar r1, IRTemp op2addr)
8598 {
8599    IRTemp op1 = newTemp(Ity_I32);
8600    IRTemp op2 = newTemp(Ity_I32);
8601    IRTemp result = newTemp(Ity_I64);
8602 
8603    assign(op1, get_gpr_w1(r1));
8604    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8605    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8606    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8607 
8608    return "ms";
8609 }
8610 
8611 static const HChar *
8612 s390_irgen_MSC(UChar r1, IRTemp op2addr)
8613 {
8614    IRTemp op1 = newTemp(Ity_I32);
8615    IRTemp op2 = newTemp(Ity_I32);
8616    IRTemp result = newTemp(Ity_I64);
8617 
8618    assign(op1, get_gpr_w1(r1));
8619    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8620    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8621    s390_cc_thunk_putSS(S390_CC_OP_MUL_32, op1, op2);
8622    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8623 
8624    return "msc";
8625 }
8626 
8627 static const HChar *
8628 s390_irgen_MSRKC(UChar r3, UChar r1, UChar r2)
8629 {
8630    IRTemp op2 = newTemp(Ity_I32);
8631    IRTemp op3 = newTemp(Ity_I32);
8632    IRTemp result = newTemp(Ity_I64);
8633 
8634    assign(op2, get_gpr_w1(r2));
8635    assign(op3, get_gpr_w1(r3));
8636    assign(result, binop(Iop_MullS32, mkexpr(op2), mkexpr(op3)));
8637    s390_cc_thunk_putSS(S390_CC_OP_MUL_32, op2, op3);
8638    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8639 
8640    return "msrkc";
8641 }
8642 
8643 static const HChar *
8644 s390_irgen_MSY(UChar r1, IRTemp op2addr)
8645 {
8646    IRTemp op1 = newTemp(Ity_I32);
8647    IRTemp op2 = newTemp(Ity_I32);
8648    IRTemp result = newTemp(Ity_I64);
8649 
8650    assign(op1, get_gpr_w1(r1));
8651    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8652    assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8653    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8654 
8655    return "msy";
8656 }
8657 
8658 static const HChar *
8659 s390_irgen_MSG(UChar r1, IRTemp op2addr)
8660 {
8661    IRTemp op1 = newTemp(Ity_I64);
8662    IRTemp op2 = newTemp(Ity_I64);
8663    IRTemp result = newTemp(Ity_I128);
8664 
8665    assign(op1, get_gpr_dw0(r1));
8666    assign(op2, load(Ity_I64, mkexpr(op2addr)));
8667    assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
8668    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8669 
8670    return "msg";
8671 }
8672 
8673 static const HChar *
8674 s390_irgen_MSGC(UChar r1, IRTemp op2addr)
8675 {
8676    IRTemp op1 = newTemp(Ity_I64);
8677    IRTemp op2 = newTemp(Ity_I64);
8678    IRTemp result = newTemp(Ity_I128);
8679 
8680    assign(op1, get_gpr_dw0(r1));
8681    assign(op2, load(Ity_I64, mkexpr(op2addr)));
8682    assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
8683    s390_cc_thunk_putSS(S390_CC_OP_MUL_64, op1, op2);
8684    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8685 
8686    return "msgc";
8687 }
8688 
8689 static const HChar *
8690 s390_irgen_MSGF(UChar r1, IRTemp op2addr)
8691 {
8692    IRTemp op1 = newTemp(Ity_I64);
8693    IRTemp op2 = newTemp(Ity_I32);
8694    IRTemp result = newTemp(Ity_I128);
8695 
8696    assign(op1, get_gpr_dw0(r1));
8697    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8698    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
8699           ));
8700    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8701 
8702    return "msgf";
8703 }
8704 
8705 static const HChar *
8706 s390_irgen_MSFI(UChar r1, UInt i2)
8707 {
8708    IRTemp op1 = newTemp(Ity_I32);
8709    Int op2;
8710    IRTemp result = newTemp(Ity_I64);
8711 
8712    assign(op1, get_gpr_w1(r1));
8713    op2 = (Int)i2;
8714    assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
8715    put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8716 
8717    return "msfi";
8718 }
8719 
8720 static const HChar *
8721 s390_irgen_MSGFI(UChar r1, UInt i2)
8722 {
8723    IRTemp op1 = newTemp(Ity_I64);
8724    Int op2;
8725    IRTemp result = newTemp(Ity_I128);
8726 
8727    assign(op1, get_gpr_dw0(r1));
8728    op2 = (Int)i2;
8729    assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
8730           op2))));
8731    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8732 
8733    return "msgfi";
8734 }
8735 
8736 static const HChar *
8737 s390_irgen_MSGRKC(UChar r3, UChar r1, UChar r2)
8738 {
8739    IRTemp op2 = newTemp(Ity_I64);
8740    IRTemp op3 = newTemp(Ity_I64);
8741    IRTemp result = newTemp(Ity_I128);
8742 
8743    assign(op2, get_gpr_dw0(r2));
8744    assign(op3, get_gpr_dw0(r3));
8745    assign(result, binop(Iop_MullS64, mkexpr(op2), mkexpr(op3)));
8746    s390_cc_thunk_putSS(S390_CC_OP_MUL_64, op2, op3);
8747    put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8748 
8749    return "msgrkc";
8750 }
8751 
8752 static const HChar *
8753 s390_irgen_OR(UChar r1, UChar r2)
8754 {
8755    IRTemp op1 = newTemp(Ity_I32);
8756    IRTemp op2 = newTemp(Ity_I32);
8757    IRTemp result = newTemp(Ity_I32);
8758 
8759    assign(op1, get_gpr_w1(r1));
8760    assign(op2, get_gpr_w1(r2));
8761    assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
8762    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8763    put_gpr_w1(r1, mkexpr(result));
8764 
8765    return "or";
8766 }
8767 
8768 static const HChar *
8769 s390_irgen_OGR(UChar r1, UChar r2)
8770 {
8771    IRTemp op1 = newTemp(Ity_I64);
8772    IRTemp op2 = newTemp(Ity_I64);
8773    IRTemp result = newTemp(Ity_I64);
8774 
8775    assign(op1, get_gpr_dw0(r1));
8776    assign(op2, get_gpr_dw0(r2));
8777    assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
8778    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8779    put_gpr_dw0(r1, mkexpr(result));
8780 
8781    return "ogr";
8782 }
8783 
8784 static const HChar *
8785 s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
8786 {
8787    IRTemp op2 = newTemp(Ity_I32);
8788    IRTemp op3 = newTemp(Ity_I32);
8789    IRTemp result = newTemp(Ity_I32);
8790 
8791    assign(op2, get_gpr_w1(r2));
8792    assign(op3, get_gpr_w1(r3));
8793    assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
8794    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8795    put_gpr_w1(r1, mkexpr(result));
8796 
8797    return "ork";
8798 }
8799 
8800 static const HChar *
8801 s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
8802 {
8803    IRTemp op2 = newTemp(Ity_I64);
8804    IRTemp op3 = newTemp(Ity_I64);
8805    IRTemp result = newTemp(Ity_I64);
8806 
8807    assign(op2, get_gpr_dw0(r2));
8808    assign(op3, get_gpr_dw0(r3));
8809    assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
8810    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8811    put_gpr_dw0(r1, mkexpr(result));
8812 
8813    return "ogrk";
8814 }
8815 
8816 static const HChar *
8817 s390_irgen_O(UChar r1, IRTemp op2addr)
8818 {
8819    IRTemp op1 = newTemp(Ity_I32);
8820    IRTemp op2 = newTemp(Ity_I32);
8821    IRTemp result = newTemp(Ity_I32);
8822 
8823    assign(op1, get_gpr_w1(r1));
8824    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8825    assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
8826    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8827    put_gpr_w1(r1, mkexpr(result));
8828 
8829    return "o";
8830 }
8831 
8832 static const HChar *
8833 s390_irgen_OY(UChar r1, IRTemp op2addr)
8834 {
8835    IRTemp op1 = newTemp(Ity_I32);
8836    IRTemp op2 = newTemp(Ity_I32);
8837    IRTemp result = newTemp(Ity_I32);
8838 
8839    assign(op1, get_gpr_w1(r1));
8840    assign(op2, load(Ity_I32, mkexpr(op2addr)));
8841    assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
8842    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8843    put_gpr_w1(r1, mkexpr(result));
8844 
8845    return "oy";
8846 }
8847 
8848 static const HChar *
8849 s390_irgen_OG(UChar r1, IRTemp op2addr)
8850 {
8851    IRTemp op1 = newTemp(Ity_I64);
8852    IRTemp op2 = newTemp(Ity_I64);
8853    IRTemp result = newTemp(Ity_I64);
8854 
8855    assign(op1, get_gpr_dw0(r1));
8856    assign(op2, load(Ity_I64, mkexpr(op2addr)));
8857    assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
8858    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8859    put_gpr_dw0(r1, mkexpr(result));
8860 
8861    return "og";
8862 }
8863 
8864 static const HChar *
8865 s390_irgen_OI(UChar i2, IRTemp op1addr)
8866 {
8867    IRTemp op1 = newTemp(Ity_I8);
8868    UChar op2;
8869    IRTemp result = newTemp(Ity_I8);
8870 
8871    assign(op1, load(Ity_I8, mkexpr(op1addr)));
8872    op2 = i2;
8873    assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
8874    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8875    store(mkexpr(op1addr), mkexpr(result));
8876 
8877    return "oi";
8878 }
8879 
8880 static const HChar *
8881 s390_irgen_OIY(UChar i2, IRTemp op1addr)
8882 {
8883    IRTemp op1 = newTemp(Ity_I8);
8884    UChar op2;
8885    IRTemp result = newTemp(Ity_I8);
8886 
8887    assign(op1, load(Ity_I8, mkexpr(op1addr)));
8888    op2 = i2;
8889    assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
8890    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8891    store(mkexpr(op1addr), mkexpr(result));
8892 
8893    return "oiy";
8894 }
8895 
8896 static const HChar *
8897 s390_irgen_OIHF(UChar r1, UInt i2)
8898 {
8899    IRTemp op1 = newTemp(Ity_I32);
8900    UInt op2;
8901    IRTemp result = newTemp(Ity_I32);
8902 
8903    assign(op1, get_gpr_w0(r1));
8904    op2 = i2;
8905    assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
8906    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8907    put_gpr_w0(r1, mkexpr(result));
8908 
8909    return "oihf";
8910 }
8911 
8912 static const HChar *
8913 s390_irgen_OIHH(UChar r1, UShort i2)
8914 {
8915    IRTemp op1 = newTemp(Ity_I16);
8916    UShort op2;
8917    IRTemp result = newTemp(Ity_I16);
8918 
8919    assign(op1, get_gpr_hw0(r1));
8920    op2 = i2;
8921    assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
8922    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8923    put_gpr_hw0(r1, mkexpr(result));
8924 
8925    return "oihh";
8926 }
8927 
8928 static const HChar *
8929 s390_irgen_OIHL(UChar r1, UShort i2)
8930 {
8931    IRTemp op1 = newTemp(Ity_I16);
8932    UShort op2;
8933    IRTemp result = newTemp(Ity_I16);
8934 
8935    assign(op1, get_gpr_hw1(r1));
8936    op2 = i2;
8937    assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
8938    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8939    put_gpr_hw1(r1, mkexpr(result));
8940 
8941    return "oihl";
8942 }
8943 
8944 static const HChar *
8945 s390_irgen_OILF(UChar r1, UInt i2)
8946 {
8947    IRTemp op1 = newTemp(Ity_I32);
8948    UInt op2;
8949    IRTemp result = newTemp(Ity_I32);
8950 
8951    assign(op1, get_gpr_w1(r1));
8952    op2 = i2;
8953    assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
8954    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8955    put_gpr_w1(r1, mkexpr(result));
8956 
8957    return "oilf";
8958 }
8959 
8960 static const HChar *
8961 s390_irgen_OILH(UChar r1, UShort i2)
8962 {
8963    IRTemp op1 = newTemp(Ity_I16);
8964    UShort op2;
8965    IRTemp result = newTemp(Ity_I16);
8966 
8967    assign(op1, get_gpr_hw2(r1));
8968    op2 = i2;
8969    assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
8970    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8971    put_gpr_hw2(r1, mkexpr(result));
8972 
8973    return "oilh";
8974 }
8975 
8976 static const HChar *
8977 s390_irgen_OILL(UChar r1, UShort i2)
8978 {
8979    IRTemp op1 = newTemp(Ity_I16);
8980    UShort op2;
8981    IRTemp result = newTemp(Ity_I16);
8982 
8983    assign(op1, get_gpr_hw3(r1));
8984    op2 = i2;
8985    assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
8986    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
8987    put_gpr_hw3(r1, mkexpr(result));
8988 
8989    return "oill";
8990 }
8991 
8992 static const HChar *
8993 s390_irgen_PFD(void)
8994 {
8995 
8996    return "pfd";
8997 }
8998 
8999 static const HChar *
9000 s390_irgen_PFDRL(void)
9001 {
9002 
9003    return "pfdrl";
9004 }
9005 
9006 static IRExpr *
9007 get_rounding_mode_from_gr0(void)
9008 {
9009    IRTemp rm_bits = newTemp(Ity_I32);
9010    IRExpr *s390rm;
9011    IRExpr *irrm;
9012 
9013    /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
9014       when PFPO insn is called. So, extract the bits at [60:63] */
9015    assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
9016    s390rm = mkexpr(rm_bits);
9017    irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
9018             mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
9019             mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
9020               mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
9021               mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
9022                 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
9023                 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
9024                   mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
9025                   mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
9026                     mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
9027                     mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
9028                       mkexpr(encode_dfp_rounding_mode(
9029                                S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
9030                       mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
9031                         mkexpr(encode_dfp_rounding_mode(
9032                                  S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
9033                         mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
9034                           mkexpr(encode_dfp_rounding_mode(
9035                                    S390_DFP_ROUND_AWAY_0)),
9036                           mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
9037                             mkexpr(encode_dfp_rounding_mode(
9038                                      S390_DFP_ROUND_PREPARE_SHORT_15)),
9039                                 /* if rounding mode is 0 or invalid (2-7)
9040                                    set S390_DFP_ROUND_PER_FPC_0 */
9041                             mkexpr(encode_dfp_rounding_mode(
9042                                      S390_DFP_ROUND_PER_FPC_0)))))))))));
9043 
9044    return irrm;
9045 }
9046 
9047 static IRExpr *
9048 s390_call_pfpo_helper(IRExpr *gr0)
9049 {
9050    IRExpr **args, *call;
9051 
9052    args = mkIRExprVec_1(gr0);
9053    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
9054                         "s390_do_pfpo", &s390_do_pfpo, args);
9055    /* Nothing is excluded from definedness checking. */
9056    call->Iex.CCall.cee->mcx_mask = 0;
9057 
9058    return call;
9059 }
9060 
9061 static const HChar *
9062 s390_irgen_PFPO(void)
9063 {
9064    IRTemp gr0 = newTemp(Ity_I32);     /* word 1 [32:63] of GR 0 */
9065    IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
9066    IRTemp fn = newTemp(Ity_I32);       /* [33:55] of GR 0 - function code */
9067    IRTemp ef = newTemp(Ity_I32);       /* Emulation Failure */
9068    IRTemp src1 = newTemp(Ity_F32);
9069    IRTemp dst1 = newTemp(Ity_D32);
9070    IRTemp src2 = newTemp(Ity_F32);
9071    IRTemp dst2 = newTemp(Ity_D64);
9072    IRTemp src3 = newTemp(Ity_F32);
9073    IRTemp dst3 = newTemp(Ity_D128);
9074    IRTemp src4 = newTemp(Ity_F64);
9075    IRTemp dst4 = newTemp(Ity_D32);
9076    IRTemp src5 = newTemp(Ity_F64);
9077    IRTemp dst5 = newTemp(Ity_D64);
9078    IRTemp src6 = newTemp(Ity_F64);
9079    IRTemp dst6 = newTemp(Ity_D128);
9080    IRTemp src7 = newTemp(Ity_F128);
9081    IRTemp dst7 = newTemp(Ity_D32);
9082    IRTemp src8 = newTemp(Ity_F128);
9083    IRTemp dst8 = newTemp(Ity_D64);
9084    IRTemp src9 = newTemp(Ity_F128);
9085    IRTemp dst9 = newTemp(Ity_D128);
9086    IRTemp src10 = newTemp(Ity_D32);
9087    IRTemp dst10 = newTemp(Ity_F32);
9088    IRTemp src11 = newTemp(Ity_D32);
9089    IRTemp dst11 = newTemp(Ity_F64);
9090    IRTemp src12 = newTemp(Ity_D32);
9091    IRTemp dst12 = newTemp(Ity_F128);
9092    IRTemp src13 = newTemp(Ity_D64);
9093    IRTemp dst13 = newTemp(Ity_F32);
9094    IRTemp src14 = newTemp(Ity_D64);
9095    IRTemp dst14 = newTemp(Ity_F64);
9096    IRTemp src15 = newTemp(Ity_D64);
9097    IRTemp dst15 = newTemp(Ity_F128);
9098    IRTemp src16 = newTemp(Ity_D128);
9099    IRTemp dst16 = newTemp(Ity_F32);
9100    IRTemp src17 = newTemp(Ity_D128);
9101    IRTemp dst17 = newTemp(Ity_F64);
9102    IRTemp src18 = newTemp(Ity_D128);
9103    IRTemp dst18 = newTemp(Ity_F128);
9104    IRExpr *irrm;
9105 
9106    if (! s390_host_has_pfpo) {
9107       emulation_failure(EmFail_S390X_pfpo);
9108       goto done;
9109    }
9110 
9111    assign(gr0, get_gpr_w1(0));
9112    /* get function code */
9113    assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
9114                     mkU32(0x7fffff)));
9115    /* get validity test bit */
9116    assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
9117                           mkU32(0x1)));
9118    irrm = get_rounding_mode_from_gr0();
9119 
9120    /* test_bit is 1 */
9121    assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
9122    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
9123 
9124    /* Return code set in GR1 is usually 0. Non-zero value is set only
9125       when exceptions are raised. See Programming Notes point 5 in the
9126       instrcution description of pfpo in POP. Since valgrind does not
9127       model exception, it might be safe to just set 0 to GR 1. */
9128    put_gpr_w1(1, mkU32(0x0));
9129    next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
9130 
9131    /* Check validity of function code in GR 0 */
9132    assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
9133    emulation_failure_with_expr(mkexpr(ef));
9134 
9135    stmt(
9136         IRStmt_Exit(
9137                     binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
9138                     Ijk_EmFail,
9139                     IRConst_U64(guest_IA_next_instr),
9140                     S390X_GUEST_OFFSET(guest_IA)
9141                     )
9142         );
9143 
9144    /* F32 -> D32 */
9145    /* get source from FPR 4,6 - already set in src1 */
9146    assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
9147    put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
9148    put_gpr_w1(1, mkU32(0x0));
9149    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
9150    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
9151 
9152    /* F32 -> D64 */
9153    assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
9154    assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
9155    put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
9156    put_gpr_w1(1, mkU32(0x0));
9157    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
9158    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
9159 
9160    /* F32 -> D128 */
9161    assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
9162    assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
9163    put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
9164    put_gpr_w1(1, mkU32(0x0));
9165    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
9166    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
9167 
9168    /* F64 -> D32 */
9169    assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
9170    assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
9171    put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
9172    put_gpr_w1(1, mkU32(0x0));
9173    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
9174    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
9175 
9176    /* F64 -> D64 */
9177    assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
9178    assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
9179    put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
9180    put_gpr_w1(1, mkU32(0x0));
9181    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
9182    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
9183 
9184    /* F64 -> D128 */
9185    assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
9186    assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
9187    put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
9188    put_gpr_w1(1, mkU32(0x0));
9189    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
9190    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
9191 
9192    /* F128 -> D32 */
9193    assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
9194    assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
9195    put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
9196    put_gpr_w1(1, mkU32(0x0));
9197    s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
9198    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
9199 
9200    /* F128 -> D64 */
9201    assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
9202    assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
9203    put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
9204    put_gpr_w1(1, mkU32(0x0));
9205    s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
9206    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
9207 
9208    /* F128 -> D128 */
9209    assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
9210    assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
9211    put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
9212    put_gpr_w1(1, mkU32(0x0));
9213    s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
9214    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
9215 
9216    /* D32 -> F32 */
9217    assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
9218    assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
9219    put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
9220    put_gpr_w1(1, mkU32(0x0));
9221    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
9222    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
9223 
9224    /* D32 -> F64 */
9225    assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
9226    assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
9227    put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
9228    put_gpr_w1(1, mkU32(0x0));
9229    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
9230    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
9231 
9232    /* D32 -> F128 */
9233    assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
9234    assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
9235    put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
9236    put_gpr_w1(1, mkU32(0x0));
9237    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
9238    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
9239 
9240    /* D64 -> F32 */
9241    assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
9242    assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
9243    put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
9244    put_gpr_w1(1, mkU32(0x0));
9245    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
9246    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
9247 
9248    /* D64 -> F64 */
9249    assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
9250    assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
9251    put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
9252    put_gpr_w1(1, mkU32(0x0));
9253    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
9254    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
9255 
9256    /* D64 -> F128 */
9257    assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
9258    assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
9259    put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
9260    put_gpr_w1(1, mkU32(0x0));
9261    s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
9262    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
9263 
9264    /* D128 -> F32 */
9265    assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
9266    assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
9267    put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
9268    put_gpr_w1(1, mkU32(0x0));
9269    s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
9270    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
9271 
9272    /* D128 -> F64 */
9273    assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
9274    assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
9275    put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
9276    put_gpr_w1(1, mkU32(0x0));
9277    s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
9278    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
9279 
9280    /* D128 -> F128 */
9281    assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
9282    assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
9283    put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
9284    put_gpr_w1(1, mkU32(0x0));
9285    s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
9286    next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
9287 
9288  done:
9289    return "pfpo";
9290 }
9291 
9292 static const HChar *
9293 s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
9294 {
9295    IRTemp amount = newTemp(Ity_I64);
9296    IRTemp op = newTemp(Ity_I32);
9297 
9298    assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
9299    assign(op, get_gpr_w1(r3));
9300    put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
9301               mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
9302               binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
9303 
9304    return "rll";
9305 }
9306 
9307 static const HChar *
9308 s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
9309 {
9310    IRTemp amount = newTemp(Ity_I64);
9311    IRTemp op = newTemp(Ity_I64);
9312 
9313    assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9314    assign(op, get_gpr_dw0(r3));
9315    put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
9316                mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
9317                binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
9318 
9319    return "rllg";
9320 }
9321 
9322 static const HChar *
9323 s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9324 {
9325    UChar from;
9326    UChar to;
9327    UChar rot;
9328    UChar t_bit;
9329    ULong mask;
9330    ULong maskc;
9331    IRTemp result = newTemp(Ity_I64);
9332    IRTemp op2 = newTemp(Ity_I64);
9333 
9334    from = i3 & 63;
9335    to = i4 & 63;
9336    rot = i5 & 63;
9337    t_bit = i3 & 128;
9338    assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
9339           get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
9340           mkU8(64 - rot))));
9341    if (from <= to) {
9342       mask = ~0ULL;
9343       mask = (mask >> from) & (mask << (63 - to));
9344       maskc = ~mask;
9345    } else {
9346       maskc = ~0ULL;
9347       maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
9348       mask = ~maskc;
9349    }
9350    assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
9351           ), mkU64(mask)));
9352    if (t_bit == 0) {
9353       put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
9354                   mkU64(maskc)), mkexpr(result)));
9355    }
9356    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9357 
9358    return "rnsbg";
9359 }
9360 
9361 static const HChar *
9362 s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9363 {
9364    UChar from;
9365    UChar to;
9366    UChar rot;
9367    UChar t_bit;
9368    ULong mask;
9369    ULong maskc;
9370    IRTemp result = newTemp(Ity_I64);
9371    IRTemp op2 = newTemp(Ity_I64);
9372 
9373    from = i3 & 63;
9374    to = i4 & 63;
9375    rot = i5 & 63;
9376    t_bit = i3 & 128;
9377    assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
9378           get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
9379           mkU8(64 - rot))));
9380    if (from <= to) {
9381       mask = ~0ULL;
9382       mask = (mask >> from) & (mask << (63 - to));
9383       maskc = ~mask;
9384    } else {
9385       maskc = ~0ULL;
9386       maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
9387       mask = ~maskc;
9388    }
9389    assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
9390           ), mkU64(mask)));
9391    if (t_bit == 0) {
9392       put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
9393                   mkU64(maskc)), mkexpr(result)));
9394    }
9395    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9396 
9397    return "rxsbg";
9398 }
9399 
9400 static const HChar *
9401 s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9402 {
9403    UChar from;
9404    UChar to;
9405    UChar rot;
9406    UChar t_bit;
9407    ULong mask;
9408    ULong maskc;
9409    IRTemp result = newTemp(Ity_I64);
9410    IRTemp op2 = newTemp(Ity_I64);
9411 
9412    from = i3 & 63;
9413    to = i4 & 63;
9414    rot = i5 & 63;
9415    t_bit = i3 & 128;
9416    assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
9417           get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
9418           mkU8(64 - rot))));
9419    if (from <= to) {
9420       mask = ~0ULL;
9421       mask = (mask >> from) & (mask << (63 - to));
9422       maskc = ~mask;
9423    } else {
9424       maskc = ~0ULL;
9425       maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
9426       mask = ~maskc;
9427    }
9428    assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
9429           ), mkU64(mask)));
9430    if (t_bit == 0) {
9431       put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
9432                   mkU64(maskc)), mkexpr(result)));
9433    }
9434    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9435 
9436    return "rosbg";
9437 }
9438 
9439 static const HChar *
9440 s390_irgen_RISBGx(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
9441                   Bool set_cc)
9442 {
9443    UChar from;
9444    UChar to;
9445    UChar rot;
9446    UChar z_bit;
9447    ULong mask;
9448    ULong maskc;
9449    IRTemp op2 = newTemp(Ity_I64);
9450    IRTemp result = newTemp(Ity_I64);
9451 
9452    from = i3 & 63;
9453    to = i4 & 63;
9454    rot = i5 & 63;
9455    z_bit = i4 & 128;
9456    assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
9457           get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
9458           mkU8(64 - rot))));
9459    if (from <= to) {
9460       mask = ~0ULL;
9461       mask = (mask >> from) & (mask << (63 - to));
9462       maskc = ~mask;
9463    } else {
9464       maskc = ~0ULL;
9465       maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
9466       mask = ~maskc;
9467    }
9468    if (z_bit == 0) {
9469       put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
9470                   mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
9471    } else {
9472       put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
9473    }
9474    assign(result, get_gpr_dw0(r1));
9475    if (set_cc) {
9476       s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
9477       return "risbg";
9478    }
9479 
9480    return "risbgn";
9481 }
9482 
9483 static const HChar *
9484 s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9485 {
9486    return s390_irgen_RISBGx(r1, r2, i3, i4, i5, True);
9487 }
9488 
9489 static const HChar *
9490 s390_irgen_RISBGN(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9491 {
9492    return s390_irgen_RISBGx(r1, r2, i3, i4, i5, False);
9493 }
9494 
9495 static IRExpr *
9496 s390_irgen_RISBxG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
9497                   Bool high)
9498 {
9499    UChar from;
9500    UChar to;
9501    UChar rot;
9502    UChar z_bit;
9503    UInt mask;
9504    UInt maskc;
9505    IRTemp op2 = newTemp(Ity_I32);
9506 
9507    from = i3 & 31;
9508    to = i4 & 31;
9509    rot = i5 & 63;
9510    z_bit = i4 & 128;
9511    if (rot == 0) {
9512       assign(op2, high ? get_gpr_w0(r2) : get_gpr_w1(r2));
9513    } else if (rot == 32) {
9514       assign(op2, high ? get_gpr_w1(r2) : get_gpr_w0(r2));
9515    } else {
9516       assign(op2,
9517              unop(high ? Iop_64HIto32 : Iop_64to32,
9518                   binop(Iop_Or64,
9519                         binop(Iop_Shl64, get_gpr_dw0(r2), mkU8(rot)),
9520                         binop(Iop_Shr64, get_gpr_dw0(r2), mkU8(64 - rot)))));
9521    }
9522    if (from <= to) {
9523       mask = ~0U;
9524       mask = (mask >> from) & (mask << (31 - to));
9525       maskc = ~mask;
9526    } else {
9527       maskc = ~0U;
9528       maskc = (maskc >> (to + 1)) & (maskc << (32 - from));
9529       mask = ~maskc;
9530    }
9531    if (z_bit) {
9532       return binop(Iop_And32, mkexpr(op2), mkU32(mask));
9533    }
9534    return binop(Iop_Or32,
9535                 binop(Iop_And32, high ? get_gpr_w0(r1) : get_gpr_w1(r1),
9536                       mkU32(maskc)),
9537                 binop(Iop_And32, mkexpr(op2), mkU32(mask)));
9538 }
9539 
9540 static const HChar *
9541 s390_irgen_RISBHG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9542 {
9543    put_gpr_w0(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, True));
9544    return "risbhg";
9545 }
9546 
9547 static const HChar *
9548 s390_irgen_RISBLG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9549 {
9550    put_gpr_w1(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, False));
9551    return "risblg";
9552 }
9553 
9554 static const HChar *
9555 s390_irgen_SAR(UChar r1, UChar r2)
9556 {
9557    put_ar_w0(r1, get_gpr_w1(r2));
9558    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
9559       s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
9560 
9561    return "sar";
9562 }
9563 
9564 static const HChar *
9565 s390_irgen_SLDA(UChar r1, IRTemp op2addr)
9566 {
9567    IRTemp p1 = newTemp(Ity_I64);
9568    IRTemp p2 = newTemp(Ity_I64);
9569    IRTemp op = newTemp(Ity_I64);
9570    IRTemp result = newTemp(Ity_I64);
9571    ULong sign_mask;
9572    IRTemp shift_amount = newTemp(Ity_I64);
9573 
9574    assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
9575    assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
9576    assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
9577           ));
9578    sign_mask = 1ULL << 63;
9579    assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9580    assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
9581           unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
9582           binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
9583    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
9584    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
9585    s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
9586 
9587    return "slda";
9588 }
9589 
9590 static const HChar *
9591 s390_irgen_SLDL(UChar r1, IRTemp op2addr)
9592 {
9593    IRTemp p1 = newTemp(Ity_I64);
9594    IRTemp p2 = newTemp(Ity_I64);
9595    IRTemp result = newTemp(Ity_I64);
9596 
9597    assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
9598    assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
9599    assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
9600           mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
9601           mkexpr(op2addr), mkU64(63)))));
9602    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
9603    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
9604 
9605    return "sldl";
9606 }
9607 
9608 static const HChar *
9609 s390_irgen_SLA(UChar r1, IRTemp op2addr)
9610 {
9611    IRTemp uop = newTemp(Ity_I32);
9612    IRTemp result = newTemp(Ity_I32);
9613    UInt sign_mask;
9614    IRTemp shift_amount = newTemp(Ity_I64);
9615    IRTemp op = newTemp(Ity_I32);
9616 
9617    assign(op, get_gpr_w1(r1));
9618    assign(uop, get_gpr_w1(r1));
9619    sign_mask = 2147483648U;
9620    assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9621    assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
9622           unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
9623           binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
9624    put_gpr_w1(r1, mkexpr(result));
9625    s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
9626 
9627    return "sla";
9628 }
9629 
9630 static const HChar *
9631 s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
9632 {
9633    IRTemp uop = newTemp(Ity_I32);
9634    IRTemp result = newTemp(Ity_I32);
9635    UInt sign_mask;
9636    IRTemp shift_amount = newTemp(Ity_I64);
9637    IRTemp op = newTemp(Ity_I32);
9638 
9639    assign(op, get_gpr_w1(r3));
9640    assign(uop, get_gpr_w1(r3));
9641    sign_mask = 2147483648U;
9642    assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9643    assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
9644           unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
9645           binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
9646    put_gpr_w1(r1, mkexpr(result));
9647    s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
9648 
9649    return "slak";
9650 }
9651 
9652 static const HChar *
9653 s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
9654 {
9655    IRTemp uop = newTemp(Ity_I64);
9656    IRTemp result = newTemp(Ity_I64);
9657    ULong sign_mask;
9658    IRTemp shift_amount = newTemp(Ity_I64);
9659    IRTemp op = newTemp(Ity_I64);
9660 
9661    assign(op, get_gpr_dw0(r3));
9662    assign(uop, get_gpr_dw0(r3));
9663    sign_mask = 9223372036854775808ULL;
9664    assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9665    assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
9666           unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
9667           binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
9668    put_gpr_dw0(r1, mkexpr(result));
9669    s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
9670 
9671    return "slag";
9672 }
9673 
9674 static const HChar *
9675 s390_irgen_SLL(UChar r1, IRTemp op2addr)
9676 {
9677    put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
9678               binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9679 
9680    return "sll";
9681 }
9682 
9683 static const HChar *
9684 s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
9685 {
9686    put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
9687               binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9688 
9689    return "sllk";
9690 }
9691 
9692 static const HChar *
9693 s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
9694 {
9695    put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
9696                binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9697 
9698    return "sllg";
9699 }
9700 
9701 static const HChar *
9702 s390_irgen_SRDA(UChar r1, IRTemp op2addr)
9703 {
9704    IRTemp p1 = newTemp(Ity_I64);
9705    IRTemp p2 = newTemp(Ity_I64);
9706    IRTemp result = newTemp(Ity_I64);
9707 
9708    assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
9709    assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
9710    assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
9711           mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
9712           mkexpr(op2addr), mkU64(63)))));
9713    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
9714    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
9715    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
9716 
9717    return "srda";
9718 }
9719 
9720 static const HChar *
9721 s390_irgen_SRDL(UChar r1, IRTemp op2addr)
9722 {
9723    IRTemp p1 = newTemp(Ity_I64);
9724    IRTemp p2 = newTemp(Ity_I64);
9725    IRTemp result = newTemp(Ity_I64);
9726 
9727    assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
9728    assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
9729    assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
9730           mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
9731           mkexpr(op2addr), mkU64(63)))));
9732    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
9733    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
9734 
9735    return "srdl";
9736 }
9737 
9738 static const HChar *
9739 s390_irgen_SRA(UChar r1, IRTemp op2addr)
9740 {
9741    IRTemp result = newTemp(Ity_I32);
9742    IRTemp op = newTemp(Ity_I32);
9743 
9744    assign(op, get_gpr_w1(r1));
9745    assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
9746           mkexpr(op2addr), mkU64(63)))));
9747    put_gpr_w1(r1, mkexpr(result));
9748    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
9749 
9750    return "sra";
9751 }
9752 
9753 static const HChar *
9754 s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
9755 {
9756    IRTemp result = newTemp(Ity_I32);
9757    IRTemp op = newTemp(Ity_I32);
9758 
9759    assign(op, get_gpr_w1(r3));
9760    assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
9761           mkexpr(op2addr), mkU64(63)))));
9762    put_gpr_w1(r1, mkexpr(result));
9763    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
9764 
9765    return "srak";
9766 }
9767 
9768 static const HChar *
9769 s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
9770 {
9771    IRTemp result = newTemp(Ity_I64);
9772    IRTemp op = newTemp(Ity_I64);
9773 
9774    assign(op, get_gpr_dw0(r3));
9775    assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
9776           mkexpr(op2addr), mkU64(63)))));
9777    put_gpr_dw0(r1, mkexpr(result));
9778    s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
9779 
9780    return "srag";
9781 }
9782 
9783 static const HChar *
9784 s390_irgen_SRL(UChar r1, IRTemp op2addr)
9785 {
9786    IRTemp op = newTemp(Ity_I32);
9787 
9788    assign(op, get_gpr_w1(r1));
9789    put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
9790               mkexpr(op2addr), mkU64(63)))));
9791 
9792    return "srl";
9793 }
9794 
9795 static const HChar *
9796 s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
9797 {
9798    IRTemp op = newTemp(Ity_I32);
9799 
9800    assign(op, get_gpr_w1(r3));
9801    put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
9802               mkexpr(op2addr), mkU64(63)))));
9803 
9804    return "srlk";
9805 }
9806 
9807 static const HChar *
9808 s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
9809 {
9810    IRTemp op = newTemp(Ity_I64);
9811 
9812    assign(op, get_gpr_dw0(r3));
9813    put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
9814                mkexpr(op2addr), mkU64(63)))));
9815 
9816    return "srlg";
9817 }
9818 
9819 static const HChar *
9820 s390_irgen_ST(UChar r1, IRTemp op2addr)
9821 {
9822    store(mkexpr(op2addr), get_gpr_w1(r1));
9823 
9824    return "st";
9825 }
9826 
9827 static const HChar *
9828 s390_irgen_STY(UChar r1, IRTemp op2addr)
9829 {
9830    store(mkexpr(op2addr), get_gpr_w1(r1));
9831 
9832    return "sty";
9833 }
9834 
9835 static const HChar *
9836 s390_irgen_STG(UChar r1, IRTemp op2addr)
9837 {
9838    store(mkexpr(op2addr), get_gpr_dw0(r1));
9839 
9840    return "stg";
9841 }
9842 
9843 static const HChar *
9844 s390_irgen_STRL(UChar r1, UInt i2)
9845 {
9846    store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
9847          get_gpr_w1(r1));
9848 
9849    return "strl";
9850 }
9851 
9852 static const HChar *
9853 s390_irgen_STGRL(UChar r1, UInt i2)
9854 {
9855    store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
9856          get_gpr_dw0(r1));
9857 
9858    return "stgrl";
9859 }
9860 
9861 static const HChar *
9862 s390_irgen_STC(UChar r1, IRTemp op2addr)
9863 {
9864    store(mkexpr(op2addr), get_gpr_b7(r1));
9865 
9866    return "stc";
9867 }
9868 
9869 static const HChar *
9870 s390_irgen_STCY(UChar r1, IRTemp op2addr)
9871 {
9872    store(mkexpr(op2addr), get_gpr_b7(r1));
9873 
9874    return "stcy";
9875 }
9876 
9877 static const HChar *
9878 s390_irgen_STCH(UChar r1, IRTemp op2addr)
9879 {
9880    store(mkexpr(op2addr), get_gpr_b3(r1));
9881 
9882    return "stch";
9883 }
9884 
9885 static const HChar *
9886 s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
9887 {
9888    UChar mask;
9889    UChar n;
9890 
9891    mask = (UChar)r3;
9892    n = 0;
9893    if ((mask & 8) != 0) {
9894       store(mkexpr(op2addr), get_gpr_b4(r1));
9895       n = n + 1;
9896    }
9897    if ((mask & 4) != 0) {
9898       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
9899       n = n + 1;
9900    }
9901    if ((mask & 2) != 0) {
9902       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
9903       n = n + 1;
9904    }
9905    if ((mask & 1) != 0) {
9906       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
9907    }
9908 
9909    return "stcm";
9910 }
9911 
9912 static const HChar *
9913 s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
9914 {
9915    UChar mask;
9916    UChar n;
9917 
9918    mask = (UChar)r3;
9919    n = 0;
9920    if ((mask & 8) != 0) {
9921       store(mkexpr(op2addr), get_gpr_b4(r1));
9922       n = n + 1;
9923    }
9924    if ((mask & 4) != 0) {
9925       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
9926       n = n + 1;
9927    }
9928    if ((mask & 2) != 0) {
9929       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
9930       n = n + 1;
9931    }
9932    if ((mask & 1) != 0) {
9933       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
9934    }
9935 
9936    return "stcmy";
9937 }
9938 
9939 static const HChar *
9940 s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
9941 {
9942    UChar mask;
9943    UChar n;
9944 
9945    mask = (UChar)r3;
9946    n = 0;
9947    if ((mask & 8) != 0) {
9948       store(mkexpr(op2addr), get_gpr_b0(r1));
9949       n = n + 1;
9950    }
9951    if ((mask & 4) != 0) {
9952       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
9953       n = n + 1;
9954    }
9955    if ((mask & 2) != 0) {
9956       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
9957       n = n + 1;
9958    }
9959    if ((mask & 1) != 0) {
9960       store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
9961    }
9962 
9963    return "stcmh";
9964 }
9965 
9966 static const HChar *
9967 s390_irgen_STH(UChar r1, IRTemp op2addr)
9968 {
9969    store(mkexpr(op2addr), get_gpr_hw3(r1));
9970 
9971    return "sth";
9972 }
9973 
9974 static const HChar *
9975 s390_irgen_STHY(UChar r1, IRTemp op2addr)
9976 {
9977    store(mkexpr(op2addr), get_gpr_hw3(r1));
9978 
9979    return "sthy";
9980 }
9981 
9982 static const HChar *
9983 s390_irgen_STHRL(UChar r1, UInt i2)
9984 {
9985    store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
9986          get_gpr_hw3(r1));
9987 
9988    return "sthrl";
9989 }
9990 
9991 static const HChar *
9992 s390_irgen_STHH(UChar r1, IRTemp op2addr)
9993 {
9994    store(mkexpr(op2addr), get_gpr_hw1(r1));
9995 
9996    return "sthh";
9997 }
9998 
9999 static const HChar *
10000 s390_irgen_STFH(UChar r1, IRTemp op2addr)
10001 {
10002    store(mkexpr(op2addr), get_gpr_w0(r1));
10003 
10004    return "stfh";
10005 }
10006 
10007 static const HChar *
10008 s390_irgen_STOC(UChar r1, IRTemp op2addr)
10009 {
10010    /* condition is checked in format handler */
10011    store(mkexpr(op2addr), get_gpr_w1(r1));
10012 
10013    return "stoc";
10014 }
10015 
10016 static const HChar *
10017 s390_irgen_STOCG(UChar r1, IRTemp op2addr)
10018 {
10019    /* condition is checked in format handler */
10020    store(mkexpr(op2addr), get_gpr_dw0(r1));
10021 
10022    return "stocg";
10023 }
10024 
10025 static const HChar *
10026 s390_irgen_STPQ(UChar r1, IRTemp op2addr)
10027 {
10028    store(mkexpr(op2addr), get_gpr_dw0(r1));
10029    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
10030 
10031    return "stpq";
10032 }
10033 
10034 static const HChar *
10035 s390_irgen_STRVH(UChar r1, IRTemp op2addr)
10036 {
10037    store(mkexpr(op2addr), get_gpr_b7(r1));
10038    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
10039 
10040    return "strvh";
10041 }
10042 
10043 static const HChar *
10044 s390_irgen_STRV(UChar r1, IRTemp op2addr)
10045 {
10046    store(mkexpr(op2addr), get_gpr_b7(r1));
10047    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
10048    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
10049    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
10050 
10051    return "strv";
10052 }
10053 
10054 static const HChar *
10055 s390_irgen_STRVG(UChar r1, IRTemp op2addr)
10056 {
10057    store(mkexpr(op2addr), get_gpr_b7(r1));
10058    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
10059    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
10060    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
10061    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
10062    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
10063    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
10064    store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
10065 
10066    return "strvg";
10067 }
10068 
10069 static const HChar *
10070 s390_irgen_SR(UChar r1, UChar r2)
10071 {
10072    IRTemp op1 = newTemp(Ity_I32);
10073    IRTemp op2 = newTemp(Ity_I32);
10074    IRTemp result = newTemp(Ity_I32);
10075 
10076    assign(op1, get_gpr_w1(r1));
10077    assign(op2, get_gpr_w1(r2));
10078    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10079    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
10080    put_gpr_w1(r1, mkexpr(result));
10081 
10082    return "sr";
10083 }
10084 
10085 static const HChar *
10086 s390_irgen_SGR(UChar r1, UChar r2)
10087 {
10088    IRTemp op1 = newTemp(Ity_I64);
10089    IRTemp op2 = newTemp(Ity_I64);
10090    IRTemp result = newTemp(Ity_I64);
10091 
10092    assign(op1, get_gpr_dw0(r1));
10093    assign(op2, get_gpr_dw0(r2));
10094    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10095    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
10096    put_gpr_dw0(r1, mkexpr(result));
10097 
10098    return "sgr";
10099 }
10100 
10101 static const HChar *
10102 s390_irgen_SGFR(UChar r1, UChar r2)
10103 {
10104    IRTemp op1 = newTemp(Ity_I64);
10105    IRTemp op2 = newTemp(Ity_I64);
10106    IRTemp result = newTemp(Ity_I64);
10107 
10108    assign(op1, get_gpr_dw0(r1));
10109    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10110    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10111    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
10112    put_gpr_dw0(r1, mkexpr(result));
10113 
10114    return "sgfr";
10115 }
10116 
10117 static const HChar *
10118 s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
10119 {
10120    IRTemp op2 = newTemp(Ity_I32);
10121    IRTemp op3 = newTemp(Ity_I32);
10122    IRTemp result = newTemp(Ity_I32);
10123 
10124    assign(op2, get_gpr_w1(r2));
10125    assign(op3, get_gpr_w1(r3));
10126    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10127    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
10128    put_gpr_w1(r1, mkexpr(result));
10129 
10130    return "srk";
10131 }
10132 
10133 static const HChar *
10134 s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
10135 {
10136    IRTemp op2 = newTemp(Ity_I64);
10137    IRTemp op3 = newTemp(Ity_I64);
10138    IRTemp result = newTemp(Ity_I64);
10139 
10140    assign(op2, get_gpr_dw0(r2));
10141    assign(op3, get_gpr_dw0(r3));
10142    assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
10143    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
10144    put_gpr_dw0(r1, mkexpr(result));
10145 
10146    return "sgrk";
10147 }
10148 
10149 static const HChar *
10150 s390_irgen_S(UChar r1, IRTemp op2addr)
10151 {
10152    IRTemp op1 = newTemp(Ity_I32);
10153    IRTemp op2 = newTemp(Ity_I32);
10154    IRTemp result = newTemp(Ity_I32);
10155 
10156    assign(op1, get_gpr_w1(r1));
10157    assign(op2, load(Ity_I32, mkexpr(op2addr)));
10158    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10159    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
10160    put_gpr_w1(r1, mkexpr(result));
10161 
10162    return "s";
10163 }
10164 
10165 static const HChar *
10166 s390_irgen_SY(UChar r1, IRTemp op2addr)
10167 {
10168    IRTemp op1 = newTemp(Ity_I32);
10169    IRTemp op2 = newTemp(Ity_I32);
10170    IRTemp result = newTemp(Ity_I32);
10171 
10172    assign(op1, get_gpr_w1(r1));
10173    assign(op2, load(Ity_I32, mkexpr(op2addr)));
10174    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10175    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
10176    put_gpr_w1(r1, mkexpr(result));
10177 
10178    return "sy";
10179 }
10180 
10181 static const HChar *
10182 s390_irgen_SG(UChar r1, IRTemp op2addr)
10183 {
10184    IRTemp op1 = newTemp(Ity_I64);
10185    IRTemp op2 = newTemp(Ity_I64);
10186    IRTemp result = newTemp(Ity_I64);
10187 
10188    assign(op1, get_gpr_dw0(r1));
10189    assign(op2, load(Ity_I64, mkexpr(op2addr)));
10190    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10191    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
10192    put_gpr_dw0(r1, mkexpr(result));
10193 
10194    return "sg";
10195 }
10196 
10197 static const HChar *
10198 s390_irgen_SGF(UChar r1, IRTemp op2addr)
10199 {
10200    IRTemp op1 = newTemp(Ity_I64);
10201    IRTemp op2 = newTemp(Ity_I64);
10202    IRTemp result = newTemp(Ity_I64);
10203 
10204    assign(op1, get_gpr_dw0(r1));
10205    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10206    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10207    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
10208    put_gpr_dw0(r1, mkexpr(result));
10209 
10210    return "sgf";
10211 }
10212 
10213 static const HChar *
10214 s390_irgen_SGH(UChar r1, IRTemp op2addr)
10215 {
10216    IRTemp op1 = newTemp(Ity_I64);
10217    IRTemp op2 = newTemp(Ity_I64);
10218    IRTemp result = newTemp(Ity_I64);
10219 
10220    assign(op1, get_gpr_dw0(r1));
10221    assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
10222    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10223    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
10224    put_gpr_dw0(r1, mkexpr(result));
10225 
10226    return "sgh";
10227 }
10228 
10229 static const HChar *
10230 s390_irgen_SH(UChar r1, IRTemp op2addr)
10231 {
10232    IRTemp op1 = newTemp(Ity_I32);
10233    IRTemp op2 = newTemp(Ity_I32);
10234    IRTemp result = newTemp(Ity_I32);
10235 
10236    assign(op1, get_gpr_w1(r1));
10237    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
10238    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10239    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
10240    put_gpr_w1(r1, mkexpr(result));
10241 
10242    return "sh";
10243 }
10244 
10245 static const HChar *
10246 s390_irgen_SHY(UChar r1, IRTemp op2addr)
10247 {
10248    IRTemp op1 = newTemp(Ity_I32);
10249    IRTemp op2 = newTemp(Ity_I32);
10250    IRTemp result = newTemp(Ity_I32);
10251 
10252    assign(op1, get_gpr_w1(r1));
10253    assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
10254    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10255    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
10256    put_gpr_w1(r1, mkexpr(result));
10257 
10258    return "shy";
10259 }
10260 
10261 static const HChar *
10262 s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
10263 {
10264    IRTemp op2 = newTemp(Ity_I32);
10265    IRTemp op3 = newTemp(Ity_I32);
10266    IRTemp result = newTemp(Ity_I32);
10267 
10268    assign(op2, get_gpr_w0(r1));
10269    assign(op3, get_gpr_w0(r2));
10270    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10271    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
10272    put_gpr_w0(r1, mkexpr(result));
10273 
10274    return "shhhr";
10275 }
10276 
10277 static const HChar *
10278 s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
10279 {
10280    IRTemp op2 = newTemp(Ity_I32);
10281    IRTemp op3 = newTemp(Ity_I32);
10282    IRTemp result = newTemp(Ity_I32);
10283 
10284    assign(op2, get_gpr_w0(r1));
10285    assign(op3, get_gpr_w1(r2));
10286    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10287    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
10288    put_gpr_w0(r1, mkexpr(result));
10289 
10290    return "shhlr";
10291 }
10292 
10293 static const HChar *
10294 s390_irgen_SLR(UChar r1, UChar r2)
10295 {
10296    IRTemp op1 = newTemp(Ity_I32);
10297    IRTemp op2 = newTemp(Ity_I32);
10298    IRTemp result = newTemp(Ity_I32);
10299 
10300    assign(op1, get_gpr_w1(r1));
10301    assign(op2, get_gpr_w1(r2));
10302    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10303    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
10304    put_gpr_w1(r1, mkexpr(result));
10305 
10306    return "slr";
10307 }
10308 
10309 static const HChar *
10310 s390_irgen_SLGR(UChar r1, UChar r2)
10311 {
10312    IRTemp op1 = newTemp(Ity_I64);
10313    IRTemp op2 = newTemp(Ity_I64);
10314    IRTemp result = newTemp(Ity_I64);
10315 
10316    assign(op1, get_gpr_dw0(r1));
10317    assign(op2, get_gpr_dw0(r2));
10318    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10319    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
10320    put_gpr_dw0(r1, mkexpr(result));
10321 
10322    return "slgr";
10323 }
10324 
10325 static const HChar *
10326 s390_irgen_SLGFR(UChar r1, UChar r2)
10327 {
10328    IRTemp op1 = newTemp(Ity_I64);
10329    IRTemp op2 = newTemp(Ity_I64);
10330    IRTemp result = newTemp(Ity_I64);
10331 
10332    assign(op1, get_gpr_dw0(r1));
10333    assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
10334    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10335    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
10336    put_gpr_dw0(r1, mkexpr(result));
10337 
10338    return "slgfr";
10339 }
10340 
10341 static const HChar *
10342 s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
10343 {
10344    IRTemp op2 = newTemp(Ity_I32);
10345    IRTemp op3 = newTemp(Ity_I32);
10346    IRTemp result = newTemp(Ity_I32);
10347 
10348    assign(op2, get_gpr_w1(r2));
10349    assign(op3, get_gpr_w1(r3));
10350    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10351    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
10352    put_gpr_w1(r1, mkexpr(result));
10353 
10354    return "slrk";
10355 }
10356 
10357 static const HChar *
10358 s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
10359 {
10360    IRTemp op2 = newTemp(Ity_I64);
10361    IRTemp op3 = newTemp(Ity_I64);
10362    IRTemp result = newTemp(Ity_I64);
10363 
10364    assign(op2, get_gpr_dw0(r2));
10365    assign(op3, get_gpr_dw0(r3));
10366    assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
10367    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
10368    put_gpr_dw0(r1, mkexpr(result));
10369 
10370    return "slgrk";
10371 }
10372 
10373 static const HChar *
10374 s390_irgen_SL(UChar r1, IRTemp op2addr)
10375 {
10376    IRTemp op1 = newTemp(Ity_I32);
10377    IRTemp op2 = newTemp(Ity_I32);
10378    IRTemp result = newTemp(Ity_I32);
10379 
10380    assign(op1, get_gpr_w1(r1));
10381    assign(op2, load(Ity_I32, mkexpr(op2addr)));
10382    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10383    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
10384    put_gpr_w1(r1, mkexpr(result));
10385 
10386    return "sl";
10387 }
10388 
10389 static const HChar *
10390 s390_irgen_SLY(UChar r1, IRTemp op2addr)
10391 {
10392    IRTemp op1 = newTemp(Ity_I32);
10393    IRTemp op2 = newTemp(Ity_I32);
10394    IRTemp result = newTemp(Ity_I32);
10395 
10396    assign(op1, get_gpr_w1(r1));
10397    assign(op2, load(Ity_I32, mkexpr(op2addr)));
10398    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10399    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
10400    put_gpr_w1(r1, mkexpr(result));
10401 
10402    return "sly";
10403 }
10404 
10405 static const HChar *
10406 s390_irgen_SLG(UChar r1, IRTemp op2addr)
10407 {
10408    IRTemp op1 = newTemp(Ity_I64);
10409    IRTemp op2 = newTemp(Ity_I64);
10410    IRTemp result = newTemp(Ity_I64);
10411 
10412    assign(op1, get_gpr_dw0(r1));
10413    assign(op2, load(Ity_I64, mkexpr(op2addr)));
10414    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10415    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
10416    put_gpr_dw0(r1, mkexpr(result));
10417 
10418    return "slg";
10419 }
10420 
10421 static const HChar *
10422 s390_irgen_SLGF(UChar r1, IRTemp op2addr)
10423 {
10424    IRTemp op1 = newTemp(Ity_I64);
10425    IRTemp op2 = newTemp(Ity_I64);
10426    IRTemp result = newTemp(Ity_I64);
10427 
10428    assign(op1, get_gpr_dw0(r1));
10429    assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
10430    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10431    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
10432    put_gpr_dw0(r1, mkexpr(result));
10433 
10434    return "slgf";
10435 }
10436 
10437 static const HChar *
10438 s390_irgen_SLFI(UChar r1, UInt i2)
10439 {
10440    IRTemp op1 = newTemp(Ity_I32);
10441    UInt op2;
10442    IRTemp result = newTemp(Ity_I32);
10443 
10444    assign(op1, get_gpr_w1(r1));
10445    op2 = i2;
10446    assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
10447    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
10448                        mkU32(op2)));
10449    put_gpr_w1(r1, mkexpr(result));
10450 
10451    return "slfi";
10452 }
10453 
10454 static const HChar *
10455 s390_irgen_SLGFI(UChar r1, UInt i2)
10456 {
10457    IRTemp op1 = newTemp(Ity_I64);
10458    ULong op2;
10459    IRTemp result = newTemp(Ity_I64);
10460 
10461    assign(op1, get_gpr_dw0(r1));
10462    op2 = (ULong)i2;
10463    assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
10464    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
10465                        mkU64(op2)));
10466    put_gpr_dw0(r1, mkexpr(result));
10467 
10468    return "slgfi";
10469 }
10470 
10471 static const HChar *
10472 s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
10473 {
10474    IRTemp op2 = newTemp(Ity_I32);
10475    IRTemp op3 = newTemp(Ity_I32);
10476    IRTemp result = newTemp(Ity_I32);
10477 
10478    assign(op2, get_gpr_w0(r1));
10479    assign(op3, get_gpr_w0(r2));
10480    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10481    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
10482    put_gpr_w0(r1, mkexpr(result));
10483 
10484    return "slhhhr";
10485 }
10486 
10487 static const HChar *
10488 s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
10489 {
10490    IRTemp op2 = newTemp(Ity_I32);
10491    IRTemp op3 = newTemp(Ity_I32);
10492    IRTemp result = newTemp(Ity_I32);
10493 
10494    assign(op2, get_gpr_w0(r1));
10495    assign(op3, get_gpr_w1(r2));
10496    assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10497    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
10498    put_gpr_w0(r1, mkexpr(result));
10499 
10500    return "slhhlr";
10501 }
10502 
10503 static const HChar *
10504 s390_irgen_SLBR(UChar r1, UChar r2)
10505 {
10506    IRTemp op1 = newTemp(Ity_I32);
10507    IRTemp op2 = newTemp(Ity_I32);
10508    IRTemp result = newTemp(Ity_I32);
10509    IRTemp borrow_in = newTemp(Ity_I32);
10510 
10511    assign(op1, get_gpr_w1(r1));
10512    assign(op2, get_gpr_w1(r2));
10513    assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
10514           s390_call_calculate_cc(), mkU8(1))));
10515    assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
10516           mkexpr(borrow_in)));
10517    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
10518    put_gpr_w1(r1, mkexpr(result));
10519 
10520    return "slbr";
10521 }
10522 
10523 static const HChar *
10524 s390_irgen_SLBGR(UChar r1, UChar r2)
10525 {
10526    IRTemp op1 = newTemp(Ity_I64);
10527    IRTemp op2 = newTemp(Ity_I64);
10528    IRTemp result = newTemp(Ity_I64);
10529    IRTemp borrow_in = newTemp(Ity_I64);
10530 
10531    assign(op1, get_gpr_dw0(r1));
10532    assign(op2, get_gpr_dw0(r2));
10533    assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
10534           binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
10535    assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
10536           mkexpr(borrow_in)));
10537    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
10538    put_gpr_dw0(r1, mkexpr(result));
10539 
10540    return "slbgr";
10541 }
10542 
10543 static const HChar *
10544 s390_irgen_SLB(UChar r1, IRTemp op2addr)
10545 {
10546    IRTemp op1 = newTemp(Ity_I32);
10547    IRTemp op2 = newTemp(Ity_I32);
10548    IRTemp result = newTemp(Ity_I32);
10549    IRTemp borrow_in = newTemp(Ity_I32);
10550 
10551    assign(op1, get_gpr_w1(r1));
10552    assign(op2, load(Ity_I32, mkexpr(op2addr)));
10553    assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
10554           s390_call_calculate_cc(), mkU8(1))));
10555    assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
10556           mkexpr(borrow_in)));
10557    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
10558    put_gpr_w1(r1, mkexpr(result));
10559 
10560    return "slb";
10561 }
10562 
10563 static const HChar *
10564 s390_irgen_SLBG(UChar r1, IRTemp op2addr)
10565 {
10566    IRTemp op1 = newTemp(Ity_I64);
10567    IRTemp op2 = newTemp(Ity_I64);
10568    IRTemp result = newTemp(Ity_I64);
10569    IRTemp borrow_in = newTemp(Ity_I64);
10570 
10571    assign(op1, get_gpr_dw0(r1));
10572    assign(op2, load(Ity_I64, mkexpr(op2addr)));
10573    assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
10574           binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
10575    assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
10576           mkexpr(borrow_in)));
10577    s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
10578    put_gpr_dw0(r1, mkexpr(result));
10579 
10580    return "slbg";
10581 }
10582 
10583 static const HChar *
10584 s390_irgen_SVC(UChar i)
10585 {
10586    IRTemp sysno = newTemp(Ity_I64);
10587 
10588    if (i != 0) {
10589       assign(sysno, mkU64(i));
10590    } else {
10591       assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
10592    }
10593    system_call(mkexpr(sysno));
10594 
10595    return "svc";
10596 }
10597 
10598 static const HChar *
10599 s390_irgen_TM(UChar i2, IRTemp op1addr)
10600 {
10601    UChar mask;
10602    IRTemp value = newTemp(Ity_I8);
10603 
10604    mask = i2;
10605    assign(value, load(Ity_I8, mkexpr(op1addr)));
10606    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
10607                        mkU8(mask)));
10608 
10609    return "tm";
10610 }
10611 
10612 static const HChar *
10613 s390_irgen_TMY(UChar i2, IRTemp op1addr)
10614 {
10615    UChar mask;
10616    IRTemp value = newTemp(Ity_I8);
10617 
10618    mask = i2;
10619    assign(value, load(Ity_I8, mkexpr(op1addr)));
10620    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
10621                        mkU8(mask)));
10622 
10623    return "tmy";
10624 }
10625 
10626 static const HChar *
10627 s390_irgen_TMHH(UChar r1, UShort i2)
10628 {
10629    UShort mask;
10630    IRTemp value = newTemp(Ity_I16);
10631 
10632    mask = i2;
10633    assign(value, get_gpr_hw0(r1));
10634    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
10635                        mkU16(mask)));
10636 
10637    return "tmhh";
10638 }
10639 
10640 static const HChar *
10641 s390_irgen_TMHL(UChar r1, UShort i2)
10642 {
10643    UShort mask;
10644    IRTemp value = newTemp(Ity_I16);
10645 
10646    mask = i2;
10647    assign(value, get_gpr_hw1(r1));
10648    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
10649                        mkU16(mask)));
10650 
10651    return "tmhl";
10652 }
10653 
10654 static const HChar *
10655 s390_irgen_TMLH(UChar r1, UShort i2)
10656 {
10657    UShort mask;
10658    IRTemp value = newTemp(Ity_I16);
10659 
10660    mask = i2;
10661    assign(value, get_gpr_hw2(r1));
10662    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
10663                        mkU16(mask)));
10664 
10665    return "tmlh";
10666 }
10667 
10668 static const HChar *
10669 s390_irgen_TMLL(UChar r1, UShort i2)
10670 {
10671    UShort mask;
10672    IRTemp value = newTemp(Ity_I16);
10673 
10674    mask = i2;
10675    assign(value, get_gpr_hw3(r1));
10676    s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
10677                        mkU16(mask)));
10678 
10679    return "tmll";
10680 }
10681 
10682 static const HChar *
10683 s390_irgen_EFPC(UChar r1)
10684 {
10685    put_gpr_w1(r1, get_fpc_w0());
10686 
10687    return "efpc";
10688 }
10689 
10690 static const HChar *
10691 s390_irgen_LER(UChar r1, UChar r2)
10692 {
10693    put_fpr_w0(r1, get_fpr_w0(r2));
10694 
10695    return "ler";
10696 }
10697 
10698 static const HChar *
10699 s390_irgen_LDR(UChar r1, UChar r2)
10700 {
10701    put_fpr_dw0(r1, get_fpr_dw0(r2));
10702 
10703    return "ldr";
10704 }
10705 
10706 static const HChar *
10707 s390_irgen_LDER(UChar r1, UChar r2)
10708 {
10709    put_fpr_dw0(r1, mkF64i(0x0));
10710    put_fpr_w0(r1, get_fpr_w0(r2));
10711 
10712    return "lder";
10713 }
10714 
10715 static const HChar *
10716 s390_irgen_LXR(UChar r1, UChar r2)
10717 {
10718    put_fpr_dw0(r1, get_fpr_dw0(r2));
10719    put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
10720 
10721    return "lxr";
10722 }
10723 
10724 static const HChar *
10725 s390_irgen_LE(UChar r1, IRTemp op2addr)
10726 {
10727    put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
10728 
10729    return "le";
10730 }
10731 
10732 static const HChar *
10733 s390_irgen_LD(UChar r1, IRTemp op2addr)
10734 {
10735    put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
10736 
10737    return "ld";
10738 }
10739 
10740 static const HChar *
10741 s390_irgen_LDE(UChar r1, IRTemp op2addr)
10742 {
10743    put_fpr_dw0(r1, mkF64i(0x0));
10744    put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
10745 
10746    return "lde";
10747 }
10748 
10749 static const HChar *
10750 s390_irgen_LEY(UChar r1, IRTemp op2addr)
10751 {
10752    put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
10753 
10754    return "ley";
10755 }
10756 
10757 static const HChar *
10758 s390_irgen_LDY(UChar r1, IRTemp op2addr)
10759 {
10760    put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
10761 
10762    return "ldy";
10763 }
10764 
10765 static const HChar *
10766 s390_irgen_LFPC(IRTemp op2addr)
10767 {
10768    put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
10769 
10770    return "lfpc";
10771 }
10772 
10773 static const HChar *
10774 s390_irgen_LZER(UChar r1)
10775 {
10776    put_fpr_w0(r1, mkF32i(0x0));
10777 
10778    return "lzer";
10779 }
10780 
10781 static const HChar *
10782 s390_irgen_LZDR(UChar r1)
10783 {
10784    put_fpr_dw0(r1, mkF64i(0x0));
10785 
10786    return "lzdr";
10787 }
10788 
10789 static const HChar *
10790 s390_irgen_LZXR(UChar r1)
10791 {
10792    put_fpr_dw0(r1, mkF64i(0x0));
10793    put_fpr_dw0(r1 + 2, mkF64i(0x0));
10794 
10795    return "lzxr";
10796 }
10797 
10798 static const HChar *
10799 s390_irgen_SRNM(IRTemp op2addr)
10800 {
10801    UInt input_mask, fpc_mask;
10802 
10803    input_mask = 3;
10804    fpc_mask = s390_host_has_fpext ? 7 : 3;
10805 
10806    put_fpc_w0(binop(Iop_Or32,
10807                     binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
10808                     binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
10809                           mkU32(input_mask))));
10810    return "srnm";
10811 }
10812 
10813 static const HChar *
10814 s390_irgen_SRNMB(IRTemp op2addr)
10815 {
10816    UInt input_mask, fpc_mask;
10817 
10818    input_mask = 7;
10819    fpc_mask = 7;
10820 
10821    put_fpc_w0(binop(Iop_Or32,
10822                     binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
10823                     binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
10824                           mkU32(input_mask))));
10825    return "srnmb";
10826 }
10827 
10828 static void
10829 s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
10830 {
10831    if (b2 == 0) {  /* This is the typical case */
10832       if (d2 > 3) {
10833          if (s390_host_has_fpext && d2 == 7) {
10834             /* ok */
10835          } else {
10836             emulation_warning(EmWarn_S390X_invalid_rounding);
10837             d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
10838          }
10839       }
10840    }
10841 
10842    s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
10843 }
10844 
10845 /* Wrapper to validate the parameter as in SRNMB is not required, as all
10846    the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
10847 static const HChar *
10848 s390_irgen_SRNMT(IRTemp op2addr)
10849 {
10850    UInt input_mask, fpc_mask;
10851 
10852    input_mask = 7;
10853    fpc_mask = 0x70;
10854 
10855    /* fpc[25:27] <- op2addr[61:63]
10856       fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
10857    put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
10858                     binop(Iop_Shl32, binop(Iop_And32,
10859                                            unop(Iop_64to32, mkexpr(op2addr)),
10860                                            mkU32(input_mask)), mkU8(4))));
10861    return "srnmt";
10862 }
10863 
10864 
10865 static const HChar *
10866 s390_irgen_SFPC(UChar r1)
10867 {
10868    put_fpc_w0(get_gpr_w1(r1));
10869 
10870    return "sfpc";
10871 }
10872 
10873 static const HChar *
10874 s390_irgen_STE(UChar r1, IRTemp op2addr)
10875 {
10876    store(mkexpr(op2addr), get_fpr_w0(r1));
10877 
10878    return "ste";
10879 }
10880 
10881 static const HChar *
10882 s390_irgen_STD(UChar r1, IRTemp op2addr)
10883 {
10884    store(mkexpr(op2addr), get_fpr_dw0(r1));
10885 
10886    return "std";
10887 }
10888 
10889 static const HChar *
10890 s390_irgen_STEY(UChar r1, IRTemp op2addr)
10891 {
10892    store(mkexpr(op2addr), get_fpr_w0(r1));
10893 
10894    return "stey";
10895 }
10896 
10897 static const HChar *
10898 s390_irgen_STDY(UChar r1, IRTemp op2addr)
10899 {
10900    store(mkexpr(op2addr), get_fpr_dw0(r1));
10901 
10902    return "stdy";
10903 }
10904 
10905 static const HChar *
10906 s390_irgen_STFPC(IRTemp op2addr)
10907 {
10908    store(mkexpr(op2addr), get_fpc_w0());
10909 
10910    return "stfpc";
10911 }
10912 
10913 static const HChar *
10914 s390_irgen_AEBR(UChar r1, UChar r2)
10915 {
10916    IRTemp op1 = newTemp(Ity_F32);
10917    IRTemp op2 = newTemp(Ity_F32);
10918    IRTemp result = newTemp(Ity_F32);
10919    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
10920 
10921    assign(op1, get_fpr_w0(r1));
10922    assign(op2, get_fpr_w0(r2));
10923    assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
10924           mkexpr(op2)));
10925    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
10926    put_fpr_w0(r1, mkexpr(result));
10927 
10928    return "aebr";
10929 }
10930 
10931 static const HChar *
10932 s390_irgen_ADBR(UChar r1, UChar r2)
10933 {
10934    IRTemp op1 = newTemp(Ity_F64);
10935    IRTemp op2 = newTemp(Ity_F64);
10936    IRTemp result = newTemp(Ity_F64);
10937    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
10938 
10939    assign(op1, get_fpr_dw0(r1));
10940    assign(op2, get_fpr_dw0(r2));
10941    assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
10942           mkexpr(op2)));
10943    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
10944    put_fpr_dw0(r1, mkexpr(result));
10945 
10946    return "adbr";
10947 }
10948 
10949 static const HChar *
10950 s390_irgen_AEB(UChar r1, IRTemp op2addr)
10951 {
10952    IRTemp op1 = newTemp(Ity_F32);
10953    IRTemp op2 = newTemp(Ity_F32);
10954    IRTemp result = newTemp(Ity_F32);
10955    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
10956 
10957    assign(op1, get_fpr_w0(r1));
10958    assign(op2, load(Ity_F32, mkexpr(op2addr)));
10959    assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
10960           mkexpr(op2)));
10961    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
10962    put_fpr_w0(r1, mkexpr(result));
10963 
10964    return "aeb";
10965 }
10966 
10967 static const HChar *
10968 s390_irgen_ADB(UChar r1, IRTemp op2addr)
10969 {
10970    IRTemp op1 = newTemp(Ity_F64);
10971    IRTemp op2 = newTemp(Ity_F64);
10972    IRTemp result = newTemp(Ity_F64);
10973    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
10974 
10975    assign(op1, get_fpr_dw0(r1));
10976    assign(op2, load(Ity_F64, mkexpr(op2addr)));
10977    assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
10978           mkexpr(op2)));
10979    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
10980    put_fpr_dw0(r1, mkexpr(result));
10981 
10982    return "adb";
10983 }
10984 
10985 static const HChar *
10986 s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
10987                  UChar r1, UChar r2)
10988 {
10989    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
10990       emulation_warning(EmWarn_S390X_fpext_rounding);
10991       m3 = S390_BFP_ROUND_PER_FPC;
10992    }
10993    IRTemp op2 = newTemp(Ity_I32);
10994 
10995    assign(op2, get_gpr_w1(r2));
10996    put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
10997                         mkexpr(op2)));
10998 
10999    return "cefbr";
11000 }
11001 
11002 static const HChar *
11003 s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
11004                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11005 {
11006    IRTemp op2 = newTemp(Ity_I32);
11007 
11008    assign(op2, get_gpr_w1(r2));
11009    put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
11010 
11011    return "cdfbr";
11012 }
11013 
11014 static const HChar *
11015 s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
11016                  UChar r1, UChar r2)
11017 {
11018    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
11019       emulation_warning(EmWarn_S390X_fpext_rounding);
11020       m3 = S390_BFP_ROUND_PER_FPC;
11021    }
11022    IRTemp op2 = newTemp(Ity_I64);
11023 
11024    assign(op2, get_gpr_dw0(r2));
11025    put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
11026                         mkexpr(op2)));
11027 
11028    return "cegbr";
11029 }
11030 
11031 static const HChar *
11032 s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
11033                  UChar r1, UChar r2)
11034 {
11035    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
11036       emulation_warning(EmWarn_S390X_fpext_rounding);
11037       m3 = S390_BFP_ROUND_PER_FPC;
11038    }
11039    IRTemp op2 = newTemp(Ity_I64);
11040 
11041    assign(op2, get_gpr_dw0(r2));
11042    put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
11043                          mkexpr(op2)));
11044 
11045    return "cdgbr";
11046 }
11047 
11048 static const HChar *
11049 s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
11050                   UChar r1, UChar r2)
11051 {
11052    if (! s390_host_has_fpext) {
11053       emulation_failure(EmFail_S390X_fpext);
11054    } else {
11055       IRTemp op2 = newTemp(Ity_I32);
11056 
11057       assign(op2, get_gpr_w1(r2));
11058       put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
11059                            mkexpr(op2)));
11060    }
11061    return "celfbr";
11062 }
11063 
11064 static const HChar *
11065 s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
11066                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11067 {
11068    if (! s390_host_has_fpext) {
11069       emulation_failure(EmFail_S390X_fpext);
11070    } else {
11071       IRTemp op2 = newTemp(Ity_I32);
11072 
11073       assign(op2, get_gpr_w1(r2));
11074       put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
11075    }
11076    return "cdlfbr";
11077 }
11078 
11079 static const HChar *
11080 s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
11081                   UChar r1, UChar r2)
11082 {
11083    if (! s390_host_has_fpext) {
11084       emulation_failure(EmFail_S390X_fpext);
11085    } else {
11086       IRTemp op2 = newTemp(Ity_I64);
11087 
11088       assign(op2, get_gpr_dw0(r2));
11089       put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
11090                            mkexpr(op2)));
11091    }
11092    return "celgbr";
11093 }
11094 
11095 static const HChar *
11096 s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
11097                   UChar r1, UChar r2)
11098 {
11099    if (! s390_host_has_fpext) {
11100       emulation_failure(EmFail_S390X_fpext);
11101    } else {
11102       IRTemp op2 = newTemp(Ity_I64);
11103 
11104       assign(op2, get_gpr_dw0(r2));
11105       put_fpr_dw0(r1, binop(Iop_I64UtoF64,
11106                             mkexpr(encode_bfp_rounding_mode(m3)),
11107                             mkexpr(op2)));
11108    }
11109    return "cdlgbr";
11110 }
11111 
11112 static const HChar *
11113 s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
11114                   UChar r1, UChar r2)
11115 {
11116    if (! s390_host_has_fpext) {
11117       emulation_failure(EmFail_S390X_fpext);
11118    } else {
11119       IRTemp op = newTemp(Ity_F32);
11120       IRTemp result = newTemp(Ity_I32);
11121       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11122 
11123       assign(op, get_fpr_w0(r2));
11124       assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
11125                            mkexpr(op)));
11126       put_gpr_w1(r1, mkexpr(result));
11127       s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
11128    }
11129    return "clfebr";
11130 }
11131 
11132 static const HChar *
11133 s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
11134                   UChar r1, UChar r2)
11135 {
11136    if (! s390_host_has_fpext) {
11137       emulation_failure(EmFail_S390X_fpext);
11138    } else {
11139       IRTemp op = newTemp(Ity_F64);
11140       IRTemp result = newTemp(Ity_I32);
11141       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11142 
11143       assign(op, get_fpr_dw0(r2));
11144       assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
11145                            mkexpr(op)));
11146       put_gpr_w1(r1, mkexpr(result));
11147       s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
11148    }
11149    return "clfdbr";
11150 }
11151 
11152 static const HChar *
11153 s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
11154                   UChar r1, UChar r2)
11155 {
11156    if (! s390_host_has_fpext) {
11157       emulation_failure(EmFail_S390X_fpext);
11158    } else {
11159       IRTemp op = newTemp(Ity_F32);
11160       IRTemp result = newTemp(Ity_I64);
11161       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11162 
11163       assign(op, get_fpr_w0(r2));
11164       assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
11165                            mkexpr(op)));
11166       put_gpr_dw0(r1, mkexpr(result));
11167       s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
11168    }
11169    return "clgebr";
11170 }
11171 
11172 static const HChar *
11173 s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
11174                   UChar r1, UChar r2)
11175 {
11176    if (! s390_host_has_fpext) {
11177       emulation_failure(EmFail_S390X_fpext);
11178    } else {
11179       IRTemp op = newTemp(Ity_F64);
11180       IRTemp result = newTemp(Ity_I64);
11181       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11182 
11183       assign(op, get_fpr_dw0(r2));
11184       assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
11185                            mkexpr(op)));
11186       put_gpr_dw0(r1, mkexpr(result));
11187       s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
11188    }
11189    return "clgdbr";
11190 }
11191 
11192 static const HChar *
11193 s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
11194                  UChar r1, UChar r2)
11195 {
11196    IRTemp op = newTemp(Ity_F32);
11197    IRTemp result = newTemp(Ity_I32);
11198    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11199 
11200    assign(op, get_fpr_w0(r2));
11201    assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
11202           mkexpr(op)));
11203    put_gpr_w1(r1, mkexpr(result));
11204    s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
11205 
11206    return "cfebr";
11207 }
11208 
11209 static const HChar *
11210 s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
11211                  UChar r1, UChar r2)
11212 {
11213    IRTemp op = newTemp(Ity_F64);
11214    IRTemp result = newTemp(Ity_I32);
11215    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11216 
11217    assign(op, get_fpr_dw0(r2));
11218    assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
11219           mkexpr(op)));
11220    put_gpr_w1(r1, mkexpr(result));
11221    s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
11222 
11223    return "cfdbr";
11224 }
11225 
11226 static const HChar *
11227 s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
11228                  UChar r1, UChar r2)
11229 {
11230    IRTemp op = newTemp(Ity_F32);
11231    IRTemp result = newTemp(Ity_I64);
11232    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11233 
11234    assign(op, get_fpr_w0(r2));
11235    assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
11236           mkexpr(op)));
11237    put_gpr_dw0(r1, mkexpr(result));
11238    s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
11239 
11240    return "cgebr";
11241 }
11242 
11243 static const HChar *
11244 s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
11245                  UChar r1, UChar r2)
11246 {
11247    IRTemp op = newTemp(Ity_F64);
11248    IRTemp result = newTemp(Ity_I64);
11249    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11250 
11251    assign(op, get_fpr_dw0(r2));
11252    assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
11253           mkexpr(op)));
11254    put_gpr_dw0(r1, mkexpr(result));
11255    s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
11256 
11257    return "cgdbr";
11258 }
11259 
11260 static const HChar *
11261 s390_irgen_DEBR(UChar r1, UChar r2)
11262 {
11263    IRTemp op1 = newTemp(Ity_F32);
11264    IRTemp op2 = newTemp(Ity_F32);
11265    IRTemp result = newTemp(Ity_F32);
11266    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11267 
11268    assign(op1, get_fpr_w0(r1));
11269    assign(op2, get_fpr_w0(r2));
11270    assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
11271           mkexpr(op2)));
11272    put_fpr_w0(r1, mkexpr(result));
11273 
11274    return "debr";
11275 }
11276 
11277 static const HChar *
11278 s390_irgen_DDBR(UChar r1, UChar r2)
11279 {
11280    IRTemp op1 = newTemp(Ity_F64);
11281    IRTemp op2 = newTemp(Ity_F64);
11282    IRTemp result = newTemp(Ity_F64);
11283    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11284 
11285    assign(op1, get_fpr_dw0(r1));
11286    assign(op2, get_fpr_dw0(r2));
11287    assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
11288           mkexpr(op2)));
11289    put_fpr_dw0(r1, mkexpr(result));
11290 
11291    return "ddbr";
11292 }
11293 
11294 static const HChar *
11295 s390_irgen_DEB(UChar r1, IRTemp op2addr)
11296 {
11297    IRTemp op1 = newTemp(Ity_F32);
11298    IRTemp op2 = newTemp(Ity_F32);
11299    IRTemp result = newTemp(Ity_F32);
11300    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11301 
11302    assign(op1, get_fpr_w0(r1));
11303    assign(op2, load(Ity_F32, mkexpr(op2addr)));
11304    assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
11305           mkexpr(op2)));
11306    put_fpr_w0(r1, mkexpr(result));
11307 
11308    return "deb";
11309 }
11310 
11311 static const HChar *
11312 s390_irgen_DDB(UChar r1, IRTemp op2addr)
11313 {
11314    IRTemp op1 = newTemp(Ity_F64);
11315    IRTemp op2 = newTemp(Ity_F64);
11316    IRTemp result = newTemp(Ity_F64);
11317    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11318 
11319    assign(op1, get_fpr_dw0(r1));
11320    assign(op2, load(Ity_F64, mkexpr(op2addr)));
11321    assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
11322           mkexpr(op2)));
11323    put_fpr_dw0(r1, mkexpr(result));
11324 
11325    return "ddb";
11326 }
11327 
11328 static const HChar *
11329 s390_irgen_LTEBR(UChar r1, UChar r2)
11330 {
11331    IRTemp result = newTemp(Ity_F32);
11332 
11333    assign(result, get_fpr_w0(r2));
11334    put_fpr_w0(r1, mkexpr(result));
11335    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11336 
11337    return "ltebr";
11338 }
11339 
11340 static const HChar *
11341 s390_irgen_LTDBR(UChar r1, UChar r2)
11342 {
11343    IRTemp result = newTemp(Ity_F64);
11344 
11345    assign(result, get_fpr_dw0(r2));
11346    put_fpr_dw0(r1, mkexpr(result));
11347    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11348 
11349    return "ltdbr";
11350 }
11351 
11352 static const HChar *
11353 s390_irgen_LCEBR(UChar r1, UChar r2)
11354 {
11355    IRTemp result = newTemp(Ity_F32);
11356 
11357    assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
11358    put_fpr_w0(r1, mkexpr(result));
11359    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11360 
11361    return "lcebr";
11362 }
11363 
11364 static const HChar *
11365 s390_irgen_LCDBR(UChar r1, UChar r2)
11366 {
11367    IRTemp result = newTemp(Ity_F64);
11368 
11369    assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11370    put_fpr_dw0(r1, mkexpr(result));
11371    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11372 
11373    return "lcdbr";
11374 }
11375 
11376 static const HChar *
11377 s390_irgen_LDEBR(UChar r1, UChar r2)
11378 {
11379    IRTemp op = newTemp(Ity_F32);
11380 
11381    assign(op, get_fpr_w0(r2));
11382    put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
11383 
11384    return "ldebr";
11385 }
11386 
11387 static const HChar *
11388 s390_irgen_LDEB(UChar r1, IRTemp op2addr)
11389 {
11390    IRTemp op = newTemp(Ity_F32);
11391 
11392    assign(op, load(Ity_F32, mkexpr(op2addr)));
11393    put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
11394 
11395    return "ldeb";
11396 }
11397 
11398 static const HChar *
11399 s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
11400                  UChar r1, UChar r2)
11401 {
11402    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
11403       emulation_warning(EmWarn_S390X_fpext_rounding);
11404       m3 = S390_BFP_ROUND_PER_FPC;
11405    }
11406    IRTemp op = newTemp(Ity_F64);
11407 
11408    assign(op, get_fpr_dw0(r2));
11409    put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
11410                         mkexpr(op)));
11411 
11412    return "ledbr";
11413 }
11414 
11415 static const HChar *
11416 s390_irgen_MEEBR(UChar r1, UChar r2)
11417 {
11418    IRTemp op1 = newTemp(Ity_F32);
11419    IRTemp op2 = newTemp(Ity_F32);
11420    IRTemp result = newTemp(Ity_F32);
11421    IRRoundingMode rounding_mode =
11422       encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11423 
11424    assign(op1, get_fpr_w0(r1));
11425    assign(op2, get_fpr_w0(r2));
11426    assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
11427           mkexpr(op2)));
11428    put_fpr_w0(r1, mkexpr(result));
11429 
11430    return "meebr";
11431 }
11432 
11433 static const HChar *
11434 s390_irgen_MDBR(UChar r1, UChar r2)
11435 {
11436    IRTemp op1 = newTemp(Ity_F64);
11437    IRTemp op2 = newTemp(Ity_F64);
11438    IRTemp result = newTemp(Ity_F64);
11439    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11440 
11441    assign(op1, get_fpr_dw0(r1));
11442    assign(op2, get_fpr_dw0(r2));
11443    assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
11444           mkexpr(op2)));
11445    put_fpr_dw0(r1, mkexpr(result));
11446 
11447    return "mdbr";
11448 }
11449 
11450 static const HChar *
11451 s390_irgen_MEEB(UChar r1, IRTemp op2addr)
11452 {
11453    IRTemp op1 = newTemp(Ity_F32);
11454    IRTemp op2 = newTemp(Ity_F32);
11455    IRTemp result = newTemp(Ity_F32);
11456    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11457 
11458    assign(op1, get_fpr_w0(r1));
11459    assign(op2, load(Ity_F32, mkexpr(op2addr)));
11460    assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
11461           mkexpr(op2)));
11462    put_fpr_w0(r1, mkexpr(result));
11463 
11464    return "meeb";
11465 }
11466 
11467 static const HChar *
11468 s390_irgen_MDB(UChar r1, IRTemp op2addr)
11469 {
11470    IRTemp op1 = newTemp(Ity_F64);
11471    IRTemp op2 = newTemp(Ity_F64);
11472    IRTemp result = newTemp(Ity_F64);
11473    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11474 
11475    assign(op1, get_fpr_dw0(r1));
11476    assign(op2, load(Ity_F64, mkexpr(op2addr)));
11477    assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
11478           mkexpr(op2)));
11479    put_fpr_dw0(r1, mkexpr(result));
11480 
11481    return "mdb";
11482 }
11483 
11484 static const HChar *
11485 s390_irgen_SEBR(UChar r1, UChar r2)
11486 {
11487    IRTemp op1 = newTemp(Ity_F32);
11488    IRTemp op2 = newTemp(Ity_F32);
11489    IRTemp result = newTemp(Ity_F32);
11490    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11491 
11492    assign(op1, get_fpr_w0(r1));
11493    assign(op2, get_fpr_w0(r2));
11494    assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
11495           mkexpr(op2)));
11496    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11497    put_fpr_w0(r1, mkexpr(result));
11498 
11499    return "sebr";
11500 }
11501 
11502 static const HChar *
11503 s390_irgen_SDBR(UChar r1, UChar r2)
11504 {
11505    IRTemp op1 = newTemp(Ity_F64);
11506    IRTemp op2 = newTemp(Ity_F64);
11507    IRTemp result = newTemp(Ity_F64);
11508    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11509 
11510    assign(op1, get_fpr_dw0(r1));
11511    assign(op2, get_fpr_dw0(r2));
11512    assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
11513           mkexpr(op2)));
11514    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11515    put_fpr_dw0(r1, mkexpr(result));
11516 
11517    return "sdbr";
11518 }
11519 
11520 static const HChar *
11521 s390_irgen_SEB(UChar r1, IRTemp op2addr)
11522 {
11523    IRTemp op1 = newTemp(Ity_F32);
11524    IRTemp op2 = newTemp(Ity_F32);
11525    IRTemp result = newTemp(Ity_F32);
11526    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11527 
11528    assign(op1, get_fpr_w0(r1));
11529    assign(op2, load(Ity_F32, mkexpr(op2addr)));
11530    assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
11531           mkexpr(op2)));
11532    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11533    put_fpr_w0(r1, mkexpr(result));
11534 
11535    return "seb";
11536 }
11537 
11538 static const HChar *
11539 s390_irgen_SDB(UChar r1, IRTemp op2addr)
11540 {
11541    IRTemp op1 = newTemp(Ity_F64);
11542    IRTemp op2 = newTemp(Ity_F64);
11543    IRTemp result = newTemp(Ity_F64);
11544    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11545 
11546    assign(op1, get_fpr_dw0(r1));
11547    assign(op2, load(Ity_F64, mkexpr(op2addr)));
11548    assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
11549           mkexpr(op2)));
11550    s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11551    put_fpr_dw0(r1, mkexpr(result));
11552 
11553    return "sdb";
11554 }
11555 
11556 static const HChar *
11557 s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
11558 {
11559    if (! s390_host_has_dfp) {
11560       emulation_failure(EmFail_S390X_DFP_insn);
11561    } else {
11562       IRTemp op1 = newTemp(Ity_D64);
11563       IRTemp op2 = newTemp(Ity_D64);
11564       IRTemp result = newTemp(Ity_D64);
11565       IRTemp rounding_mode;
11566 
11567       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
11568          emulation_warning(EmWarn_S390X_fpext_rounding);
11569          m4 = S390_DFP_ROUND_PER_FPC_0;
11570       }
11571 
11572       rounding_mode = encode_dfp_rounding_mode(m4);
11573       assign(op1, get_dpr_dw0(r2));
11574       assign(op2, get_dpr_dw0(r3));
11575       assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
11576                            mkexpr(op2)));
11577       s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
11578       put_dpr_dw0(r1, mkexpr(result));
11579    }
11580    return (m4 == 0) ? "adtr" : "adtra";
11581 }
11582 
11583 static const HChar *
11584 s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
11585 {
11586    if (! s390_host_has_dfp) {
11587       emulation_failure(EmFail_S390X_DFP_insn);
11588    } else {
11589       IRTemp op1 = newTemp(Ity_D128);
11590       IRTemp op2 = newTemp(Ity_D128);
11591       IRTemp result = newTemp(Ity_D128);
11592       IRTemp rounding_mode;
11593 
11594       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
11595          emulation_warning(EmWarn_S390X_fpext_rounding);
11596          m4 = S390_DFP_ROUND_PER_FPC_0;
11597       }
11598 
11599       rounding_mode = encode_dfp_rounding_mode(m4);
11600       assign(op1, get_dpr_pair(r2));
11601       assign(op2, get_dpr_pair(r3));
11602       assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
11603                            mkexpr(op2)));
11604       put_dpr_pair(r1, mkexpr(result));
11605 
11606       s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
11607    }
11608    return (m4 == 0) ? "axtr" : "axtra";
11609 }
11610 
11611 static const HChar *
11612 s390_irgen_CDTR(UChar r1, UChar r2)
11613 {
11614    IRTemp op1 = newTemp(Ity_D64);
11615    IRTemp op2 = newTemp(Ity_D64);
11616    IRTemp cc_vex  = newTemp(Ity_I32);
11617    IRTemp cc_s390 = newTemp(Ity_I32);
11618 
11619    assign(op1, get_dpr_dw0(r1));
11620    assign(op2, get_dpr_dw0(r2));
11621    assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
11622 
11623    assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
11624    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11625 
11626    return "cdtr";
11627 }
11628 
11629 static const HChar *
11630 s390_irgen_CXTR(UChar r1, UChar r2)
11631 {
11632    IRTemp op1 = newTemp(Ity_D128);
11633    IRTemp op2 = newTemp(Ity_D128);
11634    IRTemp cc_vex  = newTemp(Ity_I32);
11635    IRTemp cc_s390 = newTemp(Ity_I32);
11636 
11637    assign(op1, get_dpr_pair(r1));
11638    assign(op2, get_dpr_pair(r2));
11639    assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
11640 
11641    assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
11642    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11643 
11644    return "cxtr";
11645 }
11646 
11647 static const HChar *
11648 s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
11649                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11650 {
11651    if (! s390_host_has_dfp) {
11652       emulation_failure(EmFail_S390X_DFP_insn);
11653    } else {
11654       if (! s390_host_has_fpext) {
11655          emulation_failure(EmFail_S390X_fpext);
11656       } else {
11657          IRTemp op2 = newTemp(Ity_I32);
11658 
11659          assign(op2, get_gpr_w1(r2));
11660          put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
11661       }
11662    }
11663    return "cdftr";
11664 }
11665 
11666 static const HChar *
11667 s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
11668                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11669 {
11670    if (! s390_host_has_dfp) {
11671       emulation_failure(EmFail_S390X_DFP_insn);
11672    } else {
11673       if (! s390_host_has_fpext) {
11674          emulation_failure(EmFail_S390X_fpext);
11675       } else {
11676          IRTemp op2 = newTemp(Ity_I32);
11677 
11678          assign(op2, get_gpr_w1(r2));
11679          put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
11680       }
11681    }
11682    return "cxftr";
11683 }
11684 
11685 static const HChar *
11686 s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
11687                   UChar r1, UChar r2)
11688 {
11689    if (! s390_host_has_dfp) {
11690       emulation_failure(EmFail_S390X_DFP_insn);
11691    } else {
11692       IRTemp op2 = newTemp(Ity_I64);
11693 
11694       if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
11695          emulation_warning(EmWarn_S390X_fpext_rounding);
11696          m3 = S390_DFP_ROUND_PER_FPC_0;
11697       }
11698 
11699       assign(op2, get_gpr_dw0(r2));
11700       put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
11701                             mkexpr(op2)));
11702    }
11703    return (m3 == 0) ? "cdgtr" : "cdgtra";
11704 }
11705 
11706 static const HChar *
11707 s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
11708                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11709 {
11710    if (! s390_host_has_dfp) {
11711       emulation_failure(EmFail_S390X_DFP_insn);
11712    } else {
11713       IRTemp op2 = newTemp(Ity_I64);
11714 
11715       /* No emulation warning here about an non-zero m3 on hosts without
11716          floating point extension facility. No rounding is performed */
11717 
11718       assign(op2, get_gpr_dw0(r2));
11719       put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
11720    }
11721    return "cxgtr";
11722 }
11723 
11724 static const HChar *
11725 s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
11726                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11727 {
11728    if (! s390_host_has_dfp) {
11729       emulation_failure(EmFail_S390X_DFP_insn);
11730    } else {
11731       if (! s390_host_has_fpext) {
11732          emulation_failure(EmFail_S390X_fpext);
11733       } else {
11734          IRTemp op2 = newTemp(Ity_I32);
11735 
11736          assign(op2, get_gpr_w1(r2));
11737          put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
11738       }
11739    }
11740    return "cdlftr";
11741 }
11742 
11743 static const HChar *
11744 s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
11745                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11746 {
11747    if (! s390_host_has_dfp) {
11748       emulation_failure(EmFail_S390X_DFP_insn);
11749    } else {
11750       if (! s390_host_has_fpext) {
11751          emulation_failure(EmFail_S390X_fpext);
11752       } else {
11753          IRTemp op2 = newTemp(Ity_I32);
11754 
11755          assign(op2, get_gpr_w1(r2));
11756          put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
11757       }
11758    }
11759    return "cxlftr";
11760 }
11761 
11762 static const HChar *
11763 s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
11764                   UChar r1, UChar r2)
11765 {
11766    if (! s390_host_has_dfp) {
11767       emulation_failure(EmFail_S390X_DFP_insn);
11768    } else {
11769       if (! s390_host_has_fpext) {
11770          emulation_failure(EmFail_S390X_fpext);
11771       } else {
11772          IRTemp op2 = newTemp(Ity_I64);
11773 
11774          assign(op2, get_gpr_dw0(r2));
11775          put_dpr_dw0(r1, binop(Iop_I64UtoD64,
11776                                mkexpr(encode_dfp_rounding_mode(m3)),
11777                                mkexpr(op2)));
11778       }
11779    }
11780    return "cdlgtr";
11781 }
11782 
11783 static const HChar *
11784 s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
11785                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11786 {
11787    if (! s390_host_has_dfp) {
11788       emulation_failure(EmFail_S390X_DFP_insn);
11789    } else {
11790       if (! s390_host_has_fpext) {
11791          emulation_failure(EmFail_S390X_fpext);
11792       } else {
11793          IRTemp op2 = newTemp(Ity_I64);
11794 
11795          assign(op2, get_gpr_dw0(r2));
11796          put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
11797       }
11798    }
11799    return "cxlgtr";
11800 }
11801 
11802 static const HChar *
11803 s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
11804                  UChar r1, UChar r2)
11805 {
11806    if (! s390_host_has_dfp) {
11807       emulation_failure(EmFail_S390X_DFP_insn);
11808    } else {
11809       if (! s390_host_has_fpext) {
11810          emulation_failure(EmFail_S390X_fpext);
11811       } else {
11812          IRTemp op = newTemp(Ity_D64);
11813          IRTemp result = newTemp(Ity_I32);
11814          IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11815 
11816          assign(op, get_dpr_dw0(r2));
11817          assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
11818                               mkexpr(op)));
11819          put_gpr_w1(r1, mkexpr(result));
11820          s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
11821       }
11822    }
11823    return "cfdtr";
11824 }
11825 
11826 static const HChar *
11827 s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
11828                  UChar r1, UChar r2)
11829 {
11830    if (! s390_host_has_dfp) {
11831       emulation_failure(EmFail_S390X_DFP_insn);
11832    } else {
11833       if (! s390_host_has_fpext) {
11834          emulation_failure(EmFail_S390X_fpext);
11835       } else {
11836          IRTemp op = newTemp(Ity_D128);
11837          IRTemp result = newTemp(Ity_I32);
11838          IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11839 
11840          assign(op, get_dpr_pair(r2));
11841          assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
11842                               mkexpr(op)));
11843          put_gpr_w1(r1, mkexpr(result));
11844          s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op,
11845                                  rounding_mode);
11846       }
11847    }
11848    return "cfxtr";
11849 }
11850 
11851 static const HChar *
11852 s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
11853                  UChar r1, UChar r2)
11854 {
11855    if (! s390_host_has_dfp) {
11856       emulation_failure(EmFail_S390X_DFP_insn);
11857    } else {
11858       IRTemp op = newTemp(Ity_D64);
11859       IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11860 
11861       /* If fpext is not installed and m3 is in 1:7,
11862          rounding mode performed is unpredictable */
11863       if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
11864          emulation_warning(EmWarn_S390X_fpext_rounding);
11865          m3 = S390_DFP_ROUND_PER_FPC_0;
11866       }
11867 
11868       assign(op, get_dpr_dw0(r2));
11869       put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
11870       s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
11871    }
11872    return "cgdtr";
11873 }
11874 
11875 static const HChar *
11876 s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
11877                  UChar r1, UChar r2)
11878 {
11879    if (! s390_host_has_dfp) {
11880       emulation_failure(EmFail_S390X_DFP_insn);
11881    } else {
11882       IRTemp op = newTemp(Ity_D128);
11883       IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11884 
11885       /* If fpext is not installed and m3 is in 1:7,
11886          rounding mode performed is unpredictable */
11887       if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
11888          emulation_warning(EmWarn_S390X_fpext_rounding);
11889          m3 = S390_DFP_ROUND_PER_FPC_0;
11890       }
11891       assign(op, get_dpr_pair(r2));
11892       put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
11893       s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
11894    }
11895    return "cgxtr";
11896 }
11897 
11898 static const HChar *
11899 s390_irgen_CEDTR(UChar r1, UChar r2)
11900 {
11901    if (! s390_host_has_dfp) {
11902       emulation_failure(EmFail_S390X_DFP_insn);
11903    } else {
11904       IRTemp op1 = newTemp(Ity_D64);
11905       IRTemp op2 = newTemp(Ity_D64);
11906       IRTemp cc_vex  = newTemp(Ity_I32);
11907       IRTemp cc_s390 = newTemp(Ity_I32);
11908 
11909       assign(op1, get_dpr_dw0(r1));
11910       assign(op2, get_dpr_dw0(r2));
11911       assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
11912 
11913       assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
11914       s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11915    }
11916    return "cedtr";
11917 }
11918 
11919 static const HChar *
11920 s390_irgen_CEXTR(UChar r1, UChar r2)
11921 {
11922    if (! s390_host_has_dfp) {
11923       emulation_failure(EmFail_S390X_DFP_insn);
11924    } else {
11925       IRTemp op1 = newTemp(Ity_D128);
11926       IRTemp op2 = newTemp(Ity_D128);
11927       IRTemp cc_vex  = newTemp(Ity_I32);
11928       IRTemp cc_s390 = newTemp(Ity_I32);
11929 
11930       assign(op1, get_dpr_pair(r1));
11931       assign(op2, get_dpr_pair(r2));
11932       assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
11933 
11934       assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
11935       s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11936    }
11937    return "cextr";
11938 }
11939 
11940 static const HChar *
11941 s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
11942                   UChar r1, UChar r2)
11943 {
11944    if (! s390_host_has_dfp) {
11945       emulation_failure(EmFail_S390X_DFP_insn);
11946    } else {
11947       if (! s390_host_has_fpext) {
11948          emulation_failure(EmFail_S390X_fpext);
11949       } else {
11950          IRTemp op = newTemp(Ity_D64);
11951          IRTemp result = newTemp(Ity_I32);
11952          IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11953 
11954          assign(op, get_dpr_dw0(r2));
11955          assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
11956                               mkexpr(op)));
11957          put_gpr_w1(r1, mkexpr(result));
11958          s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
11959       }
11960    }
11961    return "clfdtr";
11962 }
11963 
11964 static const HChar *
11965 s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
11966                   UChar r1, UChar r2)
11967 {
11968    if (! s390_host_has_dfp) {
11969       emulation_failure(EmFail_S390X_DFP_insn);
11970    } else {
11971       if (! s390_host_has_fpext) {
11972          emulation_failure(EmFail_S390X_fpext);
11973       } else {
11974          IRTemp op = newTemp(Ity_D128);
11975          IRTemp result = newTemp(Ity_I32);
11976          IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
11977 
11978          assign(op, get_dpr_pair(r2));
11979          assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
11980                               mkexpr(op)));
11981          put_gpr_w1(r1, mkexpr(result));
11982          s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op,
11983                                  rounding_mode);
11984       }
11985    }
11986    return "clfxtr";
11987 }
11988 
11989 static const HChar *
11990 s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
11991                   UChar r1, UChar r2)
11992 {
11993    if (! s390_host_has_dfp) {
11994       emulation_failure(EmFail_S390X_DFP_insn);
11995    } else {
11996       if (! s390_host_has_fpext) {
11997          emulation_failure(EmFail_S390X_fpext);
11998       } else {
11999          IRTemp op = newTemp(Ity_D64);
12000          IRTemp result = newTemp(Ity_I64);
12001          IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
12002 
12003          assign(op, get_dpr_dw0(r2));
12004          assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
12005                               mkexpr(op)));
12006          put_gpr_dw0(r1, mkexpr(result));
12007          s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
12008       }
12009    }
12010    return "clgdtr";
12011 }
12012 
12013 static const HChar *
12014 s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
12015                   UChar r1, UChar r2)
12016 {
12017    if (! s390_host_has_dfp) {
12018       emulation_failure(EmFail_S390X_DFP_insn);
12019    } else {
12020       if (! s390_host_has_fpext) {
12021          emulation_failure(EmFail_S390X_fpext);
12022       } else {
12023          IRTemp op = newTemp(Ity_D128);
12024          IRTemp result = newTemp(Ity_I64);
12025          IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
12026 
12027          assign(op, get_dpr_pair(r2));
12028          assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
12029                               mkexpr(op)));
12030          put_gpr_dw0(r1, mkexpr(result));
12031          s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
12032                                  rounding_mode);
12033       }
12034    }
12035    return "clgxtr";
12036 }
12037 
12038 static const HChar *
12039 s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12040 {
12041    if (! s390_host_has_dfp) {
12042       emulation_failure(EmFail_S390X_DFP_insn);
12043    } else {
12044       IRTemp op1 = newTemp(Ity_D64);
12045       IRTemp op2 = newTemp(Ity_D64);
12046       IRTemp result = newTemp(Ity_D64);
12047       IRTemp rounding_mode;
12048 
12049       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12050          emulation_warning(EmWarn_S390X_fpext_rounding);
12051          m4 = S390_DFP_ROUND_PER_FPC_0;
12052       }
12053 
12054       rounding_mode = encode_dfp_rounding_mode(m4);
12055       assign(op1, get_dpr_dw0(r2));
12056       assign(op2, get_dpr_dw0(r3));
12057       assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
12058                            mkexpr(op2)));
12059       put_dpr_dw0(r1, mkexpr(result));
12060    }
12061    return (m4 == 0) ? "ddtr" : "ddtra";
12062 }
12063 
12064 static const HChar *
12065 s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12066 {
12067    if (! s390_host_has_dfp) {
12068       emulation_failure(EmFail_S390X_DFP_insn);
12069    } else {
12070       IRTemp op1 = newTemp(Ity_D128);
12071       IRTemp op2 = newTemp(Ity_D128);
12072       IRTemp result = newTemp(Ity_D128);
12073       IRTemp rounding_mode;
12074 
12075       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12076          emulation_warning(EmWarn_S390X_fpext_rounding);
12077          m4 = S390_DFP_ROUND_PER_FPC_0;
12078       }
12079 
12080       rounding_mode = encode_dfp_rounding_mode(m4);
12081       assign(op1, get_dpr_pair(r2));
12082       assign(op2, get_dpr_pair(r3));
12083       assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
12084                            mkexpr(op2)));
12085       put_dpr_pair(r1, mkexpr(result));
12086    }
12087    return (m4 == 0) ? "dxtr" : "dxtra";
12088 }
12089 
12090 static const HChar *
12091 s390_irgen_EEDTR(UChar r1, UChar r2)
12092 {
12093    if (! s390_host_has_dfp) {
12094       emulation_failure(EmFail_S390X_DFP_insn);
12095    } else {
12096       put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
12097    }
12098    return "eedtr";
12099 }
12100 
12101 static const HChar *
12102 s390_irgen_EEXTR(UChar r1, UChar r2)
12103 {
12104    if (! s390_host_has_dfp) {
12105       emulation_failure(EmFail_S390X_DFP_insn);
12106    } else {
12107       put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
12108    }
12109    return "eextr";
12110 }
12111 
12112 static const HChar *
12113 s390_irgen_ESDTR(UChar r1, UChar r2)
12114 {
12115    if (! s390_host_has_dfp) {
12116       emulation_failure(EmFail_S390X_DFP_insn);
12117    } else {
12118       put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
12119    }
12120    return "esdtr";
12121 }
12122 
12123 static const HChar *
12124 s390_irgen_ESXTR(UChar r1, UChar r2)
12125 {
12126    if (! s390_host_has_dfp) {
12127       emulation_failure(EmFail_S390X_DFP_insn);
12128    } else {
12129       put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
12130    }
12131    return "esxtr";
12132 }
12133 
12134 static const HChar *
12135 s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
12136 {
12137    if (! s390_host_has_dfp) {
12138       emulation_failure(EmFail_S390X_DFP_insn);
12139    } else {
12140       IRTemp op1 = newTemp(Ity_I64);
12141       IRTemp op2 = newTemp(Ity_D64);
12142       IRTemp result = newTemp(Ity_D64);
12143 
12144       assign(op1, get_gpr_dw0(r2));
12145       assign(op2, get_dpr_dw0(r3));
12146       assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
12147       put_dpr_dw0(r1, mkexpr(result));
12148    }
12149    return "iedtr";
12150 }
12151 
12152 static const HChar *
12153 s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
12154 {
12155    if (! s390_host_has_dfp) {
12156       emulation_failure(EmFail_S390X_DFP_insn);
12157    } else {
12158       IRTemp op1 = newTemp(Ity_I64);
12159       IRTemp op2 = newTemp(Ity_D128);
12160       IRTemp result = newTemp(Ity_D128);
12161 
12162       assign(op1, get_gpr_dw0(r2));
12163       assign(op2, get_dpr_pair(r3));
12164       assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
12165       put_dpr_pair(r1, mkexpr(result));
12166    }
12167    return "iextr";
12168 }
12169 
12170 static const HChar *
12171 s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12172 {
12173    if (! s390_host_has_dfp) {
12174       emulation_failure(EmFail_S390X_DFP_insn);
12175    } else {
12176       IRTemp op = newTemp(Ity_D32);
12177 
12178       assign(op, get_dpr_w0(r2));
12179       put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
12180    }
12181    return "ldetr";
12182 }
12183 
12184 static const HChar *
12185 s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12186 {
12187    IRTemp op = newTemp(Ity_D64);
12188 
12189    assign(op, get_dpr_dw0(r2));
12190    put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
12191 
12192    return "lxdtr";
12193 }
12194 
12195 static const HChar *
12196 s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
12197                  UChar r1, UChar r2)
12198 {
12199    if (! s390_host_has_dfp) {
12200       emulation_failure(EmFail_S390X_DFP_insn);
12201    } else {
12202       /* If fpext is not installed and m3 is in 1:7,
12203          rounding mode performed is unpredictable */
12204       if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
12205          emulation_warning(EmWarn_S390X_fpext_rounding);
12206          m3 = S390_DFP_ROUND_PER_FPC_0;
12207       }
12208       IRTemp result = newTemp(Ity_D64);
12209 
12210       assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
12211                            get_dpr_pair(r2)));
12212       put_dpr_dw0(r1, mkexpr(result));
12213    }
12214    return "ldxtr";
12215 }
12216 
12217 static const HChar *
12218 s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
12219                  UChar r1, UChar r2)
12220 {
12221    if (! s390_host_has_dfp) {
12222       emulation_failure(EmFail_S390X_DFP_insn);
12223    } else {
12224       /* If fpext is not installed and m3 is in 1:7,
12225          rounding mode performed is unpredictable */
12226       if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
12227          emulation_warning(EmWarn_S390X_fpext_rounding);
12228          m3 = S390_DFP_ROUND_PER_FPC_0;
12229       }
12230       IRTemp op = newTemp(Ity_D64);
12231 
12232       assign(op, get_dpr_dw0(r2));
12233       put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
12234                            mkexpr(op)));
12235    }
12236    return "ledtr";
12237 }
12238 
12239 static const HChar *
12240 s390_irgen_LTDTR(UChar r1, UChar r2)
12241 {
12242    IRTemp result = newTemp(Ity_D64);
12243 
12244    assign(result, get_dpr_dw0(r2));
12245    put_dpr_dw0(r1, mkexpr(result));
12246    s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
12247 
12248    return "ltdtr";
12249 }
12250 
12251 static const HChar *
12252 s390_irgen_LTXTR(UChar r1, UChar r2)
12253 {
12254    IRTemp result = newTemp(Ity_D128);
12255 
12256    assign(result, get_dpr_pair(r2));
12257    put_dpr_pair(r1, mkexpr(result));
12258    s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
12259 
12260    return "ltxtr";
12261 }
12262 
12263 static const HChar *
12264 s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12265 {
12266    if (! s390_host_has_dfp) {
12267       emulation_failure(EmFail_S390X_DFP_insn);
12268    } else {
12269       IRTemp op1 = newTemp(Ity_D64);
12270       IRTemp op2 = newTemp(Ity_D64);
12271       IRTemp result = newTemp(Ity_D64);
12272       IRTemp rounding_mode;
12273 
12274       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12275          emulation_warning(EmWarn_S390X_fpext_rounding);
12276          m4 = S390_DFP_ROUND_PER_FPC_0;
12277       }
12278 
12279       rounding_mode = encode_dfp_rounding_mode(m4);
12280       assign(op1, get_dpr_dw0(r2));
12281       assign(op2, get_dpr_dw0(r3));
12282       assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
12283                            mkexpr(op2)));
12284       put_dpr_dw0(r1, mkexpr(result));
12285    }
12286    return (m4 == 0) ? "mdtr" : "mdtra";
12287 }
12288 
12289 static const HChar *
12290 s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12291 {
12292    if (! s390_host_has_dfp) {
12293       emulation_failure(EmFail_S390X_DFP_insn);
12294    } else {
12295       IRTemp op1 = newTemp(Ity_D128);
12296       IRTemp op2 = newTemp(Ity_D128);
12297       IRTemp result = newTemp(Ity_D128);
12298       IRTemp rounding_mode;
12299 
12300       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12301          emulation_warning(EmWarn_S390X_fpext_rounding);
12302          m4 = S390_DFP_ROUND_PER_FPC_0;
12303       }
12304 
12305       rounding_mode = encode_dfp_rounding_mode(m4);
12306       assign(op1, get_dpr_pair(r2));
12307       assign(op2, get_dpr_pair(r3));
12308       assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
12309                            mkexpr(op2)));
12310       put_dpr_pair(r1, mkexpr(result));
12311    }
12312    return (m4 == 0) ? "mxtr" : "mxtra";
12313 }
12314 
12315 static const HChar *
12316 s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
12317 {
12318    if (! s390_host_has_dfp) {
12319       emulation_failure(EmFail_S390X_DFP_insn);
12320    } else {
12321       IRTemp op1 = newTemp(Ity_D64);
12322       IRTemp op2 = newTemp(Ity_D64);
12323       IRTemp result = newTemp(Ity_D64);
12324       IRTemp rounding_mode;
12325 
12326       /* If fpext is not installed and m4 is in 1:7,
12327          rounding mode performed is unpredictable */
12328       if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
12329          emulation_warning(EmWarn_S390X_fpext_rounding);
12330          m4 = S390_DFP_ROUND_PER_FPC_0;
12331       }
12332 
12333       rounding_mode = encode_dfp_rounding_mode(m4);
12334       assign(op1, get_dpr_dw0(r2));
12335       assign(op2, get_dpr_dw0(r3));
12336       assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
12337                            mkexpr(op2)));
12338       put_dpr_dw0(r1, mkexpr(result));
12339    }
12340    return "qadtr";
12341 }
12342 
12343 static const HChar *
12344 s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
12345 {
12346    if (! s390_host_has_dfp) {
12347       emulation_failure(EmFail_S390X_DFP_insn);
12348    } else {
12349       IRTemp op1 = newTemp(Ity_D128);
12350       IRTemp op2 = newTemp(Ity_D128);
12351       IRTemp result = newTemp(Ity_D128);
12352       IRTemp rounding_mode;
12353 
12354       /* If fpext is not installed and m4 is in 1:7,
12355          rounding mode performed is unpredictable */
12356       if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
12357          emulation_warning(EmWarn_S390X_fpext_rounding);
12358          m4 = S390_DFP_ROUND_PER_FPC_0;
12359       }
12360 
12361       rounding_mode = encode_dfp_rounding_mode(m4);
12362       assign(op1, get_dpr_pair(r2));
12363       assign(op2, get_dpr_pair(r3));
12364       assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
12365                            mkexpr(op2)));
12366       put_dpr_pair(r1, mkexpr(result));
12367    }
12368    return "qaxtr";
12369 }
12370 
12371 static const HChar *
12372 s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
12373 {
12374    if (! s390_host_has_dfp) {
12375       emulation_failure(EmFail_S390X_DFP_insn);
12376    } else {
12377       IRTemp op1 = newTemp(Ity_I8);
12378       IRTemp op2 = newTemp(Ity_D64);
12379       IRTemp result = newTemp(Ity_D64);
12380       IRTemp rounding_mode;
12381 
12382       /* If fpext is not installed and m4 is in 1:7,
12383          rounding mode performed is unpredictable */
12384       if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
12385          emulation_warning(EmWarn_S390X_fpext_rounding);
12386          m4 = S390_DFP_ROUND_PER_FPC_0;
12387       }
12388 
12389       rounding_mode = encode_dfp_rounding_mode(m4);
12390       assign(op1, get_gpr_b7(r2));
12391       assign(op2, get_dpr_dw0(r3));
12392       assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
12393                            mkexpr(op1), mkexpr(op2)));
12394       put_dpr_dw0(r1, mkexpr(result));
12395    }
12396    return "rrdtr";
12397 }
12398 
12399 static const HChar *
12400 s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
12401 {
12402    if (! s390_host_has_dfp) {
12403       emulation_failure(EmFail_S390X_DFP_insn);
12404    } else {
12405       IRTemp op1 = newTemp(Ity_I8);
12406       IRTemp op2 = newTemp(Ity_D128);
12407       IRTemp result = newTemp(Ity_D128);
12408       IRTemp rounding_mode;
12409 
12410       /* If fpext is not installed and m4 is in 1:7,
12411          rounding mode performed is unpredictable */
12412       if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
12413          emulation_warning(EmWarn_S390X_fpext_rounding);
12414          m4 = S390_DFP_ROUND_PER_FPC_0;
12415       }
12416 
12417       rounding_mode = encode_dfp_rounding_mode(m4);
12418       assign(op1, get_gpr_b7(r2));
12419       assign(op2, get_dpr_pair(r3));
12420       assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
12421                            mkexpr(op1), mkexpr(op2)));
12422       put_dpr_pair(r1, mkexpr(result));
12423    }
12424    return "rrxtr";
12425 }
12426 
12427 static const HChar *
12428 s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12429 {
12430    if (! s390_host_has_dfp) {
12431       emulation_failure(EmFail_S390X_DFP_insn);
12432    } else {
12433       IRTemp op1 = newTemp(Ity_D64);
12434       IRTemp op2 = newTemp(Ity_D64);
12435       IRTemp result = newTemp(Ity_D64);
12436       IRTemp rounding_mode;
12437 
12438       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12439          emulation_warning(EmWarn_S390X_fpext_rounding);
12440          m4 = S390_DFP_ROUND_PER_FPC_0;
12441       }
12442 
12443       rounding_mode = encode_dfp_rounding_mode(m4);
12444       assign(op1, get_dpr_dw0(r2));
12445       assign(op2, get_dpr_dw0(r3));
12446       assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
12447                            mkexpr(op2)));
12448       s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
12449       put_dpr_dw0(r1, mkexpr(result));
12450    }
12451    return (m4 == 0) ? "sdtr" : "sdtra";
12452 }
12453 
12454 static const HChar *
12455 s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12456 {
12457    if (! s390_host_has_dfp) {
12458       emulation_failure(EmFail_S390X_DFP_insn);
12459    } else {
12460       IRTemp op1 = newTemp(Ity_D128);
12461       IRTemp op2 = newTemp(Ity_D128);
12462       IRTemp result = newTemp(Ity_D128);
12463       IRTemp rounding_mode;
12464 
12465       if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12466          emulation_warning(EmWarn_S390X_fpext_rounding);
12467          m4 = S390_DFP_ROUND_PER_FPC_0;
12468       }
12469 
12470       rounding_mode = encode_dfp_rounding_mode(m4);
12471       assign(op1, get_dpr_pair(r2));
12472       assign(op2, get_dpr_pair(r3));
12473       assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
12474                            mkexpr(op2)));
12475       put_dpr_pair(r1, mkexpr(result));
12476 
12477       s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
12478    }
12479    return (m4 == 0) ? "sxtr" : "sxtra";
12480 }
12481 
12482 static const HChar *
12483 s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
12484 {
12485    if (! s390_host_has_dfp) {
12486       emulation_failure(EmFail_S390X_DFP_insn);
12487    } else {
12488       IRTemp op = newTemp(Ity_D64);
12489 
12490       assign(op, get_dpr_dw0(r3));
12491       put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op),
12492                             unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
12493                                                   mkU64(63)))));
12494    }
12495    return "sldt";
12496 }
12497 
12498 static const HChar *
12499 s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
12500 {
12501    if (! s390_host_has_dfp) {
12502       emulation_failure(EmFail_S390X_DFP_insn);
12503    } else {
12504       IRTemp op = newTemp(Ity_D128);
12505 
12506       assign(op, get_dpr_pair(r3));
12507       put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op),
12508                              unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
12509                                                    mkU64(63)))));
12510    }
12511    return "slxt";
12512 }
12513 
12514 static const HChar *
12515 s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
12516 {
12517    if (! s390_host_has_dfp) {
12518       emulation_failure(EmFail_S390X_DFP_insn);
12519    } else {
12520       IRTemp op = newTemp(Ity_D64);
12521 
12522       assign(op, get_dpr_dw0(r3));
12523       put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op),
12524                             unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
12525                                                   mkU64(63)))));
12526    }
12527    return "srdt";
12528 }
12529 
12530 static const HChar *
12531 s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
12532 {
12533    if (! s390_host_has_dfp) {
12534       emulation_failure(EmFail_S390X_DFP_insn);
12535    } else {
12536       IRTemp op = newTemp(Ity_D128);
12537 
12538       assign(op, get_dpr_pair(r3));
12539       put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op),
12540                              unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
12541                                                    mkU64(63)))));
12542    }
12543    return "srxt";
12544 }
12545 
12546 static const HChar *
12547 s390_irgen_TDCET(UChar r1, IRTemp op2addr)
12548 {
12549    if (! s390_host_has_dfp) {
12550       emulation_failure(EmFail_S390X_DFP_insn);
12551    } else {
12552       IRTemp value = newTemp(Ity_D32);
12553 
12554       assign(value, get_dpr_w0(r1));
12555 
12556       s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
12557    }
12558    return "tdcet";
12559 }
12560 
12561 static const HChar *
12562 s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
12563 {
12564    if (! s390_host_has_dfp) {
12565       emulation_failure(EmFail_S390X_DFP_insn);
12566    } else {
12567       IRTemp value = newTemp(Ity_D64);
12568 
12569       assign(value, get_dpr_dw0(r1));
12570 
12571       s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
12572    }
12573    return "tdcdt";
12574 }
12575 
12576 static const HChar *
12577 s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
12578 {
12579    if (! s390_host_has_dfp) {
12580       emulation_failure(EmFail_S390X_DFP_insn);
12581    } else {
12582       IRTemp value = newTemp(Ity_D128);
12583 
12584       assign(value, get_dpr_pair(r1));
12585 
12586       s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
12587    }
12588    return "tdcxt";
12589 }
12590 
12591 static const HChar *
12592 s390_irgen_TDGET(UChar r1, IRTemp op2addr)
12593 {
12594    if (! s390_host_has_dfp) {
12595       emulation_failure(EmFail_S390X_DFP_insn);
12596    } else {
12597       IRTemp value = newTemp(Ity_D32);
12598 
12599       assign(value, get_dpr_w0(r1));
12600 
12601       s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
12602    }
12603    return "tdget";
12604 }
12605 
12606 static const HChar *
12607 s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
12608 {
12609    if (! s390_host_has_dfp) {
12610       emulation_failure(EmFail_S390X_DFP_insn);
12611    } else {
12612       IRTemp value = newTemp(Ity_D64);
12613 
12614       assign(value, get_dpr_dw0(r1));
12615 
12616       s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
12617    }
12618    return "tdgdt";
12619 }
12620 
12621 static const HChar *
12622 s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
12623 {
12624    if (! s390_host_has_dfp) {
12625       emulation_failure(EmFail_S390X_DFP_insn);
12626    } else {
12627       IRTemp value = newTemp(Ity_D128);
12628 
12629       assign(value, get_dpr_pair(r1));
12630 
12631       s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
12632    }
12633    return "tdgxt";
12634 }
12635 
12636 static const HChar *
12637 s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
12638 {
12639    IRTemp len = newTemp(Ity_I64);
12640 
12641    assign(len, mkU64(length));
12642    s390_irgen_CLC_EX(len, start1, start2);
12643 
12644    return "clc";
12645 }
12646 
12647 static const HChar *
12648 s390_irgen_CLCL(UChar r1, UChar r2)
12649 {
12650    IRTemp addr1 = newTemp(Ity_I64);
12651    IRTemp addr2 = newTemp(Ity_I64);
12652    IRTemp addr1_load = newTemp(Ity_I64);
12653    IRTemp addr2_load = newTemp(Ity_I64);
12654    IRTemp len1 = newTemp(Ity_I32);
12655    IRTemp len2 = newTemp(Ity_I32);
12656    IRTemp r1p1 = newTemp(Ity_I32);   /* contents of r1 + 1 */
12657    IRTemp r2p1 = newTemp(Ity_I32);   /* contents of r2 + 1 */
12658    IRTemp single1 = newTemp(Ity_I8);
12659    IRTemp single2 = newTemp(Ity_I8);
12660    IRTemp pad = newTemp(Ity_I8);
12661 
12662    assign(addr1, get_gpr_dw0(r1));
12663    assign(r1p1, get_gpr_w1(r1 + 1));
12664    assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
12665    assign(addr2, get_gpr_dw0(r2));
12666    assign(r2p1, get_gpr_w1(r2 + 1));
12667    assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
12668    assign(pad, get_gpr_b4(r2 + 1));
12669 
12670    /* len1 == 0 and len2 == 0? Exit */
12671    s390_cc_set_val(0);
12672    next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
12673                                          mkexpr(len2)), mkU32(0)));
12674 
12675    /* Because mkite evaluates both the then-clause and the else-clause
12676       we cannot load directly from addr1 here. If len1 is 0, then adddr1
12677       may be NULL and loading from there would segfault. So we provide a
12678       valid dummy address in that case. Loading from there does no harm and
12679       the value will be discarded at runtime. */
12680    assign(addr1_load,
12681           mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
12682                 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
12683    assign(single1,
12684           mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
12685                 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
12686 
12687    assign(addr2_load,
12688           mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
12689                 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
12690    assign(single2,
12691           mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
12692                 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
12693 
12694    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
12695    /* Fields differ ? */
12696    next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
12697 
12698    /* Update len1 and addr1, unless len1 == 0. */
12699    put_gpr_dw0(r1,
12700                mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
12701                      mkexpr(addr1),
12702                      binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
12703 
12704    /* When updating len1 we must not modify bits (r1+1)[0:39] */
12705    put_gpr_w1(r1 + 1,
12706               mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
12707                     binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
12708                     binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
12709 
12710    /* Update len2 and addr2, unless len2 == 0. */
12711    put_gpr_dw0(r2,
12712                mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
12713                      mkexpr(addr2),
12714                      binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
12715 
12716    /* When updating len2 we must not modify bits (r2+1)[0:39] */
12717    put_gpr_w1(r2 + 1,
12718               mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
12719                     binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
12720                     binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
12721 
12722    iterate();
12723 
12724    return "clcl";
12725 }
12726 
12727 static const HChar *
12728 s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
12729 {
12730    IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
12731 
12732    addr1 = newTemp(Ity_I64);
12733    addr3 = newTemp(Ity_I64);
12734    addr1_load = newTemp(Ity_I64);
12735    addr3_load = newTemp(Ity_I64);
12736    len1 = newTemp(Ity_I64);
12737    len3 = newTemp(Ity_I64);
12738    single1 = newTemp(Ity_I8);
12739    single3 = newTemp(Ity_I8);
12740 
12741    assign(addr1, get_gpr_dw0(r1));
12742    assign(len1, get_gpr_dw0(r1 + 1));
12743    assign(addr3, get_gpr_dw0(r3));
12744    assign(len3, get_gpr_dw0(r3 + 1));
12745 
12746    /* len1 == 0 and len3 == 0? Exit */
12747    s390_cc_set_val(0);
12748    next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
12749                                         mkexpr(len3)), mkU64(0)));
12750 
12751    /* A mux requires both ways to be possible. This is a way to prevent clcle
12752       from reading from addr1 if it should read from the pad. Since the pad
12753       has no address, just read from the instruction, we discard that anyway */
12754    assign(addr1_load,
12755           mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
12756                 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
12757 
12758    /* same for addr3 */
12759    assign(addr3_load,
12760           mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
12761                 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
12762 
12763    assign(single1,
12764           mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
12765                 unop(Iop_64to8, mkexpr(pad2)),
12766                 load(Ity_I8, mkexpr(addr1_load))));
12767 
12768    assign(single3,
12769           mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
12770                 unop(Iop_64to8, mkexpr(pad2)),
12771                 load(Ity_I8, mkexpr(addr3_load))));
12772 
12773    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
12774    /* Both fields differ ? */
12775    next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
12776 
12777    /* If a length in 0 we must not change this length and the address */
12778    put_gpr_dw0(r1,
12779                mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
12780                      mkexpr(addr1),
12781                      binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
12782 
12783    put_gpr_dw0(r1 + 1,
12784                mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
12785                      mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
12786 
12787    put_gpr_dw0(r3,
12788                mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
12789                      mkexpr(addr3),
12790                      binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
12791 
12792    put_gpr_dw0(r3 + 1,
12793                mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
12794                      mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
12795 
12796    iterate();
12797 
12798    return "clcle";
12799 }
12800 
12801 
12802 static void
12803 s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
12804 {
12805    s390_irgen_xonc(Iop_Xor8, length, start1, start2);
12806 }
12807 
12808 
12809 static void
12810 s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
12811 {
12812    s390_irgen_xonc(Iop_And8, length, start1, start2);
12813 }
12814 
12815 
12816 static void
12817 s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
12818 {
12819    s390_irgen_xonc(Iop_Or8, length, start1, start2);
12820 }
12821 
12822 
12823 static void
12824 s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
12825 {
12826    IRTemp current1 = newTemp(Ity_I8);
12827    IRTemp current2 = newTemp(Ity_I8);
12828    IRTemp counter = newTemp(Ity_I64);
12829 
12830    assign(counter, get_counter_dw0());
12831    put_counter_dw0(mkU64(0));
12832 
12833    assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
12834                                        mkexpr(counter))));
12835    assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
12836                                        mkexpr(counter))));
12837    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
12838                       False);
12839 
12840    /* Both fields differ ? */
12841    next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
12842 
12843    /* Check for end of field */
12844    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
12845    iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
12846    put_counter_dw0(mkU64(0));
12847 }
12848 
12849 static void
12850 s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
12851 {
12852    IRTemp counter = newTemp(Ity_I64);
12853 
12854    assign(counter, get_counter_dw0());
12855 
12856    store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
12857          load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
12858 
12859    /* Check for end of field */
12860    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
12861    iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
12862    put_counter_dw0(mkU64(0));
12863 }
12864 
12865 static void
12866 s390_irgen_MVCIN_EX(IRTemp length, IRTemp start1, IRTemp start2)
12867 {
12868    IRTemp counter = newTemp(Ity_I64);
12869 
12870    assign(counter, get_counter_dw0());
12871 
12872    store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
12873          load(Ity_I8, binop(Iop_Sub64, mkexpr(start2), mkexpr(counter))));
12874 
12875    /* Check for end of field */
12876    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
12877    iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
12878    put_counter_dw0(mkU64(0));
12879 }
12880 
12881 static void
12882 s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
12883 {
12884    IRTemp op = newTemp(Ity_I8);
12885    IRTemp op1 = newTemp(Ity_I8);
12886    IRTemp result = newTemp(Ity_I64);
12887    IRTemp counter = newTemp(Ity_I64);
12888 
12889    assign(counter, get_counter_dw0());
12890 
12891    assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
12892 
12893    assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
12894 
12895    assign(op1, load(Ity_I8, mkexpr(result)));
12896    store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
12897 
12898    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
12899    iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
12900    put_counter_dw0(mkU64(0));
12901 }
12902 
12903 
12904 static void
12905 s390_irgen_EX_SS(UChar r, IRTemp addr2,
12906                  void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
12907                  UInt lensize)
12908 {
12909    IRTemp cond;
12910    IRDirty *d;
12911    IRTemp torun;
12912    ULong ovl;
12913 
12914    IRTemp start1 = newTemp(Ity_I64);
12915    IRTemp start2 = newTemp(Ity_I64);
12916    IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
12917    cond = newTemp(Ity_I1);
12918    torun = newTemp(Ity_I64);
12919 
12920    assign(torun, load(Ity_I64, mkexpr(addr2)));
12921    /* Start with a check that the saved code is still correct */
12922    assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
12923    /* If not, save the new value */
12924    d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
12925                           mkIRExprVec_1(mkexpr(torun)));
12926    d->guard = mkexpr(cond);
12927    stmt(IRStmt_Dirty(d));
12928 
12929    /* and restart */
12930    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
12931                    mkU64(guest_IA_curr_instr)));
12932    stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
12933    restart_if(mkexpr(cond));
12934 
12935    ovl = last_execute_target;
12936    assign(start1, binop(Iop_Add64, mkU64(SS_d1(ovl)),
12937           SS_b1(ovl) != 0 ? get_gpr_dw0(SS_b1(ovl)) : mkU64(0)));
12938    assign(start2, binop(Iop_Add64, mkU64(SS_d2(ovl)),
12939           SS_b2(ovl) != 0 ? get_gpr_dw0(SS_b2(ovl)) : mkU64(0)));
12940    assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
12941           r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(SS_l(ovl)))));
12942    irgen(len, start1, start2);
12943 
12944    last_execute_target = 0;
12945 }
12946 
12947 static const HChar *
12948 s390_irgen_EX(UChar r1, IRTemp addr2)
12949 {
12950    switch(last_execute_target & 0xff00000000000000ULL) {
12951    case 0:
12952    {
12953       /* no code information yet */
12954       IRDirty *d;
12955 
12956       /* so safe the code... */
12957       d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
12958                              mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
12959       stmt(IRStmt_Dirty(d));
12960       /* and restart */
12961       stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
12962                       mkU64(guest_IA_curr_instr)));
12963       stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
12964       restart_if(IRExpr_Const(IRConst_U1(True)));
12965 
12966       /* we know that this will be invalidated */
12967       put_IA(mkaddr_expr(guest_IA_next_instr));
12968       dis_res->whatNext = Dis_StopHere;
12969       dis_res->jk_StopHere = Ijk_InvalICache;
12970       break;
12971    }
12972 
12973    case 0xd200000000000000ULL:
12974       /* special case MVC */
12975       s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
12976       return "ex@mvc";
12977 
12978    case 0xd500000000000000ULL:
12979       /* special case CLC */
12980       s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
12981       return "ex@clc";
12982 
12983    case 0xd700000000000000ULL:
12984       /* special case XC */
12985       s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
12986       return "ex@xc";
12987 
12988    case 0xd600000000000000ULL:
12989       /* special case OC */
12990       s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
12991       return "ex@oc";
12992 
12993    case 0xd400000000000000ULL:
12994       /* special case NC */
12995       s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
12996       return "ex@nc";
12997 
12998    case 0xdc00000000000000ULL:
12999       /* special case TR */
13000       s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
13001       return "ex@tr";
13002 
13003    case 0xe800000000000000ULL:
13004       /* special case MVCIN */
13005       s390_irgen_EX_SS(r1, addr2, s390_irgen_MVCIN_EX, 64);
13006       return "ex@mvcin";
13007 
13008    default:
13009    {
13010       /* everything else will get a self checking prefix that also checks the
13011          register content */
13012       IRDirty *d;
13013       UChar *bytes;
13014       IRTemp cond;
13015       IRTemp orperand;
13016       IRTemp torun;
13017 
13018       cond = newTemp(Ity_I1);
13019       orperand = newTemp(Ity_I64);
13020       torun = newTemp(Ity_I64);
13021 
13022       if (r1 == 0)
13023          assign(orperand, mkU64(0));
13024       else
13025          assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
13026       /* This code is going to be translated */
13027       assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
13028              binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
13029 
13030       /* Start with a check that saved code is still correct */
13031       assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
13032              mkU64(last_execute_target)));
13033       /* If not, save the new value */
13034       d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
13035                              mkIRExprVec_1(mkexpr(torun)));
13036       d->guard = mkexpr(cond);
13037       stmt(IRStmt_Dirty(d));
13038 
13039       /* and restart */
13040       stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART), mkU64(guest_IA_curr_instr)));
13041       stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
13042       restart_if(mkexpr(cond));
13043 
13044       /* Now comes the actual translation */
13045       bytes = (UChar *) &last_execute_target;
13046       s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
13047                             dis_res);
13048       if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
13049          vex_printf("    which was executed by\n");
13050       /* dont make useless translations in the next execute */
13051       last_execute_target = 0;
13052    }
13053    }
13054    return "ex";
13055 }
13056 
13057 static const UChar *exrl_bytes;
13058 
13059 static const HChar *
13060 s390_irgen_EXRL(UChar r1, UInt offset)
13061 {
13062    IRTemp addr = newTemp(Ity_I64);
13063    Addr64 bytes_addr = guest_IA_curr_instr + offset * 2UL;
13064    UChar *bytes = exrl_bytes + offset * 2UL;
13065    /* we might save one round trip because we know the target */
13066    if (!last_execute_target)
13067       last_execute_target = ((ULong)bytes[0] << 56) | ((ULong)bytes[1] << 48) |
13068                             ((ULong)bytes[2] << 40) | ((ULong)bytes[3] << 32) |
13069                             ((ULong)bytes[4] << 24) | ((ULong)bytes[5] << 16);
13070    assign(addr, mkU64(bytes_addr));
13071    s390_irgen_EX(r1, addr);
13072    return "exrl";
13073 }
13074 
13075 static const HChar *
13076 s390_irgen_IPM(UChar r1)
13077 {
13078    // As long as we dont support SPM, lets just assume 0 as program mask
13079    put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
13080                        binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
13081 
13082    return "ipm";
13083 }
13084 
13085 
13086 static const HChar *
13087 s390_irgen_SRST(UChar r1, UChar r2)
13088 {
13089    IRTemp address = newTemp(Ity_I64);
13090    IRTemp next = newTemp(Ity_I64);
13091    IRTemp delim = newTemp(Ity_I8);
13092    IRTemp counter = newTemp(Ity_I64);
13093    IRTemp byte = newTemp(Ity_I8);
13094 
13095    assign(address, get_gpr_dw0(r2));
13096    assign(next, get_gpr_dw0(r1));
13097 
13098    assign(counter, get_counter_dw0());
13099    put_counter_dw0(mkU64(0));
13100 
13101    // start = next?  CC=2 and out r1 and r2 unchanged
13102    s390_cc_set_val(2);
13103    put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
13104    next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
13105 
13106    assign(byte, load(Ity_I8, mkexpr(address)));
13107    assign(delim, get_gpr_b7(0));
13108 
13109    // byte = delim? CC=1, R1=address
13110    s390_cc_set_val(1);
13111    put_gpr_dw0(r1,  mkexpr(address));
13112    next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
13113 
13114    // else: all equal, no end yet, loop
13115    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
13116    put_gpr_dw0(r1, mkexpr(next));
13117    put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
13118 
13119    iterate();
13120 
13121    return "srst";
13122 }
13123 
13124 static const HChar *
13125 s390_irgen_CLST(UChar r1, UChar r2)
13126 {
13127    IRTemp address1 = newTemp(Ity_I64);
13128    IRTemp address2 = newTemp(Ity_I64);
13129    IRTemp end = newTemp(Ity_I8);
13130    IRTemp counter = newTemp(Ity_I64);
13131    IRTemp byte1 = newTemp(Ity_I8);
13132    IRTemp byte2 = newTemp(Ity_I8);
13133 
13134    assign(address1, get_gpr_dw0(r1));
13135    assign(address2, get_gpr_dw0(r2));
13136    assign(end, get_gpr_b7(0));
13137    assign(counter, get_counter_dw0());
13138    put_counter_dw0(mkU64(0));
13139    assign(byte1, load(Ity_I8, mkexpr(address1)));
13140    assign(byte2, load(Ity_I8, mkexpr(address2)));
13141 
13142    // end in both? all equal, reset r1 and r2 to start values
13143    s390_cc_set_val(0);
13144    put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
13145    put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
13146    next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
13147                       binop(Iop_Or8,
13148                             binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
13149                             binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
13150 
13151    put_gpr_dw0(r1, mkexpr(address1));
13152    put_gpr_dw0(r2, mkexpr(address2));
13153 
13154    // End found in string1
13155    s390_cc_set_val(1);
13156    next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
13157 
13158    // End found in string2
13159    s390_cc_set_val(2);
13160    next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
13161 
13162    // string1 < string2
13163    s390_cc_set_val(1);
13164    next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
13165                       unop(Iop_8Uto32, mkexpr(byte2))));
13166 
13167    // string2 < string1
13168    s390_cc_set_val(2);
13169    next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
13170                       unop(Iop_8Uto32, mkexpr(byte1))));
13171 
13172    // else: all equal, no end yet, loop
13173    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
13174    put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
13175    put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
13176 
13177    iterate();
13178 
13179    return "clst";
13180 }
13181 
13182 static void
13183 s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
13184 {
13185    UChar reg;
13186    IRTemp addr = newTemp(Ity_I64);
13187 
13188    assign(addr, mkexpr(op2addr));
13189    reg = r1;
13190    do {
13191       IRTemp old = addr;
13192 
13193       reg %= 16;
13194       put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
13195       addr = newTemp(Ity_I64);
13196       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
13197       reg++;
13198    } while (reg != (r3 + 1));
13199 }
13200 
13201 static const HChar *
13202 s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
13203 {
13204    s390_irgen_load_multiple_32bit(r1, r3, op2addr);
13205 
13206    return "lm";
13207 }
13208 
13209 static const HChar *
13210 s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
13211 {
13212    s390_irgen_load_multiple_32bit(r1, r3, op2addr);
13213 
13214    return "lmy";
13215 }
13216 
13217 static const HChar *
13218 s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
13219 {
13220    UChar reg;
13221    IRTemp addr = newTemp(Ity_I64);
13222 
13223    assign(addr, mkexpr(op2addr));
13224    reg = r1;
13225    do {
13226       IRTemp old = addr;
13227 
13228       reg %= 16;
13229       put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
13230       addr = newTemp(Ity_I64);
13231       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
13232       reg++;
13233    } while (reg != (r3 + 1));
13234 
13235    return "lmh";
13236 }
13237 
13238 static const HChar *
13239 s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
13240 {
13241    UChar reg;
13242    IRTemp addr = newTemp(Ity_I64);
13243 
13244    assign(addr, mkexpr(op2addr));
13245    reg = r1;
13246    do {
13247       IRTemp old = addr;
13248 
13249       reg %= 16;
13250       put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
13251       addr = newTemp(Ity_I64);
13252       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
13253       reg++;
13254    } while (reg != (r3 + 1));
13255 
13256    return "lmg";
13257 }
13258 
13259 static void
13260 s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
13261 {
13262    UChar reg;
13263    IRTemp addr = newTemp(Ity_I64);
13264 
13265    assign(addr, mkexpr(op2addr));
13266    reg = r1;
13267    do {
13268       IRTemp old = addr;
13269 
13270       reg %= 16;
13271       store(mkexpr(addr), get_gpr_w1(reg));
13272       addr = newTemp(Ity_I64);
13273       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
13274       reg++;
13275    } while( reg != (r3 + 1));
13276 }
13277 
13278 static const HChar *
13279 s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
13280 {
13281    s390_irgen_store_multiple_32bit(r1, r3, op2addr);
13282 
13283    return "stm";
13284 }
13285 
13286 static const HChar *
13287 s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
13288 {
13289    s390_irgen_store_multiple_32bit(r1, r3, op2addr);
13290 
13291    return "stmy";
13292 }
13293 
13294 static const HChar *
13295 s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
13296 {
13297    UChar reg;
13298    IRTemp addr = newTemp(Ity_I64);
13299 
13300    assign(addr, mkexpr(op2addr));
13301    reg = r1;
13302    do {
13303       IRTemp old = addr;
13304 
13305       reg %= 16;
13306       store(mkexpr(addr), get_gpr_w0(reg));
13307       addr = newTemp(Ity_I64);
13308       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
13309       reg++;
13310    } while( reg != (r3 + 1));
13311 
13312    return "stmh";
13313 }
13314 
13315 static const HChar *
13316 s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
13317 {
13318    UChar reg;
13319    IRTemp addr = newTemp(Ity_I64);
13320 
13321    assign(addr, mkexpr(op2addr));
13322    reg = r1;
13323    do {
13324       IRTemp old = addr;
13325 
13326       reg %= 16;
13327       store(mkexpr(addr), get_gpr_dw0(reg));
13328       addr = newTemp(Ity_I64);
13329       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
13330       reg++;
13331    } while( reg != (r3 + 1));
13332 
13333    return "stmg";
13334 }
13335 
13336 static void
13337 s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
13338 {
13339    IRTemp old1 = newTemp(Ity_I8);
13340    IRTemp old2 = newTemp(Ity_I8);
13341    IRTemp new1 = newTemp(Ity_I8);
13342    IRTemp counter = newTemp(Ity_I32);
13343    IRTemp addr1 = newTemp(Ity_I64);
13344 
13345    assign(counter, get_counter_w0());
13346 
13347    assign(addr1, binop(Iop_Add64, mkexpr(start1),
13348                        unop(Iop_32Uto64, mkexpr(counter))));
13349 
13350    assign(old1, load(Ity_I8, mkexpr(addr1)));
13351    assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
13352                                    unop(Iop_32Uto64,mkexpr(counter)))));
13353    assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
13354 
13355    /* Special case: xc is used to zero memory */
13356    if (op == Iop_Xor8) {
13357       store(mkexpr(addr1),
13358             mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
13359                   mkU8(0), mkexpr(new1)));
13360    } else
13361       store(mkexpr(addr1), mkexpr(new1));
13362    put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
13363                         get_counter_w1()));
13364 
13365    /* Check for end of field */
13366    put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
13367    iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
13368    s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
13369                       False);
13370    put_counter_dw0(mkU64(0));
13371 }
13372 
13373 static const HChar *
13374 s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
13375 {
13376    IRTemp len = newTemp(Ity_I32);
13377 
13378    assign(len, mkU32(length));
13379    s390_irgen_xonc(Iop_Xor8, len, start1, start2);
13380 
13381    return "xc";
13382 }
13383 
13384 static void
13385 s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
13386 {
13387    IRTemp counter = newTemp(Ity_I32);
13388    IRTemp start = newTemp(Ity_I64);
13389    IRTemp addr  = newTemp(Ity_I64);
13390 
13391    assign(start,
13392           binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
13393 
13394    if (length < 8) {
13395       UInt i;
13396 
13397       for (i = 0; i <= length; ++i) {
13398          store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
13399       }
13400    } else {
13401      assign(counter, get_counter_w0());
13402 
13403      assign(addr, binop(Iop_Add64, mkexpr(start),
13404                         unop(Iop_32Uto64, mkexpr(counter))));
13405 
13406      store(mkexpr(addr), mkU8(0));
13407 
13408      /* Check for end of field */
13409      put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
13410      iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
13411 
13412      /* Reset counter */
13413      put_counter_dw0(mkU64(0));
13414    }
13415 
13416    s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
13417 
13418    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
13419       s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
13420 }
13421 
13422 static const HChar *
13423 s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
13424 {
13425    IRTemp len = newTemp(Ity_I32);
13426 
13427    assign(len, mkU32(length));
13428    s390_irgen_xonc(Iop_And8, len, start1, start2);
13429 
13430    return "nc";
13431 }
13432 
13433 static const HChar *
13434 s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
13435 {
13436    IRTemp len = newTemp(Ity_I32);
13437 
13438    assign(len, mkU32(length));
13439    s390_irgen_xonc(Iop_Or8, len, start1, start2);
13440 
13441    return "oc";
13442 }
13443 
13444 
13445 static const HChar *
13446 s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
13447 {
13448    IRTemp len = newTemp(Ity_I64);
13449 
13450    assign(len, mkU64(length));
13451    s390_irgen_MVC_EX(len, start1, start2);
13452 
13453    return "mvc";
13454 }
13455 
13456 static const HChar *
13457 s390_irgen_MVCIN(UChar length, IRTemp start1, IRTemp start2)
13458 {
13459    IRTemp len = newTemp(Ity_I64);
13460 
13461    assign(len, mkU64(length));
13462    s390_irgen_MVCIN_EX(len, start1, start2);
13463 
13464    return "mvcin";
13465 }
13466 
13467 static const HChar *
13468 s390_irgen_MVCL(UChar r1, UChar r2)
13469 {
13470    IRTemp addr1 = newTemp(Ity_I64);
13471    IRTemp addr2 = newTemp(Ity_I64);
13472    IRTemp addr2_load = newTemp(Ity_I64);
13473    IRTemp r1p1 = newTemp(Ity_I32);   /* contents of r1 + 1 */
13474    IRTemp r2p1 = newTemp(Ity_I32);   /* contents of r2 + 1 */
13475    IRTemp len1 = newTemp(Ity_I32);
13476    IRTemp len2 = newTemp(Ity_I32);
13477    IRTemp pad = newTemp(Ity_I8);
13478    IRTemp single = newTemp(Ity_I8);
13479 
13480    assign(addr1, get_gpr_dw0(r1));
13481    assign(r1p1, get_gpr_w1(r1 + 1));
13482    assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
13483    assign(addr2, get_gpr_dw0(r2));
13484    assign(r2p1, get_gpr_w1(r2 + 1));
13485    assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
13486    assign(pad, get_gpr_b4(r2 + 1));
13487 
13488    /* len1 == 0 ? */
13489    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
13490    next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
13491 
13492    /* Check for destructive overlap:
13493       addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
13494    s390_cc_set_val(3);
13495    IRTemp cond1 = newTemp(Ity_I32);
13496    assign(cond1, unop(Iop_1Uto32,
13497                       binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
13498    IRTemp cond2 = newTemp(Ity_I32);
13499    assign(cond2, unop(Iop_1Uto32,
13500                       binop(Iop_CmpLT64U, mkexpr(addr1),
13501                             binop(Iop_Add64, mkexpr(addr2),
13502                                   unop(Iop_32Uto64, mkexpr(len1))))));
13503    IRTemp cond3 = newTemp(Ity_I32);
13504    assign(cond3, unop(Iop_1Uto32,
13505                       binop(Iop_CmpLT64U,
13506                             mkexpr(addr1),
13507                             binop(Iop_Add64, mkexpr(addr2),
13508                                   unop(Iop_32Uto64, mkexpr(len2))))));
13509 
13510    next_insn_if(binop(Iop_CmpEQ32,
13511                       binop(Iop_And32,
13512                             binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
13513                             mkexpr(cond3)),
13514                       mkU32(1)));
13515 
13516    /* See s390_irgen_CLCL for explanation why we cannot load directly
13517       and need two steps. */
13518    assign(addr2_load,
13519           mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13520                 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
13521    assign(single,
13522           mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13523                 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
13524 
13525    store(mkexpr(addr1), mkexpr(single));
13526 
13527    /* Update addr1 and len1 */
13528    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
13529    put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
13530 
13531    /* Update addr2 and len2 */
13532    put_gpr_dw0(r2,
13533                mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13534                      mkexpr(addr2),
13535                      binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
13536 
13537    /* When updating len2 we must not modify bits (r2+1)[0:39] */
13538    put_gpr_w1(r2 + 1,
13539               mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13540                     binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
13541                     binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
13542 
13543    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
13544    iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
13545 
13546    return "mvcl";
13547 }
13548 
13549 
13550 static const HChar *
13551 s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
13552 {
13553    IRTemp addr1, addr3, addr3_load, len1, len3, single;
13554 
13555    addr1 = newTemp(Ity_I64);
13556    addr3 = newTemp(Ity_I64);
13557    addr3_load = newTemp(Ity_I64);
13558    len1 = newTemp(Ity_I64);
13559    len3 = newTemp(Ity_I64);
13560    single = newTemp(Ity_I8);
13561 
13562    assign(addr1, get_gpr_dw0(r1));
13563    assign(len1, get_gpr_dw0(r1 + 1));
13564    assign(addr3, get_gpr_dw0(r3));
13565    assign(len3, get_gpr_dw0(r3 + 1));
13566 
13567    // len1 == 0 ?
13568    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
13569    next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
13570 
13571    /* This is a hack to prevent mvcle from reading from addr3 if it
13572       should read from the pad. Since the pad has no address, just
13573       read from the instruction, we discard that anyway */
13574    assign(addr3_load,
13575           mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13576                 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
13577 
13578    assign(single,
13579           mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13580                 unop(Iop_64to8, mkexpr(pad2)),
13581                 load(Ity_I8, mkexpr(addr3_load))));
13582    store(mkexpr(addr1), mkexpr(single));
13583 
13584    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
13585 
13586    put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
13587 
13588    put_gpr_dw0(r3,
13589                mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13590                      mkexpr(addr3),
13591                      binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
13592 
13593    put_gpr_dw0(r3 + 1,
13594                mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13595                      mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
13596 
13597    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
13598    iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
13599 
13600    return "mvcle";
13601 }
13602 
13603 static const HChar *
13604 s390_irgen_MVST(UChar r1, UChar r2)
13605 {
13606    IRTemp addr1 = newTemp(Ity_I64);
13607    IRTemp addr2 = newTemp(Ity_I64);
13608    IRTemp end = newTemp(Ity_I8);
13609    IRTemp byte = newTemp(Ity_I8);
13610    IRTemp counter = newTemp(Ity_I64);
13611 
13612    assign(addr1, get_gpr_dw0(r1));
13613    assign(addr2, get_gpr_dw0(r2));
13614    assign(counter, get_counter_dw0());
13615    assign(end, get_gpr_b7(0));
13616    assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
13617    store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
13618 
13619    // We use unlimited as cpu-determined number
13620    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
13621    iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
13622 
13623    // and always set cc=1 at the end + update r1
13624    s390_cc_set_val(1);
13625    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
13626    put_counter_dw0(mkU64(0));
13627 
13628    return "mvst";
13629 }
13630 
13631 static void
13632 s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
13633 {
13634    IRTemp op1 = newTemp(Ity_I64);
13635    IRTemp result = newTemp(Ity_I64);
13636 
13637    assign(op1, binop(Iop_32HLto64,
13638                      get_gpr_w1(r1),         // high 32 bits
13639                      get_gpr_w1(r1 + 1)));   // low  32 bits
13640    assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
13641    put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));   // remainder
13642    put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
13643 }
13644 
13645 static void
13646 s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
13647 {
13648    IRTemp op1 = newTemp(Ity_I128);
13649    IRTemp result = newTemp(Ity_I128);
13650 
13651    assign(op1, binop(Iop_64HLto128,
13652                      get_gpr_dw0(r1),         // high 64 bits
13653                      get_gpr_dw0(r1 + 1)));   // low  64 bits
13654    assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
13655    put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));   // remainder
13656    put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
13657 }
13658 
13659 static void
13660 s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
13661 {
13662    IRTemp op1 = newTemp(Ity_I64);
13663    IRTemp result = newTemp(Ity_I128);
13664 
13665    assign(op1, get_gpr_dw0(r1 + 1));
13666    assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
13667    put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));   // remainder
13668    put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
13669 }
13670 
13671 static const HChar *
13672 s390_irgen_DR(UChar r1, UChar r2)
13673 {
13674    IRTemp op2 = newTemp(Ity_I32);
13675 
13676    assign(op2, get_gpr_w1(r2));
13677 
13678    s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
13679 
13680    return "dr";
13681 }
13682 
13683 static const HChar *
13684 s390_irgen_D(UChar r1, IRTemp op2addr)
13685 {
13686    IRTemp op2 = newTemp(Ity_I32);
13687 
13688    assign(op2, load(Ity_I32, mkexpr(op2addr)));
13689 
13690    s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
13691 
13692    return "d";
13693 }
13694 
13695 static const HChar *
13696 s390_irgen_DLR(UChar r1, UChar r2)
13697 {
13698    IRTemp op2 = newTemp(Ity_I32);
13699 
13700    assign(op2, get_gpr_w1(r2));
13701 
13702    s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
13703 
13704    return "dlr";
13705 }
13706 
13707 static const HChar *
13708 s390_irgen_DL(UChar r1, IRTemp op2addr)
13709 {
13710    IRTemp op2 = newTemp(Ity_I32);
13711 
13712    assign(op2, load(Ity_I32, mkexpr(op2addr)));
13713 
13714    s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
13715 
13716    return "dl";
13717 }
13718 
13719 static const HChar *
13720 s390_irgen_DLG(UChar r1, IRTemp op2addr)
13721 {
13722    IRTemp op2 = newTemp(Ity_I64);
13723 
13724    assign(op2, load(Ity_I64, mkexpr(op2addr)));
13725 
13726    s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
13727 
13728    return "dlg";
13729 }
13730 
13731 static const HChar *
13732 s390_irgen_DLGR(UChar r1, UChar r2)
13733 {
13734    IRTemp op2 = newTemp(Ity_I64);
13735 
13736    assign(op2, get_gpr_dw0(r2));
13737 
13738    s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
13739 
13740    return "dlgr";
13741 }
13742 
13743 static const HChar *
13744 s390_irgen_DSGR(UChar r1, UChar r2)
13745 {
13746    IRTemp op2 = newTemp(Ity_I64);
13747 
13748    assign(op2, get_gpr_dw0(r2));
13749 
13750    s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
13751 
13752    return "dsgr";
13753 }
13754 
13755 static const HChar *
13756 s390_irgen_DSG(UChar r1, IRTemp op2addr)
13757 {
13758    IRTemp op2 = newTemp(Ity_I64);
13759 
13760    assign(op2, load(Ity_I64, mkexpr(op2addr)));
13761 
13762    s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
13763 
13764    return "dsg";
13765 }
13766 
13767 static const HChar *
13768 s390_irgen_DSGFR(UChar r1, UChar r2)
13769 {
13770    IRTemp op2 = newTemp(Ity_I64);
13771 
13772    assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
13773 
13774    s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
13775 
13776    return "dsgfr";
13777 }
13778 
13779 static const HChar *
13780 s390_irgen_DSGF(UChar r1, IRTemp op2addr)
13781 {
13782    IRTemp op2 = newTemp(Ity_I64);
13783 
13784    assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
13785 
13786    s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
13787 
13788    return "dsgf";
13789 }
13790 
13791 static void
13792 s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
13793 {
13794    UChar reg;
13795    IRTemp addr = newTemp(Ity_I64);
13796 
13797    assign(addr, mkexpr(op2addr));
13798    reg = r1;
13799    do {
13800       IRTemp old = addr;
13801 
13802       reg %= 16;
13803       put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
13804       addr = newTemp(Ity_I64);
13805       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
13806       reg++;
13807    } while (reg != (r3 + 1));
13808 }
13809 
13810 static const HChar *
13811 s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
13812 {
13813    s390_irgen_load_ar_multiple(r1, r3, op2addr);
13814 
13815    return "lam";
13816 }
13817 
13818 static const HChar *
13819 s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
13820 {
13821    s390_irgen_load_ar_multiple(r1, r3, op2addr);
13822 
13823    return "lamy";
13824 }
13825 
13826 static void
13827 s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
13828 {
13829    UChar reg;
13830    IRTemp addr = newTemp(Ity_I64);
13831 
13832    assign(addr, mkexpr(op2addr));
13833    reg = r1;
13834    do {
13835       IRTemp old = addr;
13836 
13837       reg %= 16;
13838       store(mkexpr(addr), get_ar_w0(reg));
13839       addr = newTemp(Ity_I64);
13840       assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
13841       reg++;
13842    } while (reg != (r3 + 1));
13843 }
13844 
13845 static const HChar *
13846 s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
13847 {
13848    s390_irgen_store_ar_multiple(r1, r3, op2addr);
13849 
13850    return "stam";
13851 }
13852 
13853 static const HChar *
13854 s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
13855 {
13856    s390_irgen_store_ar_multiple(r1, r3, op2addr);
13857 
13858    return "stamy";
13859 }
13860 
13861 
13862 /* Implementation for 32-bit compare-and-swap */
13863 static void
13864 s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
13865 {
13866    IRCAS *cas;
13867    IRTemp op1 = newTemp(Ity_I32);
13868    IRTemp old_mem = newTemp(Ity_I32);
13869    IRTemp op3 = newTemp(Ity_I32);
13870    IRTemp result = newTemp(Ity_I32);
13871    IRTemp nequal = newTemp(Ity_I1);
13872 
13873    assign(op1, get_gpr_w1(r1));
13874    assign(op3, get_gpr_w1(r3));
13875 
13876    /* The first and second operands are compared. If they are equal,
13877       the third operand is stored at the second- operand location. */
13878    cas = mkIRCAS(IRTemp_INVALID, old_mem,
13879                  Iend_BE, mkexpr(op2addr),
13880                  NULL, mkexpr(op1), /* expected value */
13881                  NULL, mkexpr(op3)  /* new value */);
13882    stmt(IRStmt_CAS(cas));
13883 
13884    /* Set CC. Operands compared equal -> 0, else 1. */
13885    assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
13886    s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
13887 
13888    /* If operands were equal (cc == 0) just store the old value op1 in r1.
13889       Otherwise, store the old_value from memory in r1 and yield. */
13890    assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
13891    put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
13892    yield_if(mkexpr(nequal));
13893 }
13894 
13895 static const HChar *
13896 s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
13897 {
13898    s390_irgen_cas_32(r1, r3, op2addr);
13899 
13900    return "cs";
13901 }
13902 
13903 static const HChar *
13904 s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
13905 {
13906    s390_irgen_cas_32(r1, r3, op2addr);
13907 
13908    return "csy";
13909 }
13910 
13911 static const HChar *
13912 s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
13913 {
13914    IRCAS *cas;
13915    IRTemp op1 = newTemp(Ity_I64);
13916    IRTemp old_mem = newTemp(Ity_I64);
13917    IRTemp op3 = newTemp(Ity_I64);
13918    IRTemp result = newTemp(Ity_I64);
13919    IRTemp nequal = newTemp(Ity_I1);
13920 
13921    assign(op1, get_gpr_dw0(r1));
13922    assign(op3, get_gpr_dw0(r3));
13923 
13924    /* The first and second operands are compared. If they are equal,
13925       the third operand is stored at the second- operand location. */
13926    cas = mkIRCAS(IRTemp_INVALID, old_mem,
13927                  Iend_BE, mkexpr(op2addr),
13928                  NULL, mkexpr(op1), /* expected value */
13929                  NULL, mkexpr(op3)  /* new value */);
13930    stmt(IRStmt_CAS(cas));
13931 
13932    /* Set CC. Operands compared equal -> 0, else 1. */
13933    assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
13934    s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
13935 
13936    /* If operands were equal (cc == 0) just store the old value op1 in r1.
13937       Otherwise, store the old_value from memory in r1 and yield. */
13938    assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
13939    put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
13940    yield_if(mkexpr(nequal));
13941 
13942    return "csg";
13943 }
13944 
13945 /* Implementation for 32-bit compare-double-and-swap */
13946 static void
13947 s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
13948 {
13949    IRCAS *cas;
13950    IRTemp op1_high = newTemp(Ity_I32);
13951    IRTemp op1_low  = newTemp(Ity_I32);
13952    IRTemp old_mem_high = newTemp(Ity_I32);
13953    IRTemp old_mem_low  = newTemp(Ity_I32);
13954    IRTemp op3_high = newTemp(Ity_I32);
13955    IRTemp op3_low  = newTemp(Ity_I32);
13956    IRTemp result = newTemp(Ity_I32);
13957    IRTemp nequal = newTemp(Ity_I1);
13958 
13959    assign(op1_high, get_gpr_w1(r1));
13960    assign(op1_low,  get_gpr_w1(r1+1));
13961    assign(op3_high, get_gpr_w1(r3));
13962    assign(op3_low,  get_gpr_w1(r3+1));
13963 
13964    /* The first and second operands are compared. If they are equal,
13965       the third operand is stored at the second-operand location. */
13966    cas = mkIRCAS(old_mem_high, old_mem_low,
13967                  Iend_BE, mkexpr(op2addr),
13968                  mkexpr(op1_high), mkexpr(op1_low), /* expected value */
13969                  mkexpr(op3_high), mkexpr(op3_low)  /* new value */);
13970    stmt(IRStmt_CAS(cas));
13971 
13972    /* Set CC. Operands compared equal -> 0, else 1. */
13973    assign(result, unop(Iop_1Uto32,
13974           binop(Iop_CmpNE32,
13975                 binop(Iop_Or32,
13976                       binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
13977                       binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
13978                 mkU32(0))));
13979 
13980    s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
13981 
13982    /* If operands were equal (cc == 0) just store the old value op1 in r1.
13983       Otherwise, store the old_value from memory in r1 and yield. */
13984    assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
13985    put_gpr_w1(r1,   mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
13986    put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low),  mkexpr(op1_low)));
13987    yield_if(mkexpr(nequal));
13988 }
13989 
13990 static const HChar *
13991 s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
13992 {
13993    s390_irgen_cdas_32(r1, r3, op2addr);
13994 
13995    return "cds";
13996 }
13997 
13998 static const HChar *
13999 s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
14000 {
14001    s390_irgen_cdas_32(r1, r3, op2addr);
14002 
14003    return "cdsy";
14004 }
14005 
14006 static const HChar *
14007 s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
14008 {
14009    IRCAS *cas;
14010    IRTemp op1_high = newTemp(Ity_I64);
14011    IRTemp op1_low  = newTemp(Ity_I64);
14012    IRTemp old_mem_high = newTemp(Ity_I64);
14013    IRTemp old_mem_low  = newTemp(Ity_I64);
14014    IRTemp op3_high = newTemp(Ity_I64);
14015    IRTemp op3_low  = newTemp(Ity_I64);
14016    IRTemp result = newTemp(Ity_I64);
14017    IRTemp nequal = newTemp(Ity_I1);
14018 
14019    assign(op1_high, get_gpr_dw0(r1));
14020    assign(op1_low,  get_gpr_dw0(r1+1));
14021    assign(op3_high, get_gpr_dw0(r3));
14022    assign(op3_low,  get_gpr_dw0(r3+1));
14023 
14024    /* The first and second operands are compared. If they are equal,
14025       the third operand is stored at the second-operand location. */
14026    cas = mkIRCAS(old_mem_high, old_mem_low,
14027                  Iend_BE, mkexpr(op2addr),
14028                  mkexpr(op1_high), mkexpr(op1_low), /* expected value */
14029                  mkexpr(op3_high), mkexpr(op3_low)  /* new value */);
14030    stmt(IRStmt_CAS(cas));
14031 
14032    /* Set CC. Operands compared equal -> 0, else 1. */
14033    assign(result, unop(Iop_1Uto64,
14034           binop(Iop_CmpNE64,
14035                 binop(Iop_Or64,
14036                       binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
14037                       binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
14038                 mkU64(0))));
14039 
14040    s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
14041 
14042    /* If operands were equal (cc == 0) just store the old value op1 in r1.
14043       Otherwise, store the old_value from memory in r1 and yield. */
14044    assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
14045    put_gpr_dw0(r1,   mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
14046    put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low),  mkexpr(op1_low)));
14047    yield_if(mkexpr(nequal));
14048 
14049    return "cdsg";
14050 }
14051 
14052 
14053 /* Binary floating point */
14054 
14055 static const HChar *
14056 s390_irgen_AXBR(UChar r1, UChar r2)
14057 {
14058    IRTemp op1 = newTemp(Ity_F128);
14059    IRTemp op2 = newTemp(Ity_F128);
14060    IRTemp result = newTemp(Ity_F128);
14061    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14062 
14063    assign(op1, get_fpr_pair(r1));
14064    assign(op2, get_fpr_pair(r2));
14065    assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
14066                         mkexpr(op2)));
14067    put_fpr_pair(r1, mkexpr(result));
14068 
14069    s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14070 
14071    return "axbr";
14072 }
14073 
14074 static const HChar *
14075 s390_irgen_CEBR(UChar r1, UChar r2)
14076 {
14077    IRTemp op1 = newTemp(Ity_F32);
14078    IRTemp op2 = newTemp(Ity_F32);
14079    IRTemp cc_vex  = newTemp(Ity_I32);
14080    IRTemp cc_s390 = newTemp(Ity_I32);
14081 
14082    assign(op1, get_fpr_w0(r1));
14083    assign(op2, get_fpr_w0(r2));
14084    assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
14085 
14086    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
14087    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
14088 
14089    return "cebr";
14090 }
14091 
14092 static const HChar *
14093 s390_irgen_CDBR(UChar r1, UChar r2)
14094 {
14095    IRTemp op1 = newTemp(Ity_F64);
14096    IRTemp op2 = newTemp(Ity_F64);
14097    IRTemp cc_vex  = newTemp(Ity_I32);
14098    IRTemp cc_s390 = newTemp(Ity_I32);
14099 
14100    assign(op1, get_fpr_dw0(r1));
14101    assign(op2, get_fpr_dw0(r2));
14102    assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
14103 
14104    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
14105    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
14106 
14107    return "cdbr";
14108 }
14109 
14110 static const HChar *
14111 s390_irgen_CXBR(UChar r1, UChar r2)
14112 {
14113    IRTemp op1 = newTemp(Ity_F128);
14114    IRTemp op2 = newTemp(Ity_F128);
14115    IRTemp cc_vex  = newTemp(Ity_I32);
14116    IRTemp cc_s390 = newTemp(Ity_I32);
14117 
14118    assign(op1, get_fpr_pair(r1));
14119    assign(op2, get_fpr_pair(r2));
14120    assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
14121 
14122    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
14123    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
14124 
14125    return "cxbr";
14126 }
14127 
14128 static const HChar *
14129 s390_irgen_CEB(UChar r1, IRTemp op2addr)
14130 {
14131    IRTemp op1 = newTemp(Ity_F32);
14132    IRTemp op2 = newTemp(Ity_F32);
14133    IRTemp cc_vex  = newTemp(Ity_I32);
14134    IRTemp cc_s390 = newTemp(Ity_I32);
14135 
14136    assign(op1, get_fpr_w0(r1));
14137    assign(op2, load(Ity_F32, mkexpr(op2addr)));
14138    assign(cc_vex,  binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
14139 
14140    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
14141    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
14142 
14143    return "ceb";
14144 }
14145 
14146 static const HChar *
14147 s390_irgen_CDB(UChar r1, IRTemp op2addr)
14148 {
14149    IRTemp op1 = newTemp(Ity_F64);
14150    IRTemp op2 = newTemp(Ity_F64);
14151    IRTemp cc_vex  = newTemp(Ity_I32);
14152    IRTemp cc_s390 = newTemp(Ity_I32);
14153 
14154    assign(op1, get_fpr_dw0(r1));
14155    assign(op2, load(Ity_F64, mkexpr(op2addr)));
14156    assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
14157 
14158    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
14159    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
14160 
14161    return "cdb";
14162 }
14163 
14164 static const HChar *
14165 s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
14166                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
14167 {
14168    IRTemp op2 = newTemp(Ity_I32);
14169 
14170    assign(op2, get_gpr_w1(r2));
14171    put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
14172 
14173    return "cxfbr";
14174 }
14175 
14176 static const HChar *
14177 s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
14178                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
14179 {
14180    if (! s390_host_has_fpext) {
14181       emulation_failure(EmFail_S390X_fpext);
14182    } else {
14183       IRTemp op2 = newTemp(Ity_I32);
14184 
14185       assign(op2, get_gpr_w1(r2));
14186       put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
14187    }
14188    return "cxlfbr";
14189 }
14190 
14191 
14192 static const HChar *
14193 s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
14194                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
14195 {
14196    IRTemp op2 = newTemp(Ity_I64);
14197 
14198    assign(op2, get_gpr_dw0(r2));
14199    put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
14200 
14201    return "cxgbr";
14202 }
14203 
14204 static const HChar *
14205 s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
14206                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
14207 {
14208    if (! s390_host_has_fpext) {
14209       emulation_failure(EmFail_S390X_fpext);
14210    } else {
14211       IRTemp op2 = newTemp(Ity_I64);
14212 
14213       assign(op2, get_gpr_dw0(r2));
14214       put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
14215    }
14216    return "cxlgbr";
14217 }
14218 
14219 static const HChar *
14220 s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
14221                  UChar r1, UChar r2)
14222 {
14223    IRTemp op = newTemp(Ity_F128);
14224    IRTemp result = newTemp(Ity_I32);
14225    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
14226 
14227    assign(op, get_fpr_pair(r2));
14228    assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
14229                         mkexpr(op)));
14230    put_gpr_w1(r1, mkexpr(result));
14231    s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
14232 
14233    return "cfxbr";
14234 }
14235 
14236 static const HChar *
14237 s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
14238                   UChar r1, UChar r2)
14239 {
14240    if (! s390_host_has_fpext) {
14241       emulation_failure(EmFail_S390X_fpext);
14242    } else {
14243       IRTemp op = newTemp(Ity_F128);
14244       IRTemp result = newTemp(Ity_I32);
14245       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
14246 
14247       assign(op, get_fpr_pair(r2));
14248       assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
14249                            mkexpr(op)));
14250       put_gpr_w1(r1, mkexpr(result));
14251       s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
14252    }
14253    return "clfxbr";
14254 }
14255 
14256 
14257 static const HChar *
14258 s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
14259                  UChar r1, UChar r2)
14260 {
14261    IRTemp op = newTemp(Ity_F128);
14262    IRTemp result = newTemp(Ity_I64);
14263    IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
14264 
14265    assign(op, get_fpr_pair(r2));
14266    assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
14267                         mkexpr(op)));
14268    put_gpr_dw0(r1, mkexpr(result));
14269    s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
14270 
14271    return "cgxbr";
14272 }
14273 
14274 static const HChar *
14275 s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
14276                   UChar r1, UChar r2)
14277 {
14278    if (! s390_host_has_fpext) {
14279       emulation_failure(EmFail_S390X_fpext);
14280    } else {
14281       IRTemp op = newTemp(Ity_F128);
14282       IRTemp result = newTemp(Ity_I64);
14283       IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
14284 
14285       assign(op, get_fpr_pair(r2));
14286       assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
14287                            mkexpr(op)));
14288       put_gpr_dw0(r1, mkexpr(result));
14289       s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
14290                               rounding_mode);
14291    }
14292    return "clgxbr";
14293 }
14294 
14295 static const HChar *
14296 s390_irgen_DXBR(UChar r1, UChar r2)
14297 {
14298    IRTemp op1 = newTemp(Ity_F128);
14299    IRTemp op2 = newTemp(Ity_F128);
14300    IRTemp result = newTemp(Ity_F128);
14301    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14302 
14303    assign(op1, get_fpr_pair(r1));
14304    assign(op2, get_fpr_pair(r2));
14305    assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
14306                         mkexpr(op2)));
14307    put_fpr_pair(r1, mkexpr(result));
14308 
14309    return "dxbr";
14310 }
14311 
14312 static const HChar *
14313 s390_irgen_LTXBR(UChar r1, UChar r2)
14314 {
14315    IRTemp result = newTemp(Ity_F128);
14316 
14317    assign(result, get_fpr_pair(r2));
14318    put_fpr_pair(r1, mkexpr(result));
14319    s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14320 
14321    return "ltxbr";
14322 }
14323 
14324 static const HChar *
14325 s390_irgen_LCXBR(UChar r1, UChar r2)
14326 {
14327    IRTemp result = newTemp(Ity_F128);
14328 
14329    assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
14330    put_fpr_pair(r1, mkexpr(result));
14331    s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14332 
14333    return "lcxbr";
14334 }
14335 
14336 static const HChar *
14337 s390_irgen_LXDBR(UChar r1, UChar r2)
14338 {
14339    IRTemp op = newTemp(Ity_F64);
14340 
14341    assign(op, get_fpr_dw0(r2));
14342    put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
14343 
14344    return "lxdbr";
14345 }
14346 
14347 static const HChar *
14348 s390_irgen_LXEBR(UChar r1, UChar r2)
14349 {
14350    IRTemp op = newTemp(Ity_F32);
14351 
14352    assign(op, get_fpr_w0(r2));
14353    put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
14354 
14355    return "lxebr";
14356 }
14357 
14358 static const HChar *
14359 s390_irgen_LXDB(UChar r1, IRTemp op2addr)
14360 {
14361    IRTemp op = newTemp(Ity_F64);
14362 
14363    assign(op, load(Ity_F64, mkexpr(op2addr)));
14364    put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
14365 
14366    return "lxdb";
14367 }
14368 
14369 static const HChar *
14370 s390_irgen_LXEB(UChar r1, IRTemp op2addr)
14371 {
14372    IRTemp op = newTemp(Ity_F32);
14373 
14374    assign(op, load(Ity_F32, mkexpr(op2addr)));
14375    put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
14376 
14377    return "lxeb";
14378 }
14379 
14380 static const HChar *
14381 s390_irgen_FIEBRA(UChar m3, UChar m4 __attribute__((unused)),
14382                   UChar r1, UChar r2)
14383 {
14384    IRTemp result = newTemp(Ity_F32);
14385 
14386    assign(result, binop(Iop_RoundF32toInt, mkexpr(encode_bfp_rounding_mode(m3)),
14387                         get_fpr_w0(r2)));
14388    put_fpr_w0(r1, mkexpr(result));
14389 
14390    return "fiebra";
14391 }
14392 
14393 static const HChar *
14394 s390_irgen_FIDBRA(UChar m3, UChar m4 __attribute__((unused)),
14395                   UChar r1, UChar r2)
14396 {
14397    IRTemp result = newTemp(Ity_F64);
14398 
14399    assign(result, binop(Iop_RoundF64toInt, mkexpr(encode_bfp_rounding_mode(m3)),
14400                         get_fpr_dw0(r2)));
14401    put_fpr_dw0(r1, mkexpr(result));
14402 
14403    return "fidbra";
14404 }
14405 
14406 static const HChar *
14407 s390_irgen_FIXBRA(UChar m3, UChar m4 __attribute__((unused)),
14408                   UChar r1, UChar r2)
14409 {
14410    IRTemp result = newTemp(Ity_F128);
14411 
14412    assign(result, binop(Iop_RoundF128toInt, mkexpr(encode_bfp_rounding_mode(m3)),
14413                         get_fpr_pair(r2)));
14414    put_fpr_pair(r1, mkexpr(result));
14415 
14416    return "fixbra";
14417 }
14418 
14419 static const HChar *
14420 s390_irgen_LNEBR(UChar r1, UChar r2)
14421 {
14422    IRTemp result = newTemp(Ity_F32);
14423 
14424    assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
14425    put_fpr_w0(r1, mkexpr(result));
14426    s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
14427 
14428    return "lnebr";
14429 }
14430 
14431 static const HChar *
14432 s390_irgen_LNDBR(UChar r1, UChar r2)
14433 {
14434    IRTemp result = newTemp(Ity_F64);
14435 
14436    assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
14437    put_fpr_dw0(r1, mkexpr(result));
14438    s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
14439 
14440    return "lndbr";
14441 }
14442 
14443 static const HChar *
14444 s390_irgen_LNXBR(UChar r1, UChar r2)
14445 {
14446    IRTemp result = newTemp(Ity_F128);
14447 
14448    assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
14449    put_fpr_pair(r1, mkexpr(result));
14450    s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14451 
14452    return "lnxbr";
14453 }
14454 
14455 static const HChar *
14456 s390_irgen_LPEBR(UChar r1, UChar r2)
14457 {
14458    IRTemp result = newTemp(Ity_F32);
14459 
14460    assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
14461    put_fpr_w0(r1, mkexpr(result));
14462    s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
14463 
14464    return "lpebr";
14465 }
14466 
14467 static const HChar *
14468 s390_irgen_LPDBR(UChar r1, UChar r2)
14469 {
14470    IRTemp result = newTemp(Ity_F64);
14471 
14472    assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
14473    put_fpr_dw0(r1, mkexpr(result));
14474    s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
14475 
14476    return "lpdbr";
14477 }
14478 
14479 static const HChar *
14480 s390_irgen_LPXBR(UChar r1, UChar r2)
14481 {
14482    IRTemp result = newTemp(Ity_F128);
14483 
14484    assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
14485    put_fpr_pair(r1, mkexpr(result));
14486    s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14487 
14488    return "lpxbr";
14489 }
14490 
14491 static const HChar *
14492 s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
14493                  UChar r1, UChar r2)
14494 {
14495    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
14496       emulation_warning(EmWarn_S390X_fpext_rounding);
14497       m3 = S390_BFP_ROUND_PER_FPC;
14498    }
14499    IRTemp result = newTemp(Ity_F64);
14500 
14501    assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
14502                         get_fpr_pair(r2)));
14503    put_fpr_dw0(r1, mkexpr(result));
14504 
14505    return "ldxbr";
14506 }
14507 
14508 static const HChar *
14509 s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
14510                  UChar r1, UChar r2)
14511 {
14512    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
14513       emulation_warning(EmWarn_S390X_fpext_rounding);
14514       m3 = S390_BFP_ROUND_PER_FPC;
14515    }
14516    IRTemp result = newTemp(Ity_F32);
14517 
14518    assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
14519                         get_fpr_pair(r2)));
14520    put_fpr_w0(r1, mkexpr(result));
14521 
14522    return "lexbr";
14523 }
14524 
14525 static const HChar *
14526 s390_irgen_MXBR(UChar r1, UChar r2)
14527 {
14528    IRTemp op1 = newTemp(Ity_F128);
14529    IRTemp op2 = newTemp(Ity_F128);
14530    IRTemp result = newTemp(Ity_F128);
14531    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14532 
14533    assign(op1, get_fpr_pair(r1));
14534    assign(op2, get_fpr_pair(r2));
14535    assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
14536                         mkexpr(op2)));
14537    put_fpr_pair(r1, mkexpr(result));
14538 
14539    return "mxbr";
14540 }
14541 
14542 static const HChar *
14543 s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
14544 {
14545    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14546 
14547    put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
14548                       get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
14549 
14550    return "maebr";
14551 }
14552 
14553 static const HChar *
14554 s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
14555 {
14556    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14557 
14558    put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
14559                        get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
14560 
14561    return "madbr";
14562 }
14563 
14564 static const HChar *
14565 s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
14566 {
14567    IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
14568    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14569 
14570    put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
14571                       get_fpr_w0(r3), op2, get_fpr_w0(r1)));
14572 
14573    return "maeb";
14574 }
14575 
14576 static const HChar *
14577 s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
14578 {
14579    IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
14580    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14581 
14582    put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
14583                        get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
14584 
14585    return "madb";
14586 }
14587 
14588 static const HChar *
14589 s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
14590 {
14591    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14592 
14593    put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
14594                       get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
14595 
14596    return "msebr";
14597 }
14598 
14599 static const HChar *
14600 s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
14601 {
14602    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14603 
14604    put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
14605                        get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
14606 
14607    return "msdbr";
14608 }
14609 
14610 static const HChar *
14611 s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
14612 {
14613    IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
14614    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14615 
14616    put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
14617                       get_fpr_w0(r3), op2, get_fpr_w0(r1)));
14618 
14619    return "mseb";
14620 }
14621 
14622 static const HChar *
14623 s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
14624 {
14625    IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
14626    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14627 
14628    put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
14629                        get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
14630 
14631    return "msdb";
14632 }
14633 
14634 static const HChar *
14635 s390_irgen_SQEBR(UChar r1, UChar r2)
14636 {
14637    IRTemp result = newTemp(Ity_F32);
14638    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14639 
14640    assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
14641    put_fpr_w0(r1, mkexpr(result));
14642 
14643    return "sqebr";
14644 }
14645 
14646 static const HChar *
14647 s390_irgen_SQDBR(UChar r1, UChar r2)
14648 {
14649    IRTemp result = newTemp(Ity_F64);
14650    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14651 
14652    assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
14653    put_fpr_dw0(r1, mkexpr(result));
14654 
14655    return "sqdbr";
14656 }
14657 
14658 static const HChar *
14659 s390_irgen_SQXBR(UChar r1, UChar r2)
14660 {
14661    IRTemp result = newTemp(Ity_F128);
14662    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14663 
14664    assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
14665                         get_fpr_pair(r2)));
14666    put_fpr_pair(r1, mkexpr(result));
14667 
14668    return "sqxbr";
14669 }
14670 
14671 static const HChar *
14672 s390_irgen_SQEB(UChar r1, IRTemp op2addr)
14673 {
14674    IRTemp op = newTemp(Ity_F32);
14675    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14676 
14677    assign(op, load(Ity_F32, mkexpr(op2addr)));
14678    put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
14679 
14680    return "sqeb";
14681 }
14682 
14683 static const HChar *
14684 s390_irgen_SQDB(UChar r1, IRTemp op2addr)
14685 {
14686    IRTemp op = newTemp(Ity_F64);
14687    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14688 
14689    assign(op, load(Ity_F64, mkexpr(op2addr)));
14690    put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
14691 
14692    return "sqdb";
14693 }
14694 
14695 static const HChar *
14696 s390_irgen_SXBR(UChar r1, UChar r2)
14697 {
14698    IRTemp op1 = newTemp(Ity_F128);
14699    IRTemp op2 = newTemp(Ity_F128);
14700    IRTemp result = newTemp(Ity_F128);
14701    IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14702 
14703    assign(op1, get_fpr_pair(r1));
14704    assign(op2, get_fpr_pair(r2));
14705    assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
14706                         mkexpr(op2)));
14707    put_fpr_pair(r1, mkexpr(result));
14708    s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14709 
14710    return "sxbr";
14711 }
14712 
14713 static const HChar *
14714 s390_irgen_TCEB(UChar r1, IRTemp op2addr)
14715 {
14716    IRTemp value = newTemp(Ity_F32);
14717 
14718    assign(value, get_fpr_w0(r1));
14719 
14720    s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
14721 
14722    return "tceb";
14723 }
14724 
14725 static const HChar *
14726 s390_irgen_TCDB(UChar r1, IRTemp op2addr)
14727 {
14728    IRTemp value = newTemp(Ity_F64);
14729 
14730    assign(value, get_fpr_dw0(r1));
14731 
14732    s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
14733 
14734    return "tcdb";
14735 }
14736 
14737 static const HChar *
14738 s390_irgen_TCXB(UChar r1, IRTemp op2addr)
14739 {
14740    IRTemp value = newTemp(Ity_F128);
14741 
14742    assign(value, get_fpr_pair(r1));
14743 
14744    s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
14745 
14746    return "tcxb";
14747 }
14748 
14749 static const HChar *
14750 s390_irgen_LCDFR(UChar r1, UChar r2)
14751 {
14752    IRTemp result = newTemp(Ity_F64);
14753 
14754    assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
14755    put_fpr_dw0(r1, mkexpr(result));
14756 
14757    return "lcdfr";
14758 }
14759 
14760 static const HChar *
14761 s390_irgen_LNDFR(UChar r1, UChar r2)
14762 {
14763    IRTemp result = newTemp(Ity_F64);
14764 
14765    assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
14766    put_fpr_dw0(r1, mkexpr(result));
14767 
14768    return "lndfr";
14769 }
14770 
14771 static const HChar *
14772 s390_irgen_LPDFR(UChar r1, UChar r2)
14773 {
14774    IRTemp result = newTemp(Ity_F64);
14775 
14776    assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
14777    put_fpr_dw0(r1, mkexpr(result));
14778 
14779    return "lpdfr";
14780 }
14781 
14782 static const HChar *
14783 s390_irgen_LDGR(UChar r1, UChar r2)
14784 {
14785    put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
14786 
14787    return "ldgr";
14788 }
14789 
14790 static const HChar *
14791 s390_irgen_LGDR(UChar r1, UChar r2)
14792 {
14793    put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
14794 
14795    return "lgdr";
14796 }
14797 
14798 
14799 static const HChar *
14800 s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
14801 {
14802    IRTemp sign  = newTemp(Ity_I64);
14803    IRTemp value = newTemp(Ity_I64);
14804 
14805    assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
14806                       mkU64(1ULL << 63)));
14807    assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
14808                        mkU64((1ULL << 63) - 1)));
14809    put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
14810                                                     mkexpr(sign))));
14811 
14812    return "cpsdr";
14813 }
14814 
14815 
14816 static IRExpr *
14817 s390_call_cvb(IRExpr *in)
14818 {
14819    IRExpr **args, *call;
14820 
14821    args = mkIRExprVec_1(in);
14822    call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
14823                         "s390_do_cvb", &s390_do_cvb, args);
14824 
14825    /* Nothing is excluded from definedness checking. */
14826    call->Iex.CCall.cee->mcx_mask = 0;
14827 
14828    return call;
14829 }
14830 
14831 static const HChar *
14832 s390_irgen_CVB(UChar r1, IRTemp op2addr)
14833 {
14834    put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
14835 
14836    return "cvb";
14837 }
14838 
14839 static const HChar *
14840 s390_irgen_CVBY(UChar r1, IRTemp op2addr)
14841 {
14842    put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
14843 
14844    return "cvby";
14845 }
14846 
14847 
14848 static IRExpr *
14849 s390_call_cvd(IRExpr *in)
14850 {
14851    IRExpr **args, *call;
14852 
14853    args = mkIRExprVec_1(in);
14854    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
14855                         "s390_do_cvd", &s390_do_cvd, args);
14856 
14857    /* Nothing is excluded from definedness checking. */
14858    call->Iex.CCall.cee->mcx_mask = 0;
14859 
14860    return call;
14861 }
14862 
14863 static const HChar *
14864 s390_irgen_CVD(UChar r1, IRTemp op2addr)
14865 {
14866    store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
14867 
14868    return "cvd";
14869 }
14870 
14871 static const HChar *
14872 s390_irgen_CVDY(UChar r1, IRTemp op2addr)
14873 {
14874    store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
14875 
14876    return "cvdy";
14877 }
14878 
14879 static const HChar *
14880 s390_irgen_FLOGR(UChar r1, UChar r2)
14881 {
14882    IRTemp input    = newTemp(Ity_I64);
14883    IRTemp not_zero = newTemp(Ity_I64);
14884    IRTemp tmpnum   = newTemp(Ity_I64);
14885    IRTemp num      = newTemp(Ity_I64);
14886    IRTemp shift_amount = newTemp(Ity_I8);
14887 
14888    /* We use the "count leading zeroes" operator because the number of
14889       leading zeroes is identical with the bit position of the first '1' bit.
14890       However, that operator does not work when the input value is zero.
14891       Therefore, we set the LSB of the input value to 1 and use Clz64 on
14892       the modified value. If input == 0, then the result is 64. Otherwise,
14893       the result of Clz64 is what we want. */
14894 
14895    assign(input, get_gpr_dw0(r2));
14896    assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
14897    assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
14898 
14899    /* num = (input == 0) ? 64 : tmpnum */
14900    assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
14901                      /* == 0 */ mkU64(64),
14902                      /* != 0 */ mkexpr(tmpnum)));
14903 
14904    put_gpr_dw0(r1, mkexpr(num));
14905 
14906    /* Set the leftmost '1' bit of the input value to zero. The general scheme
14907       is to first shift the input value by NUM + 1 bits to the left which
14908       causes the leftmost '1' bit to disappear. Then we shift logically to
14909       the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
14910       Iop_Shr64 are undefined if the shift-amount is greater than or equal to
14911       the width of the value-to-be-shifted, we need to special case
14912       NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
14913       For both such INPUT values the result will be 0. */
14914 
14915    assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
14916                           mkU64(1))));
14917 
14918    put_gpr_dw0(r1 + 1,
14919                mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
14920                      /* == 0 || == 1*/ mkU64(0),
14921                      /* otherwise */
14922                      binop(Iop_Shr64,
14923                            binop(Iop_Shl64, mkexpr(input),
14924                                  mkexpr(shift_amount)),
14925                            mkexpr(shift_amount))));
14926 
14927    /* Compare the original value as an unsigned integer with 0. */
14928    s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
14929                       mktemp(Ity_I64, mkU64(0)), False);
14930 
14931    return "flogr";
14932 }
14933 
14934 static const HChar *
14935 s390_irgen_POPCNT(UChar r1, UChar r2)
14936 {
14937    Int i;
14938    IRTemp val = newTemp(Ity_I64);
14939    IRTemp mask[3];
14940 
14941    assign(val, get_gpr_dw0(r2));
14942    for (i = 0; i < 3; i++) {
14943       mask[i] = newTemp(Ity_I64);
14944    }
14945    assign(mask[0], mkU64(0x5555555555555555ULL));
14946    assign(mask[1], mkU64(0x3333333333333333ULL));
14947    assign(mask[2], mkU64(0x0F0F0F0F0F0F0F0FULL));
14948    for (i = 0; i < 3; i++) {
14949       IRTemp tmp = newTemp(Ity_I64);
14950 
14951       assign(tmp,
14952              binop(Iop_Add64,
14953                    binop(Iop_And64,
14954                          mkexpr(val),
14955                          mkexpr(mask[i])),
14956                    binop(Iop_And64,
14957                          binop(Iop_Shr64, mkexpr(val), mkU8(1 << i)),
14958                          mkexpr(mask[i]))));
14959       val = tmp;
14960    }
14961    s390_cc_thunk_putZ(S390_CC_OP_BITWISE, val);
14962    put_gpr_dw0(r1, mkexpr(val));
14963    return "popcnt";
14964 }
14965 
14966 static const HChar *
14967 s390_irgen_STCK(IRTemp op2addr)
14968 {
14969    IRDirty *d;
14970    IRTemp cc = newTemp(Ity_I64);
14971 
14972    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
14973                          &s390x_dirtyhelper_STCK,
14974                          mkIRExprVec_1(mkexpr(op2addr)));
14975    d->mFx   = Ifx_Write;
14976    d->mAddr = mkexpr(op2addr);
14977    d->mSize = 8;
14978    stmt(IRStmt_Dirty(d));
14979    s390_cc_set(cc);
14980    return "stck";
14981 }
14982 
14983 static const HChar *
14984 s390_irgen_STCKF(IRTemp op2addr)
14985 {
14986    if (! s390_host_has_stckf) {
14987       emulation_failure(EmFail_S390X_stckf);
14988    } else {
14989       IRTemp cc = newTemp(Ity_I64);
14990 
14991       IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
14992                                      &s390x_dirtyhelper_STCKF,
14993                                      mkIRExprVec_1(mkexpr(op2addr)));
14994       d->mFx   = Ifx_Write;
14995       d->mAddr = mkexpr(op2addr);
14996       d->mSize = 8;
14997       stmt(IRStmt_Dirty(d));
14998       s390_cc_set(cc);
14999    }
15000    return "stckf";
15001 }
15002 
15003 static const HChar *
15004 s390_irgen_STCKE(IRTemp op2addr)
15005 {
15006    IRDirty *d;
15007    IRTemp cc = newTemp(Ity_I64);
15008 
15009    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
15010                          &s390x_dirtyhelper_STCKE,
15011                          mkIRExprVec_1(mkexpr(op2addr)));
15012    d->mFx   = Ifx_Write;
15013    d->mAddr = mkexpr(op2addr);
15014    d->mSize = 16;
15015    stmt(IRStmt_Dirty(d));
15016    s390_cc_set(cc);
15017    return "stcke";
15018 }
15019 
15020 static const HChar *
15021 s390_irgen_STFLE(IRTemp op2addr)
15022 {
15023    if (! s390_host_has_stfle) {
15024       emulation_failure(EmFail_S390X_stfle);
15025       return "stfle";
15026    }
15027 
15028    IRDirty *d;
15029    IRTemp cc = newTemp(Ity_I64);
15030 
15031    /* IRExpr_GSPTR() => Need to pass pointer to guest state to helper */
15032    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
15033                          &s390x_dirtyhelper_STFLE,
15034                          mkIRExprVec_2(IRExpr_GSPTR(), mkexpr(op2addr)));
15035 
15036    d->nFxState = 1;
15037    vex_bzero(&d->fxState, sizeof(d->fxState));
15038 
15039    d->fxState[0].fx     = Ifx_Modify;  /* read then write */
15040    d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
15041    d->fxState[0].size   = sizeof(ULong);
15042 
15043    d->mAddr = mkexpr(op2addr);
15044    /* Pretend all double words are written */
15045    d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
15046    d->mFx   = Ifx_Write;
15047 
15048    stmt(IRStmt_Dirty(d));
15049 
15050    s390_cc_set(cc);
15051 
15052    return "stfle";
15053 }
15054 
15055 static const HChar *
15056 s390_irgen_CKSM(UChar r1,UChar r2)
15057 {
15058    IRTemp addr = newTemp(Ity_I64);
15059    IRTemp op = newTemp(Ity_I32);
15060    IRTemp len = newTemp(Ity_I64);
15061    IRTemp oldval = newTemp(Ity_I32);
15062    IRTemp mask = newTemp(Ity_I32);
15063    IRTemp newop = newTemp(Ity_I32);
15064    IRTemp result = newTemp(Ity_I32);
15065    IRTemp result1 = newTemp(Ity_I32);
15066    IRTemp inc = newTemp(Ity_I64);
15067 
15068    assign(oldval, get_gpr_w1(r1));
15069    assign(addr, get_gpr_dw0(r2));
15070    assign(len, get_gpr_dw0(r2+1));
15071 
15072    /* Condition code is always zero. */
15073    s390_cc_set_val(0);
15074 
15075    /* If length is zero, there is no need to calculate the checksum */
15076    next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
15077 
15078    /* Assiging the increment variable to adjust address and length
15079       later on. */
15080    assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
15081                            mkexpr(len), mkU64(4)));
15082 
15083    /* If length < 4 the final 4-byte 2nd operand value is computed by
15084       appending the remaining bytes to the right with 0. This is done
15085       by AND'ing the 4 bytes loaded from memory with an appropriate
15086       mask. If length >= 4, that mask is simply 0xffffffff. */
15087 
15088    assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
15089                       /* Mask computation when len < 4:
15090                          0xffffffff << (32 - (len % 4)*8) */
15091                       binop(Iop_Shl32, mkU32(0xffffffff),
15092                             unop(Iop_32to8,
15093                                  binop(Iop_Sub32, mkU32(32),
15094                                        binop(Iop_Shl32,
15095                                              unop(Iop_64to32,
15096                                                   binop(Iop_And64,
15097                                                         mkexpr(len), mkU64(3))),
15098                                              mkU8(3))))),
15099                       mkU32(0xffffffff)));
15100 
15101    assign(op, load(Ity_I32, mkexpr(addr)));
15102    assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
15103    assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
15104 
15105    /* Checking for carry */
15106    assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
15107                          binop(Iop_Add32, mkexpr(result), mkU32(1)),
15108                          mkexpr(result)));
15109 
15110    put_gpr_w1(r1, mkexpr(result1));
15111    put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
15112    put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
15113 
15114    iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
15115 
15116    return "cksm";
15117 }
15118 
15119 static const HChar *
15120 s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
15121 {
15122    IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
15123    src_addr = newTemp(Ity_I64);
15124    des_addr = newTemp(Ity_I64);
15125    tab_addr = newTemp(Ity_I64);
15126    test_byte = newTemp(Ity_I8);
15127    src_len = newTemp(Ity_I64);
15128 
15129    assign(src_addr, get_gpr_dw0(r2));
15130    assign(des_addr, get_gpr_dw0(r1));
15131    assign(tab_addr, get_gpr_dw0(1));
15132    assign(src_len, get_gpr_dw0(r1+1));
15133    assign(test_byte, get_gpr_b7(0));
15134 
15135    IRTemp op = newTemp(Ity_I8);
15136    IRTemp op1 = newTemp(Ity_I8);
15137    IRTemp result = newTemp(Ity_I64);
15138 
15139    /* End of source string? We're done; proceed to next insn */
15140    s390_cc_set_val(0);
15141    next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
15142 
15143    /* Load character from source string, index translation table and
15144       store translated character in op1. */
15145    assign(op, load(Ity_I8, mkexpr(src_addr)));
15146 
15147    assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
15148                         mkexpr(tab_addr)));
15149    assign(op1, load(Ity_I8, mkexpr(result)));
15150 
15151    if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
15152       s390_cc_set_val(1);
15153       next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
15154    }
15155    store(get_gpr_dw0(r1), mkexpr(op1));
15156 
15157    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
15158    put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
15159    put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
15160 
15161    iterate();
15162 
15163    return "troo";
15164 }
15165 
15166 static const HChar *
15167 s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
15168 {
15169    IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
15170    src_addr = newTemp(Ity_I64);
15171    des_addr = newTemp(Ity_I64);
15172    tab_addr = newTemp(Ity_I64);
15173    test_byte = newTemp(Ity_I8);
15174    src_len = newTemp(Ity_I64);
15175 
15176    assign(src_addr, get_gpr_dw0(r2));
15177    assign(des_addr, get_gpr_dw0(r1));
15178    assign(tab_addr, get_gpr_dw0(1));
15179    assign(src_len, get_gpr_dw0(r1+1));
15180    assign(test_byte, get_gpr_b7(0));
15181 
15182    IRTemp op = newTemp(Ity_I16);
15183    IRTemp op1 = newTemp(Ity_I8);
15184    IRTemp result = newTemp(Ity_I64);
15185 
15186    /* End of source string? We're done; proceed to next insn */
15187    s390_cc_set_val(0);
15188    next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
15189 
15190    /* Load character from source string, index translation table and
15191       store translated character in op1. */
15192    assign(op, load(Ity_I16, mkexpr(src_addr)));
15193 
15194    assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
15195                         mkexpr(tab_addr)));
15196 
15197    assign(op1, load(Ity_I8, mkexpr(result)));
15198 
15199    if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
15200       s390_cc_set_val(1);
15201       next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
15202    }
15203    store(get_gpr_dw0(r1), mkexpr(op1));
15204 
15205    put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
15206    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
15207    put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
15208 
15209    iterate();
15210 
15211    return "trto";
15212 }
15213 
15214 static const HChar *
15215 s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
15216 {
15217    IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
15218    src_addr = newTemp(Ity_I64);
15219    des_addr = newTemp(Ity_I64);
15220    tab_addr = newTemp(Ity_I64);
15221    test_byte = newTemp(Ity_I16);
15222    src_len = newTemp(Ity_I64);
15223 
15224    assign(src_addr, get_gpr_dw0(r2));
15225    assign(des_addr, get_gpr_dw0(r1));
15226    assign(tab_addr, get_gpr_dw0(1));
15227    assign(src_len, get_gpr_dw0(r1+1));
15228    assign(test_byte, get_gpr_hw3(0));
15229 
15230    IRTemp op = newTemp(Ity_I8);
15231    IRTemp op1 = newTemp(Ity_I16);
15232    IRTemp result = newTemp(Ity_I64);
15233 
15234    /* End of source string? We're done; proceed to next insn */
15235    s390_cc_set_val(0);
15236    next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
15237 
15238    /* Load character from source string, index translation table and
15239       store translated character in op1. */
15240    assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
15241 
15242    assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
15243                         mkexpr(tab_addr)));
15244    assign(op1, load(Ity_I16, mkexpr(result)));
15245 
15246    if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
15247       s390_cc_set_val(1);
15248       next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
15249    }
15250    store(get_gpr_dw0(r1), mkexpr(op1));
15251 
15252    put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
15253    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
15254    put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
15255 
15256    iterate();
15257 
15258    return "trot";
15259 }
15260 
15261 static const HChar *
15262 s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
15263 {
15264    IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
15265    src_addr = newTemp(Ity_I64);
15266    des_addr = newTemp(Ity_I64);
15267    tab_addr = newTemp(Ity_I64);
15268    test_byte = newTemp(Ity_I16);
15269    src_len = newTemp(Ity_I64);
15270 
15271    assign(src_addr, get_gpr_dw0(r2));
15272    assign(des_addr, get_gpr_dw0(r1));
15273    assign(tab_addr, get_gpr_dw0(1));
15274    assign(src_len, get_gpr_dw0(r1+1));
15275    assign(test_byte, get_gpr_hw3(0));
15276 
15277    IRTemp op = newTemp(Ity_I16);
15278    IRTemp op1 = newTemp(Ity_I16);
15279    IRTemp result = newTemp(Ity_I64);
15280 
15281    /* End of source string? We're done; proceed to next insn */
15282    s390_cc_set_val(0);
15283    next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
15284 
15285    /* Load character from source string, index translation table and
15286       store translated character in op1. */
15287    assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
15288 
15289    assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
15290                         mkexpr(tab_addr)));
15291    assign(op1, load(Ity_I16, mkexpr(result)));
15292 
15293    if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
15294       s390_cc_set_val(1);
15295       next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
15296    }
15297 
15298    store(get_gpr_dw0(r1), mkexpr(op1));
15299 
15300    put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
15301    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
15302    put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
15303 
15304    iterate();
15305 
15306    return "trtt";
15307 }
15308 
15309 static const HChar *
15310 s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
15311 {
15312    IRTemp len = newTemp(Ity_I64);
15313 
15314    assign(len, mkU64(length));
15315    s390_irgen_TR_EX(len, start1, start2);
15316 
15317    return "tr";
15318 }
15319 
15320 static const HChar *
15321 s390_irgen_TRE(UChar r1,UChar r2)
15322 {
15323    IRTemp src_addr, tab_addr, src_len, test_byte;
15324    src_addr = newTemp(Ity_I64);
15325    tab_addr = newTemp(Ity_I64);
15326    src_len = newTemp(Ity_I64);
15327    test_byte = newTemp(Ity_I8);
15328 
15329    assign(src_addr, get_gpr_dw0(r1));
15330    assign(src_len, get_gpr_dw0(r1+1));
15331    assign(tab_addr, get_gpr_dw0(r2));
15332    assign(test_byte, get_gpr_b7(0));
15333 
15334    IRTemp op = newTemp(Ity_I8);
15335    IRTemp op1 = newTemp(Ity_I8);
15336    IRTemp result = newTemp(Ity_I64);
15337 
15338    /* End of source string? We're done; proceed to next insn */
15339    s390_cc_set_val(0);
15340    next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
15341 
15342    /* Load character from source string and compare with test byte */
15343    assign(op, load(Ity_I8, mkexpr(src_addr)));
15344 
15345    s390_cc_set_val(1);
15346    next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
15347 
15348    assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
15349 			mkexpr(tab_addr)));
15350 
15351    assign(op1, load(Ity_I8, mkexpr(result)));
15352 
15353    store(get_gpr_dw0(r1), mkexpr(op1));
15354    put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
15355    put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
15356 
15357    iterate();
15358 
15359    return "tre";
15360 }
15361 
15362 static IRExpr *
15363 s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
15364 {
15365    IRExpr **args, *call;
15366    args = mkIRExprVec_2(srcval, low_surrogate);
15367    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15368                        "s390_do_cu21", &s390_do_cu21, args);
15369 
15370    /* Nothing is excluded from definedness checking. */
15371    call->Iex.CCall.cee->mcx_mask = 0;
15372 
15373    return call;
15374 }
15375 
15376 static const HChar *
15377 s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
15378 {
15379    IRTemp addr1 = newTemp(Ity_I64);
15380    IRTemp addr2 = newTemp(Ity_I64);
15381    IRTemp len1 = newTemp(Ity_I64);
15382    IRTemp len2 = newTemp(Ity_I64);
15383 
15384    assign(addr1, get_gpr_dw0(r1));
15385    assign(addr2, get_gpr_dw0(r2));
15386    assign(len1, get_gpr_dw0(r1 + 1));
15387    assign(len2, get_gpr_dw0(r2 + 1));
15388 
15389    /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
15390       there are less than 2 bytes left, then the 2nd operand is exhausted
15391       and we're done here. cc = 0 */
15392    s390_cc_set_val(0);
15393    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
15394 
15395    /* There are at least two bytes there. Read them. */
15396    IRTemp srcval = newTemp(Ity_I32);
15397    assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
15398 
15399    /* Find out whether this is a high surrogate. I.e. SRCVAL lies
15400       inside the interval [0xd800 - 0xdbff] */
15401    IRTemp  is_high_surrogate = newTemp(Ity_I32);
15402    IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
15403                          mkU32(1), mkU32(0));
15404    IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
15405                          mkU32(1), mkU32(0));
15406    assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
15407 
15408    /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
15409       then the 2nd operand is exhausted and we're done here. cc = 0 */
15410    IRExpr *not_enough_bytes =
15411       mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
15412 
15413    next_insn_if(binop(Iop_CmpEQ32,
15414                       binop(Iop_And32, mkexpr(is_high_surrogate),
15415                             not_enough_bytes), mkU32(1)));
15416 
15417    /* The 2nd operand is not exhausted. If the first 2 bytes are a high
15418       surrogate, read the next two bytes (low surrogate). */
15419    IRTemp  low_surrogate = newTemp(Ity_I32);
15420    IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
15421 
15422    assign(low_surrogate,
15423           mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
15424                 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
15425                 mkU32(0)));  // any value is fine; it will not be used
15426 
15427    /* Call the helper */
15428    IRTemp retval = newTemp(Ity_I64);
15429    assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
15430                                  unop(Iop_32Uto64, mkexpr(low_surrogate))));
15431 
15432    /* Before we can test whether the 1st operand is exhausted we need to
15433       test for an invalid low surrogate. Because cc=2 outranks cc=1. */
15434    if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
15435       IRExpr *invalid_low_surrogate =
15436          binop(Iop_And64, mkexpr(retval), mkU64(0xff));
15437 
15438       s390_cc_set_val(2);
15439       next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
15440    }
15441 
15442    /* Now test whether the 1st operand is exhausted */
15443    IRTemp num_bytes = newTemp(Ity_I64);
15444    assign(num_bytes, binop(Iop_And64,
15445                            binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
15446                            mkU64(0xff)));
15447    s390_cc_set_val(1);
15448    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
15449 
15450    /* Extract the bytes to be stored at addr1 */
15451    IRTemp data = newTemp(Ity_I64);
15452    assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
15453 
15454    /* To store the bytes construct 4 dirty helper calls. The helper calls
15455       are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
15456       one of them will be called at runtime. */
15457    UInt i;
15458    for (i = 1; i <= 4; ++i) {
15459       IRDirty *d;
15460 
15461       d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
15462                             &s390x_dirtyhelper_CUxy,
15463                             mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
15464                                           mkexpr(num_bytes)));
15465       d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
15466       d->mFx   = Ifx_Write;
15467       d->mAddr = mkexpr(addr1);
15468       d->mSize = i;
15469       stmt(IRStmt_Dirty(d));
15470    }
15471 
15472    /* Update source address and length */
15473    IRTemp num_src_bytes = newTemp(Ity_I64);
15474    assign(num_src_bytes,
15475           mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
15476                 mkU64(4), mkU64(2)));
15477    put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
15478    put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
15479 
15480    /* Update destination address and length */
15481    put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
15482    put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
15483 
15484    iterate();
15485 
15486    return "cu21";
15487 }
15488 
15489 static IRExpr *
15490 s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
15491 {
15492    IRExpr **args, *call;
15493    args = mkIRExprVec_2(srcval, low_surrogate);
15494    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15495                        "s390_do_cu24", &s390_do_cu24, args);
15496 
15497    /* Nothing is excluded from definedness checking. */
15498    call->Iex.CCall.cee->mcx_mask = 0;
15499 
15500    return call;
15501 }
15502 
15503 static const HChar *
15504 s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
15505 {
15506    IRTemp addr1 = newTemp(Ity_I64);
15507    IRTemp addr2 = newTemp(Ity_I64);
15508    IRTemp len1 = newTemp(Ity_I64);
15509    IRTemp len2 = newTemp(Ity_I64);
15510 
15511    assign(addr1, get_gpr_dw0(r1));
15512    assign(addr2, get_gpr_dw0(r2));
15513    assign(len1, get_gpr_dw0(r1 + 1));
15514    assign(len2, get_gpr_dw0(r2 + 1));
15515 
15516    /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
15517       there are less than 2 bytes left, then the 2nd operand is exhausted
15518       and we're done here. cc = 0 */
15519    s390_cc_set_val(0);
15520    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
15521 
15522    /* There are at least two bytes there. Read them. */
15523    IRTemp srcval = newTemp(Ity_I32);
15524    assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
15525 
15526    /* Find out whether this is a high surrogate. I.e. SRCVAL lies
15527       inside the interval [0xd800 - 0xdbff] */
15528    IRTemp  is_high_surrogate = newTemp(Ity_I32);
15529    IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
15530                          mkU32(1), mkU32(0));
15531    IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
15532                          mkU32(1), mkU32(0));
15533    assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
15534 
15535    /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
15536       then the 2nd operand is exhausted and we're done here. cc = 0 */
15537    IRExpr *not_enough_bytes =
15538       mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
15539 
15540    next_insn_if(binop(Iop_CmpEQ32,
15541                       binop(Iop_And32, mkexpr(is_high_surrogate),
15542                             not_enough_bytes),
15543                       mkU32(1)));
15544 
15545    /* The 2nd operand is not exhausted. If the first 2 bytes are a high
15546       surrogate, read the next two bytes (low surrogate). */
15547    IRTemp  low_surrogate = newTemp(Ity_I32);
15548    IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
15549 
15550    assign(low_surrogate,
15551           mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
15552                 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
15553                 mkU32(0)));  // any value is fine; it will not be used
15554 
15555    /* Call the helper */
15556    IRTemp retval = newTemp(Ity_I64);
15557    assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
15558                                  unop(Iop_32Uto64, mkexpr(low_surrogate))));
15559 
15560    /* Before we can test whether the 1st operand is exhausted we need to
15561       test for an invalid low surrogate. Because cc=2 outranks cc=1. */
15562    if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
15563       IRExpr *invalid_low_surrogate =
15564          binop(Iop_And64, mkexpr(retval), mkU64(0xff));
15565 
15566       s390_cc_set_val(2);
15567       next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
15568    }
15569 
15570    /* Now test whether the 1st operand is exhausted */
15571    s390_cc_set_val(1);
15572    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
15573 
15574    /* Extract the bytes to be stored at addr1 */
15575    IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
15576 
15577    store(mkexpr(addr1), data);
15578 
15579    /* Update source address and length */
15580    IRTemp num_src_bytes = newTemp(Ity_I64);
15581    assign(num_src_bytes,
15582           mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
15583                 mkU64(4), mkU64(2)));
15584    put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
15585    put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
15586 
15587    /* Update destination address and length */
15588    put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
15589    put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkU64(4)));
15590 
15591    iterate();
15592 
15593    return "cu24";
15594 }
15595 
15596 static IRExpr *
15597 s390_call_cu42(IRExpr *srcval)
15598 {
15599    IRExpr **args, *call;
15600    args = mkIRExprVec_1(srcval);
15601    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15602                        "s390_do_cu42", &s390_do_cu42, args);
15603 
15604    /* Nothing is excluded from definedness checking. */
15605    call->Iex.CCall.cee->mcx_mask = 0;
15606 
15607    return call;
15608 }
15609 
15610 static const HChar *
15611 s390_irgen_CU42(UChar r1, UChar r2)
15612 {
15613    IRTemp addr1 = newTemp(Ity_I64);
15614    IRTemp addr2 = newTemp(Ity_I64);
15615    IRTemp len1 = newTemp(Ity_I64);
15616    IRTemp len2 = newTemp(Ity_I64);
15617 
15618    assign(addr1, get_gpr_dw0(r1));
15619    assign(addr2, get_gpr_dw0(r2));
15620    assign(len1, get_gpr_dw0(r1 + 1));
15621    assign(len2, get_gpr_dw0(r2 + 1));
15622 
15623    /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
15624       there are less than 4 bytes left, then the 2nd operand is exhausted
15625       and we're done here. cc = 0 */
15626    s390_cc_set_val(0);
15627    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
15628 
15629    /* Read the 2nd operand. */
15630    IRTemp srcval = newTemp(Ity_I32);
15631    assign(srcval, load(Ity_I32, mkexpr(addr2)));
15632 
15633    /* Call the helper */
15634    IRTemp retval = newTemp(Ity_I64);
15635    assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
15636 
15637    /* If the UTF-32 character was invalid, set cc=2 and we're done.
15638       cc=2 outranks cc=1 (1st operand exhausted) */
15639    IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
15640 
15641    s390_cc_set_val(2);
15642    next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
15643 
15644    /* Now test whether the 1st operand is exhausted */
15645    IRTemp num_bytes = newTemp(Ity_I64);
15646    assign(num_bytes, binop(Iop_And64,
15647                            binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
15648                            mkU64(0xff)));
15649    s390_cc_set_val(1);
15650    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
15651 
15652    /* Extract the bytes to be stored at addr1 */
15653    IRTemp data = newTemp(Ity_I64);
15654    assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
15655 
15656    /* To store the bytes construct 2 dirty helper calls. The helper calls
15657       are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
15658       that only one of them will be called at runtime. */
15659 
15660    Int i;
15661    for (i = 2; i <= 4; ++i) {
15662       IRDirty *d;
15663 
15664       if (i == 3) continue;  // skip this one
15665 
15666       d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
15667                             &s390x_dirtyhelper_CUxy,
15668                             mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
15669                                           mkexpr(num_bytes)));
15670       d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
15671       d->mFx   = Ifx_Write;
15672       d->mAddr = mkexpr(addr1);
15673       d->mSize = i;
15674       stmt(IRStmt_Dirty(d));
15675    }
15676 
15677    /* Update source address and length */
15678    put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
15679    put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkU64(4)));
15680 
15681    /* Update destination address and length */
15682    put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
15683    put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
15684 
15685    iterate();
15686 
15687    return "cu42";
15688 }
15689 
15690 static IRExpr *
15691 s390_call_cu41(IRExpr *srcval)
15692 {
15693    IRExpr **args, *call;
15694    args = mkIRExprVec_1(srcval);
15695    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15696                        "s390_do_cu41", &s390_do_cu41, args);
15697 
15698    /* Nothing is excluded from definedness checking. */
15699    call->Iex.CCall.cee->mcx_mask = 0;
15700 
15701    return call;
15702 }
15703 
15704 static const HChar *
15705 s390_irgen_CU41(UChar r1, UChar r2)
15706 {
15707    IRTemp addr1 = newTemp(Ity_I64);
15708    IRTemp addr2 = newTemp(Ity_I64);
15709    IRTemp len1 = newTemp(Ity_I64);
15710    IRTemp len2 = newTemp(Ity_I64);
15711 
15712    assign(addr1, get_gpr_dw0(r1));
15713    assign(addr2, get_gpr_dw0(r2));
15714    assign(len1, get_gpr_dw0(r1 + 1));
15715    assign(len2, get_gpr_dw0(r2 + 1));
15716 
15717    /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
15718       there are less than 4 bytes left, then the 2nd operand is exhausted
15719       and we're done here. cc = 0 */
15720    s390_cc_set_val(0);
15721    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
15722 
15723    /* Read the 2nd operand. */
15724    IRTemp srcval = newTemp(Ity_I32);
15725    assign(srcval, load(Ity_I32, mkexpr(addr2)));
15726 
15727    /* Call the helper */
15728    IRTemp retval = newTemp(Ity_I64);
15729    assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
15730 
15731    /* If the UTF-32 character was invalid, set cc=2 and we're done.
15732       cc=2 outranks cc=1 (1st operand exhausted) */
15733    IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
15734 
15735    s390_cc_set_val(2);
15736    next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
15737 
15738    /* Now test whether the 1st operand is exhausted */
15739    IRTemp num_bytes = newTemp(Ity_I64);
15740    assign(num_bytes, binop(Iop_And64,
15741                            binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
15742                            mkU64(0xff)));
15743    s390_cc_set_val(1);
15744    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
15745 
15746    /* Extract the bytes to be stored at addr1 */
15747    IRTemp data = newTemp(Ity_I64);
15748    assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
15749 
15750    /* To store the bytes construct 4 dirty helper calls. The helper calls
15751       are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
15752       one of them will be called at runtime. */
15753    UInt i;
15754    for (i = 1; i <= 4; ++i) {
15755       IRDirty *d;
15756 
15757       d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
15758                             &s390x_dirtyhelper_CUxy,
15759                             mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
15760                                           mkexpr(num_bytes)));
15761       d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
15762       d->mFx   = Ifx_Write;
15763       d->mAddr = mkexpr(addr1);
15764       d->mSize = i;
15765       stmt(IRStmt_Dirty(d));
15766    }
15767 
15768    /* Update source address and length */
15769    put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
15770    put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkU64(4)));
15771 
15772    /* Update destination address and length */
15773    put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
15774    put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
15775 
15776    iterate();
15777 
15778    return "cu41";
15779 }
15780 
15781 static IRExpr *
15782 s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
15783 {
15784    IRExpr **args, *call;
15785    args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
15786    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
15787                         &s390_do_cu12_cu14_helper1, args);
15788 
15789    /* Nothing is excluded from definedness checking. */
15790    call->Iex.CCall.cee->mcx_mask = 0;
15791 
15792    return call;
15793 }
15794 
15795 static IRExpr *
15796 s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
15797                        IRExpr *byte4, IRExpr *stuff)
15798 {
15799    IRExpr **args, *call;
15800    args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
15801    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15802                         "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
15803 
15804    /* Nothing is excluded from definedness checking. */
15805    call->Iex.CCall.cee->mcx_mask = 0;
15806 
15807    return call;
15808 }
15809 
15810 static IRExpr *
15811 s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
15812                        IRExpr *byte4, IRExpr *stuff)
15813 {
15814    IRExpr **args, *call;
15815    args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
15816    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15817                         "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
15818 
15819    /* Nothing is excluded from definedness checking. */
15820    call->Iex.CCall.cee->mcx_mask = 0;
15821 
15822    return call;
15823 }
15824 
15825 static void
15826 s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
15827 {
15828    IRTemp addr1 = newTemp(Ity_I64);
15829    IRTemp addr2 = newTemp(Ity_I64);
15830    IRTemp len1 = newTemp(Ity_I64);
15831    IRTemp len2 = newTemp(Ity_I64);
15832 
15833    assign(addr1, get_gpr_dw0(r1));
15834    assign(addr2, get_gpr_dw0(r2));
15835    assign(len1, get_gpr_dw0(r1 + 1));
15836    assign(len2, get_gpr_dw0(r2 + 1));
15837 
15838    UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
15839 
15840    /* We're processing the 2nd operand 1 byte at a time. Therefore, if
15841       there is less than 1 byte left, then the 2nd operand is exhausted
15842       and we're done here. cc = 0 */
15843    s390_cc_set_val(0);
15844    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
15845 
15846    /* There is at least one byte there. Read it. */
15847    IRTemp byte1 = newTemp(Ity_I64);
15848    assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
15849 
15850    /* Call the helper to get number of bytes and invalid byte indicator */
15851    IRTemp retval1 = newTemp(Ity_I64);
15852    assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
15853                                                mkU64(extended_checking)));
15854 
15855    /* Check for invalid 1st byte */
15856    IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
15857    s390_cc_set_val(2);
15858    next_insn_if(is_invalid);
15859 
15860    /* How many bytes do we have to read? */
15861    IRTemp num_src_bytes = newTemp(Ity_I64);
15862    assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
15863 
15864    /* Now test whether the 2nd operand is exhausted */
15865    s390_cc_set_val(0);
15866    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
15867 
15868    /* Read the remaining bytes */
15869    IRExpr *cond, *addr, *byte2, *byte3, *byte4;
15870 
15871    cond  = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
15872    addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
15873    byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
15874    cond  = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
15875    addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
15876    byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
15877    cond  = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
15878    addr  = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
15879    byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
15880 
15881    /* Call the helper to get the converted value and invalid byte indicator.
15882       We can pass at most 5 arguments; therefore some encoding is needed
15883       here */
15884    IRExpr *stuff = binop(Iop_Or64,
15885                          binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
15886                          mkU64(extended_checking));
15887    IRTemp retval2 = newTemp(Ity_I64);
15888 
15889    if (is_cu12) {
15890       assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
15891                                              byte4, stuff));
15892    } else {
15893       assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
15894                                              byte4, stuff));
15895    }
15896 
15897    /* Check for invalid character */
15898    s390_cc_set_val(2);
15899    is_invalid = unop(Iop_64to1, mkexpr(retval2));
15900    next_insn_if(is_invalid);
15901 
15902    /* Now test whether the 1st operand is exhausted */
15903    IRTemp num_bytes = newTemp(Ity_I64);
15904    assign(num_bytes, binop(Iop_And64,
15905                            binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
15906                            mkU64(0xff)));
15907    s390_cc_set_val(1);
15908    next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
15909 
15910    /* Extract the bytes to be stored at addr1 */
15911    IRTemp data = newTemp(Ity_I64);
15912    assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
15913 
15914    if (is_cu12) {
15915       /* To store the bytes construct 2 dirty helper calls. The helper calls
15916          are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
15917          that only one of them will be called at runtime. */
15918 
15919       Int i;
15920       for (i = 2; i <= 4; ++i) {
15921          IRDirty *d;
15922 
15923          if (i == 3) continue;  // skip this one
15924 
15925          d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
15926                                &s390x_dirtyhelper_CUxy,
15927                                mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
15928                                              mkexpr(num_bytes)));
15929          d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
15930          d->mFx   = Ifx_Write;
15931          d->mAddr = mkexpr(addr1);
15932          d->mSize = i;
15933          stmt(IRStmt_Dirty(d));
15934       }
15935    } else {
15936       // cu14
15937       store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
15938    }
15939 
15940    /* Update source address and length */
15941    put_gpr_dw0(r2,     binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
15942    put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2),  mkexpr(num_src_bytes)));
15943 
15944    /* Update destination address and length */
15945    put_gpr_dw0(r1,     binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
15946    put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1),  mkexpr(num_bytes)));
15947 
15948    iterate();
15949 }
15950 
15951 static const HChar *
15952 s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
15953 {
15954    s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
15955 
15956    return "cu12";
15957 }
15958 
15959 static const HChar *
15960 s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
15961 {
15962    s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
15963 
15964    return "cu14";
15965 }
15966 
15967 static IRExpr *
15968 s390_call_ecag(IRExpr *op2addr)
15969 {
15970    IRExpr **args, *call;
15971 
15972    args = mkIRExprVec_1(op2addr);
15973    call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15974                         "s390_do_ecag", &s390_do_ecag, args);
15975 
15976    /* Nothing is excluded from definedness checking. */
15977    call->Iex.CCall.cee->mcx_mask = 0;
15978 
15979    return call;
15980 }
15981 
15982 static const HChar *
15983 s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
15984 {
15985    if (! s390_host_has_gie) {
15986       emulation_failure(EmFail_S390X_ecag);
15987    } else {
15988       put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
15989    }
15990 
15991    return "ecag";
15992 }
15993 
15994 static const HChar *
15995 s390_irgen_VL(UChar v1, IRTemp op2addr)
15996 {
15997    put_vr_qw(v1, load(Ity_V128, mkexpr(op2addr)));
15998 
15999    return "vl";
16000 }
16001 
16002 static const HChar *
16003 s390_irgen_VLR(UChar v1, UChar v2)
16004 {
16005    put_vr_qw(v1, get_vr_qw(v2));
16006 
16007    return "vlr";
16008 }
16009 
16010 static const HChar *
16011 s390_irgen_VST(UChar v1, IRTemp op2addr)
16012 {
16013    store(mkexpr(op2addr), get_vr_qw(v1));
16014 
16015    return "vst";
16016 }
16017 
16018 static const HChar *
16019 s390_irgen_VLREP(UChar v1, IRTemp op2addr, UChar m3)
16020 {
16021    IRType o2type = s390_vr_get_type(m3);
16022    IRExpr* o2 = load(o2type, mkexpr(op2addr));
16023    s390_vr_fill(v1, o2);
16024    return "vlrep";
16025 }
16026 
16027 static const HChar *
16028 s390_irgen_VLEB(UChar v1, IRTemp op2addr, UChar m3)
16029 {
16030    IRExpr* o2 = load(Ity_I8, mkexpr(op2addr));
16031    put_vr(v1, Ity_I8, m3, o2);
16032 
16033    return "vleb";
16034 }
16035 
16036 static const HChar *
16037 s390_irgen_VLEH(UChar v1, IRTemp op2addr, UChar m3)
16038 {
16039    IRExpr* o2 = load(Ity_I16, mkexpr(op2addr));
16040    put_vr(v1, Ity_I16, m3, o2);
16041 
16042    return "vleh";
16043 }
16044 
16045 static const HChar *
16046 s390_irgen_VLEF(UChar v1, IRTemp op2addr, UChar m3)
16047 {
16048    IRExpr* o2 = load(Ity_I32, mkexpr(op2addr));
16049    put_vr(v1, Ity_I32, m3, o2);
16050 
16051    return "vlef";
16052 }
16053 
16054 static const HChar *
16055 s390_irgen_VLEG(UChar v1, IRTemp op2addr, UChar m3)
16056 {
16057    IRExpr* o2 = load(Ity_I64, mkexpr(op2addr));
16058    put_vr(v1, Ity_I64, m3, o2);
16059 
16060    return "vleg";
16061 }
16062 
16063 static const HChar *
16064 s390_irgen_VLEIB(UChar v1, UShort i2, UChar m3)
16065 {
16066    IRExpr* o2 = unop(Iop_16to8, mkU16(i2));
16067    put_vr(v1, Ity_I8, m3, o2);
16068 
16069    return "vleib";
16070 }
16071 
16072 static const HChar *
16073 s390_irgen_VLEIH(UChar v1, UShort i2, UChar m3)
16074 {
16075    IRExpr* o2 = mkU16(i2);
16076    put_vr(v1, Ity_I16, m3, o2);
16077 
16078    return "vleih";
16079 }
16080 
16081 static const HChar *
16082 s390_irgen_VLEIF(UChar v1, UShort i2, UChar m3)
16083 {
16084    IRExpr* o2 = unop(Iop_16Sto32, mkU16(i2));
16085    put_vr(v1, Ity_I32, m3, o2);
16086 
16087    return "vleif";
16088 }
16089 
16090 static const HChar *
16091 s390_irgen_VLEIG(UChar v1, UShort i2, UChar m3)
16092 {
16093    IRExpr* o2 = unop(Iop_16Sto64, mkU16(i2));
16094    put_vr(v1, Ity_I64, m3, o2);
16095 
16096    return "vleig";
16097 }
16098 
16099 static const HChar *
16100 s390_irgen_VLGV(UChar r1, IRTemp op2addr, UChar v3, UChar m4)
16101 {
16102    IRType o2type = s390_vr_get_type(m4);
16103    IRExpr* index = unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), mkU64(0xf)));
16104    IRExpr* o2;
16105    IRExpr* result;
16106    switch (o2type) {
16107    case Ity_I8:
16108       o2 = binop(Iop_GetElem8x16, get_vr_qw(v3), index);
16109       result = unop(Iop_8Uto64, o2);
16110       break;
16111    case Ity_I16:
16112       o2 = binop(Iop_GetElem16x8, get_vr_qw(v3), index);
16113       result = unop(Iop_16Uto64, o2);
16114       break;
16115    case Ity_I32:
16116       o2 = binop(Iop_GetElem32x4, get_vr_qw(v3), index);
16117       result = unop(Iop_32Uto64, o2);
16118       break;
16119    case Ity_I64:
16120       result = binop(Iop_GetElem64x2, get_vr_qw(v3), index);
16121       break;
16122    default:
16123       ppIRType(o2type);
16124       vpanic("s390_irgen_VLGV: unknown o2type");
16125    }
16126 
16127    put_gpr_dw0(r1, result);
16128    return "vlgv";
16129 }
16130 
16131 static const HChar *
16132 s390_irgen_VGBM(UChar v1, UShort i2, UChar m3 __attribute__((unused)))
16133 {
16134    put_vr_qw(v1, IRExpr_Const(IRConst_V128(i2)));
16135 
16136    return "vgbm";
16137 }
16138 
16139 static const HChar *
16140 s390_irgen_VGM(UChar v1, UShort i2, UChar m3)
16141 {
16142    UChar from = (i2 & 0xff00) >> 8;
16143    UChar to   = (i2 & 0x00ff);
16144    ULong value = 0UL;
16145    IRType type = s390_vr_get_type(m3);
16146    vassert(from <= to);
16147 
16148    UChar maxIndex = 0;
16149    switch (type) {
16150    case Ity_I8:
16151       maxIndex = 7;
16152       break;
16153    case Ity_I16:
16154       maxIndex = 15;
16155       break;
16156    case Ity_I32:
16157       maxIndex = 31;
16158       break;
16159    case Ity_I64:
16160       maxIndex = 63;
16161       break;
16162    default:
16163       vpanic("s390_irgen_VGM: unknown type");
16164    }
16165 
16166    for(UChar index = from; index <= to; index++) {
16167       value |= (1ULL << (maxIndex - index));
16168    }
16169 
16170    IRExpr *fillValue;
16171    switch (type) {
16172    case Ity_I8:
16173       fillValue = mkU8(value);
16174       break;
16175    case Ity_I16:
16176       fillValue = mkU16(value);
16177       break;
16178    case Ity_I32:
16179       fillValue = mkU32(value);
16180       break;
16181    case Ity_I64:
16182       fillValue = mkU64(value);
16183       break;
16184    default:
16185       vpanic("s390_irgen_VGM: unknown type");
16186    }
16187 
16188    s390_vr_fill(v1, fillValue);
16189    return "vgm";
16190 }
16191 
16192 static const HChar *
16193 s390_irgen_VLLEZ(UChar v1, IRTemp op2addr, UChar m3)
16194 {
16195    IRType type = s390_vr_get_type(m3);
16196    IRExpr* op2 = load(type, mkexpr(op2addr));
16197    IRExpr* op2as64bit;
16198    switch (type) {
16199    case Ity_I8:
16200       op2as64bit = unop(Iop_8Uto64, op2);
16201       break;
16202    case Ity_I16:
16203       op2as64bit = unop(Iop_16Uto64, op2);
16204       break;
16205    case Ity_I32:
16206       op2as64bit = unop(Iop_32Uto64, op2);
16207       break;
16208    case Ity_I64:
16209       op2as64bit = op2;
16210       break;
16211    default:
16212       vpanic("s390_irgen_VLLEZ: unknown type");
16213    }
16214 
16215    put_vr_dw0(v1, op2as64bit);
16216    put_vr_dw1(v1, mkU64(0));
16217    return "vllez";
16218 }
16219 
16220 static const HChar *
16221 s390_irgen_VGEF(UChar v1, IRTemp op2addr, UChar m3)
16222 {
16223    put_vr(v1, Ity_I32, m3, load(Ity_I32, mkexpr(op2addr)));
16224    return "vgef";
16225 }
16226 
16227 static const HChar *
16228 s390_irgen_VGEG(UChar v1, IRTemp op2addr, UChar m3)
16229 {
16230    put_vr(v1, Ity_I64, m3, load(Ity_I64, mkexpr(op2addr)));
16231    return "vgeg";
16232 }
16233 
16234 static const HChar *
16235 s390_irgen_VLM(UChar v1, IRTemp op2addr, UChar v3)
16236 {
16237    IRExpr* current = mkexpr(op2addr);
16238    vassert(v3 >= v1);
16239    vassert(v3 - v1 <= 16);
16240 
16241    for(UChar vr = v1; vr <= v3; vr++) {
16242          IRExpr* next = binop(Iop_Add64, current, mkU64(16));
16243          put_vr_qw(vr, load(Ity_V128, current));
16244          current = next;
16245    }
16246 
16247    return "vlm";
16248 }
16249 
16250 static const HChar *
16251 s390_irgen_VLVGP(UChar v1, UChar r2, UChar r3)
16252 {
16253    put_vr_qw(v1, binop(Iop_64HLtoV128, get_gpr_dw0(r2), get_gpr_dw0(r3)));
16254 
16255    return "vlvgp";
16256 }
16257 
16258 static const HChar *
16259 s390_irgen_VLVG(UChar v1, IRTemp op2addr, UChar r3, UChar m4)
16260 {
16261    IRType type = s390_vr_get_type(m4);
16262    IRExpr* index = unop(Iop_64to8, mkexpr(op2addr));
16263    IRExpr* vr = get_vr_qw(v1);
16264    IRExpr* operand;
16265    switch (type) {
16266    case Ity_I8:
16267       operand = unop(Iop_64to8, get_gpr_dw0(r3));
16268       put_vr_qw(v1, triop(Iop_SetElem8x16, vr, index, operand));
16269       break;
16270    case Ity_I16:
16271       operand = unop(Iop_64to16, get_gpr_dw0(r3));
16272       put_vr_qw(v1, triop(Iop_SetElem16x8, vr, index, operand));
16273       break;
16274    case Ity_I32:
16275       operand = unop(Iop_64to32, get_gpr_dw0(r3));
16276       put_vr_qw(v1, triop(Iop_SetElem32x4, vr, index, operand));
16277       break;
16278    case Ity_I64:
16279       operand = get_gpr_dw0(r3);
16280       put_vr_qw(v1, triop(Iop_SetElem64x2, vr, index, operand));
16281       break;
16282    default:
16283       vpanic("s390_irgen_VLVG: unknown type");
16284    }
16285 
16286    return "vlvg";
16287 }
16288 
16289 static const HChar *
16290 s390_irgen_VMRH(UChar v1, UChar v2, UChar v3, UChar m4)
16291 {
16292    const IROp ops[] = { Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
16293                         Iop_InterleaveHI32x4, Iop_InterleaveHI64x2 };
16294    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
16295    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
16296 
16297    return "vmrh";
16298 }
16299 
16300 static const HChar *
16301 s390_irgen_VMRL(UChar v1, UChar v2, UChar v3, UChar m4)
16302 {
16303    const IROp ops[] = { Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
16304                         Iop_InterleaveLO32x4, Iop_InterleaveLO64x2 };
16305    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
16306    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
16307 
16308    return "vmrl";
16309 }
16310 
16311 static const HChar *
16312 s390_irgen_VPK(UChar v1, UChar v2, UChar v3, UChar m4)
16313 {
16314    const IROp ops[] = { Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8,
16315                         Iop_NarrowBin64to32x4 };
16316    Char index = m4 - 1;
16317    vassert((index >= 0) && (index < sizeof(ops) / sizeof(ops[0])));
16318    put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3)));
16319    return "vpk";
16320 }
16321 
16322 static const HChar *
16323 s390_irgen_VPERM(UChar v1, UChar v2, UChar v3, UChar v4)
16324 {
16325    put_vr_qw(v1, triop(Iop_Perm8x16x2,
16326              get_vr_qw(v2), get_vr_qw(v3), get_vr_qw(v4)));
16327 
16328    return "vperm";
16329 }
16330 
16331 static const HChar *
16332 s390_irgen_VSCEF(UChar v1, IRTemp op2addr, UChar m3)
16333 {
16334    store(mkexpr(op2addr), get_vr(v1, Ity_I32, m3));
16335    return "vscef";
16336 }
16337 
16338 static const HChar *
16339 s390_irgen_VSCEG(UChar v1, IRTemp op2addr, UChar m3)
16340 {
16341    store(mkexpr(op2addr), get_vr(v1, Ity_I64, m3));
16342    return "vsceg";
16343 }
16344 
16345 static const HChar *
16346 s390_irgen_VPDI(UChar v1, UChar v2, UChar v3, UChar m4)
16347 {
16348    /* Theese bits are reserved by specification */
16349    vassert((m4 & 2) == 0);
16350    vassert((m4 & 8) == 0);
16351 
16352    if((m4 & 4) != 0)
16353       put_vr_dw0(v1, get_vr_dw1(v2));
16354    else
16355       put_vr_dw0(v1, get_vr_dw0(v2));
16356 
16357    if((m4 & 1) != 0)
16358       put_vr_dw1(v1, get_vr_dw1(v3));
16359    else
16360       put_vr_dw1(v1, get_vr_dw0(v3));
16361 
16362    return "vpdi";
16363 }
16364 
16365 static const HChar *
16366 s390_irgen_VSEG(UChar v1, UChar v2, UChar m3)
16367 {
16368    IRType type = s390_vr_get_type(m3);
16369    switch(type) {
16370    case Ity_I8:
16371       put_vr_dw0(v1, unop(Iop_8Sto64, get_vr_b7(v2)));
16372       put_vr_dw1(v1, unop(Iop_8Sto64, get_vr_b15(v2)));
16373       break;
16374    case Ity_I16:
16375       put_vr_dw0(v1, unop(Iop_16Sto64, get_vr_hw3(v2)));
16376       put_vr_dw1(v1, unop(Iop_16Sto64, get_vr_hw7(v2)));
16377       break;
16378    case Ity_I32:
16379       put_vr_dw0(v1, unop(Iop_32Sto64, get_vr_w1(v2)));
16380       put_vr_dw1(v1, unop(Iop_32Sto64, get_vr_w3(v2)));
16381       break;
16382    default:
16383       ppIRType(type);
16384       vpanic("s390_irgen_VSEG: unknown type");
16385    }
16386 
16387    return "vseg";
16388 }
16389 
16390 static const HChar *
16391 s390_irgen_VSTEB(UChar v1, IRTemp op2addr, UChar m3)
16392 {
16393    store(mkexpr(op2addr), get_vr(v1, Ity_I8, m3));
16394 
16395    return "vsteb";
16396 }
16397 
16398 static const HChar *
16399 s390_irgen_VSTEH(UChar v1, IRTemp op2addr, UChar m3)
16400 {
16401    store(mkexpr(op2addr), get_vr(v1, Ity_I16, m3));
16402 
16403    return "vsteh";
16404 }
16405 
16406 static const HChar *
16407 s390_irgen_VSTEF(UChar v1, IRTemp op2addr, UChar m3)
16408 {
16409    store(mkexpr(op2addr), get_vr(v1, Ity_I32, m3));
16410 
16411    return "vstef";
16412 }
16413 
16414 static const HChar *
16415 s390_irgen_VSTEG(UChar v1, IRTemp op2addr, UChar m3)
16416 {
16417    store(mkexpr(op2addr), get_vr(v1, Ity_I64, m3));
16418 
16419    return "vsteg";
16420 }
16421 
16422 static const HChar *
16423 s390_irgen_VSTM(UChar v1, IRTemp op2addr, UChar v3)
16424 {
16425    IRExpr* current = mkexpr(op2addr);
16426    vassert(v3 >= v1);
16427    vassert(v3 - v1 <= 16);
16428 
16429    for(UChar vr = v1; vr <= v3; vr++) {
16430          IRExpr* next = binop(Iop_Add64, current, mkU64(16));
16431          store(current, get_vr_qw(vr));
16432          current = next;
16433    }
16434 
16435    return "vstm";
16436 }
16437 
16438 static const HChar *
16439 s390_irgen_VUPH(UChar v1, UChar v2, UChar m3)
16440 {
16441    const IROp ops[] = { Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2 };
16442    vassert(m3 < sizeof(ops) / sizeof(ops[0]));
16443    put_vr_qw(v1, unop(ops[m3], get_vr_dw0(v2)));
16444 
16445    return "vuph";
16446 }
16447 
16448 static const HChar *
16449 s390_irgen_VUPLH(UChar v1, UChar v2, UChar m3)
16450 {
16451    const IROp ops[] = { Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2 };
16452    vassert(m3 < sizeof(ops) / sizeof(ops[0]));
16453    put_vr_qw(v1, unop(ops[m3], get_vr_dw0(v2)));
16454    return "vuplh";
16455 }
16456 
16457 static const HChar *
16458 s390_irgen_VUPL(UChar v1, UChar v2, UChar m3)
16459 {
16460    const IROp ops[] = { Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2 };
16461    vassert(m3 < sizeof(ops) / sizeof(ops[0]));
16462    put_vr_qw(v1, unop(ops[m3], get_vr_dw1(v2)));
16463 
16464    return "vupl";
16465 }
16466 
16467 static const HChar *
16468 s390_irgen_VUPLL(UChar v1, UChar v2, UChar m3)
16469 {
16470    const IROp ops[] = { Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2 };
16471    vassert(m3 < sizeof(ops) / sizeof(ops[0]));
16472    put_vr_qw(v1, unop(ops[m3], get_vr_dw1(v2)));
16473 
16474    return "vupll";
16475 }
16476 
16477 static const HChar *
16478 s390_irgen_VREP(UChar v1, UChar v3, UShort i2, UChar m4)
16479 {
16480    IRType type = s390_vr_get_type(m4);
16481    IRExpr* arg = get_vr(v3, type, i2);
16482    s390_vr_fill(v1, arg);
16483 
16484    return "vrep";
16485 }
16486 
16487 static const HChar *
16488 s390_irgen_VREPI(UChar v1, UShort i2, UChar m3)
16489 {
16490    IRType type = s390_vr_get_type(m3);
16491    IRExpr *value;
16492    switch (type) {
16493    case Ity_I8:
16494       value = mkU8((UChar)i2);
16495       break;
16496    case Ity_I16:
16497       value = mkU16(i2);
16498       break;
16499    case Ity_I32:
16500       value = unop(Iop_16Sto32, mkU16(i2));
16501       break;
16502    case Ity_I64:
16503       value = unop(Iop_16Sto64, mkU16(i2));
16504       break;
16505   default:
16506     ppIRType(type);
16507     vpanic("s390_irgen_VREPI: unknown type");
16508   }
16509   s390_vr_fill(v1, value);
16510 
16511   return "vrepi";
16512 }
16513 
16514 static const HChar *
16515 s390_irgen_VPKS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
16516 {
16517    if (!s390_vr_is_cs_set(m5)) {
16518       const IROp ops[] = { Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8,
16519                            Iop_QNarrowBin64Sto32Sx4 };
16520       Char index = m4 - 1;
16521       vassert((index >= 0) && (index < sizeof(ops) / sizeof(ops[0])));
16522       put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3)));
16523 
16524    } else {
16525       IRDirty* d;
16526       IRTemp cc = newTemp(Ity_I64);
16527 
16528       s390x_vec_op_details_t details = { .serialized = 0ULL };
16529       details.op = S390_VEC_OP_VPKS;
16530       details.v1 = v1;
16531       details.v2 = v2;
16532       details.v3 = v3;
16533       details.m4 = m4;
16534       details.m5 = m5;
16535 
16536       d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
16537                             &s390x_dirtyhelper_vec_op,
16538                             mkIRExprVec_2(IRExpr_GSPTR(),
16539                                           mkU64(details.serialized)));
16540 
16541       d->nFxState = 3;
16542       vex_bzero(&d->fxState, sizeof(d->fxState));
16543       d->fxState[0].fx     = Ifx_Read;
16544       d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
16545       d->fxState[0].size   = sizeof(V128);
16546       d->fxState[1].fx     = Ifx_Read;
16547       d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
16548       d->fxState[1].size   = sizeof(V128);
16549       d->fxState[2].fx     = Ifx_Write;
16550       d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
16551       d->fxState[2].size   = sizeof(V128);
16552 
16553       stmt(IRStmt_Dirty(d));
16554       s390_cc_set(cc);
16555    }
16556 
16557    return "vpks";
16558 }
16559 
16560 static const HChar *
16561 s390_irgen_VPKLS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
16562 {
16563    if (!s390_vr_is_cs_set(m5)) {
16564       const IROp ops[] = { Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8,
16565                            Iop_QNarrowBin64Uto32Ux4 };
16566       Char index = m4 - 1;
16567       vassert((index >= 0) && (index < sizeof(ops) / sizeof(ops[0])));
16568       put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3)));
16569 
16570    } else {
16571       IRDirty* d;
16572       IRTemp cc = newTemp(Ity_I64);
16573 
16574       s390x_vec_op_details_t details = { .serialized = 0ULL };
16575       details.op = S390_VEC_OP_VPKLS;
16576       details.v1 = v1;
16577       details.v2 = v2;
16578       details.v3 = v3;
16579       details.m4 = m4;
16580       details.m5 = m5;
16581 
16582       d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
16583                             &s390x_dirtyhelper_vec_op,
16584                             mkIRExprVec_2(IRExpr_GSPTR(),
16585                                           mkU64(details.serialized)));
16586 
16587       d->nFxState = 3;
16588       vex_bzero(&d->fxState, sizeof(d->fxState));
16589       d->fxState[0].fx     = Ifx_Read;
16590       d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
16591       d->fxState[0].size   = sizeof(V128);
16592       d->fxState[1].fx     = Ifx_Read;
16593       d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
16594       d->fxState[1].size   = sizeof(V128);
16595       d->fxState[2].fx     = Ifx_Write;
16596       d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
16597       d->fxState[2].size   = sizeof(V128);
16598 
16599       stmt(IRStmt_Dirty(d));
16600       s390_cc_set(cc);
16601    }
16602 
16603    return "vpkls";
16604 }
16605 
16606 static const HChar *
16607 s390_irgen_VSEL(UChar v1, UChar v2, UChar v3, UChar v4)
16608 {
16609    IRExpr* vIfTrue = get_vr_qw(v2);
16610    IRExpr* vIfFalse = get_vr_qw(v3);
16611    IRExpr* vCond = get_vr_qw(v4);
16612 
16613    put_vr_qw(v1, s390_V128_bitwiseITE(vCond, vIfTrue, vIfFalse));
16614    return "vsel";
16615 }
16616 
16617 static const HChar *
16618 s390_irgen_VLBB(UChar v1, IRTemp addr, UChar m3)
16619 {
16620    IRExpr* maxIndex = binop(Iop_Sub32,
16621                             s390_getCountToBlockBoundary(addr, m3),
16622                             mkU32(1));
16623 
16624    s390_vr_loadWithLength(v1, addr, maxIndex);
16625 
16626    return "vlbb";
16627 }
16628 
16629 static const HChar *
16630 s390_irgen_VLL(UChar v1, IRTemp addr, UChar r3)
16631 {
16632    s390_vr_loadWithLength(v1, addr, get_gpr_w1(r3));
16633 
16634    return "vll";
16635 }
16636 
16637 static const HChar *
16638 s390_irgen_VSTL(UChar v1, IRTemp addr, UChar r3)
16639 {
16640    IRTemp counter = newTemp(Ity_I64);
16641    IRTemp maxIndexToStore = newTemp(Ity_I64);
16642    IRTemp gpr3 = newTemp(Ity_I64);
16643 
16644    assign(gpr3, unop(Iop_32Uto64, get_gpr_w1(r3)));
16645    assign(maxIndexToStore, mkite(binop(Iop_CmpLE64U,
16646                                        mkexpr(gpr3),
16647                                        mkU64(16)
16648                                        ),
16649                                  mkexpr(gpr3),
16650                                  mkU64(16)
16651                                  )
16652          );
16653 
16654    assign(counter, get_counter_dw0());
16655 
16656    store(binop(Iop_Add64, mkexpr(addr), mkexpr(counter)),
16657          binop(Iop_GetElem8x16, get_vr_qw(v1), unop(Iop_64to8, mkexpr(counter))));
16658 
16659    /* Check for end of field */
16660    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
16661    iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(maxIndexToStore)));
16662    put_counter_dw0(mkU64(0));
16663 
16664    return "vstl";
16665 }
16666 
16667 static const HChar *
16668 s390_irgen_VX(UChar v1, UChar v2, UChar v3)
16669 {
16670    put_vr_qw(v1, binop(Iop_XorV128, get_vr_qw(v2), get_vr_qw(v3)));
16671 
16672    return "vx";
16673 }
16674 
16675 static const HChar *
16676 s390_irgen_VN(UChar v1, UChar v2, UChar v3)
16677 {
16678    put_vr_qw(v1, binop(Iop_AndV128, get_vr_qw(v2), get_vr_qw(v3)));
16679 
16680    return "vn";
16681 }
16682 
16683 static const HChar *
16684 s390_irgen_VO(UChar v1, UChar v2, UChar v3)
16685 {
16686    put_vr_qw(v1, binop(Iop_OrV128, get_vr_qw(v2), get_vr_qw(v3)));
16687 
16688    return "vo";
16689 }
16690 
16691 static const HChar *
16692 s390_irgen_VNO(UChar v1, UChar v2, UChar v3)
16693 {
16694    put_vr_qw(v1, unop(Iop_NotV128,
16695                       binop(Iop_OrV128, get_vr_qw(v2), get_vr_qw(v3))));
16696 
16697    return "vno";
16698 }
16699 
16700 static const HChar *
16701 s390_irgen_LZRF(UChar r1, IRTemp op2addr)
16702 {
16703    IRTemp op2 = newTemp(Ity_I32);
16704 
16705    assign(op2, binop(Iop_And32, load(Ity_I32, mkexpr(op2addr)), mkU32(0xffffff00)));
16706    put_gpr_w1(r1, mkexpr(op2));
16707 
16708    return "lzrf";
16709 }
16710 
16711 static const HChar *
16712 s390_irgen_LZRG(UChar r1, IRTemp op2addr)
16713 {
16714    IRTemp op2 = newTemp(Ity_I64);
16715 
16716    assign(op2, binop(Iop_And64, load(Ity_I64, mkexpr(op2addr)), mkU64(0xffffffffffffff00UL)));
16717    put_gpr_dw0(r1, mkexpr(op2));
16718 
16719    return "lzrg";
16720 }
16721 
16722 static const HChar *
16723 s390_irgen_LLZRGF(UChar r1, IRTemp op2addr)
16724 {
16725    IRTemp op2 = newTemp(Ity_I32);
16726 
16727    assign(op2, binop(Iop_And32, load(Ity_I32, mkexpr(op2addr)), mkU32(0xffffff00)));
16728    put_gpr_w1(r1, mkexpr(op2));
16729    put_gpr_w0(r1, mkU32(0));
16730 
16731    return "llzrgf";
16732 }
16733 
16734 static const HChar *
16735 s390_irgen_LOCFH(UChar r1, IRTemp op2addr)
16736 {
16737    /* condition is checked in format handler */
16738    put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
16739 
16740    return "locfh";
16741 }
16742 
16743 static const HChar *
16744 s390_irgen_LOCFHR(UChar m3, UChar r1, UChar r2)
16745 {
16746    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
16747    put_gpr_w0(r1, get_gpr_w0(r2));
16748 
16749    return "locfhr";
16750 }
16751 
16752 static const HChar *
16753 s390_irgen_LOCHHI(UChar r1, UChar m3, UShort i2, UChar unused)
16754 {
16755    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
16756    put_gpr_w0(r1, mkU32((UInt)(Int)(Short)i2));
16757 
16758    return "lochhi";
16759 }
16760 
16761 static const HChar *
16762 s390_irgen_LOCHI(UChar r1, UChar m3, UShort i2, UChar unused)
16763 {
16764    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
16765    put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
16766 
16767    return "lochi";
16768 }
16769 
16770 static const HChar *
16771 s390_irgen_LOCGHI(UChar r1, UChar m3, UShort i2, UChar unused)
16772 {
16773    next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
16774    put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
16775 
16776    return "locghi";
16777 }
16778 
16779 static const HChar *
16780 s390_irgen_STOCFH(UChar r1, IRTemp op2addr)
16781 {
16782    /* condition is checked in format handler */
16783    store(mkexpr(op2addr), get_gpr_w1(r1));
16784 
16785    return "stocfh";
16786 }
16787 
16788 static const HChar *
16789 s390_irgen_LCBB(UChar r1, IRTemp op2addr, UChar m3)
16790 {
16791    IRTemp op2 = newTemp(Ity_I32);
16792    assign(op2, s390_getCountToBlockBoundary(op2addr, m3));
16793    put_gpr_w1(r1, mkexpr(op2));
16794 
16795    IRExpr* cc = mkite(binop(Iop_CmpEQ32, mkexpr(op2), mkU32(16)), mkU64(0), mkU64(3));
16796    s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), cc, mkU64(0), mkU64(0));
16797 
16798    return "lcbb";
16799 }
16800 
16801 /* Regarding the use of
16802    // Dummy helper which is used to signal VEX library that memory was loaded
16803    sha512_loadparam
16804      = unsafeIRDirty_0_N(0, "s390x_dirtyhelper_PPNO_sha512_load_param_block",
16805                              &s390x_dirtyhelper_PPNO_sha512_load_param_block,
16806                              mkIRExprVec_0());
16807 
16808    in the following function (s390_irgen_PPNO).  This is a workaround to get
16809    around the fact that IRDirty annotations cannot indicate two memory side
16810    effects, which are unfortunately necessary here.  It will possibly lead to
16811    losing undefinedness (undefinedness in some inputs might not be propagated
16812    to the outputs as it shouod, in Memcheck).  The correct fix would be to
16813    extend IRDirty to represent two memory side effects, but that's quite a bit
16814    of work.
16815 
16816    Here's a summary of what this insn does.
16817 
16818    // getReg(RegisterNumber n) returns the value of GPR number 'n'
16819 
16820    // reg1 and reg2 are even
16821    void ppno(RegisterNumber reg1, RegisterNumber reg2) {
16822 
16823        switch(getReg(0)) {
16824        case 0x0:
16825            // Query mode, ignore reg1 and reg2
16826            // Write 16 bytes                    at  getReg(1)
16827            break;
16828 
16829        case 0x3:
16830            // SHA-512 generate mode, ignore reg2
16831 
16832            // Read 240 bytes                    at  getReg(1)
16833            // Write getReg(reg1 + 1) bytes      at  getReg(reg1)
16834            // Write some of 240 bytes starting  at  getReg(1)
16835            break;
16836 
16837        case 0x83:
16838            // SHA-512 seed mode, ignore reg1
16839 
16840            // Read some of 240 bytes starting  at  getReg(1)
16841            // Read getReg(reg2 + 1) bytes      at  getReg(reg2)
16842            // Write 240 bytes                  at  getReg(1)
16843            break;
16844 
16845        default:
16846            // Specification exception, abort execution.
16847        }
16848    }
16849 */
16850 /* Also known as "prno"
16851    If you implement new functions please don't forget to update
16852    "s390x_dirtyhelper_PPNO_query" function.
16853  */
16854 static const HChar *
16855 s390_irgen_PPNO(UChar r1, UChar r2)
16856 {
16857    if (!s390_host_has_msa5) {
16858       emulation_failure(EmFail_S390X_ppno);
16859       return "ppno";
16860    }
16861 
16862    /* Theese conditions lead to specification exception */
16863    vassert(r1 % 2 == 0);
16864    vassert(r2 % 2 == 0);
16865    vassert((r1 != 0) && (r2 != 0));
16866 
16867    IRDirty *query, *sha512_gen, *sha512_seed, *sha512_loadparam;
16868    IRTemp gpr1num = newTemp(Ity_I64);
16869    IRTemp gpr2num = newTemp(Ity_I64);
16870 
16871    IRTemp funcCode = newTemp(Ity_I8);
16872    IRTemp is_query = newTemp(Ity_I1);
16873    IRTemp is_sha512_gen = newTemp(Ity_I1);
16874    IRTemp is_sha512_seed = newTemp(Ity_I1);
16875    IRTemp is_sha512 = newTemp(Ity_I1);
16876 
16877    assign(funcCode, unop(Iop_64to8, binop(Iop_And64, get_gpr_dw0(0),
16878                                           mkU64(0xffULL))));
16879    assign(gpr1num, mkU64(r1));
16880    assign(gpr2num, mkU64(r2));
16881 
16882    assign(is_query, binop(Iop_CmpEQ8, mkexpr(funcCode), mkU8(S390_PPNO_QUERY)));
16883    assign(is_sha512_gen, binop(Iop_CmpEQ8, mkexpr(funcCode),
16884                                mkU8(S390_PPNO_SHA512_GEN)));
16885    assign(is_sha512_seed, binop(Iop_CmpEQ8, mkexpr(funcCode),
16886                                 mkU8(S390_PPNO_SHA512_SEED)));
16887    assign(is_sha512, binop(Iop_CmpEQ8,
16888                            mkU8(S390_PPNO_SHA512_GEN),
16889                            binop(Iop_And8,
16890                                  mkexpr(funcCode),
16891                                  mkU8(S390_PPNO_SHA512_GEN)
16892                                  )
16893                            ));
16894 
16895    query = unsafeIRDirty_0_N(0, "s390x_dirtyhelper_PPNO_query",
16896                              &s390x_dirtyhelper_PPNO_query,
16897                              mkIRExprVec_3(IRExpr_GSPTR(), mkexpr(gpr1num),
16898                                            mkexpr(gpr2num)));
16899    query->guard = mkexpr(is_query);
16900    query->nFxState = 1;
16901    vex_bzero(&query->fxState, sizeof(query->fxState));
16902    query->fxState[0].fx     = Ifx_Read;
16903    query->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
16904    query->fxState[0].size   = 2 * sizeof(ULong); /* gpr0 and gpr1 are read */
16905    query->mAddr = get_gpr_dw0(1);
16906    query->mSize = S390_PPNO_PARAM_BLOCK_SIZE_QUERY;
16907    query->mFx   = Ifx_Write;
16908 
16909    IRTemp gen_cc = newTemp(Ity_I64);
16910    sha512_gen = unsafeIRDirty_1_N(gen_cc, 0, "s390x_dirtyhelper_PPNO_sha512",
16911                              &s390x_dirtyhelper_PPNO_sha512,
16912                              mkIRExprVec_3(IRExpr_GSPTR(), mkexpr(gpr1num),
16913                                            mkexpr(gpr2num)));
16914    sha512_gen->guard = mkexpr(is_sha512_gen);
16915    sha512_gen->nFxState = 3;
16916    vex_bzero(&sha512_gen->fxState, sizeof(sha512_gen->fxState));
16917    sha512_gen->fxState[0].fx     = Ifx_Read;
16918    sha512_gen->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
16919    sha512_gen->fxState[0].size   = 2 * sizeof(ULong); /* gpr0 and gpr1 are read */
16920    sha512_gen->fxState[1].fx     = Ifx_Read;
16921    sha512_gen->fxState[1].offset = S390X_GUEST_OFFSET(guest_r0) + r1 * sizeof(ULong);
16922    sha512_gen->fxState[1].size   = sizeof(ULong);
16923    sha512_gen->fxState[2].fx     = Ifx_Modify;
16924    sha512_gen->fxState[2].offset = S390X_GUEST_OFFSET(guest_r0) + (r1 + 1) * sizeof(ULong);
16925    sha512_gen->fxState[2].size   = sizeof(ULong);
16926    sha512_gen->mAddr = get_gpr_dw0(r1);
16927    sha512_gen->mSize = S390_PPNO_MAX_SIZE_SHA512_GEN;
16928    sha512_gen->mFx   = Ifx_Write;
16929 
16930    IRTemp unused = newTemp(Ity_I64);
16931    sha512_seed = unsafeIRDirty_1_N(unused, 0, "s390x_dirtyhelper_PPNO_sha512",
16932                              &s390x_dirtyhelper_PPNO_sha512,
16933                              mkIRExprVec_3(IRExpr_GSPTR(), mkexpr(gpr1num),
16934                                            mkexpr(gpr2num)));
16935    sha512_seed->guard = mkexpr(is_sha512_seed);
16936    sha512_seed->nFxState = 2;
16937    vex_bzero(&sha512_seed->fxState, sizeof(sha512_seed->fxState));
16938    sha512_seed->fxState[0].fx     = Ifx_Read;
16939    sha512_seed->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
16940    sha512_seed->fxState[0].size   = 2 * sizeof(ULong); /* gpr0 and gpr1 are read */
16941    sha512_seed->fxState[1].fx     = Ifx_Read;
16942    sha512_seed->fxState[1].offset = S390X_GUEST_OFFSET(guest_r0) + r2 * sizeof(ULong);
16943    sha512_seed->fxState[1].size   = 2 * sizeof(ULong); /* r2 and r2 + 1 are read */
16944    sha512_seed->mAddr = get_gpr_dw0(r2);
16945    sha512_seed->mSize = S390_PPNO_MAX_SIZE_SHA512_SEED;
16946    sha512_seed->mFx   = Ifx_Write;
16947 
16948    /* Dummy helper which is used to signal VEX library that memory was loaded */
16949    sha512_loadparam =
16950       unsafeIRDirty_0_N(0, "s390x_dirtyhelper_PPNO_sha512_load_param_block",
16951                         &s390x_dirtyhelper_PPNO_sha512_load_param_block,
16952                         mkIRExprVec_0());
16953    sha512_loadparam->guard = mkexpr(is_sha512);
16954    sha512_loadparam->nFxState = 0;
16955    vex_bzero(&sha512_loadparam->fxState, sizeof(sha512_loadparam->fxState));
16956    sha512_loadparam->mAddr = get_gpr_dw0(1);
16957    sha512_loadparam->mSize = S390_PPNO_PARAM_BLOCK_SIZE_SHA512;
16958    sha512_loadparam->mFx   = Ifx_Read;
16959 
16960    IRDirty* sha512_saveparam =
16961       unsafeIRDirty_0_N(0, "s390x_dirtyhelper_PPNO_sha512_save_param_block",
16962                         &s390x_dirtyhelper_PPNO_sha512_load_param_block,
16963                         mkIRExprVec_0());
16964    sha512_saveparam->guard = mkexpr(is_sha512);
16965    sha512_saveparam->nFxState = 0;
16966    vex_bzero(&sha512_saveparam->fxState, sizeof(sha512_saveparam->fxState));
16967    sha512_saveparam->mAddr = get_gpr_dw0(1);
16968    sha512_saveparam->mSize = S390_PPNO_PARAM_BLOCK_SIZE_SHA512;
16969    sha512_saveparam->mFx   = Ifx_Write;
16970 
16971    stmt(IRStmt_Dirty(query));
16972    stmt(IRStmt_Dirty(sha512_loadparam));
16973    stmt(IRStmt_Dirty(sha512_gen));
16974    stmt(IRStmt_Dirty(sha512_seed));
16975    stmt(IRStmt_Dirty(sha512_saveparam));
16976 
16977    IRTemp cc = newTemp(Ity_I64);
16978    assign(cc,
16979           mkite(mkexpr(is_sha512_gen),
16980                 mkexpr(gen_cc),
16981                 mkU64(0)
16982                )
16983          );
16984 
16985    s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
16986 
16987    return "ppno";
16988 }
16989 
16990 static const HChar *
16991 s390_irgen_VFAE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
16992 {
16993    IRDirty* d;
16994    IRTemp cc = newTemp(Ity_I64);
16995 
16996    /* Check for specification exception */
16997    vassert(m4 < 3);
16998 
16999    s390x_vec_op_details_t details = { .serialized = 0ULL };
17000    details.op = S390_VEC_OP_VFAE;
17001    details.v1 = v1;
17002    details.v2 = v2;
17003    details.v3 = v3;
17004    details.m4 = m4;
17005    details.m5 = m5;
17006 
17007    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17008                          &s390x_dirtyhelper_vec_op,
17009                          mkIRExprVec_2(IRExpr_GSPTR(),
17010                                        mkU64(details.serialized)));
17011 
17012    d->nFxState = 3;
17013    vex_bzero(&d->fxState, sizeof(d->fxState));
17014    d->fxState[0].fx     = Ifx_Read;
17015    d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17016    d->fxState[0].size   = sizeof(V128);
17017    d->fxState[1].fx     = Ifx_Read;
17018    d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17019    d->fxState[1].size   = sizeof(V128);
17020    d->fxState[2].fx     = Ifx_Write;
17021    d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17022    d->fxState[2].size   = sizeof(V128);
17023 
17024    stmt(IRStmt_Dirty(d));
17025 
17026    if (s390_vr_is_cs_set(m5)) {
17027       s390_cc_set(cc);
17028    }
17029 
17030    return "vfae";
17031 }
17032 
17033 static const HChar *
17034 s390_irgen_VFEE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17035 {
17036    IRDirty* d;
17037    IRTemp cc = newTemp(Ity_I64);
17038 
17039    /* Check for specification exception */
17040    vassert(m4 < 3);
17041    vassert((m5 & 0b1100) == 0);
17042 
17043    s390x_vec_op_details_t details = { .serialized = 0ULL };
17044    details.op = S390_VEC_OP_VFEE;
17045    details.v1 = v1;
17046    details.v2 = v2;
17047    details.v3 = v3;
17048    details.m4 = m4;
17049    details.m5 = m5;
17050 
17051    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17052                          &s390x_dirtyhelper_vec_op,
17053                          mkIRExprVec_2(IRExpr_GSPTR(),
17054                                        mkU64(details.serialized)));
17055 
17056    d->nFxState = 3;
17057    vex_bzero(&d->fxState, sizeof(d->fxState));
17058    d->fxState[0].fx     = Ifx_Read;
17059    d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17060    d->fxState[0].size   = sizeof(V128);
17061    d->fxState[1].fx     = Ifx_Read;
17062    d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17063    d->fxState[1].size   = sizeof(V128);
17064    d->fxState[2].fx     = Ifx_Write;
17065    d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17066    d->fxState[2].size   = sizeof(V128);
17067 
17068    stmt(IRStmt_Dirty(d));
17069 
17070    if (s390_vr_is_cs_set(m5)) {
17071       s390_cc_set(cc);
17072    }
17073 
17074    return "vfee";
17075 }
17076 
17077 static const HChar *
17078 s390_irgen_VFENE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17079 {
17080    const Bool negateComparison = True;
17081    const IRType type = s390_vr_get_type(m4);
17082 
17083    /* Check for specification exception */
17084    vassert(m4 < 3);
17085    vassert((m5 & 0b1100) == 0);
17086 
17087    static const IROp elementGetters[] = {
17088       Iop_GetElem8x16, Iop_GetElem16x8, Iop_GetElem32x4
17089    };
17090    IROp getter = elementGetters[m4];
17091 
17092    static const IROp elementComparators[] = {
17093       Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32
17094    };
17095    IROp comparator = elementComparators[m4];
17096 
17097    static const IROp resultConverter[] = {Iop_64to8, Iop_64to16, Iop_64to32};
17098    IROp converter = resultConverter[m4];
17099 
17100    IRTemp isZeroElem;
17101 
17102    IRTemp counter = newTemp(Ity_I64);
17103    assign(counter, get_counter_dw0());
17104 
17105    IRTemp arg1 = newTemp(type);
17106    assign(arg1, binop(getter, get_vr_qw(v2), unop(Iop_64to8, mkexpr(counter))));
17107    IRTemp arg2 = newTemp(type);
17108    assign(arg2, binop(getter, get_vr_qw(v3), unop(Iop_64to8, mkexpr(counter))));
17109 
17110    IRTemp isGoodPair = newTemp(Ity_I1);
17111    if(negateComparison) {
17112       assign(isGoodPair, unop(Iop_Not1, binop(comparator, mkexpr(arg1),
17113                                               mkexpr(arg2))));
17114    } else {
17115       assign(isGoodPair, binop(comparator, mkexpr(arg1), mkexpr(arg2)));
17116    }
17117 
17118    if(s390_vr_is_zs_set(m5)) {
17119       isZeroElem = newTemp(Ity_I1);
17120       assign(isZeroElem, binop(comparator, mkexpr(arg1),
17121                                unop(converter, mkU64(0))));
17122    }
17123 
17124    static const UChar invalidIndices[] = {16, 8, 4};
17125    const UChar invalidIndex = invalidIndices[m4];
17126    IRTemp endOfVectorIsReached = newTemp(Ity_I1);
17127    assign(endOfVectorIsReached, binop(Iop_CmpEQ64, mkexpr(counter),
17128                                       mkU64(invalidIndex)));
17129 
17130    put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
17131    IRExpr* shouldBreak = binop(Iop_Or32,
17132                                unop(Iop_1Uto32, mkexpr(isGoodPair)),
17133                                unop(Iop_1Uto32, mkexpr(endOfVectorIsReached))
17134                               );
17135    if(s390_vr_is_zs_set(m5)) {
17136       shouldBreak = binop(Iop_Or32,
17137                           shouldBreak,
17138                           unop(Iop_1Uto32, mkexpr(isZeroElem)));
17139    }
17140    iterate_if(binop(Iop_CmpEQ32, shouldBreak, mkU32(0)));
17141 
17142    IRExpr* foundIndex = binop(Iop_Sub64, get_counter_dw0(), mkU64(1));
17143    if(m4 > 0) {
17144       /* We should return index of byte but we found index of element in
17145          general case.
17146             if byte elem (m4 == 0) then indexOfByte = indexOfElement
17147             if halfword elem (m4 == 1) then indexOfByte = 2 * indexOfElement
17148                                                         = indexOfElement << 1
17149             if word elem (m4 == 2) then indexOfByte = 4 * indexOfElement
17150                                                     = indexOfElement << 2
17151       */
17152       foundIndex = binop(Iop_Shl64, foundIndex, mkU8(m4));
17153    }
17154 
17155    IRTemp result = newTemp(Ity_I64);
17156    assign(result, mkite(mkexpr(endOfVectorIsReached),
17157                         mkU64(16),
17158                         foundIndex));
17159    put_vr_qw(v1, binop(Iop_64HLtoV128, mkexpr(result), mkU64(0)));
17160 
17161 
17162    if (s390_vr_is_cs_set(m5)) {
17163       static const IROp to64Converters[] = {Iop_8Uto64, Iop_16Uto64, Iop_32Uto64};
17164       IROp to64Converter = to64Converters[m4];
17165 
17166       IRExpr* arg1IsLessThanArg2 = binop(Iop_CmpLT64U,
17167                                          unop(to64Converter, mkexpr(arg1)),
17168                                          unop(to64Converter, mkexpr(arg2)));
17169 
17170       IRExpr* ccexp = mkite(binop(Iop_CmpEQ32,
17171                                   unop(Iop_1Uto32, mkexpr(isGoodPair)),
17172                                   mkU32(1)),
17173                             mkite(arg1IsLessThanArg2, mkU64(1), mkU64(2)),
17174                             mkU64(3));
17175 
17176       if(s390_vr_is_zs_set(m5)) {
17177          IRExpr* arg2IsZero = binop(comparator, mkexpr(arg2),
17178                                     unop(converter, mkU64(0)));
17179          IRExpr* bothArgsAreZero = binop(Iop_And32,
17180                                          unop(Iop_1Uto32, mkexpr(isZeroElem)),
17181                                          unop(Iop_1Uto32, arg2IsZero));
17182          ccexp = mkite(binop(Iop_CmpEQ32, bothArgsAreZero, mkU32(1)),
17183                        mkU64(0),
17184                        ccexp);
17185       }
17186       IRTemp cc = newTemp(Ity_I64);
17187       assign(cc, ccexp);
17188 
17189       s390_cc_set(cc);
17190    }
17191 
17192 
17193    put_counter_dw0(mkU64(0));
17194    return "vfene";
17195 }
17196 
17197 static const HChar *
17198 s390_irgen_VISTR(UChar v1, UChar v2, UChar m3, UChar m5)
17199 {
17200    IRDirty* d;
17201    IRTemp cc = newTemp(Ity_I64);
17202 
17203    /* Check for specification exception */
17204    vassert(m3 < 3);
17205    vassert((m5 & 0b1110) == 0);
17206 
17207    s390x_vec_op_details_t details = { .serialized = 0ULL };
17208    details.op = S390_VEC_OP_VISTR;
17209    details.v1 = v1;
17210    details.v2 = v2;
17211    details.m4 = m3;
17212    details.m5 = m5;
17213 
17214    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17215                          &s390x_dirtyhelper_vec_op,
17216                          mkIRExprVec_2(IRExpr_GSPTR(),
17217                                        mkU64(details.serialized)));
17218 
17219    d->nFxState = 2;
17220    vex_bzero(&d->fxState, sizeof(d->fxState));
17221    d->fxState[0].fx     = Ifx_Read;
17222    d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17223    d->fxState[0].size   = sizeof(V128);
17224    d->fxState[1].fx     = Ifx_Write;
17225    d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17226    d->fxState[1].size   = sizeof(V128);
17227 
17228    stmt(IRStmt_Dirty(d));
17229 
17230    if (s390_vr_is_cs_set(m5)) {
17231       s390_cc_set(cc);
17232    }
17233 
17234    return "vistr";
17235 }
17236 
17237 static const HChar *
17238 s390_irgen_VSTRC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
17239 {
17240    IRDirty* d;
17241    IRTemp cc = newTemp(Ity_I64);
17242 
17243    /* Check for specification exception */
17244    vassert(m5 < 3);
17245 
17246    s390x_vec_op_details_t details = { .serialized = 0ULL };
17247    details.op = S390_VEC_OP_VSTRC;
17248    details.v1 = v1;
17249    details.v2 = v2;
17250    details.v3 = v3;
17251    details.v4 = v4;
17252    details.m4 = m5;
17253    details.m5 = m6;
17254 
17255    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17256                          &s390x_dirtyhelper_vec_op,
17257                          mkIRExprVec_2(IRExpr_GSPTR(),
17258                                        mkU64(details.serialized)));
17259 
17260    d->nFxState = 4;
17261    vex_bzero(&d->fxState, sizeof(d->fxState));
17262    d->fxState[0].fx     = Ifx_Read;
17263    d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17264    d->fxState[0].size   = sizeof(V128);
17265    d->fxState[1].fx     = Ifx_Read;
17266    d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17267    d->fxState[1].size   = sizeof(V128);
17268    d->fxState[2].fx     = Ifx_Read;
17269    d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128);
17270    d->fxState[2].size   = sizeof(V128);
17271    d->fxState[3].fx     = Ifx_Write;
17272    d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17273    d->fxState[3].size   = sizeof(V128);
17274 
17275    stmt(IRStmt_Dirty(d));
17276 
17277    if (s390_vr_is_cs_set(m6)) {
17278       s390_cc_set(cc);
17279    }
17280 
17281    return "vstrc";
17282 }
17283 
17284 static const HChar *
17285 s390_irgen_VNC(UChar v1, UChar v2, UChar v3)
17286 {
17287    put_vr_qw(v1, binop(Iop_AndV128,
17288              get_vr_qw(v2), unop(Iop_NotV128, get_vr_qw(v3)))
17289              );
17290 
17291    return "vnc";
17292 }
17293 
17294 static const HChar *
17295 s390_irgen_VA(UChar v1, UChar v2, UChar v3, UChar m4)
17296 {
17297    const IROp ops[] = { Iop_Add8x16, Iop_Add16x8, Iop_Add32x4,
17298                         Iop_Add64x2, Iop_Add128x1 };
17299    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17300    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17301 
17302    return "va";
17303 }
17304 
17305 static const HChar *
17306 s390_irgen_VS(UChar v1, UChar v2, UChar v3, UChar m4)
17307 {
17308    const IROp ops[] = { Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4,
17309                         Iop_Sub64x2, Iop_Sub128x1 };
17310    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17311    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17312 
17313    return "vs";
17314 }
17315 
17316 static const HChar *
17317 s390_irgen_VMX(UChar v1, UChar v2, UChar v3, UChar m4)
17318 {
17319    const IROp ops[] = { Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4, Iop_Max64Sx2 };
17320    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17321    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17322 
17323    return "vmx";
17324 }
17325 
17326 static const HChar *
17327 s390_irgen_VMXL(UChar v1, UChar v2, UChar v3, UChar m4)
17328 {
17329    const IROp ops[] = { Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4, Iop_Max64Ux2 };
17330    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17331    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17332 
17333    return "vmxl";
17334 }
17335 
17336 static const HChar *
17337 s390_irgen_VMN(UChar v1, UChar v2, UChar v3, UChar m4)
17338 {
17339    const IROp ops[] = { Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4, Iop_Min64Sx2 };
17340    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17341    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17342 
17343    return "vmn";
17344 }
17345 
17346 static const HChar *
17347 s390_irgen_VMNL(UChar v1, UChar v2, UChar v3, UChar m4)
17348 {
17349    const IROp ops[] = { Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4, Iop_Min64Ux2 };
17350    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17351    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17352 
17353    return "vmnl";
17354 }
17355 
17356 static const HChar *
17357 s390_irgen_VAVG(UChar v1, UChar v2, UChar v3, UChar m4)
17358 {
17359    const IROp ops[] = { Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4, Iop_Avg64Sx2 };
17360    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17361    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17362 
17363    return "vavg";
17364 }
17365 
17366 static const HChar *
17367 s390_irgen_VAVGL(UChar v1, UChar v2, UChar v3, UChar m4)
17368 {
17369    const IROp ops[] = { Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4, Iop_Avg64Ux2 };
17370    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17371    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17372 
17373    return "vavgl";
17374 }
17375 
17376 static const HChar *
17377 s390_irgen_VLC(UChar v1, UChar v2, UChar m3)
17378 {
17379    vassert(m3 < 4);
17380    IRType type = s390_vr_get_type(m3);
17381    put_vr_qw(v1, s390_V128_get_complement(get_vr_qw(v2), type));
17382    return "vlc";
17383 }
17384 
17385 static const HChar *
17386 s390_irgen_VLP(UChar v1, UChar v2, UChar m3)
17387 {
17388    const IROp ops[] = { Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4, Iop_Abs64x2 };
17389    vassert(m3 < sizeof(ops) / sizeof(ops[0]));
17390    put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2)));
17391 
17392    return "vlp";
17393 }
17394 
17395 static const HChar *
17396 s390_irgen_VCH(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17397 {
17398    if (!s390_vr_is_cs_set(m5)) {
17399       const IROp ops[] = { Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4,
17400                            Iop_CmpGT64Sx2 };
17401       vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17402       put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17403 
17404    } else {
17405       IRDirty* d;
17406       IRTemp cc = newTemp(Ity_I64);
17407 
17408       s390x_vec_op_details_t details = { .serialized = 0ULL };
17409       details.op = S390_VEC_OP_VCH;
17410       details.v1 = v1;
17411       details.v2 = v2;
17412       details.v3 = v3;
17413       details.m4 = m4;
17414       details.m5 = m5;
17415 
17416       d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17417                             &s390x_dirtyhelper_vec_op,
17418                             mkIRExprVec_2(IRExpr_GSPTR(),
17419                                           mkU64(details.serialized)));
17420 
17421       d->nFxState = 3;
17422       vex_bzero(&d->fxState, sizeof(d->fxState));
17423       d->fxState[0].fx     = Ifx_Read;
17424       d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17425       d->fxState[0].size   = sizeof(V128);
17426       d->fxState[1].fx     = Ifx_Read;
17427       d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17428       d->fxState[1].size   = sizeof(V128);
17429       d->fxState[2].fx     = Ifx_Write;
17430       d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17431       d->fxState[2].size   = sizeof(V128);
17432 
17433       stmt(IRStmt_Dirty(d));
17434       s390_cc_set(cc);
17435    }
17436 
17437    return "vch";
17438 }
17439 
17440 static const HChar *
17441 s390_irgen_VCHL(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17442 {
17443    if (!s390_vr_is_cs_set(m5)) {
17444       const IROp ops[] = { Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4,
17445                            Iop_CmpGT64Ux2 };
17446       vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17447       put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17448 
17449    } else {
17450       IRDirty* d;
17451       IRTemp cc = newTemp(Ity_I64);
17452 
17453       s390x_vec_op_details_t details = { .serialized = 0ULL };
17454       details.op = S390_VEC_OP_VCHL;
17455       details.v1 = v1;
17456       details.v2 = v2;
17457       details.v3 = v3;
17458       details.m4 = m4;
17459       details.m5 = m5;
17460 
17461       d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17462                             &s390x_dirtyhelper_vec_op,
17463                             mkIRExprVec_2(IRExpr_GSPTR(),
17464                                           mkU64(details.serialized)));
17465 
17466       d->nFxState = 3;
17467       vex_bzero(&d->fxState, sizeof(d->fxState));
17468       d->fxState[0].fx     = Ifx_Read;
17469       d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17470       d->fxState[0].size   = sizeof(V128);
17471       d->fxState[1].fx     = Ifx_Read;
17472       d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17473       d->fxState[1].size   = sizeof(V128);
17474       d->fxState[2].fx     = Ifx_Write;
17475       d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17476       d->fxState[2].size   = sizeof(V128);
17477 
17478       stmt(IRStmt_Dirty(d));
17479       s390_cc_set(cc);
17480    }
17481 
17482    return "vchl";
17483 }
17484 
17485 static const HChar *
17486 s390_irgen_VCLZ(UChar v1, UChar v2, UChar m3)
17487 {
17488    const IROp ops[] = { Iop_Clz8x16, Iop_Clz16x8, Iop_Clz32x4, Iop_Clz64x2 };
17489    vassert(m3 < sizeof(ops) / sizeof(ops[0]));
17490    put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2)));
17491 
17492    return "vclz";
17493 }
17494 
17495 static const HChar *
17496 s390_irgen_VCTZ(UChar v1, UChar v2, UChar m3)
17497 {
17498    const IROp ops[] = { Iop_Ctz8x16, Iop_Ctz16x8, Iop_Ctz32x4, Iop_Ctz64x2 };
17499    vassert(m3 < sizeof(ops) / sizeof(ops[0]));
17500    put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2)));
17501 
17502    return "vctz";
17503 }
17504 
17505 static const HChar *
17506 s390_irgen_VPOPCT(UChar v1, UChar v2, UChar m3)
17507 {
17508    vassert(m3 == 0);
17509 
17510    put_vr_qw(v1, unop(Iop_Cnt8x16, get_vr_qw(v2)));
17511 
17512    return "vpopct";
17513 }
17514 
17515 static const HChar *
17516 s390_irgen_VML(UChar v1, UChar v2, UChar v3, UChar m4)
17517 {
17518    const IROp ops[] = { Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4 };
17519    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17520    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17521 
17522    return "vml";
17523 }
17524 
17525 static const HChar *
17526 s390_irgen_VMLH(UChar v1, UChar v2, UChar v3, UChar m4)
17527 {
17528    const IROp ops[] = { Iop_MulHi8Ux16, Iop_MulHi16Ux8, Iop_MulHi32Ux4 };
17529    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17530    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17531 
17532    return "vmlh";
17533 }
17534 
17535 static const HChar *
17536 s390_irgen_VMH(UChar v1, UChar v2, UChar v3, UChar m4)
17537 {
17538    const IROp ops[] = { Iop_MulHi8Sx16, Iop_MulHi16Sx8, Iop_MulHi32Sx4 };
17539    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17540    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17541 
17542    return "vmh";
17543 }
17544 
17545 static const HChar *
17546 s390_irgen_VME(UChar v1, UChar v2, UChar v3, UChar m4)
17547 {
17548    const IROp ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4 };
17549    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17550    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17551 
17552    return "vme";
17553 }
17554 
17555 static const HChar *
17556 s390_irgen_VMLE(UChar v1, UChar v2, UChar v3, UChar m4)
17557 {
17558    const IROp ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4 };
17559    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17560    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17561 
17562    return "vmle";
17563 }
17564 
17565 static const HChar *
17566 s390_irgen_VESLV(UChar v1, UChar v2, UChar v3, UChar m4)
17567 {
17568    const IROp ops[] = { Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2};
17569    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17570    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17571 
17572    return "veslv";
17573 }
17574 
17575 static const HChar *
17576 s390_irgen_VESL(UChar v1, IRTemp op2addr, UChar v3, UChar m4)
17577 {
17578    IRExpr* shift_amount = unop(Iop_64to8, mkexpr(op2addr));
17579    const IROp ops[] = { Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2 };
17580    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17581    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_amount));
17582 
17583    return "vesl";
17584 }
17585 
17586 static const HChar *
17587 s390_irgen_VESRAV(UChar v1, UChar v2, UChar v3, UChar m4)
17588 {
17589    const IROp ops[] = { Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2 };
17590    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17591    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17592 
17593    return "vesrav";
17594 }
17595 
17596 static const HChar *
17597 s390_irgen_VESRA(UChar v1, IRTemp op2addr, UChar v3, UChar m4)
17598 {
17599    IRExpr* shift_amount = unop(Iop_64to8, mkexpr(op2addr));
17600    const IROp ops[] = { Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2 };
17601    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17602    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_amount));
17603 
17604    return "vesra";
17605 }
17606 
17607 static const HChar *
17608 s390_irgen_VESRLV(UChar v1, UChar v2, UChar v3, UChar m4)
17609 {
17610    const IROp ops[] = { Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2 };
17611    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17612    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17613 
17614    return "vesrlv";
17615 }
17616 
17617 static const HChar *
17618 s390_irgen_VESRL(UChar v1, IRTemp op2addr, UChar v3, UChar m4)
17619 {
17620    IRExpr* shift_amount = unop(Iop_64to8, mkexpr(op2addr));
17621    const IROp ops[] = { Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2 };
17622    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17623    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_amount));
17624 
17625    return "vesrl";
17626 }
17627 
17628 static const HChar *
17629 s390_irgen_VERLLV(UChar v1, UChar v2, UChar v3, UChar m4)
17630 {
17631    const IROp ops[] = { Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2 };
17632    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17633    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17634 
17635    return "verllv";
17636 }
17637 
17638 static const HChar *
17639 s390_irgen_VERLL(UChar v1, IRTemp op2addr, UChar v3, UChar m4)
17640 {
17641    /*
17642       There is no Iop_RolN?x?? operations
17643       so we have to use VECTOR x VECTOR variant.
17644     */
17645    IRExpr* shift_vector = unop(Iop_Dup8x16, unop(Iop_64to8, mkexpr(op2addr)));
17646    const IROp ops[] = { Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2 };
17647    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17648    put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_vector));
17649 
17650    return "verll";
17651 }
17652 
17653 static const HChar *
17654 s390_irgen_VSL(UChar v1, UChar v2, UChar v3)
17655 {
17656    IRTemp shift_amount = newTemp(Ity_I8);
17657    assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b00000111)));
17658 
17659    put_vr_qw(v1, binop(Iop_ShlV128, get_vr_qw(v2), mkexpr(shift_amount)));
17660    return "vsl";
17661 }
17662 
17663 static const HChar *
17664 s390_irgen_VSRL(UChar v1, UChar v2, UChar v3)
17665 {
17666    IRTemp shift_amount = newTemp(Ity_I8);
17667    assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b00000111)));
17668 
17669    put_vr_qw(v1, binop(Iop_ShrV128, get_vr_qw(v2), mkexpr(shift_amount)));
17670    return "vsrl";
17671 }
17672 
17673 static const HChar *
17674 s390_irgen_VSRA(UChar v1, UChar v2, UChar v3)
17675 {
17676    IRTemp shift_amount = newTemp(Ity_I8);
17677    assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b00000111)));
17678 
17679    put_vr_qw(v1, binop(Iop_SarV128, get_vr_qw(v2), mkexpr(shift_amount)));
17680    return "vsra";
17681 }
17682 
17683 static const HChar *
17684 s390_irgen_VERIM(UChar v1, UChar v2, UChar v3, UChar i4, UChar m5)
17685 {
17686    /*
17687       There is no Iop_RolN?x?? operations
17688       so we have to use VECTOR x VECTOR variant.
17689     */
17690    const IROp ops[] = { Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2 };
17691    vassert(m5 < sizeof(ops) / sizeof(ops[0]));
17692    IRExpr* shift_vector = unop(Iop_Dup8x16, mkU8(i4));
17693    IRExpr* rotated_vector = binop(ops[m5], get_vr_qw(v2), shift_vector);
17694 
17695    /* result = (result & ~mask) | (rotated_vector & mask) */
17696    IRExpr* mask = get_vr_qw(v3);
17697    IRExpr* result = get_vr_qw(v1);
17698    put_vr_qw(v1, s390_V128_bitwiseITE(mask, rotated_vector, result));
17699 
17700    return "verim";
17701 }
17702 
17703 static const HChar *
17704 s390_irgen_VEC(UChar v1, UChar v2, UChar m3)
17705 {
17706    IRType type = s390_vr_get_type(m3);
17707    IRTemp op1 = newTemp(type);
17708    IRTemp op2 = newTemp(type);
17709 
17710    switch(type) {
17711    case Ity_I8:
17712       assign(op1, get_vr_b7(v1));
17713       assign(op2, get_vr_b7(v2));
17714       break;
17715    case Ity_I16:
17716       assign(op1, get_vr_hw3(v1));
17717       assign(op2, get_vr_hw3(v2));
17718       break;
17719    case Ity_I32:
17720       assign(op1, get_vr_w1(v1));
17721       assign(op2, get_vr_w1(v2));
17722       break;
17723    case Ity_I64:
17724       assign(op1, get_vr_dw0(v1));
17725       assign(op2, get_vr_dw0(v2));
17726       break;
17727    default:
17728       vpanic("s390_irgen_VEC: unknown type");
17729    }
17730 
17731    s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
17732 
17733    return "vec";
17734 }
17735 
17736 static const HChar *
17737 s390_irgen_VECL(UChar v1, UChar v2, UChar m3)
17738 {
17739    IRType type = s390_vr_get_type(m3);
17740    IRTemp op1 = newTemp(type);
17741    IRTemp op2 = newTemp(type);
17742 
17743    switch(type) {
17744    case Ity_I8:
17745       assign(op1, get_vr_b7(v1));
17746       assign(op2, get_vr_b7(v2));
17747       break;
17748    case Ity_I16:
17749       assign(op1, get_vr_hw3(v1));
17750       assign(op2, get_vr_hw3(v2));
17751       break;
17752    case Ity_I32:
17753       assign(op1, get_vr_w1(v1));
17754       assign(op2, get_vr_w1(v2));
17755       break;
17756    case Ity_I64:
17757       assign(op1, get_vr_dw0(v1));
17758       assign(op2, get_vr_dw0(v2));
17759       break;
17760    default:
17761       vpanic("s390_irgen_VECL: unknown type");
17762    }
17763 
17764    s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
17765 
17766    return "vecl";
17767 }
17768 
17769 static const HChar *
17770 s390_irgen_VCEQ(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17771 {
17772    if (!s390_vr_is_cs_set(m5)) {
17773       const IROp ops[] = { Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4,
17774                            Iop_CmpEQ64x2 };
17775       vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17776       put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17777 
17778    } else {
17779       IRDirty* d;
17780       IRTemp cc = newTemp(Ity_I64);
17781 
17782       s390x_vec_op_details_t details = { .serialized = 0ULL };
17783       details.op = S390_VEC_OP_VCEQ;
17784       details.v1 = v1;
17785       details.v2 = v2;
17786       details.v3 = v3;
17787       details.m4 = m4;
17788       details.m5 = m5;
17789 
17790       d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17791                             &s390x_dirtyhelper_vec_op,
17792                             mkIRExprVec_2(IRExpr_GSPTR(),
17793                                           mkU64(details.serialized)));
17794 
17795       d->nFxState = 3;
17796       vex_bzero(&d->fxState, sizeof(d->fxState));
17797       d->fxState[0].fx     = Ifx_Read;
17798       d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17799       d->fxState[0].size   = sizeof(V128);
17800       d->fxState[1].fx     = Ifx_Read;
17801       d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17802       d->fxState[1].size   = sizeof(V128);
17803       d->fxState[2].fx     = Ifx_Write;
17804       d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17805       d->fxState[2].size   = sizeof(V128);
17806 
17807       stmt(IRStmt_Dirty(d));
17808       s390_cc_set(cc);
17809    }
17810 
17811    return "vceq";
17812 }
17813 
17814 static const HChar *
17815 s390_irgen_VSLB(UChar v1, UChar v2, UChar v3)
17816 {
17817    IRTemp shift_amount = newTemp(Ity_I8);
17818    assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b01111000)));
17819 
17820    put_vr_qw(v1, binop(Iop_ShlV128, get_vr_qw(v2), mkexpr(shift_amount)));
17821    return "vslb";
17822 }
17823 
17824 static const HChar *
17825 s390_irgen_VSRLB(UChar v1, UChar v2, UChar v3)
17826 {
17827    IRTemp shift_amount = newTemp(Ity_I8);
17828    assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b01111000)));
17829 
17830    put_vr_qw(v1, binop(Iop_ShrV128, get_vr_qw(v2), mkexpr(shift_amount)));
17831    return "vsrlb";
17832 }
17833 
17834 static const HChar *
17835 s390_irgen_VSRAB(UChar v1, UChar v2, UChar v3)
17836 {
17837    IRTemp shift_amount = newTemp(Ity_I8);
17838    assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b01111000)));
17839 
17840    put_vr_qw(v1, binop(Iop_SarV128, get_vr_qw(v2), mkexpr(shift_amount)));
17841    return "vsrab";
17842 }
17843 
17844 static const HChar *
17845 s390_irgen_VSLDB(UChar v1, UChar v2, UChar v3, UChar i4)
17846 {
17847    UChar imm = i4 & 0b00001111;
17848 
17849    if (imm == 0) {
17850       /* Just copy v2. */
17851       put_vr_qw(v1, get_vr_qw(v2));
17852    } else {
17853       /* Concatenate v2's tail with v3's head. */
17854       put_vr_qw(v1,
17855                 binop(Iop_OrV128,
17856                       binop(Iop_ShlV128, get_vr_qw(v2), mkU8(imm * 8)),
17857                       binop(Iop_ShrV128, get_vr_qw(v3), mkU8((16 - imm) * 8))
17858                      )
17859                );
17860    }
17861 
17862    return "vsldb";
17863 }
17864 
17865 static const HChar *
17866 s390_irgen_VMO(UChar v1, UChar v2, UChar v3, UChar m4)
17867 {
17868    const IROp ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8,
17869                         Iop_MullEven32Sx4 };
17870    UChar shifts[] = { 8, 16, 32 };
17871    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17872    IRExpr* result = binop(ops[m4],
17873                           binop(Iop_ShlV128, get_vr_qw(v2), mkU8(shifts[m4])),
17874                           binop(Iop_ShlV128, get_vr_qw(v3), mkU8(shifts[m4]))
17875                          );
17876    put_vr_qw(v1, result);
17877 
17878    return "vmo";
17879 }
17880 
17881 static const HChar *
17882 s390_irgen_VMLO(UChar v1, UChar v2, UChar v3, UChar m4)
17883 {
17884    const IROp ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8,
17885                         Iop_MullEven32Ux4 };
17886    UChar shifts[] = { 8, 16, 32 };
17887    vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17888    IRExpr* result = binop(ops[m4],
17889                           binop(Iop_ShlV128, get_vr_qw(v2), mkU8(shifts[m4])),
17890                           binop(Iop_ShlV128, get_vr_qw(v3), mkU8(shifts[m4]))
17891                          );
17892    put_vr_qw(v1, result);
17893 
17894    return "vmlo";
17895 }
17896 
17897 static const HChar *
17898 s390_irgen_VMAE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17899 {
17900    const IROp mul_ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8,
17901                             Iop_MullEven32Sx4 };
17902    const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2};
17903    vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
17904 
17905    IRExpr* mul_result = binop(mul_ops[m5], get_vr_qw(v2), get_vr_qw(v3));
17906    IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
17907    put_vr_qw(v1, result);
17908 
17909    return "vmae";
17910 }
17911 
17912 static const HChar *
17913 s390_irgen_VMALE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17914 {
17915    const IROp mul_ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8,
17916                             Iop_MullEven32Ux4 };
17917    const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2 };
17918    vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
17919 
17920    IRExpr* mul_result = binop(mul_ops[m5], get_vr_qw(v2), get_vr_qw(v3));
17921    IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
17922    put_vr_qw(v1, result);
17923 
17924    return "vmale";
17925 }
17926 
17927 static const HChar *
17928 s390_irgen_VMAO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17929 {
17930    const IROp mul_ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8,
17931                             Iop_MullEven32Sx4 };
17932    const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2 };
17933    UChar shifts[] = { 8, 16, 32 };
17934    vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
17935 
17936    IRExpr* mul_result =
17937       binop(mul_ops[m5],
17938             binop(Iop_ShlV128, get_vr_qw(v2), mkU8(shifts[m5])),
17939             binop(Iop_ShlV128, get_vr_qw(v3), mkU8(shifts[m5])));
17940    IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
17941    put_vr_qw(v1, result);
17942 
17943    return "vmao";
17944 }
17945 
17946 static const HChar *
17947 s390_irgen_VMALO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17948 {
17949    const IROp mul_ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8,
17950                             Iop_MullEven32Ux4 };
17951    const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2 };
17952    UChar shifts[] = { 8, 16, 32 };
17953    vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
17954 
17955    IRExpr* mul_result = binop(mul_ops[m5],
17956                               binop(Iop_ShlV128,
17957                                     get_vr_qw(v2), mkU8(shifts[m5])),
17958                               binop(Iop_ShlV128,
17959                                     get_vr_qw(v3), mkU8(shifts[m5]))
17960    );
17961 
17962    IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
17963    put_vr_qw(v1, result);
17964 
17965    return "vmalo";
17966 }
17967 
17968 static const HChar *
17969 s390_irgen_VMAL(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
17970 {
17971    const IROp mul_ops[] = { Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4 };
17972    const IROp add_ops[] = { Iop_Add8x16, Iop_Add16x8, Iop_Add32x4 };
17973    vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
17974 
17975    IRExpr* mul_result = binop(mul_ops[m5], get_vr_qw(v2), get_vr_qw(v3));
17976    IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
17977    put_vr_qw(v1, result);
17978 
17979    return "vmal";
17980 }
17981 
17982 static const HChar *
17983 s390_irgen_VSUM(UChar v1, UChar v2, UChar v3, UChar m4)
17984 {
17985    IRType type = s390_vr_get_type(m4);
17986    IRExpr* mask;
17987    IRExpr* sum;
17988    switch(type) {
17989    case Ity_I8:
17990       sum = unop(Iop_PwAddL16Ux8, unop(Iop_PwAddL8Ux16, get_vr_qw(v2)));
17991       mask = IRExpr_Const(IRConst_V128(0b0001000100010001));
17992       break;
17993    case Ity_I16:
17994       sum = unop(Iop_PwAddL16Ux8, get_vr_qw(v2));
17995       mask = IRExpr_Const(IRConst_V128(0b0011001100110011));
17996       break;
17997    default:
17998       vpanic("s390_irgen_VSUM: invalid type ");
17999    }
18000 
18001    IRExpr* addition = binop(Iop_AndV128, get_vr_qw(v3), mask);
18002    put_vr_qw(v1, binop(Iop_Add32x4, sum, addition));
18003 
18004    return "vsum";
18005 }
18006 
18007 static const HChar *
18008 s390_irgen_VSUMG(UChar v1, UChar v2, UChar v3, UChar m4)
18009 {
18010    IRType type = s390_vr_get_type(m4);
18011    IRExpr* mask;
18012    IRExpr* sum;
18013    switch(type) {
18014    case Ity_I16:
18015       sum = unop(Iop_PwAddL32Ux4, unop(Iop_PwAddL16Ux8, get_vr_qw(v2)));
18016       mask = IRExpr_Const(IRConst_V128(0b0000001100000011));
18017       break;
18018    case Ity_I32:
18019       sum = unop(Iop_PwAddL32Ux4, get_vr_qw(v2));
18020       mask = IRExpr_Const(IRConst_V128(0b0000111100001111));
18021       break;
18022    default:
18023       vpanic("s390_irgen_VSUMG: invalid type ");
18024    }
18025 
18026    IRExpr* addition = binop(Iop_AndV128, get_vr_qw(v3), mask);
18027    put_vr_qw(v1, binop(Iop_Add64x2, sum, addition));
18028 
18029    return "vsumg";
18030 }
18031 
18032 static const HChar *
18033 s390_irgen_VSUMQ(UChar v1, UChar v2, UChar v3, UChar m4)
18034 {
18035    IRType type = s390_vr_get_type(m4);
18036    IRExpr* mask;
18037    IRExpr* sum;
18038    switch(type) {
18039    case Ity_I32:
18040       sum = unop(Iop_PwAddL64Ux2, unop(Iop_PwAddL32Ux4, get_vr_qw(v2)));
18041       mask = IRExpr_Const(IRConst_V128(0b0000000000001111));
18042       break;
18043    case Ity_I64:
18044       sum = unop(Iop_PwAddL64Ux2, get_vr_qw(v2));
18045       mask = IRExpr_Const(IRConst_V128(0b0000000011111111));
18046       break;
18047    default:
18048       vpanic("s390_irgen_VSUMQ: invalid type ");
18049    }
18050 
18051    IRExpr* addition = binop(Iop_AndV128, get_vr_qw(v3), mask);
18052    put_vr_qw(v1, binop(Iop_Add128x1, sum, addition));
18053 
18054    return "vsumq";
18055 }
18056 
18057 static const HChar *
18058 s390_irgen_VTM(UChar v1, UChar v2)
18059 {
18060    IRDirty* d;
18061    IRTemp cc = newTemp(Ity_I64);
18062 
18063    s390x_vec_op_details_t details = { .serialized = 0ULL };
18064    details.op = S390_VEC_OP_VTM;
18065    details.v2 = v1;
18066    details.v3 = v2;
18067    details.read_only = 1;
18068 
18069    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18070                          &s390x_dirtyhelper_vec_op,
18071                          mkIRExprVec_2(IRExpr_GSPTR(),
18072                                        mkU64(details.serialized)));
18073 
18074    d->nFxState = 2;
18075    vex_bzero(&d->fxState, sizeof(d->fxState));
18076    d->fxState[0].fx     = Ifx_Read;
18077    d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18078    d->fxState[0].size   = sizeof(V128);
18079    d->fxState[1].fx     = Ifx_Read;
18080    d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18081    d->fxState[1].size   = sizeof(V128);
18082 
18083    stmt(IRStmt_Dirty(d));
18084    s390_cc_set(cc);
18085 
18086    return "vtm";
18087 }
18088 
18089 static const HChar *
18090 s390_irgen_VAC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18091 {
18092    vassert(m5 == 4); /* specification exception otherwise */
18093 
18094    IRTemp sum = newTemp(Ity_V128);
18095    assign(sum, binop(Iop_Add128x1, get_vr_qw(v2), get_vr_qw(v3)));
18096 
18097    IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0), mkU64(1));
18098    IRExpr* carry_in = binop(Iop_AndV128, get_vr_qw(v4), mask);
18099    put_vr_qw(v1, binop(Iop_Add128x1, mkexpr(sum), carry_in));
18100 
18101    return "vac";
18102 }
18103 
18104 static const HChar *
18105 s390_irgen_VACC(UChar v1, UChar v2, UChar v3, UChar m4)
18106 {
18107    IRType type = s390_vr_get_type(m4);
18108    IRExpr* arg1 = get_vr_qw(v2);
18109    IRExpr* arg2 = get_vr_qw(v3);
18110 
18111    put_vr_qw(v1, s390_V128_calculate_carry_out(arg1, arg2, type, False));
18112    return "vacc";
18113 }
18114 
18115 static const HChar *
18116 s390_irgen_VACCC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18117 {
18118    vassert(m5 == 4); /* specification exception otherwise */
18119    IRExpr* result =
18120          s390_V128_calculate_carry_out_with_carry(get_vr_qw(v2),
18121                                                   get_vr_qw(v3),
18122                                                   get_vr_qw(v4)
18123                                                   );
18124 
18125    put_vr_qw(v1, result);
18126    return "vaccc";
18127 }
18128 
18129 static const HChar*
18130 s390_irgen_VCKSM(UChar v1, UChar v2, UChar v3)
18131 {
18132 
18133    IRTemp sum1 = s390_checksum_add(get_vr_w1(v3), get_vr_w0(v2));
18134    IRTemp sum2 = s390_checksum_add(mkexpr(sum1), get_vr_w1(v2));
18135    IRTemp sum3 = s390_checksum_add(mkexpr(sum2), get_vr_w2(v2));
18136    IRTemp result = s390_checksum_add(mkexpr(sum3), get_vr_w3(v2));
18137 
18138    put_vr_qw(v1, binop(Iop_64HLtoV128,
18139                        unop(Iop_32Uto64, mkexpr(result)), mkU64(0ULL)));
18140 
18141    return "vcksm";
18142 }
18143 
18144 static const HChar *
18145 s390_irgen_VGFM(UChar v1, UChar v2, UChar v3, UChar m4)
18146 {
18147    IRDirty* d;
18148    IRTemp cc = newTemp(Ity_I64);
18149 
18150    s390x_vec_op_details_t details = { .serialized = 0ULL };
18151    details.op = S390_VEC_OP_VGFM;
18152    details.v1 = v1;
18153    details.v2 = v2;
18154    details.v3 = v3;
18155    details.m4 = m4;
18156 
18157    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18158                          &s390x_dirtyhelper_vec_op,
18159                          mkIRExprVec_2(IRExpr_GSPTR(),
18160                                        mkU64(details.serialized)));
18161 
18162    d->nFxState = 3;
18163    vex_bzero(&d->fxState, sizeof(d->fxState));
18164    d->fxState[0].fx     = Ifx_Read;
18165    d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18166    d->fxState[0].size   = sizeof(V128);
18167    d->fxState[1].fx     = Ifx_Read;
18168    d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18169    d->fxState[1].size   = sizeof(V128);
18170    d->fxState[2].fx     = Ifx_Write;
18171    d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18172    d->fxState[2].size   = sizeof(V128);
18173 
18174    stmt(IRStmt_Dirty(d));
18175    return "vgfm";
18176 }
18177 
18178 static const HChar *
18179 s390_irgen_VGFMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18180 {
18181    IRDirty* d;
18182    IRTemp cc = newTemp(Ity_I64);
18183 
18184    s390x_vec_op_details_t details = { .serialized = 0ULL };
18185    details.op = S390_VEC_OP_VGFMA;
18186    details.v1 = v1;
18187    details.v2 = v2;
18188    details.v3 = v3;
18189    details.v4 = v4;
18190    details.m4 = m5;
18191 
18192    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18193                          &s390x_dirtyhelper_vec_op,
18194                          mkIRExprVec_2(IRExpr_GSPTR(),
18195                                        mkU64(details.serialized)));
18196 
18197    d->nFxState = 4;
18198    vex_bzero(&d->fxState, sizeof(d->fxState));
18199    d->fxState[0].fx     = Ifx_Read;
18200    d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18201    d->fxState[0].size   = sizeof(V128);
18202    d->fxState[1].fx     = Ifx_Read;
18203    d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18204    d->fxState[1].size   = sizeof(V128);
18205    d->fxState[2].fx     = Ifx_Read;
18206    d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128);
18207    d->fxState[2].size   = sizeof(V128);
18208    d->fxState[3].fx     = Ifx_Write;
18209    d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18210    d->fxState[3].size   = sizeof(V128);
18211 
18212    stmt(IRStmt_Dirty(d));
18213    return "vgfma";
18214 }
18215 
18216 static const HChar *
18217 s390_irgen_VSBI(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18218 {
18219    vassert(m5 == 4); /* specification exception otherwise */
18220 
18221    IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0ULL), mkU64(1ULL));
18222    IRExpr* carry_in = binop(Iop_AndV128, get_vr_qw(v4), mask);
18223 
18224    IRTemp sum = newTemp(Ity_V128);
18225    assign(sum, binop(Iop_Add128x1,
18226                      get_vr_qw(v2),
18227                      unop(Iop_NotV128, get_vr_qw(v3))
18228                      )
18229          );
18230 
18231    put_vr_qw(v1, binop(Iop_Add128x1, mkexpr(sum), carry_in));
18232    return "vsbi";
18233 }
18234 
18235 static const HChar *
18236 s390_irgen_VSCBI(UChar v1, UChar v2, UChar v3, UChar m4)
18237 {
18238    IRType type = s390_vr_get_type(m4);
18239    IRExpr* arg1 = get_vr_qw(v2);
18240    IRExpr* arg2 = s390_V128_get_complement(get_vr_qw(v3), type);
18241    IRExpr* result = s390_V128_calculate_carry_out(arg1, arg2, type, True);
18242 
18243    put_vr_qw(v1, result);
18244    return "vscbi";
18245 }
18246 
18247 static const HChar *
18248 s390_irgen_VSBCBI(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18249 {
18250    vassert(m5 == 4); /* specification exception otherwise */
18251    IRExpr* result =
18252       s390_V128_calculate_carry_out_with_carry(get_vr_qw(v2),
18253                                                unop(Iop_NotV128, get_vr_qw(v3)),
18254                                                get_vr_qw(v4));
18255 
18256    put_vr_qw(v1, result);
18257    return "vsbcbi";
18258 }
18259 
18260 static const HChar *
18261 s390_irgen_VMAH(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18262 {
18263    IRDirty* d;
18264    IRTemp cc = newTemp(Ity_I64);
18265 
18266    /* Check for specification exception */
18267    vassert(m5 < 3);
18268 
18269    s390x_vec_op_details_t details = { .serialized = 0ULL };
18270    details.op = S390_VEC_OP_VMAH;
18271    details.v1 = v1;
18272    details.v2 = v2;
18273    details.v3 = v3;
18274    details.v4 = v4;
18275    details.m4 = m5;
18276 
18277    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18278                          &s390x_dirtyhelper_vec_op,
18279                          mkIRExprVec_2(IRExpr_GSPTR(),
18280                                        mkU64(details.serialized)));
18281 
18282    d->nFxState = 4;
18283    vex_bzero(&d->fxState, sizeof(d->fxState));
18284    d->fxState[0].fx     = Ifx_Read;
18285    d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18286    d->fxState[0].size   = sizeof(V128);
18287    d->fxState[1].fx     = Ifx_Read;
18288    d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18289    d->fxState[1].size   = sizeof(V128);
18290    d->fxState[2].fx     = Ifx_Read;
18291    d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128);
18292    d->fxState[2].size   = sizeof(V128);
18293    d->fxState[3].fx     = Ifx_Write;
18294    d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18295    d->fxState[3].size   = sizeof(V128);
18296 
18297    stmt(IRStmt_Dirty(d));
18298 
18299    return "vmah";
18300 }
18301 
18302 static const HChar *
18303 s390_irgen_VMALH(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18304 {
18305    IRDirty* d;
18306    IRTemp cc = newTemp(Ity_I64);
18307 
18308    /* Check for specification exception */
18309    vassert(m5 < 3);
18310 
18311    s390x_vec_op_details_t details = { .serialized = 0ULL };
18312    details.op = S390_VEC_OP_VMALH;
18313    details.v1 = v1;
18314    details.v2 = v2;
18315    details.v3 = v3;
18316    details.v4 = v4;
18317    details.m4 = m5;
18318 
18319    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18320                          &s390x_dirtyhelper_vec_op,
18321                          mkIRExprVec_2(IRExpr_GSPTR(),
18322                                        mkU64(details.serialized)));
18323 
18324    d->nFxState = 4;
18325    vex_bzero(&d->fxState, sizeof(d->fxState));
18326    d->fxState[0].fx     = Ifx_Read;
18327    d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18328    d->fxState[0].size   = sizeof(V128);
18329    d->fxState[1].fx     = Ifx_Read;
18330    d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18331    d->fxState[1].size   = sizeof(V128);
18332    d->fxState[2].fx     = Ifx_Read;
18333    d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128);
18334    d->fxState[2].size   = sizeof(V128);
18335    d->fxState[3].fx     = Ifx_Write;
18336    d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18337    d->fxState[3].size   = sizeof(V128);
18338 
18339    stmt(IRStmt_Dirty(d));
18340 
18341    return "vmalh";
18342 }
18343 
18344 static void
18345 s390_vector_fp_convert(IROp op, IRType fromType, IRType toType,
18346                        UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18347 {
18348    Bool isSingleElementOp = s390_vr_is_single_element_control_set(m4);
18349    UChar maxIndex = isSingleElementOp ? 0 : 1;
18350 
18351    /* For Iop_F32toF64 we do this:
18352       f32[0] -> f64[0]
18353       f32[2] -> f64[1]
18354 
18355       For Iop_F64toF32 we do this:
18356       f64[0] -> f32[0]
18357       f64[1] -> f32[2]
18358 
18359       The magic below with scaling factors is used to achieve the logic
18360       described above.
18361    */
18362    const UChar sourceIndexScaleFactor = (op == Iop_F32toF64) ? 2 : 1;
18363    const UChar destinationIndexScaleFactor = (op == Iop_F64toF32) ? 2 : 1;
18364 
18365    const Bool isUnary = (op == Iop_F32toF64);
18366    for (UChar i = 0; i <= maxIndex; i++) {
18367       IRExpr* argument = get_vr(v2, fromType, i * sourceIndexScaleFactor);
18368       IRExpr* result;
18369       if (!isUnary) {
18370          result = binop(op,
18371                         mkexpr(encode_bfp_rounding_mode(m5)),
18372                         argument);
18373       } else {
18374          result = unop(op, argument);
18375       }
18376       put_vr(v1, toType, i * destinationIndexScaleFactor, result);
18377    }
18378 
18379    if (isSingleElementOp) {
18380       put_vr_dw1(v1, mkU64(0));
18381    }
18382 }
18383 
18384 static const HChar *
18385 s390_irgen_VCDG(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18386 {
18387    s390_insn_assert("vcdg", m3 == 3);
18388 
18389    if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18390       emulation_warning(EmWarn_S390X_fpext_rounding);
18391       m5 = S390_BFP_ROUND_PER_FPC;
18392    }
18393 
18394    s390_vector_fp_convert(Iop_I64StoF64, Ity_I64, Ity_F64, v1, v2, m3, m4, m5);
18395 
18396    return "vcdg";
18397 }
18398 
18399 static const HChar *
18400 s390_irgen_VCDLG(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18401 {
18402    s390_insn_assert("vcdlg", m3 == 3);
18403 
18404    if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18405       emulation_warning(EmWarn_S390X_fpext_rounding);
18406       m5 = S390_BFP_ROUND_PER_FPC;
18407    }
18408 
18409    s390_vector_fp_convert(Iop_I64UtoF64, Ity_I64, Ity_F64, v1, v2, m3, m4, m5);
18410 
18411    return "vcdlg";
18412 }
18413 
18414 static const HChar *
18415 s390_irgen_VCGD(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18416 {
18417    s390_insn_assert("vcgd", m3 == 3);
18418 
18419    if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18420       emulation_warning(EmWarn_S390X_fpext_rounding);
18421       m5 = S390_BFP_ROUND_PER_FPC;
18422    }
18423 
18424    s390_vector_fp_convert(Iop_F64toI64S, Ity_F64, Ity_I64, v1, v2, m3, m4, m5);
18425 
18426    return "vcgd";
18427 }
18428 
18429 static const HChar *
18430 s390_irgen_VCLGD(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18431 {
18432    s390_insn_assert("vclgd", m3 == 3);
18433 
18434    if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18435       emulation_warning(EmWarn_S390X_fpext_rounding);
18436       m5 = S390_BFP_ROUND_PER_FPC;
18437    }
18438 
18439    s390_vector_fp_convert(Iop_F64toI64U, Ity_F64, Ity_I64, v1, v2, m3, m4, m5);
18440 
18441    return "vclgd";
18442 }
18443 
18444 static const HChar *
18445 s390_irgen_VFI(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18446 {
18447    s390_insn_assert("vfi", m3 == 3);
18448 
18449    if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18450       emulation_warning(EmWarn_S390X_fpext_rounding);
18451       m5 = S390_BFP_ROUND_PER_FPC;
18452    }
18453 
18454    s390_vector_fp_convert(Iop_RoundF64toInt, Ity_F64, Ity_F64,
18455                           v1, v2, m3, m4, m5);
18456 
18457    return "vcgld";
18458 }
18459 
18460 static const HChar *
18461 s390_irgen_VLDE(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18462 {
18463    s390_insn_assert("vlde", m3 == 2);
18464 
18465    s390_vector_fp_convert(Iop_F32toF64, Ity_F32, Ity_F64, v1, v2, m3, m4, m5);
18466 
18467    return "vlde";
18468 }
18469 
18470 static const HChar *
18471 s390_irgen_VLED(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18472 {
18473    s390_insn_assert("vled", m3 == 3);
18474 
18475    if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18476       m5 = S390_BFP_ROUND_PER_FPC;
18477    }
18478 
18479    s390_vector_fp_convert(Iop_F64toF32, Ity_F64, Ity_F32, v1, v2, m3, m4, m5);
18480 
18481    return "vled";
18482 }
18483 
18484 static const HChar *
18485 s390_irgen_VFPSO(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18486 {
18487    s390_insn_assert("vfpso", m3 == 3);
18488 
18489    IRExpr* result;
18490    switch (m5) {
18491    case 0: {
18492       /* Invert sign */
18493       if (!s390_vr_is_single_element_control_set(m4)) {
18494          result = unop(Iop_Neg64Fx2, get_vr_qw(v2));
18495       }
18496       else {
18497          result = binop(Iop_64HLtoV128,
18498                         unop(Iop_ReinterpF64asI64,
18499                              unop(Iop_NegF64, get_vr(v2, Ity_F64, 0))),
18500                         mkU64(0));
18501       }
18502       break;
18503    }
18504 
18505    case 1: {
18506       /* Set sign to negative */
18507       IRExpr* highHalf = mkU64(0x8000000000000000ULL);
18508       if (!s390_vr_is_single_element_control_set(m4)) {
18509          IRExpr* lowHalf = highHalf;
18510          IRExpr* mask = binop(Iop_64HLtoV128, highHalf, lowHalf);
18511          result = binop(Iop_OrV128, get_vr_qw(v2), mask);
18512       }
18513       else {
18514          result = binop(Iop_64HLtoV128,
18515                         binop(Iop_Or64, get_vr_dw0(v2), highHalf),
18516                         mkU64(0ULL));
18517       }
18518 
18519       break;
18520    }
18521 
18522    case 2: {
18523       /* Set sign to positive */
18524       if (!s390_vr_is_single_element_control_set(m4)) {
18525          result = unop(Iop_Abs64Fx2, get_vr_qw(v2));
18526       }
18527       else {
18528          result = binop(Iop_64HLtoV128,
18529                         unop(Iop_ReinterpF64asI64,
18530                              unop(Iop_AbsF64, get_vr(v2, Ity_F64, 0))),
18531                         mkU64(0));
18532       }
18533 
18534       break;
18535    }
18536 
18537    default:
18538       vpanic("s390_irgen_VFPSO: Invalid m5 value");
18539    }
18540 
18541    put_vr_qw(v1, result);
18542    if (s390_vr_is_single_element_control_set(m4)) {
18543       put_vr_dw1(v1, mkU64(0ULL));
18544    }
18545 
18546    return "vfpso";
18547 }
18548 
18549 static void s390x_vec_fp_binary_op(IROp generalOp, IROp singleElementOp,
18550                                    UChar v1, UChar v2, UChar v3, UChar m4,
18551                                    UChar m5)
18552 {
18553    IRExpr* result;
18554    if (!s390_vr_is_single_element_control_set(m5)) {
18555       result = triop(generalOp, get_bfp_rounding_mode_from_fpc(),
18556                      get_vr_qw(v2), get_vr_qw(v3));
18557    } else {
18558       IRExpr* highHalf = triop(singleElementOp,
18559                                get_bfp_rounding_mode_from_fpc(),
18560                                get_vr(v2, Ity_F64, 0),
18561                                get_vr(v3, Ity_F64, 0));
18562       result = binop(Iop_64HLtoV128, unop(Iop_ReinterpF64asI64, highHalf),
18563                      mkU64(0ULL));
18564    }
18565 
18566    put_vr_qw(v1, result);
18567 }
18568 
18569 static void s390x_vec_fp_unary_op(IROp generalOp, IROp singleElementOp,
18570                                   UChar v1, UChar v2, UChar m3, UChar m4)
18571 {
18572    IRExpr* result;
18573    if (!s390_vr_is_single_element_control_set(m4)) {
18574       result = binop(generalOp, get_bfp_rounding_mode_from_fpc(),
18575                      get_vr_qw(v2));
18576    }
18577    else {
18578       IRExpr* highHalf = binop(singleElementOp,
18579                                get_bfp_rounding_mode_from_fpc(),
18580                                get_vr(v2, Ity_F64, 0));
18581       result = binop(Iop_64HLtoV128, unop(Iop_ReinterpF64asI64, highHalf),
18582                      mkU64(0ULL));
18583    }
18584 
18585    put_vr_qw(v1, result);
18586 }
18587 
18588 
18589 static void
18590 s390_vector_fp_mulAddOrSub(IROp singleElementOp,
18591                            UChar v1, UChar v2, UChar v3, UChar v4,
18592                            UChar m5, UChar m6)
18593 {
18594    Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
18595    IRTemp irrm_temp = newTemp(Ity_I32);
18596    assign(irrm_temp, get_bfp_rounding_mode_from_fpc());
18597    IRExpr* irrm = mkexpr(irrm_temp);
18598    IRExpr* result;
18599    IRExpr* highHalf = qop(singleElementOp,
18600                           irrm,
18601                           get_vr(v2, Ity_F64, 0),
18602                           get_vr(v3, Ity_F64, 0),
18603                           get_vr(v4, Ity_F64, 0));
18604 
18605    if (isSingleElementOp) {
18606       result = binop(Iop_64HLtoV128, unop(Iop_ReinterpF64asI64, highHalf),
18607                      mkU64(0ULL));
18608    } else {
18609       IRExpr* lowHalf = qop(singleElementOp,
18610                             irrm,
18611                             get_vr(v2, Ity_F64, 1),
18612                             get_vr(v3, Ity_F64, 1),
18613                             get_vr(v4, Ity_F64, 1));
18614       result = binop(Iop_64HLtoV128, unop(Iop_ReinterpF64asI64, highHalf),
18615                      unop(Iop_ReinterpF64asI64, lowHalf));
18616    }
18617 
18618    put_vr_qw(v1, result);
18619 }
18620 
18621 static const HChar *
18622 s390_irgen_VFA(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
18623 {
18624    s390_insn_assert("vfa", m4 == 3);
18625    s390x_vec_fp_binary_op(Iop_Add64Fx2, Iop_AddF64, v1, v2, v3, m4, m5);
18626    return "vfa";
18627 }
18628 
18629 static const HChar *
18630 s390_irgen_VFS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
18631 {
18632    s390_insn_assert("vfs", m4 == 3);
18633    s390x_vec_fp_binary_op(Iop_Sub64Fx2, Iop_SubF64, v1, v2, v3, m4, m5);
18634    return "vfs";
18635 }
18636 
18637 static const HChar *
18638 s390_irgen_VFM(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
18639 {
18640    s390_insn_assert("vfm", m4 == 3);
18641    s390x_vec_fp_binary_op(Iop_Mul64Fx2, Iop_MulF64, v1, v2, v3, m4, m5);
18642    return "vfm";
18643 }
18644 
18645 static const HChar *
18646 s390_irgen_VFD(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
18647 {
18648    s390_insn_assert("vfd", m4 == 3);
18649    s390x_vec_fp_binary_op(Iop_Div64Fx2, Iop_DivF64, v1, v2, v3, m4, m5);
18650    return "vfd";
18651 }
18652 
18653 static const HChar *
18654 s390_irgen_VFSQ(UChar v1, UChar v2, UChar m3, UChar m4)
18655 {
18656    s390_insn_assert("vfsq", m3 == 3);
18657    s390x_vec_fp_unary_op(Iop_Sqrt64Fx2, Iop_SqrtF64, v1, v2, m3, m4);
18658 
18659    return "vfsq";
18660 }
18661 
18662 static const HChar *
18663 s390_irgen_VFMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
18664 {
18665    s390_insn_assert("vfma", m6 == 3);
18666    s390_vector_fp_mulAddOrSub(Iop_MAddF64, v1, v2, v3, v4, m5, m6);
18667    return "vfma";
18668 }
18669 
18670 static const HChar *
18671 s390_irgen_VFMS(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
18672 {
18673    s390_insn_assert("vfms", m6 == 3);
18674    s390_vector_fp_mulAddOrSub(Iop_MSubF64, v1, v2, v3, v4, m5, m6);
18675    return "vfms";
18676 }
18677 
18678 static const HChar *
18679 s390_irgen_WFC(UChar v1, UChar v2, UChar m3, UChar m4)
18680 {
18681    s390_insn_assert("wfc", m3 == 3);
18682    s390_insn_assert("wfc", m4 == 0);
18683 
18684    IRTemp cc_vex = newTemp(Ity_I32);
18685    assign(cc_vex, binop(Iop_CmpF64,
18686                         get_vr(v1, Ity_F64, 0), get_vr(v2, Ity_F64, 0)));
18687 
18688    IRTemp cc_s390 = newTemp(Ity_I32);
18689    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
18690    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
18691 
18692    return "wfc";
18693 }
18694 
18695 static const HChar *
18696 s390_irgen_WFK(UChar v1, UChar v2, UChar m3, UChar m4)
18697 {
18698    s390_irgen_WFC(v1, v2, m3, m4);
18699 
18700    return "wfk";
18701 }
18702 
18703 static const HChar *
18704 s390_irgen_VFCE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6)
18705 {
18706    s390_insn_assert("vfce", m4 == 3);
18707 
18708    Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
18709    if (!s390_vr_is_cs_set(m6)) {
18710       if (!isSingleElementOp) {
18711          put_vr_qw(v1, binop(Iop_CmpEQ64Fx2, get_vr_qw(v2), get_vr_qw(v3)));
18712       } else {
18713          IRExpr* comparisonResult = binop(Iop_CmpF64, get_vr(v2, Ity_F64, 0),
18714                                           get_vr(v3, Ity_F64, 0));
18715          IRExpr* result = mkite(binop(Iop_CmpEQ32, comparisonResult,
18716                                       mkU32(Ircr_EQ)),
18717                                 mkU64(0xffffffffffffffffULL),
18718                                 mkU64(0ULL));
18719          put_vr_qw(v1, binop(Iop_64HLtoV128, result, mkU64(0ULL)));
18720       }
18721    } else {
18722       IRDirty* d;
18723       IRTemp cc = newTemp(Ity_I64);
18724 
18725       s390x_vec_op_details_t details = { .serialized = 0ULL };
18726       details.op = S390_VEC_OP_VFCE;
18727       details.v1 = v1;
18728       details.v2 = v2;
18729       details.v3 = v3;
18730       details.m4 = m4;
18731       details.m5 = m5;
18732       details.m6 = m6;
18733 
18734       d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18735                             &s390x_dirtyhelper_vec_op,
18736                             mkIRExprVec_2(IRExpr_GSPTR(),
18737                                           mkU64(details.serialized)));
18738 
18739       const UChar elementSize = isSingleElementOp ? sizeof(ULong) : sizeof(V128);
18740       d->nFxState = 3;
18741       vex_bzero(&d->fxState, sizeof(d->fxState));
18742       d->fxState[0].fx = Ifx_Read;
18743       d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18744       d->fxState[0].size = elementSize;
18745       d->fxState[1].fx = Ifx_Read;
18746       d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18747       d->fxState[1].size = elementSize;
18748       d->fxState[2].fx = Ifx_Write;
18749       d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18750       d->fxState[2].size = sizeof(V128);
18751 
18752       stmt(IRStmt_Dirty(d));
18753       s390_cc_set(cc);
18754    }
18755 
18756    return "vfce";
18757 }
18758 
18759 static const HChar *
18760 s390_irgen_VFCH(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6)
18761 {
18762    vassert(m4 == 3);
18763 
18764    Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
18765    if (!s390_vr_is_cs_set(m6)) {
18766       if (!isSingleElementOp) {
18767          put_vr_qw(v1, binop(Iop_CmpLE64Fx2, get_vr_qw(v3), get_vr_qw(v2)));
18768       } else {
18769          IRExpr* comparisonResult = binop(Iop_CmpF64, get_vr(v2, Ity_F64, 0),
18770                                           get_vr(v3, Ity_F64, 0));
18771          IRExpr* result = mkite(binop(Iop_CmpEQ32, comparisonResult,
18772                                       mkU32(Ircr_GT)),
18773                                 mkU64(0xffffffffffffffffULL),
18774                                 mkU64(0ULL));
18775          put_vr_qw(v1, binop(Iop_64HLtoV128, result, mkU64(0ULL)));
18776       }
18777    }
18778    else {
18779       IRDirty* d;
18780       IRTemp cc = newTemp(Ity_I64);
18781 
18782       s390x_vec_op_details_t details = { .serialized = 0ULL };
18783       details.op = S390_VEC_OP_VFCH;
18784       details.v1 = v1;
18785       details.v2 = v2;
18786       details.v3 = v3;
18787       details.m4 = m4;
18788       details.m5 = m5;
18789       details.m6 = m6;
18790 
18791       d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18792                             &s390x_dirtyhelper_vec_op,
18793                             mkIRExprVec_2(IRExpr_GSPTR(),
18794                                           mkU64(details.serialized)));
18795 
18796       const UChar elementSize = isSingleElementOp ? sizeof(ULong) : sizeof(V128);
18797       d->nFxState = 3;
18798       vex_bzero(&d->fxState, sizeof(d->fxState));
18799       d->fxState[0].fx = Ifx_Read;
18800       d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18801       d->fxState[0].size = elementSize;
18802       d->fxState[1].fx = Ifx_Read;
18803       d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18804       d->fxState[1].size = elementSize;
18805       d->fxState[2].fx = Ifx_Write;
18806       d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18807       d->fxState[2].size = sizeof(V128);
18808 
18809       stmt(IRStmt_Dirty(d));
18810       s390_cc_set(cc);
18811    }
18812 
18813    return "vfch";
18814 }
18815 
18816 static const HChar *
18817 s390_irgen_VFCHE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6)
18818 {
18819    s390_insn_assert("vfche", m4 == 3);
18820 
18821    Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
18822    if (!s390_vr_is_cs_set(m6)) {
18823       if (!isSingleElementOp) {
18824          put_vr_qw(v1, binop(Iop_CmpLT64Fx2, get_vr_qw(v3), get_vr_qw(v2)));
18825       }
18826       else {
18827          IRExpr* comparisonResult = binop(Iop_CmpF64, get_vr(v3, Ity_F64, 0),
18828                                           get_vr(v2, Ity_F64, 0));
18829          IRExpr* result = mkite(binop(Iop_CmpEQ32, comparisonResult,
18830                                       mkU32(Ircr_LT)),
18831                                 mkU64(0xffffffffffffffffULL),
18832                                 mkU64(0ULL));
18833          put_vr_qw(v1, binop(Iop_64HLtoV128, result, mkU64(0ULL)));
18834       }
18835    }
18836    else {
18837       IRDirty* d;
18838       IRTemp cc = newTemp(Ity_I64);
18839 
18840       s390x_vec_op_details_t details = { .serialized = 0ULL };
18841       details.op = S390_VEC_OP_VFCHE;
18842       details.v1 = v1;
18843       details.v2 = v2;
18844       details.v3 = v3;
18845       details.m4 = m4;
18846       details.m5 = m5;
18847       details.m6 = m6;
18848 
18849       d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18850                             &s390x_dirtyhelper_vec_op,
18851                             mkIRExprVec_2(IRExpr_GSPTR(),
18852                                           mkU64(details.serialized)));
18853 
18854       const UChar elementSize = isSingleElementOp ? sizeof(ULong) : sizeof(V128);
18855       d->nFxState = 3;
18856       vex_bzero(&d->fxState, sizeof(d->fxState));
18857       d->fxState[0].fx = Ifx_Read;
18858       d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18859       d->fxState[0].size = elementSize;
18860       d->fxState[1].fx = Ifx_Read;
18861       d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18862       d->fxState[1].size = elementSize;
18863       d->fxState[2].fx = Ifx_Write;
18864       d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18865       d->fxState[2].size = sizeof(V128);
18866 
18867       stmt(IRStmt_Dirty(d));
18868       s390_cc_set(cc);
18869    }
18870 
18871    return "vfche";
18872 }
18873 
18874 static const HChar *
18875 s390_irgen_VFTCI(UChar v1, UChar v2, UShort i3, UChar m4, UChar m5)
18876 {
18877    s390_insn_assert("vftci", m4 == 3);
18878 
18879    Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
18880 
18881    IRDirty* d;
18882    IRTemp cc = newTemp(Ity_I64);
18883 
18884    s390x_vec_op_details_t details = { .serialized = 0ULL };
18885    details.op = S390_VEC_OP_VFTCI;
18886    details.v1 = v1;
18887    details.v2 = v2;
18888    details.i3 = i3;
18889    details.m4 = m4;
18890    details.m5 = m5;
18891 
18892    d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18893                          &s390x_dirtyhelper_vec_op,
18894                          mkIRExprVec_2(IRExpr_GSPTR(),
18895                                        mkU64(details.serialized)));
18896 
18897    const UChar elementSize = isSingleElementOp ? sizeof(ULong) : sizeof(V128);
18898    d->nFxState = 2;
18899    vex_bzero(&d->fxState, sizeof(d->fxState));
18900    d->fxState[0].fx = Ifx_Read;
18901    d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18902    d->fxState[0].size = elementSize;
18903    d->fxState[1].fx = Ifx_Write;
18904    d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18905    d->fxState[1].size = sizeof(V128);
18906 
18907    stmt(IRStmt_Dirty(d));
18908    s390_cc_set(cc);
18909 
18910    return "vftci";
18911 }
18912 
18913 /* New insns are added here.
18914    If an insn is contingent on a facility being installed also
18915    check whether the list of supported facilities in function
18916    s390x_dirtyhelper_STFLE needs updating */
18917 
18918 /*------------------------------------------------------------*/
18919 /*--- Build IR for special instructions                    ---*/
18920 /*------------------------------------------------------------*/
18921 
18922 static void
18923 s390_irgen_client_request(void)
18924 {
18925    if (0)
18926       vex_printf("%%R3 = client_request ( %%R2 )\n");
18927 
18928    Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
18929                                      + S390_SPECIAL_OP_SIZE;
18930 
18931    dis_res->jk_StopHere = Ijk_ClientReq;
18932    dis_res->whatNext = Dis_StopHere;
18933 
18934    put_IA(mkaddr_expr(next));
18935 }
18936 
18937 static void
18938 s390_irgen_guest_NRADDR(void)
18939 {
18940    if (0)
18941       vex_printf("%%R3 = guest_NRADDR\n");
18942 
18943    put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
18944 }
18945 
18946 static void
18947 s390_irgen_call_noredir(void)
18948 {
18949    Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
18950                                      + S390_SPECIAL_OP_SIZE;
18951 
18952    /* Continue after special op */
18953    put_gpr_dw0(14, mkaddr_expr(next));
18954 
18955    /* The address is in REG1, all parameters are in the right (guest) places */
18956    put_IA(get_gpr_dw0(1));
18957 
18958    dis_res->whatNext = Dis_StopHere;
18959    dis_res->jk_StopHere = Ijk_NoRedir;
18960 }
18961 
18962 static s390_decode_t
18963 s390_decode_2byte_and_irgen(const UChar *bytes)
18964 {
18965    UShort ovl = ((UShort)bytes[0] << 8) | (UShort)bytes[1];
18966 
18967    switch (ovl & 0xffff) {
18968    case 0x0101: /* PR */ goto unimplemented;
18969    case 0x0102: /* UPT */ goto unimplemented;
18970    case 0x0104: /* PTFF */ goto unimplemented;
18971    case 0x0107: /* SCKPF */ goto unimplemented;
18972    case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
18973    case 0x010b: /* TAM */ goto unimplemented;
18974    case 0x010c: /* SAM24 */ goto unimplemented;
18975    case 0x010d: /* SAM31 */ goto unimplemented;
18976    case 0x010e: /* SAM64 */ goto unimplemented;
18977    case 0x01ff: /* TRAP2 */ goto unimplemented;
18978    }
18979 
18980    switch ((ovl & 0xff00) >> 8) {
18981    case 0x04: /* SPM */ goto unimplemented;
18982    case 0x05: /* BALR */ goto unimplemented;
18983    case 0x06: s390_format_RR_RR(s390_irgen_BCTR, RR_r1(ovl), RR_r2(ovl));
18984                                 goto ok;
18985    case 0x07: s390_format_RR(s390_irgen_BCR, RR_r1(ovl), RR_r2(ovl));
18986                              goto ok;
18987    case 0x0a: s390_format_I(s390_irgen_SVC, I_i(ovl));  goto ok;
18988    case 0x0b: /* BSM */ goto unimplemented;
18989    case 0x0c: /* BASSM */ goto unimplemented;
18990    case 0x0d: s390_format_RR_RR(s390_irgen_BASR, RR_r1(ovl), RR_r2(ovl));
18991                                 goto ok;
18992    case 0x0e: s390_format_RR(s390_irgen_MVCL, RR_r1(ovl), RR_r2(ovl));
18993                              goto ok;
18994    case 0x0f: s390_format_RR(s390_irgen_CLCL, RR_r1(ovl), RR_r2(ovl));
18995                              goto ok;
18996    case 0x10: s390_format_RR_RR(s390_irgen_LPR, RR_r1(ovl), RR_r2(ovl));
18997                                 goto ok;
18998    case 0x11: s390_format_RR_RR(s390_irgen_LNR, RR_r1(ovl), RR_r2(ovl));
18999                                 goto ok;
19000    case 0x12: s390_format_RR_RR(s390_irgen_LTR, RR_r1(ovl), RR_r2(ovl));
19001                                 goto ok;
19002    case 0x13: s390_format_RR_RR(s390_irgen_LCR, RR_r1(ovl), RR_r2(ovl));
19003                                 goto ok;
19004    case 0x14: s390_format_RR_RR(s390_irgen_NR, RR_r1(ovl), RR_r2(ovl));
19005                                 goto ok;
19006    case 0x15: s390_format_RR_RR(s390_irgen_CLR, RR_r1(ovl), RR_r2(ovl));
19007                                 goto ok;
19008    case 0x16: s390_format_RR_RR(s390_irgen_OR, RR_r1(ovl), RR_r2(ovl));
19009                                 goto ok;
19010    case 0x17: s390_format_RR_RR(s390_irgen_XR, RR_r1(ovl), RR_r2(ovl));
19011                                 goto ok;
19012    case 0x18: s390_format_RR_RR(s390_irgen_LR, RR_r1(ovl), RR_r2(ovl));
19013                                 goto ok;
19014    case 0x19: s390_format_RR_RR(s390_irgen_CR, RR_r1(ovl), RR_r2(ovl));
19015                                 goto ok;
19016    case 0x1a: s390_format_RR_RR(s390_irgen_AR, RR_r1(ovl), RR_r2(ovl));
19017                                 goto ok;
19018    case 0x1b: s390_format_RR_RR(s390_irgen_SR, RR_r1(ovl), RR_r2(ovl));
19019                                 goto ok;
19020    case 0x1c: s390_format_RR_RR(s390_irgen_MR, RR_r1(ovl), RR_r2(ovl));
19021                                 goto ok;
19022    case 0x1d: s390_format_RR_RR(s390_irgen_DR, RR_r1(ovl), RR_r2(ovl));
19023                                 goto ok;
19024    case 0x1e: s390_format_RR_RR(s390_irgen_ALR, RR_r1(ovl), RR_r2(ovl));
19025                                 goto ok;
19026    case 0x1f: s390_format_RR_RR(s390_irgen_SLR, RR_r1(ovl), RR_r2(ovl));
19027                                 goto ok;
19028    case 0x20: /* LPDR */ goto unimplemented;
19029    case 0x21: /* LNDR */ goto unimplemented;
19030    case 0x22: /* LTDR */ goto unimplemented;
19031    case 0x23: /* LCDR */ goto unimplemented;
19032    case 0x24: /* HDR */ goto unimplemented;
19033    case 0x25: /* LDXR */ goto unimplemented;
19034    case 0x26: /* MXR */ goto unimplemented;
19035    case 0x27: /* MXDR */ goto unimplemented;
19036    case 0x28: s390_format_RR_FF(s390_irgen_LDR, RR_r1(ovl), RR_r2(ovl));
19037                                 goto ok;
19038    case 0x29: /* CDR */ goto unimplemented;
19039    case 0x2a: /* ADR */ goto unimplemented;
19040    case 0x2b: /* SDR */ goto unimplemented;
19041    case 0x2c: /* MDR */ goto unimplemented;
19042    case 0x2d: /* DDR */ goto unimplemented;
19043    case 0x2e: /* AWR */ goto unimplemented;
19044    case 0x2f: /* SWR */ goto unimplemented;
19045    case 0x30: /* LPER */ goto unimplemented;
19046    case 0x31: /* LNER */ goto unimplemented;
19047    case 0x32: /* LTER */ goto unimplemented;
19048    case 0x33: /* LCER */ goto unimplemented;
19049    case 0x34: /* HER */ goto unimplemented;
19050    case 0x35: /* LEDR */ goto unimplemented;
19051    case 0x36: /* AXR */ goto unimplemented;
19052    case 0x37: /* SXR */ goto unimplemented;
19053    case 0x38: s390_format_RR_FF(s390_irgen_LER, RR_r1(ovl), RR_r2(ovl));
19054                                 goto ok;
19055    case 0x39: /* CER */ goto unimplemented;
19056    case 0x3a: /* AER */ goto unimplemented;
19057    case 0x3b: /* SER */ goto unimplemented;
19058    case 0x3c: /* MDER */ goto unimplemented;
19059    case 0x3d: /* DER */ goto unimplemented;
19060    case 0x3e: /* AUR */ goto unimplemented;
19061    case 0x3f: /* SUR */ goto unimplemented;
19062    }
19063 
19064    return S390_DECODE_UNKNOWN_INSN;
19065 
19066 ok:
19067    return S390_DECODE_OK;
19068 
19069 unimplemented:
19070    return S390_DECODE_UNIMPLEMENTED_INSN;
19071 }
19072 
19073 static s390_decode_t
19074 s390_decode_4byte_and_irgen(const UChar *bytes)
19075 {
19076    UInt ovl = ((UInt)bytes[0] << 24) | ((UInt)bytes[1] << 16) |
19077               ((UInt)bytes[2] << 8) | (UInt)bytes[3];
19078 
19079    switch ((ovl & 0xff0f0000) >> 16) {
19080    case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, RI_r1(ovl),
19081                                   RI_i2(ovl));  goto ok;
19082    case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, RI_r1(ovl),
19083                                   RI_i2(ovl));  goto ok;
19084    case 0xa502: s390_format_RI_RU(s390_irgen_IILH, RI_r1(ovl),
19085                                   RI_i2(ovl));  goto ok;
19086    case 0xa503: s390_format_RI_RU(s390_irgen_IILL, RI_r1(ovl),
19087                                   RI_i2(ovl));  goto ok;
19088    case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, RI_r1(ovl),
19089                                   RI_i2(ovl));  goto ok;
19090    case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, RI_r1(ovl),
19091                                   RI_i2(ovl));  goto ok;
19092    case 0xa506: s390_format_RI_RU(s390_irgen_NILH, RI_r1(ovl),
19093                                   RI_i2(ovl));  goto ok;
19094    case 0xa507: s390_format_RI_RU(s390_irgen_NILL, RI_r1(ovl),
19095                                   RI_i2(ovl));  goto ok;
19096    case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, RI_r1(ovl),
19097                                   RI_i2(ovl));  goto ok;
19098    case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, RI_r1(ovl),
19099                                   RI_i2(ovl));  goto ok;
19100    case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, RI_r1(ovl),
19101                                   RI_i2(ovl));  goto ok;
19102    case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, RI_r1(ovl),
19103                                   RI_i2(ovl));  goto ok;
19104    case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, RI_r1(ovl),
19105                                   RI_i2(ovl));  goto ok;
19106    case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, RI_r1(ovl),
19107                                   RI_i2(ovl));  goto ok;
19108    case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, RI_r1(ovl),
19109                                   RI_i2(ovl));  goto ok;
19110    case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, RI_r1(ovl),
19111                                   RI_i2(ovl));  goto ok;
19112    case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, RI_r1(ovl),
19113                                   RI_i2(ovl));  goto ok;
19114    case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, RI_r1(ovl),
19115                                   RI_i2(ovl));  goto ok;
19116    case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, RI_r1(ovl),
19117                                   RI_i2(ovl));  goto ok;
19118    case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, RI_r1(ovl),
19119                                   RI_i2(ovl));  goto ok;
19120    case 0xa704: s390_format_RI(s390_irgen_BRC, RI_r1(ovl), RI_i2(ovl));
19121                                goto ok;
19122    case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, RI_r1(ovl),
19123                                   RI_i2(ovl));  goto ok;
19124    case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, RI_r1(ovl),
19125                                   RI_i2(ovl));  goto ok;
19126    case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, RI_r1(ovl),
19127                                   RI_i2(ovl));  goto ok;
19128    case 0xa708: s390_format_RI_RI(s390_irgen_LHI, RI_r1(ovl), RI_i2(ovl));
19129                                   goto ok;
19130    case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, RI_r1(ovl),
19131                                   RI_i2(ovl));  goto ok;
19132    case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, RI_r1(ovl), RI_i2(ovl));
19133                                   goto ok;
19134    case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, RI_r1(ovl),
19135                                   RI_i2(ovl));  goto ok;
19136    case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, RI_r1(ovl), RI_i2(ovl));
19137                                   goto ok;
19138    case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, RI_r1(ovl),
19139                                   RI_i2(ovl));  goto ok;
19140    case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, RI_r1(ovl), RI_i2(ovl));
19141                                   goto ok;
19142    case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, RI_r1(ovl),
19143                                   RI_i2(ovl));  goto ok;
19144    }
19145 
19146    switch ((ovl & 0xffff0000) >> 16) {
19147    case 0x8000: /* SSM */ goto unimplemented;
19148    case 0x8200: /* LPSW */ goto unimplemented;
19149    case 0x9300: /* TS */ goto unimplemented;
19150    case 0xb202: /* STIDP */ goto unimplemented;
19151    case 0xb204: /* SCK */ goto unimplemented;
19152    case 0xb205: s390_format_S_RD(s390_irgen_STCK, S_b2(ovl), S_d2(ovl));
19153                 goto ok;
19154    case 0xb206: /* SCKC */ goto unimplemented;
19155    case 0xb207: /* STCKC */ goto unimplemented;
19156    case 0xb208: /* SPT */ goto unimplemented;
19157    case 0xb209: /* STPT */ goto unimplemented;
19158    case 0xb20a: /* SPKA */ goto unimplemented;
19159    case 0xb20b: /* IPK */ goto unimplemented;
19160    case 0xb20d: /* PTLB */ goto unimplemented;
19161    case 0xb210: /* SPX */ goto unimplemented;
19162    case 0xb211: /* STPX */ goto unimplemented;
19163    case 0xb212: /* STAP */ goto unimplemented;
19164    case 0xb214: /* SIE */ goto unimplemented;
19165    case 0xb218: /* PC */ goto unimplemented;
19166    case 0xb219: /* SAC */ goto unimplemented;
19167    case 0xb21a: /* CFC */ goto unimplemented;
19168    case 0xb221: /* IPTE */ goto unimplemented;
19169    case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, RRE_r1(ovl));  goto ok;
19170    case 0xb223: /* IVSK */ goto unimplemented;
19171    case 0xb224: /* IAC */ goto unimplemented;
19172    case 0xb225: /* SSAR */ goto unimplemented;
19173    case 0xb226: /* EPAR */ goto unimplemented;
19174    case 0xb227: /* ESAR */ goto unimplemented;
19175    case 0xb228: /* PT */ goto unimplemented;
19176    case 0xb229: /* ISKE */ goto unimplemented;
19177    case 0xb22a: /* RRBE */ goto unimplemented;
19178    case 0xb22b: /* SSKE */ goto unimplemented;
19179    case 0xb22c: /* TB */ goto unimplemented;
19180    case 0xb22d: /* DXR */ goto unimplemented;
19181    case 0xb22e: /* PGIN */ goto unimplemented;
19182    case 0xb22f: /* PGOUT */ goto unimplemented;
19183    case 0xb230: /* CSCH */ goto unimplemented;
19184    case 0xb231: /* HSCH */ goto unimplemented;
19185    case 0xb232: /* MSCH */ goto unimplemented;
19186    case 0xb233: /* SSCH */ goto unimplemented;
19187    case 0xb234: /* STSCH */ goto unimplemented;
19188    case 0xb235: /* TSCH */ goto unimplemented;
19189    case 0xb236: /* TPI */ goto unimplemented;
19190    case 0xb237: /* SAL */ goto unimplemented;
19191    case 0xb238: /* RSCH */ goto unimplemented;
19192    case 0xb239: /* STCRW */ goto unimplemented;
19193    case 0xb23a: /* STCPS */ goto unimplemented;
19194    case 0xb23b: /* RCHP */ goto unimplemented;
19195    case 0xb23c: /* SCHM */ goto unimplemented;
19196    case 0xb240: /* BAKR */ goto unimplemented;
19197    case 0xb241: s390_format_RRE(s390_irgen_CKSM, RRE_r1(ovl),
19198                                 RRE_r2(ovl));  goto ok;
19199    case 0xb244: /* SQDR */ goto unimplemented;
19200    case 0xb245: /* SQER */ goto unimplemented;
19201    case 0xb246: /* STURA */ goto unimplemented;
19202    case 0xb247: /* MSTA */ goto unimplemented;
19203    case 0xb248: /* PALB */ goto unimplemented;
19204    case 0xb249: /* EREG */ goto unimplemented;
19205    case 0xb24a: /* ESTA */ goto unimplemented;
19206    case 0xb24b: /* LURA */ goto unimplemented;
19207    case 0xb24c: /* TAR */ goto unimplemented;
19208    case 0xb24d: s390_format_RRE(s390_irgen_CPYA, RRE_r1(ovl),
19209                                 RRE_r2(ovl));  goto ok;
19210    case 0xb24e: s390_format_RRE(s390_irgen_SAR, RRE_r1(ovl), RRE_r2(ovl));
19211                                 goto ok;
19212    case 0xb24f: s390_format_RRE(s390_irgen_EAR, RRE_r1(ovl), RRE_r2(ovl));
19213                                 goto ok;
19214    case 0xb250: /* CSP */ goto unimplemented;
19215    case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, RRE_r1(ovl),
19216                                    RRE_r2(ovl));  goto ok;
19217    case 0xb254: /* MVPG */ goto unimplemented;
19218    case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, RRE_r1(ovl),
19219                                    RRE_r2(ovl));  goto ok;
19220    case 0xb257: /* CUSE */ goto unimplemented;
19221    case 0xb258: /* BSG */ goto unimplemented;
19222    case 0xb25a: /* BSA */ goto unimplemented;
19223    case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, RRE_r1(ovl),
19224                                    RRE_r2(ovl));  goto ok;
19225    case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, RRE_r1(ovl),
19226                                    RRE_r2(ovl));  goto ok;
19227    case 0xb263: /* CMPSC */ goto unimplemented;
19228    case 0xb274: /* SIGA */ goto unimplemented;
19229    case 0xb276: /* XSCH */ goto unimplemented;
19230    case 0xb277: /* RP */ goto unimplemented;
19231    case 0xb278: s390_format_S_RD(s390_irgen_STCKE, S_b2(ovl), S_d2(ovl));goto ok;
19232    case 0xb279: /* SACF */ goto unimplemented;
19233    case 0xb27c: s390_format_S_RD(s390_irgen_STCKF, S_b2(ovl), S_d2(ovl));goto ok;
19234    case 0xb27d: /* STSI */ goto unimplemented;
19235    case 0xb280: /* LPP */ goto unimplemented;
19236    case 0xb284: /* LCCTL */ goto unimplemented;
19237    case 0xb285: /* LPCTL */ goto unimplemented;
19238    case 0xb286: /* QSI */ goto unimplemented;
19239    case 0xb287: /* LSCTL */ goto unimplemented;
19240    case 0xb28e: /* QCTRI */ goto unimplemented;
19241    case 0xb299: s390_format_S_RD(s390_irgen_SRNM, S_b2(ovl), S_d2(ovl));
19242                                  goto ok;
19243    case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, S_b2(ovl), S_d2(ovl));
19244                                  goto ok;
19245    case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, S_b2(ovl), S_d2(ovl));
19246                                  goto ok;
19247    case 0xb2a5: s390_format_RRE_FF(s390_irgen_TRE, RRE_r1(ovl), RRE_r2(ovl));  goto ok;
19248    case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, RRF3_r3(ovl),
19249                                        RRF3_r1(ovl), RRF3_r2(ovl));
19250       goto ok;
19251    case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, RRF3_r3(ovl),
19252                                        RRF3_r1(ovl), RRF3_r2(ovl));
19253       goto ok;
19254    case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, S_b2(ovl), S_d2(ovl));
19255                                  goto ok;
19256    case 0xb2b1: /* STFL */ goto unimplemented;
19257    case 0xb2b2: /* LPSWE */ goto unimplemented;
19258    case 0xb2b8: s390_irgen_srnmb_wrapper(S_b2(ovl), S_d2(ovl));
19259       goto ok;
19260    case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, S_b2(ovl), S_d2(ovl));
19261       goto ok;
19262    case 0xb2bd: /* LFAS */ goto unimplemented;
19263    case 0xb2e0: /* SCCTR */ goto unimplemented;
19264    case 0xb2e1: /* SPCTR */ goto unimplemented;
19265    case 0xb2e4: /* ECCTR */ goto unimplemented;
19266    case 0xb2e5: /* EPCTR */ goto unimplemented;
19267    case 0xb2e8: /* PPA */ goto unimplemented;
19268    case 0xb2ec: /* ETND */ goto unimplemented;
19269    case 0xb2ed: /* ECPGA */ goto unimplemented;
19270    case 0xb2f8: /* TEND */ goto unimplemented;
19271    case 0xb2fa: /* NIAI */ goto unimplemented;
19272    case 0xb2fc: /* TABORT */ goto unimplemented;
19273    case 0xb2ff: /* TRAP4 */ goto unimplemented;
19274    case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, RRE_r1(ovl),
19275                                    RRE_r2(ovl));  goto ok;
19276    case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, RRE_r1(ovl),
19277                                    RRE_r2(ovl));  goto ok;
19278    case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, RRE_r1(ovl),
19279                                    RRE_r2(ovl));  goto ok;
19280    case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, RRE_r1(ovl),
19281                                    RRE_r2(ovl));  goto ok;
19282    case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, RRE_r1(ovl),
19283                                    RRE_r2(ovl));  goto ok;
19284    case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, RRE_r1(ovl),
19285                                    RRE_r2(ovl));  goto ok;
19286    case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, RRE_r1(ovl),
19287                                    RRE_r2(ovl));  goto ok;
19288    case 0xb307: /* MXDBR */ goto unimplemented;
19289    case 0xb308: /* KEBR */ goto unimplemented;
19290    case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, RRE_r1(ovl),
19291                                    RRE_r2(ovl));  goto ok;
19292    case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, RRE_r1(ovl),
19293                                    RRE_r2(ovl));  goto ok;
19294    case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, RRE_r1(ovl),
19295                                    RRE_r2(ovl));  goto ok;
19296    case 0xb30c: /* MDEBR */ goto unimplemented;
19297    case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, RRE_r1(ovl),
19298                                    RRE_r2(ovl));  goto ok;
19299    case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, RRF_r1(ovl),
19300                                      RRF_r3(ovl), RRF_r2(ovl));  goto ok;
19301    case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, RRF_r1(ovl),
19302                                      RRF_r3(ovl), RRF_r2(ovl));  goto ok;
19303    case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, RRE_r1(ovl),
19304                                    RRE_r2(ovl));  goto ok;
19305    case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, RRE_r1(ovl),
19306                                    RRE_r2(ovl));  goto ok;
19307    case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, RRE_r1(ovl),
19308                                    RRE_r2(ovl));  goto ok;
19309    case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, RRE_r1(ovl),
19310                                    RRE_r2(ovl));  goto ok;
19311    case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, RRE_r1(ovl),
19312                                    RRE_r2(ovl));  goto ok;
19313    case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, RRE_r1(ovl),
19314                                    RRE_r2(ovl));  goto ok;
19315    case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, RRE_r1(ovl),
19316                                    RRE_r2(ovl));  goto ok;
19317    case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, RRE_r1(ovl),
19318                                    RRE_r2(ovl));  goto ok;
19319    case 0xb318: /* KDBR */ goto unimplemented;
19320    case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, RRE_r1(ovl),
19321                                    RRE_r2(ovl));  goto ok;
19322    case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, RRE_r1(ovl),
19323                                    RRE_r2(ovl));  goto ok;
19324    case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, RRE_r1(ovl),
19325                                    RRE_r2(ovl));  goto ok;
19326    case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, RRE_r1(ovl),
19327                                    RRE_r2(ovl));  goto ok;
19328    case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, RRE_r1(ovl),
19329                                    RRE_r2(ovl));  goto ok;
19330    case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, RRF_r1(ovl),
19331                                      RRF_r3(ovl), RRF_r2(ovl));  goto ok;
19332    case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, RRF_r1(ovl),
19333                                      RRF_r3(ovl), RRF_r2(ovl));  goto ok;
19334    case 0xb324: s390_format_RRE_FF(s390_irgen_LDER, RRE_r1(ovl),
19335                                    RRE_r2(ovl)); goto ok;
19336    case 0xb325: /* LXDR */ goto unimplemented;
19337    case 0xb326: /* LXER */ goto unimplemented;
19338    case 0xb32e: /* MAER */ goto unimplemented;
19339    case 0xb32f: /* MSER */ goto unimplemented;
19340    case 0xb336: /* SQXR */ goto unimplemented;
19341    case 0xb337: /* MEER */ goto unimplemented;
19342    case 0xb338: /* MAYLR */ goto unimplemented;
19343    case 0xb339: /* MYLR */ goto unimplemented;
19344    case 0xb33a: /* MAYR */ goto unimplemented;
19345    case 0xb33b: /* MYR */ goto unimplemented;
19346    case 0xb33c: /* MAYHR */ goto unimplemented;
19347    case 0xb33d: /* MYHR */ goto unimplemented;
19348    case 0xb33e: /* MADR */ goto unimplemented;
19349    case 0xb33f: /* MSDR */ goto unimplemented;
19350    case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, RRE_r1(ovl),
19351                                    RRE_r2(ovl));  goto ok;
19352    case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, RRE_r1(ovl),
19353                                    RRE_r2(ovl));  goto ok;
19354    case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, RRE_r1(ovl),
19355                                    RRE_r2(ovl));  goto ok;
19356    case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, RRE_r1(ovl),
19357                                    RRE_r2(ovl));  goto ok;
19358    case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, RRF2_m3(ovl),
19359                                      RRF2_m4(ovl), RRF2_r1(ovl),
19360                                      RRF2_r2(ovl));  goto ok;
19361    case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, RRF2_m3(ovl),
19362                                      RRF2_m4(ovl), RRF2_r1(ovl),
19363                                      RRF2_r2(ovl));  goto ok;
19364    case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, RRF2_m3(ovl),
19365                                      RRF2_m4(ovl), RRF2_r1(ovl),
19366                                      RRF2_r2(ovl));  goto ok;
19367    case 0xb347: s390_format_RRF_UUFF(s390_irgen_FIXBRA, RRF2_m3(ovl),
19368                                      RRF2_m4(ovl), RRF2_r1(ovl),
19369                                      RRF2_r2(ovl));  goto ok;
19370    case 0xb348: /* KXBR */ goto unimplemented;
19371    case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, RRE_r1(ovl),
19372                                    RRE_r2(ovl));  goto ok;
19373    case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, RRE_r1(ovl),
19374                                    RRE_r2(ovl));  goto ok;
19375    case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, RRE_r1(ovl),
19376                                    RRE_r2(ovl));  goto ok;
19377    case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, RRE_r1(ovl),
19378                                    RRE_r2(ovl));  goto ok;
19379    case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, RRE_r1(ovl),
19380                                    RRE_r2(ovl));  goto ok;
19381    case 0xb350: /* TBEDR */ goto unimplemented;
19382    case 0xb351: /* TBDR */ goto unimplemented;
19383    case 0xb353: /* DIEBR */ goto unimplemented;
19384    case 0xb357: s390_format_RRF_UUFF(s390_irgen_FIEBRA, RRF2_m3(ovl),
19385                                      RRF2_m4(ovl), RRF2_r1(ovl),
19386                                      RRF2_r2(ovl));  goto ok;
19387    case 0xb358: /* THDER */ goto unimplemented;
19388    case 0xb359: /* THDR */ goto unimplemented;
19389    case 0xb35b: /* DIDBR */ goto unimplemented;
19390    case 0xb35f: s390_format_RRF_UUFF(s390_irgen_FIDBRA, RRF2_m3(ovl),
19391                                      RRF2_m4(ovl), RRF2_r1(ovl),
19392                                      RRF2_r2(ovl));  goto ok;
19393    case 0xb360: /* LPXR */ goto unimplemented;
19394    case 0xb361: /* LNXR */ goto unimplemented;
19395    case 0xb362: /* LTXR */ goto unimplemented;
19396    case 0xb363: /* LCXR */ goto unimplemented;
19397    case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, RRE_r1(ovl),
19398                                    RRE_r2(ovl));  goto ok;
19399    case 0xb366: /* LEXR */ goto unimplemented;
19400    case 0xb367: /* FIXR */ goto unimplemented;
19401    case 0xb369: /* CXR */ goto unimplemented;
19402    case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, RRE_r1(ovl),
19403                                    RRE_r2(ovl));  goto ok;
19404    case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, RRE_r1(ovl),
19405                                    RRE_r2(ovl));  goto ok;
19406    case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, RRF3_r3(ovl),
19407                                       RRF3_r1(ovl), RRF3_r2(ovl));
19408                                       goto ok;
19409    case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, RRE_r1(ovl),
19410                                    RRE_r2(ovl));  goto ok;
19411    case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, RRE_r1(ovl));  goto ok;
19412    case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, RRE_r1(ovl));  goto ok;
19413    case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, RRE_r1(ovl));  goto ok;
19414    case 0xb377: /* FIER */ goto unimplemented;
19415    case 0xb37f: /* FIDR */ goto unimplemented;
19416    case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, RRE_r1(ovl));  goto ok;
19417    case 0xb385: /* SFASR */ goto unimplemented;
19418    case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, RRE_r1(ovl));  goto ok;
19419    case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, RRF2_m3(ovl),
19420                                      RRF2_m4(ovl), RRF2_r1(ovl),
19421                                      RRF2_r2(ovl));  goto ok;
19422    case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, RRF2_m3(ovl),
19423                                      RRF2_m4(ovl), RRF2_r1(ovl),
19424                                      RRF2_r2(ovl));  goto ok;
19425    case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, RRF2_m3(ovl),
19426                                      RRF2_m4(ovl), RRF2_r1(ovl),
19427                                      RRF2_r2(ovl));  goto ok;
19428    case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, RRF2_m3(ovl),
19429                                      RRF2_m4(ovl), RRF2_r1(ovl),
19430                                      RRF2_r2(ovl));  goto ok;
19431    case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, RRF2_m3(ovl),
19432                                      RRF2_m4(ovl), RRF2_r1(ovl),
19433                                      RRF2_r2(ovl));  goto ok;
19434    case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, RRF2_m3(ovl),
19435                                      RRF2_m4(ovl), RRF2_r1(ovl),
19436                                      RRF2_r2(ovl));  goto ok;
19437    case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, RRF2_m3(ovl),
19438                                      RRF2_m4(ovl), RRF2_r1(ovl),
19439                                      RRF2_r2(ovl));  goto ok;
19440    case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, RRF2_m3(ovl),
19441                                      RRF2_m4(ovl), RRF2_r1(ovl),
19442                                      RRF2_r2(ovl));  goto ok;
19443    case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, RRF2_m3(ovl),
19444                                      RRF2_m4(ovl), RRF2_r1(ovl),
19445                                      RRF2_r2(ovl));  goto ok;
19446    case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, RRF2_m3(ovl),
19447                                      RRF2_m4(ovl), RRF2_r1(ovl),
19448                                      RRF2_r2(ovl));  goto ok;
19449    case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, RRF2_m3(ovl),
19450                                      RRF2_m4(ovl), RRF2_r1(ovl),
19451                                      RRF2_r2(ovl));  goto ok;
19452    case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, RRF2_m3(ovl),
19453                                      RRF2_m4(ovl), RRF2_r1(ovl),
19454                                      RRF2_r2(ovl));  goto ok;
19455    case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, RRF2_m3(ovl),
19456                                      RRF2_m4(ovl), RRF2_r1(ovl),
19457                                      RRF2_r2(ovl));  goto ok;
19458    case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, RRF2_m3(ovl),
19459                                      RRF2_m4(ovl), RRF2_r1(ovl),
19460                                      RRF2_r2(ovl));  goto ok;
19461    case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, RRF2_m3(ovl),
19462                                      RRF2_m4(ovl), RRF2_r1(ovl),
19463                                      RRF2_r2(ovl));  goto ok;
19464    case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, RRF2_m3(ovl),
19465                                      RRF2_m4(ovl), RRF2_r1(ovl),
19466                                      RRF2_r2(ovl));  goto ok;
19467    case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, RRF2_m3(ovl),
19468                                      RRF2_m4(ovl), RRF2_r1(ovl),
19469                                      RRF2_r2(ovl));  goto ok;
19470    case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, RRF2_m3(ovl),
19471                                      RRF2_m4(ovl), RRF2_r1(ovl),
19472                                      RRF2_r2(ovl));  goto ok;
19473    case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, RRF2_m3(ovl),
19474                                      RRF2_m4(ovl), RRF2_r1(ovl),
19475                                      RRF2_r2(ovl));  goto ok;
19476    case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, RRF2_m3(ovl),
19477                                      RRF2_m4(ovl), RRF2_r1(ovl),
19478                                      RRF2_r2(ovl));  goto ok;
19479    case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, RRF2_m3(ovl),
19480                                      RRF2_m4(ovl), RRF2_r1(ovl),
19481                                      RRF2_r2(ovl));  goto ok;
19482    case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, RRF2_m3(ovl),
19483                                      RRF2_m4(ovl), RRF2_r1(ovl),
19484                                      RRF2_r2(ovl));  goto ok;
19485    case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, RRF2_m3(ovl),
19486                                      RRF2_m4(ovl), RRF2_r1(ovl),
19487                                      RRF2_r2(ovl));  goto ok;
19488    case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, RRF2_m3(ovl),
19489                                      RRF2_m4(ovl), RRF2_r1(ovl),
19490                                      RRF2_r2(ovl));  goto ok;
19491    case 0xb3b4: /* CEFR */ goto unimplemented;
19492    case 0xb3b5: /* CDFR */ goto unimplemented;
19493    case 0xb3b6: /* CXFR */ goto unimplemented;
19494    case 0xb3b8: /* CFER */ goto unimplemented;
19495    case 0xb3b9: /* CFDR */ goto unimplemented;
19496    case 0xb3ba: /* CFXR */ goto unimplemented;
19497    case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, RRE_r1(ovl),
19498                                    RRE_r2(ovl));  goto ok;
19499    case 0xb3c4: /* CEGR */ goto unimplemented;
19500    case 0xb3c5: /* CDGR */ goto unimplemented;
19501    case 0xb3c6: /* CXGR */ goto unimplemented;
19502    case 0xb3c8: /* CGER */ goto unimplemented;
19503    case 0xb3c9: /* CGDR */ goto unimplemented;
19504    case 0xb3ca: /* CGXR */ goto unimplemented;
19505    case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, RRE_r1(ovl),
19506                                    RRE_r2(ovl));  goto ok;
19507    case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, RRF4_r3(ovl),
19508                                       RRF4_m4(ovl), RRF4_r1(ovl),
19509                                       RRF4_r2(ovl)); goto ok;
19510    case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, RRF4_r3(ovl),
19511                                       RRF4_m4(ovl), RRF4_r1(ovl),
19512                                       RRF4_r2(ovl)); goto ok;
19513    case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, RRF4_r3(ovl),
19514                                       RRF4_m4(ovl), RRF4_r1(ovl),
19515                                       RRF4_r2(ovl)); goto ok;
19516    case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, RRF4_r3(ovl),
19517                                       RRF4_m4(ovl), RRF4_r1(ovl),
19518                                       RRF4_r2(ovl)); goto ok;
19519    case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, RRF5_m4(ovl),
19520                                      RRF5_r1(ovl), RRF5_r2(ovl)); goto ok;
19521    case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, RRF2_m3(ovl),
19522                                      RRF2_m4(ovl), RRF2_r1(ovl),
19523                                      RRF2_r2(ovl));  goto ok;
19524    case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, RRE_r1(ovl),
19525                                    RRE_r2(ovl));  goto ok;
19526    case 0xb3d7: /* FIDTR */ goto unimplemented;
19527    case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, RRF4_r3(ovl),
19528                                      RRF4_m4(ovl), RRF4_r1(ovl),
19529                                      RRF4_r2(ovl)); goto ok;
19530    case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, RRF4_r3(ovl),
19531                                      RRF4_m4(ovl), RRF4_r1(ovl),
19532                                      RRF4_r2(ovl)); goto ok;
19533    case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, RRF4_r3(ovl),
19534                                      RRF4_m4(ovl), RRF4_r1(ovl),
19535                                      RRF4_r2(ovl)); goto ok;
19536    case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, RRF4_r3(ovl),
19537                                      RRF4_m4(ovl), RRF4_r1(ovl),
19538                                      RRF4_r2(ovl)); goto ok;
19539    case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, RRF5_m4(ovl),
19540                                      RRF5_r1(ovl), RRF5_r2(ovl)); goto ok;
19541    case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, RRF2_m3(ovl),
19542                                      RRF2_m4(ovl), RRF2_r1(ovl),
19543                                      RRF2_r2(ovl));  goto ok;
19544    case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, RRE_r1(ovl),
19545                                    RRE_r2(ovl));  goto ok;
19546    case 0xb3df: /* FIXTR */ goto unimplemented;
19547    case 0xb3e0: /* KDTR */ goto unimplemented;
19548    case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, RRF2_m3(ovl),
19549                                      RRF2_m4(ovl), RRF2_r1(ovl),
19550                                      RRF2_r2(ovl));  goto ok;
19551    case 0xb3e2: /* CUDTR */ goto unimplemented;
19552    case 0xb3e3: /* CSDTR */ goto unimplemented;
19553    case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, RRE_r1(ovl),
19554                                    RRE_r2(ovl));  goto ok;
19555    case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, RRE_r1(ovl),
19556                                    RRE_r2(ovl));  goto ok;
19557    case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, RRE_r1(ovl),
19558                                    RRE_r2(ovl));  goto ok;
19559    case 0xb3e8: /* KXTR */ goto unimplemented;
19560    case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, RRF2_m3(ovl),
19561                                      RRF2_m4(ovl), RRF2_r1(ovl),
19562                                      RRF2_r2(ovl));  goto ok;
19563    case 0xb3ea: /* CUXTR */ goto unimplemented;
19564    case 0xb3eb: /* CSXTR */ goto unimplemented;
19565    case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, RRE_r1(ovl),
19566                                    RRE_r2(ovl));  goto ok;
19567    case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, RRE_r1(ovl),
19568                                    RRE_r2(ovl));  goto ok;
19569    case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, RRE_r1(ovl),
19570                                    RRE_r2(ovl));  goto ok;
19571    case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, RRF2_m3(ovl),
19572                                      RRF2_m4(ovl), RRF2_r1(ovl),
19573                                      RRF2_r2(ovl));  goto ok;
19574    case 0xb3f2: /* CDUTR */ goto unimplemented;
19575    case 0xb3f3: /* CDSTR */ goto unimplemented;
19576    case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, RRE_r1(ovl),
19577                                    RRE_r2(ovl));  goto ok;
19578    case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, RRF4_r3(ovl),
19579                                      RRF4_m4(ovl), RRF4_r1(ovl),
19580                                      RRF4_r2(ovl)); goto ok;
19581    case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, RRF3_r3(ovl),
19582                                      RRF3_r1(ovl), RRF3_r2(ovl)); goto ok;
19583    case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, RRF4_r3(ovl),
19584                                      RRF4_m4(ovl), RRF4_r1(ovl),
19585                                      RRF4_r2(ovl)); goto ok;
19586    case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, RRF2_m3(ovl),
19587                                      RRF2_m4(ovl), RRF2_r1(ovl),
19588                                      RRF2_r2(ovl));  goto ok;
19589    case 0xb3fa: /* CXUTR */ goto unimplemented;
19590    case 0xb3fb: /* CXSTR */ goto unimplemented;
19591    case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, RRE_r1(ovl),
19592                                    RRE_r2(ovl));  goto ok;
19593    case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, RRF4_r3(ovl),
19594                                      RRF4_m4(ovl), RRF4_r1(ovl),
19595                                      RRF4_r2(ovl)); goto ok;
19596    case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, RRF3_r3(ovl),
19597                                      RRF3_r1(ovl), RRF3_r2(ovl)); goto ok;
19598    case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, RRF4_r3(ovl),
19599                                      RRF4_m4(ovl), RRF4_r1(ovl),
19600                                      RRF4_r2(ovl)); goto ok;
19601    case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, RRE_r1(ovl),
19602                                    RRE_r2(ovl));  goto ok;
19603    case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, RRE_r1(ovl),
19604                                    RRE_r2(ovl));  goto ok;
19605    case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, RRE_r1(ovl),
19606                                    RRE_r2(ovl));  goto ok;
19607    case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, RRE_r1(ovl),
19608                                    RRE_r2(ovl));  goto ok;
19609    case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, RRE_r1(ovl),
19610                                    RRE_r2(ovl));  goto ok;
19611    case 0xb905: /* LURAG */ goto unimplemented;
19612    case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, RRE_r1(ovl),
19613                                    RRE_r2(ovl));  goto ok;
19614    case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, RRE_r1(ovl),
19615                                    RRE_r2(ovl));  goto ok;
19616    case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, RRE_r1(ovl),
19617                                    RRE_r2(ovl));  goto ok;
19618    case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, RRE_r1(ovl),
19619                                    RRE_r2(ovl));  goto ok;
19620    case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, RRE_r1(ovl),
19621                                    RRE_r2(ovl));  goto ok;
19622    case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, RRE_r1(ovl),
19623                                    RRE_r2(ovl));  goto ok;
19624    case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, RRE_r1(ovl),
19625                                    RRE_r2(ovl));  goto ok;
19626    case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, RRE_r1(ovl),
19627                                    RRE_r2(ovl));  goto ok;
19628    case 0xb90e: /* EREGG */ goto unimplemented;
19629    case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, RRE_r1(ovl),
19630                                    RRE_r2(ovl));  goto ok;
19631    case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, RRE_r1(ovl),
19632                                    RRE_r2(ovl));  goto ok;
19633    case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, RRE_r1(ovl),
19634                                    RRE_r2(ovl));  goto ok;
19635    case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, RRE_r1(ovl),
19636                                    RRE_r2(ovl));  goto ok;
19637    case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, RRE_r1(ovl),
19638                                    RRE_r2(ovl));  goto ok;
19639    case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, RRE_r1(ovl),
19640                                    RRE_r2(ovl));  goto ok;
19641    case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, RRE_r1(ovl),
19642                                    RRE_r2(ovl));  goto ok;
19643    case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, RRE_r1(ovl),
19644                                    RRE_r2(ovl));  goto ok;
19645    case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, RRE_r1(ovl),
19646                                    RRE_r2(ovl));  goto ok;
19647    case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, RRE_r1(ovl),
19648                                    RRE_r2(ovl));  goto ok;
19649    case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, RRE_r1(ovl),
19650                                    RRE_r2(ovl));  goto ok;
19651    case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, RRE_r1(ovl),
19652                                    RRE_r2(ovl));  goto ok;
19653    case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, RRE_r1(ovl),
19654                                    RRE_r2(ovl));  goto ok;
19655    case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, RRE_r1(ovl),
19656                                    RRE_r2(ovl));  goto ok;
19657    case 0xb91e: /* KMAC */ goto unimplemented;
19658    case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, RRE_r1(ovl),
19659                                    RRE_r2(ovl));  goto ok;
19660    case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, RRE_r1(ovl),
19661                                    RRE_r2(ovl));  goto ok;
19662    case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, RRE_r1(ovl),
19663                                    RRE_r2(ovl));  goto ok;
19664    case 0xb925: /* STURG */ goto unimplemented;
19665    case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, RRE_r1(ovl),
19666                                    RRE_r2(ovl));  goto ok;
19667    case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, RRE_r1(ovl),
19668                                    RRE_r2(ovl));  goto ok;
19669    case 0xb928: /* PCKMO */ goto unimplemented;
19670    case 0xb929: /* KMA */ goto unimplemented;
19671    case 0xb92a: /* KMF */ goto unimplemented;
19672    case 0xb92b: /* KMO */ goto unimplemented;
19673    case 0xb92c: /* PCC */ goto unimplemented;
19674    case 0xb92d: /* KMCTR */ goto unimplemented;
19675    case 0xb92e: /* KM */ goto unimplemented;
19676    case 0xb92f: /* KMC */ goto unimplemented;
19677    case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, RRE_r1(ovl),
19678                                    RRE_r2(ovl));  goto ok;
19679    case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, RRE_r1(ovl),
19680                                    RRE_r2(ovl));  goto ok;
19681    case 0xb93c: s390_format_RRE_RR(s390_irgen_PPNO, RRE_r1(ovl),
19682                                    RRE_r2(ovl));  goto ok;
19683    case 0xb93e: /* KIMD */ goto unimplemented;
19684    case 0xb93f: /* KLMD */ goto unimplemented;
19685    case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, RRF2_m3(ovl),
19686                                      RRF2_m4(ovl), RRF2_r1(ovl),
19687                                      RRF2_r2(ovl));  goto ok;
19688    case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, RRF2_m3(ovl),
19689                                      RRF2_m4(ovl), RRF2_r1(ovl),
19690                                      RRF2_r2(ovl));  goto ok;
19691    case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, RRF2_m3(ovl),
19692                                      RRF2_m4(ovl), RRF2_r1(ovl),
19693                                      RRF2_r2(ovl));  goto ok;
19694    case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, RRE_r1(ovl),
19695                                    RRE_r2(ovl));  goto ok;
19696    case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, RRF2_m3(ovl),
19697                                      RRF2_m4(ovl), RRF2_r1(ovl),
19698                                      RRF2_r2(ovl));  goto ok;
19699    case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, RRF2_m3(ovl),
19700                                      RRF2_m4(ovl), RRF2_r1(ovl),
19701                                      RRF2_r2(ovl));  goto ok;
19702    case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, RRF2_m3(ovl),
19703                                      RRF2_m4(ovl), RRF2_r1(ovl),
19704                                      RRF2_r2(ovl));  goto ok;
19705    case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, RRF2_m3(ovl),
19706                                      RRF2_m4(ovl), RRF2_r1(ovl),
19707                                      RRF2_r2(ovl));  goto ok;
19708    case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, RRF2_m3(ovl),
19709                                      RRF2_m4(ovl), RRF2_r1(ovl),
19710                                      RRF2_r2(ovl));  goto ok;
19711    case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, RRF2_m3(ovl),
19712                                      RRF2_m4(ovl), RRF2_r1(ovl),
19713                                      RRF2_r2(ovl));  goto ok;
19714    case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, RRF2_m3(ovl),
19715                                      RRF2_m4(ovl), RRF2_r1(ovl),
19716                                      RRF2_r2(ovl));  goto ok;
19717    case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, RRF2_m3(ovl),
19718                                      RRF2_m4(ovl), RRF2_r1(ovl),
19719                                      RRF2_r2(ovl));  goto ok;
19720    case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, RRF2_m3(ovl),
19721                                      RRF2_m4(ovl), RRF2_r1(ovl),
19722                                      RRF2_r2(ovl));  goto ok;
19723    case 0xb960: s390_format_RRF_U0RR(s390_irgen_CGRT, RRF2_m3(ovl),
19724                                      RRF2_r1(ovl), RRF2_r2(ovl),
19725                                      S390_XMNM_CAB); goto ok;
19726    case 0xb961: s390_format_RRF_U0RR(s390_irgen_CLGRT, RRF2_m3(ovl),
19727                                      RRF2_r1(ovl), RRF2_r2(ovl),
19728                                      S390_XMNM_CAB); goto ok;
19729    case 0xb972: s390_format_RRF_U0RR(s390_irgen_CRT, RRF2_m3(ovl),
19730                                      RRF2_r1(ovl), RRF2_r2(ovl),
19731                                      S390_XMNM_CAB); goto ok;
19732    case 0xb973: s390_format_RRF_U0RR(s390_irgen_CLRT, RRF2_m3(ovl),
19733                                      RRF2_r1(ovl), RRF2_r2(ovl),
19734                                      S390_XMNM_CAB); goto ok;
19735    case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, RRE_r1(ovl),
19736                                    RRE_r2(ovl));  goto ok;
19737    case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, RRE_r1(ovl),
19738                                    RRE_r2(ovl));  goto ok;
19739    case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, RRE_r1(ovl),
19740                                    RRE_r2(ovl));  goto ok;
19741    case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, RRE_r1(ovl),
19742                                    RRE_r2(ovl));  goto ok;
19743    case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, RRE_r1(ovl),
19744                                    RRE_r2(ovl));  goto ok;
19745    case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, RRE_r1(ovl),
19746                                    RRE_r2(ovl));  goto ok;
19747    case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, RRE_r1(ovl),
19748                                    RRE_r2(ovl));  goto ok;
19749    case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, RRE_r1(ovl),
19750                                    RRE_r2(ovl));  goto ok;
19751    case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, RRE_r1(ovl),
19752                                    RRE_r2(ovl));  goto ok;
19753    case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, RRE_r1(ovl),
19754                                    RRE_r2(ovl));  goto ok;
19755    case 0xb98a: /* CSPG */ goto unimplemented;
19756    case 0xb98d: /* EPSW */ goto unimplemented;
19757    case 0xb98e: /* IDTE */ goto unimplemented;
19758    case 0xb98f: /* CRDTE */ goto unimplemented;
19759    case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, RRF3_r3(ovl),
19760                                    RRF3_r1(ovl), RRF3_r2(ovl));  goto ok;
19761    case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, RRF3_r3(ovl),
19762                                    RRF3_r1(ovl), RRF3_r2(ovl));  goto ok;
19763    case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, RRF3_r3(ovl),
19764                                    RRF3_r1(ovl), RRF3_r2(ovl));  goto ok;
19765    case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, RRF3_r3(ovl),
19766                                    RRF3_r1(ovl), RRF3_r2(ovl));  goto ok;
19767    case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, RRE_r1(ovl),
19768                                    RRE_r2(ovl));  goto ok;
19769    case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, RRE_r1(ovl),
19770                                    RRE_r2(ovl));  goto ok;
19771    case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, RRE_r1(ovl),
19772                                    RRE_r2(ovl));  goto ok;
19773    case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, RRE_r1(ovl),
19774                                    RRE_r2(ovl));  goto ok;
19775    case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, RRE_r1(ovl),
19776                                    RRE_r2(ovl));  goto ok;
19777    case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, RRE_r1(ovl),
19778                                    RRE_r2(ovl));  goto ok;
19779    case 0xb99a: /* EPAIR */ goto unimplemented;
19780    case 0xb99b: /* ESAIR */ goto unimplemented;
19781    case 0xb99d: /* ESEA */ goto unimplemented;
19782    case 0xb99e: /* PTI */ goto unimplemented;
19783    case 0xb99f: /* SSAIR */ goto unimplemented;
19784    case 0xb9a1: /* TPEI */ goto unimplemented;
19785    case 0xb9a2: /* PTF */ goto unimplemented;
19786    case 0xb9aa: /* LPTEA */ goto unimplemented;
19787    case 0xb9ac: /* IRBM */ goto unimplemented;
19788    case 0xb9ae: /* RRBM */ goto unimplemented;
19789    case 0xb9af: /* PFMF */ goto unimplemented;
19790    case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, RRF3_r3(ovl),
19791                                        RRF3_r1(ovl), RRF3_r2(ovl));
19792       goto ok;
19793    case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, RRF3_r3(ovl),
19794                                        RRF3_r1(ovl), RRF3_r2(ovl));
19795       goto ok;
19796    case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, RRE_r1(ovl),
19797                                    RRE_r2(ovl));  goto ok;
19798    case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, RRE_r1(ovl),
19799                                    RRE_r2(ovl));  goto ok;
19800    case 0xb9bd: /* TRTRE */ goto unimplemented;
19801    case 0xb9be: /* SRSTU */ goto unimplemented;
19802    case 0xb9bf: /* TRTE */ goto unimplemented;
19803    case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, RRF4_r3(ovl),
19804                                       RRF4_r1(ovl), RRF4_r2(ovl));
19805                                       goto ok;
19806    case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, RRF4_r3(ovl),
19807                                       RRF4_r1(ovl), RRF4_r2(ovl));
19808                                       goto ok;
19809    case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, RRF4_r3(ovl),
19810                                       RRF4_r1(ovl), RRF4_r2(ovl));
19811                                       goto ok;
19812    case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, RRF4_r3(ovl),
19813                                       RRF4_r1(ovl), RRF4_r2(ovl));
19814                                       goto ok;
19815    case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, RRE_r1(ovl),
19816                                    RRE_r2(ovl));  goto ok;
19817    case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, RRE_r1(ovl),
19818                                    RRE_r2(ovl));  goto ok;
19819    case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, RRF4_r3(ovl),
19820                                       RRF4_r1(ovl), RRF4_r2(ovl));
19821                                       goto ok;
19822    case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, RRF4_r3(ovl),
19823                                       RRF4_r1(ovl), RRF4_r2(ovl));
19824                                       goto ok;
19825    case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, RRF4_r3(ovl),
19826                                       RRF4_r1(ovl), RRF4_r2(ovl));
19827                                       goto ok;
19828    case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, RRF4_r3(ovl),
19829                                       RRF4_r1(ovl), RRF4_r2(ovl));
19830                                       goto ok;
19831    case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, RRE_r1(ovl),
19832                                    RRE_r2(ovl));  goto ok;
19833    case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, RRE_r1(ovl),
19834                                    RRE_r2(ovl));  goto ok;
19835    case 0xb9e0: s390_format_RRF_U0RR(s390_irgen_LOCFHR, RRF3_r3(ovl),
19836                                      RRF3_r1(ovl), RRF3_r2(ovl),
19837                                      S390_XMNM_LOCFHR);  goto ok;
19838    case 0xb9e1: s390_format_RRE_RR(s390_irgen_POPCNT, RRE_r1(ovl),
19839                                    RRE_r2(ovl));  goto ok;
19840    case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, RRF3_r3(ovl),
19841                                      RRF3_r1(ovl), RRF3_r2(ovl),
19842                                      S390_XMNM_LOCGR);  goto ok;
19843    case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, RRF4_r3(ovl),
19844                                       RRF4_r1(ovl), RRF4_r2(ovl));
19845                                       goto ok;
19846    case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, RRF4_r3(ovl),
19847                                       RRF4_r1(ovl), RRF4_r2(ovl));
19848                                       goto ok;
19849    case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, RRF4_r3(ovl),
19850                                       RRF4_r1(ovl), RRF4_r2(ovl));
19851                                       goto ok;
19852    case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, RRF4_r3(ovl),
19853                                       RRF4_r1(ovl), RRF4_r2(ovl));
19854                                       goto ok;
19855    case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, RRF4_r3(ovl),
19856                                       RRF4_r1(ovl), RRF4_r2(ovl));
19857                                       goto ok;
19858    case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, RRF4_r3(ovl),
19859                                       RRF4_r1(ovl), RRF4_r2(ovl));
19860                                       goto ok;
19861    case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, RRF4_r3(ovl),
19862                                       RRF4_r1(ovl), RRF4_r2(ovl));
19863                                       goto ok;
19864    case 0xb9ec: s390_format_RRF_R0RR2(s390_irgen_MGRK, RRF4_r3(ovl),
19865                                       RRF4_r1(ovl), RRF4_r2(ovl));
19866                                       goto ok;
19867    case 0xb9ed: s390_format_RRF_R0RR2(s390_irgen_MSGRKC, RRF4_r3(ovl),
19868                                       RRF4_r1(ovl), RRF4_r2(ovl));
19869                                       goto ok;
19870    case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, RRF3_r3(ovl),
19871                                      RRF3_r1(ovl), RRF3_r2(ovl),
19872                                      S390_XMNM_LOCR);  goto ok;
19873    case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, RRF4_r3(ovl),
19874                                       RRF4_r1(ovl), RRF4_r2(ovl));
19875                                       goto ok;
19876    case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, RRF4_r3(ovl),
19877                                       RRF4_r1(ovl), RRF4_r2(ovl));
19878                                       goto ok;
19879    case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, RRF4_r3(ovl),
19880                                       RRF4_r1(ovl), RRF4_r2(ovl));
19881                                       goto ok;
19882    case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, RRF4_r3(ovl),
19883                                       RRF4_r1(ovl), RRF4_r2(ovl));
19884                                       goto ok;
19885    case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, RRF4_r3(ovl),
19886                                       RRF4_r1(ovl), RRF4_r2(ovl));
19887                                       goto ok;
19888    case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, RRF4_r3(ovl),
19889                                       RRF4_r1(ovl), RRF4_r2(ovl));
19890                                       goto ok;
19891    case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, RRF4_r3(ovl),
19892                                       RRF4_r1(ovl), RRF4_r2(ovl));
19893                                       goto ok;
19894    case 0xb9fd: s390_format_RRF_R0RR2(s390_irgen_MSRKC, RRF4_r3(ovl),
19895                                       RRF4_r1(ovl), RRF4_r2(ovl));
19896                                       goto ok;
19897    }
19898 
19899    switch ((ovl & 0xff000000) >> 24) {
19900    case 0x40: s390_format_RX_RRRD(s390_irgen_STH, RX_r1(ovl), RX_x2(ovl),
19901                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19902    case 0x41: s390_format_RX_RRRD(s390_irgen_LA, RX_r1(ovl), RX_x2(ovl),
19903                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19904    case 0x42: s390_format_RX_RRRD(s390_irgen_STC, RX_r1(ovl), RX_x2(ovl),
19905                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19906    case 0x43: s390_format_RX_RRRD(s390_irgen_IC, RX_r1(ovl), RX_x2(ovl),
19907                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19908    case 0x44: s390_format_RX_RRRD(s390_irgen_EX, RX_r1(ovl), RX_x2(ovl),
19909                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19910    case 0x45: /* BAL */ goto unimplemented;
19911    case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, RX_r1(ovl), RX_x2(ovl),
19912                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19913    case 0x47: s390_format_RX(s390_irgen_BC, RX_r1(ovl), RX_x2(ovl),
19914                              RX_b2(ovl), RX_d2(ovl));  goto ok;
19915    case 0x48: s390_format_RX_RRRD(s390_irgen_LH, RX_r1(ovl), RX_x2(ovl),
19916                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19917    case 0x49: s390_format_RX_RRRD(s390_irgen_CH, RX_r1(ovl), RX_x2(ovl),
19918                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19919    case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, RX_r1(ovl), RX_x2(ovl),
19920                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19921    case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, RX_r1(ovl), RX_x2(ovl),
19922                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19923    case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, RX_r1(ovl), RX_x2(ovl),
19924                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19925    case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, RX_r1(ovl), RX_x2(ovl),
19926                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19927    case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, RX_r1(ovl), RX_x2(ovl),
19928                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19929    case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, RX_r1(ovl), RX_x2(ovl),
19930                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19931    case 0x50: s390_format_RX_RRRD(s390_irgen_ST, RX_r1(ovl), RX_x2(ovl),
19932                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19933    case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, RX_r1(ovl), RX_x2(ovl),
19934                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19935    case 0x54: s390_format_RX_RRRD(s390_irgen_N, RX_r1(ovl), RX_x2(ovl),
19936                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19937    case 0x55: s390_format_RX_RRRD(s390_irgen_CL, RX_r1(ovl), RX_x2(ovl),
19938                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19939    case 0x56: s390_format_RX_RRRD(s390_irgen_O, RX_r1(ovl), RX_x2(ovl),
19940                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19941    case 0x57: s390_format_RX_RRRD(s390_irgen_X, RX_r1(ovl), RX_x2(ovl),
19942                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19943    case 0x58: s390_format_RX_RRRD(s390_irgen_L, RX_r1(ovl), RX_x2(ovl),
19944                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19945    case 0x59: s390_format_RX_RRRD(s390_irgen_C, RX_r1(ovl), RX_x2(ovl),
19946                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19947    case 0x5a: s390_format_RX_RRRD(s390_irgen_A, RX_r1(ovl), RX_x2(ovl),
19948                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19949    case 0x5b: s390_format_RX_RRRD(s390_irgen_S, RX_r1(ovl), RX_x2(ovl),
19950                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19951    case 0x5c: s390_format_RX_RRRD(s390_irgen_M, RX_r1(ovl), RX_x2(ovl),
19952                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19953    case 0x5d: s390_format_RX_RRRD(s390_irgen_D, RX_r1(ovl), RX_x2(ovl),
19954                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19955    case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, RX_r1(ovl), RX_x2(ovl),
19956                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19957    case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, RX_r1(ovl), RX_x2(ovl),
19958                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19959    case 0x60: s390_format_RX_FRRD(s390_irgen_STD, RX_r1(ovl), RX_x2(ovl),
19960                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19961    case 0x67: /* MXD */ goto unimplemented;
19962    case 0x68: s390_format_RX_FRRD(s390_irgen_LD, RX_r1(ovl), RX_x2(ovl),
19963                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19964    case 0x69: /* CD */ goto unimplemented;
19965    case 0x6a: /* AD */ goto unimplemented;
19966    case 0x6b: /* SD */ goto unimplemented;
19967    case 0x6c: /* MD */ goto unimplemented;
19968    case 0x6d: /* DD */ goto unimplemented;
19969    case 0x6e: /* AW */ goto unimplemented;
19970    case 0x6f: /* SW */ goto unimplemented;
19971    case 0x70: s390_format_RX_FRRD(s390_irgen_STE, RX_r1(ovl), RX_x2(ovl),
19972                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19973    case 0x71: s390_format_RX_RRRD(s390_irgen_MS, RX_r1(ovl), RX_x2(ovl),
19974                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19975    case 0x78: s390_format_RX_FRRD(s390_irgen_LE, RX_r1(ovl), RX_x2(ovl),
19976                                   RX_b2(ovl), RX_d2(ovl));  goto ok;
19977    case 0x79: /* CE */ goto unimplemented;
19978    case 0x7a: /* AE */ goto unimplemented;
19979    case 0x7b: /* SE */ goto unimplemented;
19980    case 0x7c: /* MDE */ goto unimplemented;
19981    case 0x7d: /* DE */ goto unimplemented;
19982    case 0x7e: /* AU */ goto unimplemented;
19983    case 0x7f: /* SU */ goto unimplemented;
19984    case 0x83: /* DIAG */ goto unimplemented;
19985    case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, RSI_r1(ovl),
19986                                   RSI_r3(ovl), RSI_i2(ovl));  goto ok;
19987    case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, RSI_r1(ovl),
19988                                   RSI_r3(ovl), RSI_i2(ovl));  goto ok;
19989    case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, RS_r1(ovl), RS_r3(ovl),
19990                                   RS_b2(ovl), RS_d2(ovl));  goto ok;
19991    case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, RS_r1(ovl), RS_r3(ovl),
19992                                   RS_b2(ovl), RS_d2(ovl));  goto ok;
19993    case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, RS_r1(ovl), RS_b2(ovl),
19994                                   RS_d2(ovl));  goto ok;
19995    case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, RS_r1(ovl), RS_b2(ovl),
19996                                   RS_d2(ovl));  goto ok;
19997    case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, RS_r1(ovl), RS_b2(ovl),
19998                                   RS_d2(ovl));  goto ok;
19999    case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, RS_r1(ovl), RS_b2(ovl),
20000                                   RS_d2(ovl));  goto ok;
20001    case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, RS_r1(ovl), RS_b2(ovl),
20002                                   RS_d2(ovl));  goto ok;
20003    case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, RS_r1(ovl), RS_b2(ovl),
20004                                   RS_d2(ovl));  goto ok;
20005    case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, RS_r1(ovl), RS_b2(ovl),
20006                                   RS_d2(ovl));  goto ok;
20007    case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, RS_r1(ovl), RS_b2(ovl),
20008                                   RS_d2(ovl));  goto ok;
20009    case 0x90: s390_format_RS_RRRD(s390_irgen_STM, RS_r1(ovl), RS_r3(ovl),
20010                                   RS_b2(ovl), RS_d2(ovl));  goto ok;
20011    case 0x91: s390_format_SI_URD(s390_irgen_TM, SI_i2(ovl), SI_b1(ovl),
20012                                  SI_d1(ovl));  goto ok;
20013    case 0x92: s390_format_SI_URD(s390_irgen_MVI, SI_i2(ovl), SI_b1(ovl),
20014                                  SI_d1(ovl));  goto ok;
20015    case 0x94: s390_format_SI_URD(s390_irgen_NI, SI_i2(ovl), SI_b1(ovl),
20016                                  SI_d1(ovl));  goto ok;
20017    case 0x95: s390_format_SI_URD(s390_irgen_CLI, SI_i2(ovl), SI_b1(ovl),
20018                                  SI_d1(ovl));  goto ok;
20019    case 0x96: s390_format_SI_URD(s390_irgen_OI, SI_i2(ovl), SI_b1(ovl),
20020                                  SI_d1(ovl));  goto ok;
20021    case 0x97: s390_format_SI_URD(s390_irgen_XI, SI_i2(ovl), SI_b1(ovl),
20022                                  SI_d1(ovl));  goto ok;
20023    case 0x98: s390_format_RS_RRRD(s390_irgen_LM, RS_r1(ovl), RS_r3(ovl),
20024                                   RS_b2(ovl), RS_d2(ovl));  goto ok;
20025    case 0x99: /* TRACE */ goto unimplemented;
20026    case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, RS_r1(ovl), RS_r3(ovl),
20027                                   RS_b2(ovl), RS_d2(ovl));  goto ok;
20028    case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, RS_r1(ovl), RS_r3(ovl),
20029                                   RS_b2(ovl), RS_d2(ovl));  goto ok;
20030    case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, RS_r1(ovl),
20031                                   RS_r3(ovl), RS_b2(ovl), RS_d2(ovl));
20032                                   goto ok;
20033    case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, RS_r1(ovl),
20034                                   RS_r3(ovl), RS_b2(ovl), RS_d2(ovl));
20035                                   goto ok;
20036    case 0xac: /* STNSM */ goto unimplemented;
20037    case 0xad: /* STOSM */ goto unimplemented;
20038    case 0xae: /* SIGP */ goto unimplemented;
20039    case 0xaf: /* MC */ goto unimplemented;
20040    case 0xb1: /* LRA */ goto unimplemented;
20041    case 0xb6: /* STCTL */ goto unimplemented;
20042    case 0xb7: /* LCTL */ goto unimplemented;
20043    case 0xba: s390_format_RS_RRRD(s390_irgen_CS, RS_r1(ovl), RS_r3(ovl),
20044                                   RS_b2(ovl), RS_d2(ovl));  goto ok;
20045    case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, RS_r1(ovl), RS_r3(ovl),
20046                                   RS_b2(ovl), RS_d2(ovl));  goto ok;
20047    case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, RS_r1(ovl), RS_r3(ovl),
20048                                   RS_b2(ovl), RS_d2(ovl));  goto ok;
20049    case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, RS_r1(ovl), RS_r3(ovl),
20050                                   RS_b2(ovl), RS_d2(ovl));  goto ok;
20051    case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, RS_r1(ovl), RS_r3(ovl),
20052                                   RS_b2(ovl), RS_d2(ovl));  goto ok;
20053    }
20054 
20055    return S390_DECODE_UNKNOWN_INSN;
20056 
20057 ok:
20058    return S390_DECODE_OK;
20059 
20060 unimplemented:
20061    return S390_DECODE_UNIMPLEMENTED_INSN;
20062 }
20063 
20064 static s390_decode_t
20065 s390_decode_6byte_and_irgen(const UChar *bytes)
20066 {
20067    ULong ovl = ((ULong)bytes[0] << 56) | ((ULong)bytes[1] << 48) |
20068                ((ULong)bytes[2] << 40) | ((ULong)bytes[3] << 32) |
20069                ((ULong)bytes[4] << 24) | ((ULong)bytes[5] << 16);
20070 
20071    switch ((ovl >> 16) & 0xff00000000ffULL) {
20072    case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, RXY_r1(ovl),
20073                                                 RXY_x2(ovl), RXY_b2(ovl),
20074                                                 RXY_dl2(ovl),
20075                                                 RXY_dh2(ovl));  goto ok;
20076    case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
20077    case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, RXY_r1(ovl),
20078                                                 RXY_x2(ovl), RXY_b2(ovl),
20079                                                 RXY_dl2(ovl),
20080                                                 RXY_dh2(ovl));  goto ok;
20081    case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, RXY_r1(ovl),
20082                                                 RXY_x2(ovl), RXY_b2(ovl),
20083                                                 RXY_dl2(ovl),
20084                                                 RXY_dh2(ovl));  goto ok;
20085    case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, RXY_r1(ovl),
20086                                                 RXY_x2(ovl), RXY_b2(ovl),
20087                                                 RXY_dl2(ovl),
20088                                                 RXY_dh2(ovl));  goto ok;
20089    case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, RXY_r1(ovl),
20090                                                 RXY_x2(ovl), RXY_b2(ovl),
20091                                                 RXY_dl2(ovl),
20092                                                 RXY_dh2(ovl));  goto ok;
20093    case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, RXY_r1(ovl),
20094                                                 RXY_x2(ovl), RXY_b2(ovl),
20095                                                 RXY_dl2(ovl),
20096                                                 RXY_dh2(ovl));  goto ok;
20097    case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, RXY_r1(ovl),
20098                                                 RXY_x2(ovl), RXY_b2(ovl),
20099                                                 RXY_dl2(ovl),
20100                                                 RXY_dh2(ovl));  goto ok;
20101    case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, RXY_r1(ovl),
20102                                                 RXY_x2(ovl), RXY_b2(ovl),
20103                                                 RXY_dl2(ovl),
20104                                                 RXY_dh2(ovl));  goto ok;
20105    case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, RXY_r1(ovl),
20106                                                 RXY_x2(ovl), RXY_b2(ovl),
20107                                                 RXY_dl2(ovl),
20108                                                 RXY_dh2(ovl));  goto ok;
20109    case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
20110    case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, RXY_r1(ovl),
20111                                                 RXY_x2(ovl), RXY_b2(ovl),
20112                                                 RXY_dl2(ovl),
20113                                                 RXY_dh2(ovl));  goto ok;
20114    case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, RXY_r1(ovl),
20115                                                 RXY_x2(ovl), RXY_b2(ovl),
20116                                                 RXY_dl2(ovl),
20117                                                 RXY_dh2(ovl));  goto ok;
20118    case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
20119    case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, RXY_r1(ovl),
20120                                                 RXY_x2(ovl), RXY_b2(ovl),
20121                                                 RXY_dl2(ovl),
20122                                                 RXY_dh2(ovl));  goto ok;
20123    case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, RXY_r1(ovl),
20124                                                 RXY_x2(ovl), RXY_b2(ovl),
20125                                                 RXY_dl2(ovl),
20126                                                 RXY_dh2(ovl));  goto ok;
20127    case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, RXY_r1(ovl),
20128                                                 RXY_x2(ovl), RXY_b2(ovl),
20129                                                 RXY_dl2(ovl),
20130                                                 RXY_dh2(ovl));  goto ok;
20131    case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, RXY_r1(ovl),
20132                                                 RXY_x2(ovl), RXY_b2(ovl),
20133                                                 RXY_dl2(ovl),
20134                                                 RXY_dh2(ovl));  goto ok;
20135    case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, RXY_r1(ovl),
20136                                                 RXY_x2(ovl), RXY_b2(ovl),
20137                                                 RXY_dl2(ovl),
20138                                                 RXY_dh2(ovl));  goto ok;
20139    case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, RXY_r1(ovl),
20140                                                 RXY_x2(ovl), RXY_b2(ovl),
20141                                                 RXY_dl2(ovl),
20142                                                 RXY_dh2(ovl));  goto ok;
20143    case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, RXY_r1(ovl),
20144                                                 RXY_x2(ovl), RXY_b2(ovl),
20145                                                 RXY_dl2(ovl),
20146                                                 RXY_dh2(ovl));  goto ok;
20147    case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, RXY_r1(ovl),
20148                                                 RXY_x2(ovl), RXY_b2(ovl),
20149                                                 RXY_dl2(ovl),
20150                                                 RXY_dh2(ovl));  goto ok;
20151    case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, RXY_r1(ovl),
20152                                                 RXY_x2(ovl), RXY_b2(ovl),
20153                                                 RXY_dl2(ovl),
20154                                                 RXY_dh2(ovl));  goto ok;
20155    case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, RXY_r1(ovl),
20156                                                 RXY_x2(ovl), RXY_b2(ovl),
20157                                                 RXY_dl2(ovl),
20158                                                 RXY_dh2(ovl));  goto ok;
20159    case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, RXY_r1(ovl),
20160                                                 RXY_x2(ovl), RXY_b2(ovl),
20161                                                 RXY_dl2(ovl),
20162                                                 RXY_dh2(ovl));  goto ok;
20163    case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, RXY_r1(ovl),
20164                                                 RXY_x2(ovl), RXY_b2(ovl),
20165                                                 RXY_dl2(ovl),
20166                                                 RXY_dh2(ovl));  goto ok;
20167    case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, RXY_r1(ovl),
20168                                                 RXY_x2(ovl), RXY_b2(ovl),
20169                                                 RXY_dl2(ovl),
20170                                                 RXY_dh2(ovl));  goto ok;
20171    case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, RXY_r1(ovl),
20172                                                 RXY_x2(ovl), RXY_b2(ovl),
20173                                                 RXY_dl2(ovl),
20174                                                 RXY_dh2(ovl));  goto ok;
20175    case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, RXY_r1(ovl),
20176                                                 RXY_x2(ovl), RXY_b2(ovl),
20177                                                 RXY_dl2(ovl),
20178                                                 RXY_dh2(ovl));  goto ok;
20179    case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
20180    case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, RXY_r1(ovl),
20181                                                 RXY_x2(ovl), RXY_b2(ovl),
20182                                                 RXY_dl2(ovl),
20183                                                 RXY_dh2(ovl));  goto ok;
20184    case 0xe3000000002aULL: s390_format_RXY_RRRD(s390_irgen_LZRG, RXY_r1(ovl),
20185                                                 RXY_x2(ovl), RXY_b2(ovl),
20186                                                 RXY_dl2(ovl),
20187                                                 RXY_dh2(ovl));  goto ok;
20188    case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
20189    case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
20190                                                 RXY_r1(ovl), RXY_x2(ovl),
20191                                                 RXY_b2(ovl), RXY_dl2(ovl),
20192                                                 RXY_dh2(ovl));  goto ok;
20193    case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, RXY_r1(ovl),
20194                                                 RXY_x2(ovl), RXY_b2(ovl),
20195                                                 RXY_dl2(ovl),
20196                                                 RXY_dh2(ovl));  goto ok;
20197    case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, RXY_r1(ovl),
20198                                                 RXY_x2(ovl), RXY_b2(ovl),
20199                                                 RXY_dl2(ovl),
20200                                                 RXY_dh2(ovl));  goto ok;
20201    case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, RXY_r1(ovl),
20202                                                 RXY_x2(ovl), RXY_b2(ovl),
20203                                                 RXY_dl2(ovl),
20204                                                 RXY_dh2(ovl));  goto ok;
20205    case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, RXY_r1(ovl),
20206                                                 RXY_x2(ovl), RXY_b2(ovl),
20207                                                 RXY_dl2(ovl),
20208                                                 RXY_dh2(ovl));  goto ok;
20209    case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, RXY_r1(ovl),
20210                                                 RXY_x2(ovl), RXY_b2(ovl),
20211                                                 RXY_dl2(ovl),
20212                                                 RXY_dh2(ovl));  goto ok;
20213    case 0xe30000000038ULL: s390_format_RXY_RRRD(s390_irgen_AGH, RXY_r1(ovl),
20214                                                 RXY_x2(ovl), RXY_b2(ovl),
20215                                                 RXY_dl2(ovl),
20216                                                 RXY_dh2(ovl));  goto ok;
20217    case 0xe30000000039ULL: s390_format_RXY_RRRD(s390_irgen_SGH, RXY_r1(ovl),
20218                                                 RXY_x2(ovl), RXY_b2(ovl),
20219                                                 RXY_dl2(ovl),
20220                                                 RXY_dh2(ovl));  goto ok;
20221    case 0xe3000000003aULL: s390_format_RXY_RRRD(s390_irgen_LLZRGF, RXY_r1(ovl),
20222                                                 RXY_x2(ovl), RXY_b2(ovl),
20223                                                 RXY_dl2(ovl),
20224                                                 RXY_dh2(ovl));  goto ok;
20225    case 0xe3000000003bULL: s390_format_RXY_RRRD(s390_irgen_LZRF, RXY_r1(ovl),
20226                                                 RXY_x2(ovl), RXY_b2(ovl),
20227                                                 RXY_dl2(ovl),
20228                                                 RXY_dh2(ovl));  goto ok;
20229    case 0xe3000000003cULL: s390_format_RXY_RRRD(s390_irgen_MGH, RXY_r1(ovl),
20230                                                 RXY_x2(ovl), RXY_b2(ovl),
20231                                                 RXY_dl2(ovl),
20232                                                 RXY_dh2(ovl));  goto ok;
20233    case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, RXY_r1(ovl),
20234                                                 RXY_x2(ovl), RXY_b2(ovl),
20235                                                 RXY_dl2(ovl),
20236                                                 RXY_dh2(ovl));  goto ok;
20237    case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
20238                                                 RXY_r1(ovl), RXY_x2(ovl),
20239                                                 RXY_b2(ovl), RXY_dl2(ovl),
20240                                                 RXY_dh2(ovl));  goto ok;
20241    case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, RXY_r1(ovl),
20242                                                 RXY_x2(ovl), RXY_b2(ovl),
20243                                                 RXY_dl2(ovl),
20244                                                 RXY_dh2(ovl));  goto ok;
20245    case 0xe30000000047ULL: s390_format_RXY_RRRD(s390_irgen_BIC, RXY_r1(ovl),
20246                                                 RXY_x2(ovl), RXY_b2(ovl),
20247                                                 RXY_dl2(ovl),
20248                                                 RXY_dh2(ovl));  goto ok;
20249    case 0xe30000000048ULL: /* LLGFSG */ goto unimplemented;
20250    case 0xe30000000049ULL: /* STGSC */ goto unimplemented;
20251    case 0xe3000000004cULL: /* LGG */ goto unimplemented;
20252    case 0xe3000000004dULL: /* LGSC */ goto unimplemented;
20253    case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, RXY_r1(ovl),
20254                                                 RXY_x2(ovl), RXY_b2(ovl),
20255                                                 RXY_dl2(ovl),
20256                                                 RXY_dh2(ovl));  goto ok;
20257    case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, RXY_r1(ovl),
20258                                                 RXY_x2(ovl), RXY_b2(ovl),
20259                                                 RXY_dl2(ovl),
20260                                                 RXY_dh2(ovl));  goto ok;
20261    case 0xe30000000053ULL: s390_format_RXY_RRRD(s390_irgen_MSC, RXY_r1(ovl),
20262                                                 RXY_x2(ovl), RXY_b2(ovl),
20263                                                 RXY_dl2(ovl),
20264                                                 RXY_dh2(ovl));  goto ok;
20265    case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, RXY_r1(ovl),
20266                                                 RXY_x2(ovl), RXY_b2(ovl),
20267                                                 RXY_dl2(ovl),
20268                                                 RXY_dh2(ovl));  goto ok;
20269    case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, RXY_r1(ovl),
20270                                                 RXY_x2(ovl), RXY_b2(ovl),
20271                                                 RXY_dl2(ovl),
20272                                                 RXY_dh2(ovl));  goto ok;
20273    case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, RXY_r1(ovl),
20274                                                 RXY_x2(ovl), RXY_b2(ovl),
20275                                                 RXY_dl2(ovl),
20276                                                 RXY_dh2(ovl));  goto ok;
20277    case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, RXY_r1(ovl),
20278                                                 RXY_x2(ovl), RXY_b2(ovl),
20279                                                 RXY_dl2(ovl),
20280                                                 RXY_dh2(ovl));  goto ok;
20281    case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, RXY_r1(ovl),
20282                                                 RXY_x2(ovl), RXY_b2(ovl),
20283                                                 RXY_dl2(ovl),
20284                                                 RXY_dh2(ovl));  goto ok;
20285    case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, RXY_r1(ovl),
20286                                                 RXY_x2(ovl), RXY_b2(ovl),
20287                                                 RXY_dl2(ovl),
20288                                                 RXY_dh2(ovl));  goto ok;
20289    case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, RXY_r1(ovl),
20290                                                 RXY_x2(ovl), RXY_b2(ovl),
20291                                                 RXY_dl2(ovl),
20292                                                 RXY_dh2(ovl));  goto ok;
20293    case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, RXY_r1(ovl),
20294                                                 RXY_x2(ovl), RXY_b2(ovl),
20295                                                 RXY_dl2(ovl),
20296                                                 RXY_dh2(ovl));  goto ok;
20297    case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, RXY_r1(ovl),
20298                                                 RXY_x2(ovl), RXY_b2(ovl),
20299                                                 RXY_dl2(ovl),
20300                                                 RXY_dh2(ovl));  goto ok;
20301    case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, RXY_r1(ovl),
20302                                                 RXY_x2(ovl), RXY_b2(ovl),
20303                                                 RXY_dl2(ovl),
20304                                                 RXY_dh2(ovl));  goto ok;
20305    case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, RXY_r1(ovl),
20306                                                 RXY_x2(ovl), RXY_b2(ovl),
20307                                                 RXY_dl2(ovl),
20308                                                 RXY_dh2(ovl));  goto ok;
20309    case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, RXY_r1(ovl),
20310                                                 RXY_x2(ovl), RXY_b2(ovl),
20311                                                 RXY_dl2(ovl),
20312                                                 RXY_dh2(ovl));  goto ok;
20313    case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, RXY_r1(ovl),
20314                                                 RXY_x2(ovl), RXY_b2(ovl),
20315                                                 RXY_dl2(ovl),
20316                                                 RXY_dh2(ovl));  goto ok;
20317    case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, RXY_r1(ovl),
20318                                                 RXY_x2(ovl), RXY_b2(ovl),
20319                                                 RXY_dl2(ovl),
20320                                                 RXY_dh2(ovl));  goto ok;
20321    case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, RXY_r1(ovl),
20322                                                 RXY_x2(ovl), RXY_b2(ovl),
20323                                                 RXY_dl2(ovl),
20324                                                 RXY_dh2(ovl));  goto ok;
20325    case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, RXY_r1(ovl),
20326                                                 RXY_x2(ovl), RXY_b2(ovl),
20327                                                 RXY_dl2(ovl),
20328                                                 RXY_dh2(ovl));  goto ok;
20329    case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, RXY_r1(ovl),
20330                                                 RXY_x2(ovl), RXY_b2(ovl),
20331                                                 RXY_dl2(ovl),
20332                                                 RXY_dh2(ovl));  goto ok;
20333    case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, RXY_r1(ovl),
20334                                                 RXY_x2(ovl), RXY_b2(ovl),
20335                                                 RXY_dl2(ovl),
20336                                                 RXY_dh2(ovl));  goto ok;
20337    case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, RXY_r1(ovl),
20338                                                 RXY_x2(ovl), RXY_b2(ovl),
20339                                                 RXY_dl2(ovl),
20340                                                 RXY_dh2(ovl));  goto ok;
20341    case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, RXY_r1(ovl),
20342                                                 RXY_x2(ovl), RXY_b2(ovl),
20343                                                 RXY_dl2(ovl),
20344                                                 RXY_dh2(ovl));  goto ok;
20345    case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, RXY_r1(ovl),
20346                                                 RXY_x2(ovl), RXY_b2(ovl),
20347                                                 RXY_dl2(ovl),
20348                                                 RXY_dh2(ovl));  goto ok;
20349    case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, RXY_r1(ovl),
20350                                                 RXY_x2(ovl), RXY_b2(ovl),
20351                                                 RXY_dl2(ovl),
20352                                                 RXY_dh2(ovl));  goto ok;
20353    case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, RXY_r1(ovl),
20354                                                 RXY_x2(ovl), RXY_b2(ovl),
20355                                                 RXY_dl2(ovl),
20356                                                 RXY_dh2(ovl));  goto ok;
20357    case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, RXY_r1(ovl),
20358                                                 RXY_x2(ovl), RXY_b2(ovl),
20359                                                 RXY_dl2(ovl),
20360                                                 RXY_dh2(ovl));  goto ok;
20361    case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, RXY_r1(ovl),
20362                                                 RXY_x2(ovl), RXY_b2(ovl),
20363                                                 RXY_dl2(ovl),
20364                                                 RXY_dh2(ovl));  goto ok;
20365    case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, RXY_r1(ovl),
20366                                                 RXY_x2(ovl), RXY_b2(ovl),
20367                                                 RXY_dl2(ovl),
20368                                                 RXY_dh2(ovl));  goto ok;
20369    case 0xe30000000083ULL: s390_format_RXY_RRRD(s390_irgen_MSGC, RXY_r1(ovl),
20370                                                 RXY_x2(ovl), RXY_b2(ovl),
20371                                                 RXY_dl2(ovl),
20372                                                 RXY_dh2(ovl));  goto ok;
20373    case 0xe30000000084ULL: s390_format_RXY_RRRD(s390_irgen_MG, RXY_r1(ovl),
20374                                                 RXY_x2(ovl), RXY_b2(ovl),
20375                                                 RXY_dl2(ovl),
20376                                                 RXY_dh2(ovl));  goto ok;
20377    case 0xe30000000085ULL: s390_format_RXY_RRRD(s390_irgen_LGAT, RXY_r1(ovl),
20378                                                 RXY_x2(ovl), RXY_b2(ovl),
20379                                                 RXY_dl2(ovl),
20380                                                 RXY_dh2(ovl));  goto ok;
20381 
20382    case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, RXY_r1(ovl),
20383                                                 RXY_x2(ovl), RXY_b2(ovl),
20384                                                 RXY_dl2(ovl),
20385                                                 RXY_dh2(ovl));  goto ok;
20386    case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, RXY_r1(ovl),
20387                                                 RXY_x2(ovl), RXY_b2(ovl),
20388                                                 RXY_dl2(ovl),
20389                                                 RXY_dh2(ovl));  goto ok;
20390    case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, RXY_r1(ovl),
20391                                                 RXY_x2(ovl), RXY_b2(ovl),
20392                                                 RXY_dl2(ovl),
20393                                                 RXY_dh2(ovl));  goto ok;
20394    case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, RXY_r1(ovl),
20395                                                 RXY_x2(ovl), RXY_b2(ovl),
20396                                                 RXY_dl2(ovl),
20397                                                 RXY_dh2(ovl));  goto ok;
20398    case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, RXY_r1(ovl),
20399                                                 RXY_x2(ovl), RXY_b2(ovl),
20400                                                 RXY_dl2(ovl),
20401                                                 RXY_dh2(ovl));  goto ok;
20402    case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, RXY_r1(ovl),
20403                                                 RXY_x2(ovl), RXY_b2(ovl),
20404                                                 RXY_dl2(ovl),
20405                                                 RXY_dh2(ovl));  goto ok;
20406    case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, RXY_r1(ovl),
20407                                                 RXY_x2(ovl), RXY_b2(ovl),
20408                                                 RXY_dl2(ovl),
20409                                                 RXY_dh2(ovl));  goto ok;
20410    case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, RXY_r1(ovl),
20411                                                 RXY_x2(ovl), RXY_b2(ovl),
20412                                                 RXY_dl2(ovl),
20413                                                 RXY_dh2(ovl));  goto ok;
20414    case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, RXY_r1(ovl),
20415                                                 RXY_x2(ovl), RXY_b2(ovl),
20416                                                 RXY_dl2(ovl),
20417                                                 RXY_dh2(ovl));  goto ok;
20418    case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, RXY_r1(ovl),
20419                                                 RXY_x2(ovl), RXY_b2(ovl),
20420                                                 RXY_dl2(ovl),
20421                                                 RXY_dh2(ovl));  goto ok;
20422    case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, RXY_r1(ovl),
20423                                                 RXY_x2(ovl), RXY_b2(ovl),
20424                                                 RXY_dl2(ovl),
20425                                                 RXY_dh2(ovl));  goto ok;
20426    case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, RXY_r1(ovl),
20427                                                 RXY_x2(ovl), RXY_b2(ovl),
20428                                                 RXY_dl2(ovl),
20429                                                 RXY_dh2(ovl));  goto ok;
20430    case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, RXY_r1(ovl),
20431                                                 RXY_x2(ovl), RXY_b2(ovl),
20432                                                 RXY_dl2(ovl),
20433                                                 RXY_dh2(ovl));  goto ok;
20434    case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, RXY_r1(ovl),
20435                                                 RXY_x2(ovl), RXY_b2(ovl),
20436                                                 RXY_dl2(ovl),
20437                                                 RXY_dh2(ovl));  goto ok;
20438    case 0xe3000000009cULL: s390_format_RXY_RRRD(s390_irgen_LLGTAT, RXY_r1(ovl),
20439                                                 RXY_x2(ovl), RXY_b2(ovl),
20440                                                 RXY_dl2(ovl),
20441                                                 RXY_dh2(ovl));  goto ok;
20442    case 0xe3000000009dULL: s390_format_RXY_RRRD(s390_irgen_LLGFAT, RXY_r1(ovl),
20443                                                 RXY_x2(ovl), RXY_b2(ovl),
20444                                                 RXY_dl2(ovl),
20445                                                 RXY_dh2(ovl));  goto ok;
20446    case 0xe3000000009fULL: s390_format_RXY_RRRD(s390_irgen_LAT, RXY_r1(ovl),
20447                                                 RXY_x2(ovl), RXY_b2(ovl),
20448                                                 RXY_dl2(ovl),
20449                                                 RXY_dh2(ovl));  goto ok;
20450    case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, RXY_r1(ovl),
20451                                                 RXY_x2(ovl), RXY_b2(ovl),
20452                                                 RXY_dl2(ovl),
20453                                                 RXY_dh2(ovl));  goto ok;
20454    case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, RXY_r1(ovl),
20455                                                 RXY_x2(ovl), RXY_b2(ovl),
20456                                                 RXY_dl2(ovl),
20457                                                 RXY_dh2(ovl));  goto ok;
20458    case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, RXY_r1(ovl),
20459                                                 RXY_x2(ovl), RXY_b2(ovl),
20460                                                 RXY_dl2(ovl),
20461                                                 RXY_dh2(ovl));  goto ok;
20462    case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, RXY_r1(ovl),
20463                                                 RXY_x2(ovl), RXY_b2(ovl),
20464                                                 RXY_dl2(ovl),
20465                                                 RXY_dh2(ovl));  goto ok;
20466    case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, RXY_r1(ovl),
20467                                                 RXY_x2(ovl), RXY_b2(ovl),
20468                                                 RXY_dl2(ovl),
20469                                                 RXY_dh2(ovl));  goto ok;
20470    case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, RXY_r1(ovl),
20471                                                 RXY_x2(ovl), RXY_b2(ovl),
20472                                                 RXY_dl2(ovl),
20473                                                 RXY_dh2(ovl));  goto ok;
20474    case 0xe300000000c8ULL: s390_format_RXY_RRRD(s390_irgen_LFHAT, RXY_r1(ovl),
20475                                                 RXY_x2(ovl), RXY_b2(ovl),
20476                                                 RXY_dl2(ovl),
20477                                                 RXY_dh2(ovl));  goto ok;
20478    case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, RXY_r1(ovl),
20479                                                 RXY_x2(ovl), RXY_b2(ovl),
20480                                                 RXY_dl2(ovl),
20481                                                 RXY_dh2(ovl));  goto ok;
20482    case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, RXY_r1(ovl),
20483                                                 RXY_x2(ovl), RXY_b2(ovl),
20484                                                 RXY_dl2(ovl),
20485                                                 RXY_dh2(ovl));  goto ok;
20486    case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, RXY_r1(ovl),
20487                                                 RXY_x2(ovl), RXY_b2(ovl),
20488                                                 RXY_dl2(ovl),
20489                                                 RXY_dh2(ovl));  goto ok;
20490    case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, RXY_r1(ovl),
20491                                                 RXY_x2(ovl), RXY_b2(ovl),
20492                                                 RXY_dl2(ovl),
20493                                                 RXY_dh2(ovl));  goto ok;
20494    case 0xe60000000034ULL: /* VPKZ */ goto unimplemented;
20495    case 0xe60000000035ULL: /* VLRL */ goto unimplemented;
20496    case 0xe60000000037ULL: /* VLRLR */ goto unimplemented;
20497    case 0xe6000000003cULL: /* VUPKZ */ goto unimplemented;
20498    case 0xe6000000003dULL: /* VSTRL */ goto unimplemented;
20499    case 0xe6000000003fULL: /* VSTRLR */ goto unimplemented;
20500    case 0xe60000000049ULL: /* VLIP */ goto unimplemented;
20501    case 0xe60000000050ULL: /* VCVB */ goto unimplemented;
20502    case 0xe60000000052ULL: /* VCVBG */ goto unimplemented;
20503    case 0xe60000000058ULL: /* VCVD */ goto unimplemented;
20504    case 0xe60000000059ULL: /* VSRP */ goto unimplemented;
20505    case 0xe6000000005aULL: /* VCVDG */ goto unimplemented;
20506    case 0xe6000000005bULL: /* VPSOP */ goto unimplemented;
20507    case 0xe6000000005fULL: /* VTP */ goto unimplemented;
20508    case 0xe60000000071ULL: /* VAP */ goto unimplemented;
20509    case 0xe60000000073ULL: /* VSP */ goto unimplemented;
20510    case 0xe60000000077ULL: /* VCP */ goto unimplemented;
20511    case 0xe60000000078ULL: /* VMP */ goto unimplemented;
20512    case 0xe60000000079ULL: /* VMSP */ goto unimplemented;
20513    case 0xe6000000007aULL: /* VDP */ goto unimplemented;
20514    case 0xe6000000007bULL: /* VRP */ goto unimplemented;
20515    case 0xe6000000007eULL: /* VSDP */ goto unimplemented;
20516    case 0xe70000000000ULL: s390_format_VRX_VRRDM(s390_irgen_VLEB, VRX_v1(ovl),
20517                                                  VRX_x2(ovl), VRX_b2(ovl),
20518                                                  VRX_d2(ovl), VRX_m3(ovl),
20519                                                  VRX_rxb(ovl));  goto ok;
20520    case 0xe70000000001ULL: s390_format_VRX_VRRDM(s390_irgen_VLEH, VRX_v1(ovl),
20521                                                  VRX_x2(ovl), VRX_b2(ovl),
20522                                                  VRX_d2(ovl), VRX_m3(ovl),
20523                                                  VRX_rxb(ovl));  goto ok;
20524    case 0xe70000000002ULL: s390_format_VRX_VRRDM(s390_irgen_VLEG, VRX_v1(ovl),
20525                                                  VRX_x2(ovl), VRX_b2(ovl),
20526                                                  VRX_d2(ovl), VRX_m3(ovl),
20527                                                  VRX_rxb(ovl));  goto ok;
20528    case 0xe70000000003ULL: s390_format_VRX_VRRDM(s390_irgen_VLEF, VRX_v1(ovl),
20529                                                  VRX_x2(ovl), VRX_b2(ovl),
20530                                                  VRX_d2(ovl), VRX_m3(ovl),
20531                                                  VRX_rxb(ovl));  goto ok;
20532    case 0xe70000000004ULL: s390_format_VRX_VRRDM(s390_irgen_VLLEZ, VRX_v1(ovl),
20533                                                  VRX_x2(ovl), VRX_b2(ovl),
20534                                                  VRX_d2(ovl), VRX_m3(ovl),
20535                                                  VRX_rxb(ovl));  goto ok;
20536    case 0xe70000000005ULL: s390_format_VRX_VRRDM(s390_irgen_VLREP, VRX_v1(ovl),
20537                                                 VRX_x2(ovl), VRX_b2(ovl),
20538                                                 VRX_d2(ovl), VRX_m3(ovl),
20539                                                 VRX_rxb(ovl));  goto ok;
20540    case 0xe70000000006ULL: s390_format_VRX_VRRD(s390_irgen_VL, VRX_v1(ovl),
20541                                                 VRX_x2(ovl), VRX_b2(ovl),
20542                                                 VRX_d2(ovl), VRX_rxb(ovl));  goto ok;
20543    case 0xe70000000007ULL: s390_format_VRX_VRRDM(s390_irgen_VLBB, VRX_v1(ovl),
20544                                                  VRX_x2(ovl), VRX_b2(ovl),
20545                                                  VRX_d2(ovl), VRX_m3(ovl),
20546                                                  VRX_rxb(ovl));  goto ok;
20547    case 0xe70000000008ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEB, VRX_v1(ovl),
20548                                                  VRX_x2(ovl), VRX_b2(ovl),
20549                                                  VRX_d2(ovl), VRX_m3(ovl),
20550                                                  VRX_rxb(ovl));  goto ok;
20551    case 0xe70000000009ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEH, VRX_v1(ovl),
20552                                                  VRX_x2(ovl), VRX_b2(ovl),
20553                                                  VRX_d2(ovl), VRX_m3(ovl),
20554                                                  VRX_rxb(ovl));  goto ok;
20555    case 0xe7000000000aULL: s390_format_VRX_VRRDM(s390_irgen_VSTEG, VRX_v1(ovl),
20556                                                  VRX_x2(ovl), VRX_b2(ovl),
20557                                                  VRX_d2(ovl), VRX_m3(ovl),
20558                                                  VRX_rxb(ovl));  goto ok;
20559    case 0xe7000000000bULL: s390_format_VRX_VRRDM(s390_irgen_VSTEF, VRX_v1(ovl),
20560                                                  VRX_x2(ovl), VRX_b2(ovl),
20561                                                  VRX_d2(ovl), VRX_m3(ovl),
20562                                                  VRX_rxb(ovl));  goto ok;
20563    case 0xe7000000000eULL: s390_format_VRX_VRRD(s390_irgen_VST, VRX_v1(ovl),
20564                                                 VRX_x2(ovl), VRX_b2(ovl),
20565                                                 VRX_d2(ovl), VRX_rxb(ovl));  goto ok;
20566    case 0xe70000000012ULL: s390_format_VRV_VVRDMT(s390_irgen_VGEG, VRX_v1(ovl),
20567                                                   VRX_x2(ovl), VRX_b2(ovl),
20568                                                   VRX_d2(ovl), VRX_m3(ovl),
20569                                                   VRX_rxb(ovl), Ity_I64);  goto ok;
20570    case 0xe70000000013ULL: s390_format_VRV_VVRDMT(s390_irgen_VGEF, VRX_v1(ovl),
20571                                                   VRX_x2(ovl), VRX_b2(ovl),
20572                                                   VRX_d2(ovl), VRX_m3(ovl),
20573                                                   VRX_rxb(ovl), Ity_I32);  goto ok;
20574    case 0xe7000000001aULL: s390_format_VRV_VVRDMT(s390_irgen_VSCEG, VRX_v1(ovl),
20575                                                   VRX_x2(ovl), VRX_b2(ovl),
20576                                                   VRX_d2(ovl), VRX_m3(ovl),
20577                                                   VRX_rxb(ovl), Ity_I64);  goto ok;
20578    case 0xe7000000001bULL: s390_format_VRV_VVRDMT(s390_irgen_VSCEF, VRX_v1(ovl),
20579                                                   VRX_x2(ovl), VRX_b2(ovl),
20580                                                   VRX_d2(ovl), VRX_m3(ovl),
20581                                                   VRX_rxb(ovl), Ity_I32);  goto ok;
20582    case 0xe70000000021ULL: s390_format_VRS_RRDVM(s390_irgen_VLGV, VRS_v1(ovl),
20583                                                 VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl),
20584                                                 VRS_m4(ovl), VRS_rxb(ovl));  goto ok;
20585    case 0xe70000000022ULL: s390_format_VRS_VRRDM(s390_irgen_VLVG, VRS_v1(ovl),
20586                                                 VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl),
20587                                                 VRS_m4(ovl), VRS_rxb(ovl));  goto ok;
20588    case 0xe70000000027ULL: s390_format_RXE_RRRDR(s390_irgen_LCBB, RXE_r1(ovl),
20589                                                  RXE_x2(ovl), RXE_b2(ovl),
20590                                                  RXE_d2(ovl), RXE_m3(ovl));  goto ok;
20591    case 0xe70000000030ULL: s390_format_VRS_VRDVM(s390_irgen_VESL, VRS_v1(ovl),
20592                                                  VRS_b2(ovl), VRS_d2(ovl),
20593                                                  VRS_v3(ovl), VRS_m4(ovl),
20594                                                  VRS_rxb(ovl));  goto ok;
20595    case 0xe70000000033ULL: s390_format_VRS_VRDVM(s390_irgen_VERLL, VRS_v1(ovl),
20596                                                  VRS_b2(ovl), VRS_d2(ovl),
20597                                                  VRS_v3(ovl), VRS_m4(ovl),
20598                                                  VRS_rxb(ovl));  goto ok;
20599    case 0xe70000000036ULL: s390_format_VRS_VRDV(s390_irgen_VLM, VRS_v1(ovl),
20600                                                 VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl),
20601                                                 VRS_rxb(ovl));  goto ok;
20602    case 0xe70000000037ULL: s390_format_VRS_VRRD(s390_irgen_VLL, VRS_v1(ovl),
20603                                                 VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl),
20604                                                 VRS_rxb(ovl));  goto ok;
20605    case 0xe70000000038ULL: s390_format_VRS_VRDVM(s390_irgen_VESRL, VRS_v1(ovl),
20606                                                  VRS_b2(ovl), VRS_d2(ovl),
20607                                                  VRS_v3(ovl), VRS_m4(ovl),
20608                                                  VRS_rxb(ovl));  goto ok;
20609    case 0xe7000000003aULL: s390_format_VRS_VRDVM(s390_irgen_VESRA, VRS_v1(ovl),
20610                                                  VRS_b2(ovl), VRS_d2(ovl),
20611                                                  VRS_v3(ovl), VRS_m4(ovl),
20612                                                  VRS_rxb(ovl));  goto ok;
20613    case 0xe7000000003eULL: s390_format_VRS_VRDV(s390_irgen_VSTM, VRS_v1(ovl),
20614                                                 VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl),
20615                                                 VRS_rxb(ovl));  goto ok;
20616    case 0xe7000000003fULL: s390_format_VRS_VRRD(s390_irgen_VSTL, VRS_v1(ovl),
20617                                                 VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl),
20618                                                 VRS_rxb(ovl));  goto ok;
20619    case 0xe70000000040ULL: s390_format_VRI_VIM(s390_irgen_VLEIB, VRI_v1(ovl),
20620                                                  VRI_i2(ovl), VRI_m3(ovl),
20621                                                  VRI_rxb(ovl));  goto ok;
20622    case 0xe70000000041ULL: s390_format_VRI_VIM(s390_irgen_VLEIH, VRI_v1(ovl),
20623                                                VRI_i2(ovl), VRI_m3(ovl),
20624                                                VRI_rxb(ovl));  goto ok;
20625    case 0xe70000000042ULL: s390_format_VRI_VIM(s390_irgen_VLEIG, VRI_v1(ovl),
20626                                                VRI_i2(ovl), VRI_m3(ovl),
20627                                                VRI_rxb(ovl));  goto ok;
20628    case 0xe70000000043ULL: s390_format_VRI_VIM(s390_irgen_VLEIF, VRI_v1(ovl),
20629                                                VRI_i2(ovl), VRI_m3(ovl),
20630                                                VRI_rxb(ovl));  goto ok;break;
20631    case 0xe70000000044ULL: s390_format_VRI_VIM(s390_irgen_VGBM, VRI_v1(ovl),
20632                                                VRI_i2(ovl), VRI_m3(ovl),
20633                                                VRI_rxb(ovl));  goto ok;
20634    case 0xe70000000045ULL: s390_format_VRI_VIM(s390_irgen_VREPI, VRI_v1(ovl),
20635                                                VRI_i2(ovl), VRI_m3(ovl),
20636                                                VRI_rxb(ovl));  goto ok;
20637    case 0xe70000000046ULL: s390_format_VRI_VIM(s390_irgen_VGM, VRI_v1(ovl),
20638                                                VRI_i2(ovl), VRI_m3(ovl),
20639                                                VRI_rxb(ovl));  goto ok;
20640    case 0xe7000000004aULL: s390_format_VRI_VVIMM(s390_irgen_VFTCI, VRIe_v1(ovl),
20641                                                  VRIe_v2(ovl), VRIe_i3(ovl),
20642                                                  VRIe_m4(ovl), VRIe_m5(ovl),
20643                                                  VRIe_rxb(ovl));  goto ok;
20644    case 0xe7000000004dULL: s390_format_VRI_VVIM(s390_irgen_VREP, VRI_v1(ovl),
20645                                                VRI_v3(ovl), VRI_i2(ovl),
20646                                                VRI_m3(ovl), VRI_rxb(ovl));  goto ok;
20647    case 0xe70000000050ULL: s390_format_VRR_VVM(s390_irgen_VPOPCT, VRR_v1(ovl),
20648                                                VRR_v2(ovl), VRR_m4(ovl),
20649                                                VRR_rxb(ovl));  goto ok;
20650    case 0xe70000000052ULL: s390_format_VRR_VVM(s390_irgen_VCTZ, VRR_v1(ovl),
20651                                                VRR_v2(ovl), VRR_m4(ovl),
20652                                                VRR_rxb(ovl));  goto ok;
20653    case 0xe70000000053ULL: s390_format_VRR_VVM(s390_irgen_VCLZ, VRR_v1(ovl),
20654                                                VRR_v2(ovl), VRR_m4(ovl),
20655                                                VRR_rxb(ovl));  goto ok;
20656    case 0xe70000000056ULL: s390_format_VRR_VV(s390_irgen_VLR, VRR_v1(ovl),
20657                                               VRR_v2(ovl), VRR_rxb(ovl));  goto ok;
20658    case 0xe7000000005cULL: s390_format_VRR_VVMM(s390_irgen_VISTR, VRR_v1(ovl),
20659                                                 VRR_v2(ovl), VRR_m4(ovl),
20660                                                 VRR_m5(ovl), VRR_rxb(ovl));  goto ok;
20661    case 0xe7000000005fULL: s390_format_VRR_VVM(s390_irgen_VSEG, VRR_v1(ovl),
20662                                                VRR_v2(ovl), VRR_m4(ovl),
20663                                                VRR_rxb(ovl));  goto ok;
20664    case 0xe70000000060ULL: s390_format_VRR_VVVM(s390_irgen_VMRL, VRR_v1(ovl),
20665                                                VRR_v2(ovl), VRR_r3(ovl),
20666                                                VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20667    case 0xe70000000061ULL: s390_format_VRR_VVVM(s390_irgen_VMRH, VRR_v1(ovl),
20668                                                VRR_v2(ovl), VRR_r3(ovl),
20669                                                VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20670    case 0xe70000000062ULL: s390_format_VRR_VRR(s390_irgen_VLVGP, VRR_v1(ovl),
20671                                                VRR_v2(ovl), VRR_r3(ovl),
20672                                                VRR_rxb(ovl));  goto ok;
20673    case 0xe70000000064ULL: s390_format_VRR_VVVM(s390_irgen_VSUM, VRR_v1(ovl),
20674                                                 VRR_v2(ovl), VRR_r3(ovl),
20675                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20676    case 0xe70000000065ULL: s390_format_VRR_VVVM(s390_irgen_VSUMG, VRR_v1(ovl),
20677                                                 VRR_v2(ovl), VRR_r3(ovl),
20678                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20679    case 0xe70000000066ULL: s390_format_VRR_VVV(s390_irgen_VCKSM, VRR_v1(ovl),
20680                                                VRR_v2(ovl), VRR_r3(ovl),
20681                                                VRR_rxb(ovl));  goto ok;
20682    case 0xe70000000067ULL: s390_format_VRR_VVVM(s390_irgen_VSUMQ, VRR_v1(ovl),
20683                                                 VRR_v2(ovl), VRR_r3(ovl),
20684                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20685    case 0xe70000000068ULL: s390_format_VRR_VVV(s390_irgen_VN, VRR_v1(ovl),
20686                                                VRR_v2(ovl), VRR_r3(ovl),
20687                                                VRR_rxb(ovl));  goto ok;
20688    case 0xe70000000069ULL: s390_format_VRR_VVV(s390_irgen_VNC, VRR_v1(ovl),
20689                                                VRR_v2(ovl), VRR_r3(ovl),
20690                                                VRR_rxb(ovl));  goto ok;
20691    case 0xe7000000006aULL: s390_format_VRR_VVV(s390_irgen_VO, VRR_v1(ovl),
20692                                                VRR_v2(ovl), VRR_r3(ovl),
20693                                                VRR_rxb(ovl));  goto ok;
20694    case 0xe7000000006bULL: s390_format_VRR_VVV(s390_irgen_VNO, VRR_v1(ovl),
20695                                                VRR_v2(ovl), VRR_r3(ovl),
20696                                                VRR_rxb(ovl));  goto ok;
20697    case 0xe7000000006cULL: /* VNX */ goto unimplemented;
20698    case 0xe7000000006dULL: s390_format_VRR_VVV(s390_irgen_VX, VRR_v1(ovl),
20699                                                VRR_v2(ovl), VRR_r3(ovl),
20700                                                VRR_rxb(ovl));  goto ok;
20701    case 0xe7000000006eULL: /* VNN */ goto unimplemented;
20702    case 0xe7000000006fULL: /* VOC */ goto unimplemented;
20703    case 0xe70000000070ULL: s390_format_VRR_VVVM(s390_irgen_VESLV, VRR_v1(ovl),
20704                                                 VRR_v2(ovl), VRR_r3(ovl),
20705                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20706    case 0xe70000000072ULL: s390_format_VRId_VVVIM(s390_irgen_VERIM, VRId_v1(ovl),
20707                                                   VRId_v2(ovl), VRId_v3(ovl),
20708                                                   VRId_i4(ovl), VRId_m5(ovl),
20709                                                   VRId_rxb(ovl));  goto ok;
20710    case 0xe70000000073ULL: s390_format_VRR_VVVM(s390_irgen_VERLLV, VRR_v1(ovl),
20711                                                 VRR_v2(ovl), VRR_r3(ovl),
20712                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20713    case 0xe70000000074ULL: s390_format_VRR_VVV(s390_irgen_VSL, VRR_v1(ovl),
20714                                                VRR_v2(ovl), VRR_r3(ovl),
20715                                                VRR_rxb(ovl));  goto ok;
20716    case 0xe70000000075ULL: s390_format_VRR_VVV(s390_irgen_VSLB, VRR_v1(ovl),
20717                                                VRR_v2(ovl), VRR_r3(ovl),
20718                                                VRR_rxb(ovl));  goto ok;
20719    case 0xe70000000077ULL: s390_format_VRId_VVVI(s390_irgen_VSLDB, VRId_v1(ovl),
20720                                                  VRId_v2(ovl), VRId_v3(ovl),
20721                                                  VRId_i4(ovl), VRId_rxb(ovl));  goto ok;
20722    case 0xe70000000078ULL: s390_format_VRR_VVVM(s390_irgen_VESRLV, VRR_v1(ovl),
20723                                                 VRR_v2(ovl), VRR_r3(ovl),
20724                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20725    case 0xe7000000007aULL: s390_format_VRR_VVVM(s390_irgen_VESRAV, VRR_v1(ovl),
20726                                                 VRR_v2(ovl), VRR_r3(ovl),
20727                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20728    case 0xe7000000007cULL: s390_format_VRR_VVV(s390_irgen_VSRL, VRR_v1(ovl),
20729                                                VRR_v2(ovl), VRR_r3(ovl),
20730                                                VRR_rxb(ovl));  goto ok;
20731    case 0xe7000000007dULL: s390_format_VRR_VVV(s390_irgen_VSRLB, VRR_v1(ovl),
20732                                                VRR_v2(ovl), VRR_r3(ovl),
20733                                                VRR_rxb(ovl));  goto ok;
20734    case 0xe7000000007eULL: s390_format_VRR_VVV(s390_irgen_VSRA, VRR_v1(ovl),
20735                                                VRR_v2(ovl), VRR_r3(ovl),
20736                                                VRR_rxb(ovl));  goto ok;
20737    case 0xe7000000007fULL: s390_format_VRR_VVV(s390_irgen_VSRAB, VRR_v1(ovl),
20738                                                VRR_v2(ovl), VRR_r3(ovl),
20739                                                VRR_rxb(ovl));  goto ok;
20740    case 0xe70000000080ULL: s390_format_VRR_VVVMM(s390_irgen_VFEE, VRR_v1(ovl),
20741                                                  VRR_v2(ovl), VRR_r3(ovl),
20742                                                  VRR_m4(ovl), VRR_m5(ovl),
20743                                                  VRR_rxb(ovl));  goto ok;
20744    case 0xe70000000081ULL: s390_format_VRR_VVVMM(s390_irgen_VFENE, VRR_v1(ovl),
20745                                                  VRR_v2(ovl), VRR_r3(ovl),
20746                                                  VRR_m4(ovl), VRR_m5(ovl),
20747                                                  VRR_rxb(ovl));  goto ok;
20748    case 0xe70000000082ULL: s390_format_VRR_VVVMM(s390_irgen_VFAE, VRR_v1(ovl),
20749                                                  VRR_v2(ovl), VRR_r3(ovl),
20750                                                  VRR_m4(ovl), VRR_m5(ovl),
20751                                                  VRR_rxb(ovl));  goto ok;
20752    case 0xe70000000084ULL: s390_format_VRR_VVVM(s390_irgen_VPDI, VRR_v1(ovl),
20753                                                VRR_v2(ovl), VRR_r3(ovl),
20754                                                VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20755    case 0xe70000000085ULL: /* VBPERM */ goto unimplemented;
20756    case 0xe7000000008aULL: s390_format_VRR_VVVVMM(s390_irgen_VSTRC, VRRd_v1(ovl),
20757                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20758                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20759                                                   VRRd_m6(ovl),
20760                                                   VRRd_rxb(ovl));  goto ok;
20761    case 0xe7000000008cULL: s390_format_VRR_VVVV(s390_irgen_VPERM, VRR_v1(ovl),
20762                                                VRR_v2(ovl), VRR_r3(ovl),
20763                                                VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20764    case 0xe7000000008dULL: s390_format_VRR_VVVV(s390_irgen_VSEL, VRR_v1(ovl),
20765                                                VRR_v2(ovl), VRR_r3(ovl),
20766                                                VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20767    case 0xe7000000008eULL: s390_format_VRR_VVVVMM(s390_irgen_VFMS, VRRe_v1(ovl),
20768                                                   VRRe_v2(ovl), VRRe_v3(ovl),
20769                                                   VRRe_v4(ovl), VRRe_m5(ovl),
20770                                                   VRRe_m6(ovl),
20771                                                   VRRe_rxb(ovl));  goto ok;
20772    case 0xe7000000008fULL: s390_format_VRR_VVVVMM(s390_irgen_VFMA, VRRe_v1(ovl),
20773                                                   VRRe_v2(ovl), VRRe_v3(ovl),
20774                                                   VRRe_v4(ovl), VRRe_m5(ovl),
20775                                                   VRRe_m6(ovl),
20776                                                   VRRe_rxb(ovl));  goto ok;
20777    case 0xe70000000094ULL: s390_format_VRR_VVVM(s390_irgen_VPK, VRR_v1(ovl),
20778                                                VRR_v2(ovl), VRR_r3(ovl),
20779                                                VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20780    case 0xe70000000095ULL: s390_format_VRR_VVVMM(s390_irgen_VPKLS, VRR_v1(ovl),
20781                                                VRR_v2(ovl), VRR_r3(ovl),
20782                                                VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl));  goto ok;
20783    case 0xe70000000097ULL: s390_format_VRR_VVVMM(s390_irgen_VPKS, VRR_v1(ovl),
20784                                                VRR_v2(ovl), VRR_r3(ovl),
20785                                                VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl));  goto ok;
20786    case 0xe7000000009eULL: /* VFNMS */ goto unimplemented;
20787    case 0xe7000000009fULL: /* VFNMA */ goto unimplemented;
20788    case 0xe700000000a1ULL: s390_format_VRR_VVVM(s390_irgen_VMLH, VRR_v1(ovl),
20789                                                 VRR_v2(ovl), VRR_r3(ovl),
20790                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20791    case 0xe700000000a2ULL: s390_format_VRR_VVVM(s390_irgen_VML, VRR_v1(ovl),
20792                                                 VRR_v2(ovl), VRR_r3(ovl),
20793                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20794    case 0xe700000000a3ULL: s390_format_VRR_VVVM(s390_irgen_VMH, VRR_v1(ovl),
20795                                                 VRR_v2(ovl), VRR_r3(ovl),
20796                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20797    case 0xe700000000a4ULL: s390_format_VRR_VVVM(s390_irgen_VMLE, VRR_v1(ovl),
20798                                                 VRR_v2(ovl), VRR_r3(ovl),
20799                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20800    case 0xe700000000a5ULL: s390_format_VRR_VVVM(s390_irgen_VMLO, VRR_v1(ovl),
20801                                                 VRR_v2(ovl), VRR_r3(ovl),
20802                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20803    case 0xe700000000a6ULL: s390_format_VRR_VVVM(s390_irgen_VME, VRR_v1(ovl),
20804                                                 VRR_v2(ovl), VRR_r3(ovl),
20805                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20806    case 0xe700000000a7ULL: s390_format_VRR_VVVM(s390_irgen_VMO, VRR_v1(ovl),
20807                                                 VRR_v2(ovl), VRR_r3(ovl),
20808                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20809    case 0xe700000000a9ULL: s390_format_VRRd_VVVVM(s390_irgen_VMALH, VRRd_v1(ovl),
20810                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20811                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20812                                                   VRRd_rxb(ovl));  goto ok;
20813    case 0xe700000000aaULL: s390_format_VRRd_VVVVM(s390_irgen_VMAL, VRRd_v1(ovl),
20814                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20815                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20816                                                   VRRd_rxb(ovl));  goto ok;
20817    case 0xe700000000abULL: s390_format_VRRd_VVVVM(s390_irgen_VMAH, VRRd_v1(ovl),
20818                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20819                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20820                                                   VRRd_rxb(ovl));  goto ok;
20821    case 0xe700000000acULL: s390_format_VRRd_VVVVM(s390_irgen_VMALE, VRRd_v1(ovl),
20822                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20823                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20824                                                   VRRd_rxb(ovl));  goto ok;
20825    case 0xe700000000adULL: s390_format_VRRd_VVVVM(s390_irgen_VMALO, VRRd_v1(ovl),
20826                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20827                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20828                                                   VRRd_rxb(ovl));  goto ok;
20829    case 0xe700000000aeULL: s390_format_VRRd_VVVVM(s390_irgen_VMAE, VRRd_v1(ovl),
20830                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20831                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20832                                                   VRRd_rxb(ovl));  goto ok;
20833    case 0xe700000000afULL: s390_format_VRRd_VVVVM(s390_irgen_VMAO, VRRd_v1(ovl),
20834                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20835                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20836                                                   VRRd_rxb(ovl));  goto ok;
20837    case 0xe700000000b4ULL: s390_format_VRR_VVVM(s390_irgen_VGFM, VRR_v1(ovl),
20838                                                 VRR_v2(ovl), VRR_r3(ovl),
20839                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20840    case 0xe700000000b8ULL: /* VMSL */ goto unimplemented;
20841    case 0xe700000000b9ULL: s390_format_VRRd_VVVVM(s390_irgen_VACCC, VRRd_v1(ovl),
20842                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20843                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20844                                                   VRRd_rxb(ovl));  goto ok;
20845    case 0xe700000000bbULL: s390_format_VRRd_VVVVM(s390_irgen_VAC, VRRd_v1(ovl),
20846                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20847                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20848                                                   VRRd_rxb(ovl));  goto ok;
20849    case 0xe700000000bcULL: s390_format_VRRd_VVVVM(s390_irgen_VGFMA, VRRd_v1(ovl),
20850                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20851                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20852                                                   VRRd_rxb(ovl));  goto ok;
20853    case 0xe700000000bdULL: s390_format_VRRd_VVVVM(s390_irgen_VSBCBI, VRRd_v1(ovl),
20854                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20855                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20856                                                   VRRd_rxb(ovl));  goto ok;
20857    case 0xe700000000bfULL: s390_format_VRRd_VVVVM(s390_irgen_VSBI, VRRd_v1(ovl),
20858                                                   VRRd_v2(ovl), VRRd_v3(ovl),
20859                                                   VRRd_v4(ovl), VRRd_m5(ovl),
20860                                                   VRRd_rxb(ovl));  goto ok;
20861    case 0xe700000000c0ULL: s390_format_VRRa_VVMMM(s390_irgen_VCLGD, VRRa_v1(ovl),
20862                                                   VRRa_v2(ovl), VRRa_m3(ovl),
20863                                                   VRRa_m4(ovl), VRRa_m5(ovl),
20864                                                   VRRa_rxb(ovl)); goto ok;
20865    case 0xe700000000c1ULL: s390_format_VRRa_VVMMM(s390_irgen_VCDLG, VRRa_v1(ovl),
20866                                                   VRRa_v2(ovl), VRRa_m3(ovl),
20867                                                   VRRa_m4(ovl), VRRa_m5(ovl),
20868                                                   VRRa_rxb(ovl)); goto ok;
20869    case 0xe700000000c2ULL: s390_format_VRRa_VVMMM(s390_irgen_VCGD, VRRa_v1(ovl),
20870                                                   VRRa_v2(ovl), VRRa_m3(ovl),
20871                                                   VRRa_m4(ovl), VRRa_m5(ovl),
20872                                                   VRRa_rxb(ovl)); goto ok;
20873    case 0xe700000000c3ULL: s390_format_VRRa_VVMMM(s390_irgen_VCDG, VRRa_v1(ovl),
20874                                                   VRRa_v2(ovl), VRRa_m3(ovl),
20875                                                   VRRa_m4(ovl), VRRa_m5(ovl),
20876                                                   VRRa_rxb(ovl)); goto ok;
20877    case 0xe700000000c4ULL: s390_format_VRRa_VVMMM(s390_irgen_VLDE, VRRa_v1(ovl),
20878                                                   VRRa_v2(ovl), VRRa_m3(ovl),
20879                                                   VRRa_m4(ovl), VRRa_m5(ovl),
20880                                                   VRRa_rxb(ovl)); goto ok;
20881    case 0xe700000000c5ULL: s390_format_VRRa_VVMMM(s390_irgen_VLED, VRRa_v1(ovl),
20882                                                   VRRa_v2(ovl), VRRa_m3(ovl),
20883                                                   VRRa_m4(ovl), VRRa_m5(ovl),
20884                                                   VRRa_rxb(ovl)); goto ok;
20885    case 0xe700000000c7ULL: s390_format_VRRa_VVMMM(s390_irgen_VFI, VRRa_v1(ovl),
20886                                                   VRRa_v2(ovl), VRRa_m3(ovl),
20887                                                   VRRa_m4(ovl), VRRa_m5(ovl),
20888                                                   VRRa_rxb(ovl)); goto ok;
20889    case 0xe700000000caULL: s390_format_VRRa_VVMM(s390_irgen_WFK, VRRa_v1(ovl),
20890                                                  VRRa_v2(ovl), VRRa_m3(ovl),
20891                                                  VRRa_m4(ovl),
20892                                                  VRRa_rxb(ovl)); goto ok;
20893    case 0xe700000000cbULL: s390_format_VRRa_VVMM(s390_irgen_WFC, VRRa_v1(ovl),
20894                                                  VRRa_v2(ovl), VRRa_m3(ovl),
20895                                                  VRRa_m4(ovl),
20896                                                  VRRa_rxb(ovl)); goto ok;
20897    case 0xe700000000ccULL: s390_format_VRRa_VVMMM(s390_irgen_VFPSO, VRRa_v1(ovl),
20898                                                   VRRa_v2(ovl), VRRa_m3(ovl),
20899                                                   VRRa_m4(ovl), VRRa_m5(ovl),
20900                                                   VRRa_rxb(ovl)); goto ok;
20901    case 0xe700000000ceULL: s390_format_VRRa_VVMM(s390_irgen_VFSQ, VRRa_v1(ovl),
20902                                                  VRRa_v2(ovl), VRRa_m3(ovl),
20903                                                  VRRa_m4(ovl),
20904                                                  VRRa_rxb(ovl)); goto ok;
20905    case 0xe700000000d4ULL: s390_format_VRR_VVM(s390_irgen_VUPLL, VRR_v1(ovl),
20906                                                VRR_v2(ovl), VRR_m4(ovl),
20907                                                VRR_rxb(ovl));  goto ok;
20908    case 0xe700000000d5ULL: s390_format_VRR_VVM(s390_irgen_VUPLH, VRR_v1(ovl),
20909                                                VRR_v2(ovl), VRR_m4(ovl),
20910                                                VRR_rxb(ovl));  goto ok;
20911    case 0xe700000000d6ULL: s390_format_VRR_VVM(s390_irgen_VUPL, VRR_v1(ovl),
20912                                                VRR_v2(ovl), VRR_m4(ovl),
20913                                                VRR_rxb(ovl));  goto ok;
20914    case 0xe700000000d7ULL: s390_format_VRR_VVM(s390_irgen_VUPH, VRR_v1(ovl),
20915                                                VRR_v2(ovl), VRR_m4(ovl),
20916                                                VRR_rxb(ovl));  goto ok;
20917    case 0xe700000000d8ULL: s390_format_VRR_VV(s390_irgen_VTM, VRR_v1(ovl),
20918                                               VRR_v2(ovl), VRR_rxb(ovl));  goto ok;
20919    case 0xe700000000d9ULL: s390_format_VRR_VVM(s390_irgen_VECL, VRR_v1(ovl),
20920                                                VRR_v2(ovl), VRR_m4(ovl),
20921                                                VRR_rxb(ovl));  goto ok;
20922    case 0xe700000000dbULL: s390_format_VRR_VVM(s390_irgen_VEC, VRR_v1(ovl),
20923                                                VRR_v2(ovl), VRR_m4(ovl),
20924                                                VRR_rxb(ovl));  goto ok;
20925    case 0xe700000000deULL: s390_format_VRR_VVM(s390_irgen_VLC, VRR_v1(ovl),
20926                                                VRR_v2(ovl), VRR_m4(ovl),
20927                                                VRR_rxb(ovl));  goto ok;
20928    case 0xe700000000dfULL: s390_format_VRR_VVM(s390_irgen_VLP, VRR_v1(ovl),
20929                                                VRR_v2(ovl), VRR_m4(ovl),
20930                                                VRR_rxb(ovl));  goto ok;
20931    case 0xe700000000e2ULL: s390_format_VRRa_VVVMM(s390_irgen_VFS, VRRa_v1(ovl),
20932                                                   VRRa_v2(ovl), VRRa_v3(ovl),
20933                                                   VRRa_m3(ovl), VRRa_m4(ovl),
20934                                                   VRRa_rxb(ovl)); goto ok;
20935    case 0xe700000000e3ULL: s390_format_VRRa_VVVMM(s390_irgen_VFA, VRRa_v1(ovl),
20936                                                   VRRa_v2(ovl), VRRa_v3(ovl),
20937                                                   VRRa_m3(ovl), VRRa_m4(ovl),
20938                                                   VRRa_rxb(ovl)); goto ok;
20939    case 0xe700000000e5ULL: s390_format_VRRa_VVVMM(s390_irgen_VFD, VRRa_v1(ovl),
20940                                                   VRRa_v2(ovl), VRRa_v3(ovl),
20941                                                   VRRa_m3(ovl), VRRa_m4(ovl),
20942                                                   VRRa_rxb(ovl)); goto ok;
20943    case 0xe700000000e7ULL: s390_format_VRRa_VVVMM(s390_irgen_VFM, VRRa_v1(ovl),
20944                                                   VRRa_v2(ovl), VRRa_v3(ovl),
20945                                                   VRRa_m3(ovl), VRRa_m4(ovl),
20946                                                   VRRa_rxb(ovl)); goto ok;
20947    case 0xe700000000e8ULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCE, VRRa_v1(ovl),
20948                                                    VRRa_v2(ovl), VRRa_v3(ovl),
20949                                                    VRRa_m3(ovl), VRRa_m4(ovl),
20950                                                    VRRa_m5(ovl),
20951                                                    VRRa_rxb(ovl)); goto ok;
20952    case 0xe700000000eaULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCHE, VRRa_v1(ovl),
20953                                                    VRRa_v2(ovl), VRRa_v3(ovl),
20954                                                    VRRa_m3(ovl), VRRa_m4(ovl),
20955                                                    VRRa_m5(ovl),
20956                                                    VRRa_rxb(ovl)); goto ok;
20957    case 0xe700000000ebULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCH, VRRa_v1(ovl),
20958                                                    VRRa_v2(ovl), VRRa_v3(ovl),
20959                                                    VRRa_m3(ovl), VRRa_m4(ovl),
20960                                                    VRRa_m5(ovl),
20961                                                    VRRa_rxb(ovl)); goto ok;
20962    case 0xe700000000eeULL: /* VFMIN */ goto unimplemented;
20963    case 0xe700000000efULL: /* VFMAX */ goto unimplemented;
20964    case 0xe700000000f0ULL: s390_format_VRR_VVVM(s390_irgen_VAVGL, VRR_v1(ovl),
20965                                                 VRR_v2(ovl), VRR_r3(ovl),
20966                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20967    case 0xe700000000f1ULL: s390_format_VRR_VVVM(s390_irgen_VACC, VRR_v1(ovl),
20968                                                 VRR_v2(ovl), VRR_r3(ovl),
20969                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20970    case 0xe700000000f2ULL: s390_format_VRR_VVVM(s390_irgen_VAVG, VRR_v1(ovl),
20971                                                 VRR_v2(ovl), VRR_r3(ovl),
20972                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20973    case 0xe700000000f3ULL: s390_format_VRR_VVVM(s390_irgen_VA, VRR_v1(ovl),
20974                                                 VRR_v2(ovl), VRR_r3(ovl),
20975                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20976    case 0xe700000000f5ULL: s390_format_VRR_VVVM(s390_irgen_VSCBI, VRR_v1(ovl),
20977                                                 VRR_v2(ovl), VRR_r3(ovl),
20978                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20979    case 0xe700000000f7ULL: s390_format_VRR_VVVM(s390_irgen_VS, VRR_v1(ovl),
20980                                                 VRR_v2(ovl), VRR_r3(ovl),
20981                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20982    case 0xe700000000f8ULL: s390_format_VRR_VVVMM(s390_irgen_VCEQ, VRR_v1(ovl),
20983                                                  VRR_v2(ovl), VRR_r3(ovl),
20984                                                  VRR_m4(ovl), VRR_m5(ovl),
20985                                                  VRR_rxb(ovl));  goto ok;
20986    case 0xe700000000f9ULL: s390_format_VRR_VVVMM(s390_irgen_VCHL, VRR_v1(ovl),
20987                                                  VRR_v2(ovl), VRR_r3(ovl),
20988                                                  VRR_m4(ovl), VRR_m5(ovl),
20989                                                  VRR_rxb(ovl));  goto ok;
20990    case 0xe700000000fbULL: s390_format_VRR_VVVMM(s390_irgen_VCH, VRR_v1(ovl),
20991                                                  VRR_v2(ovl), VRR_r3(ovl),
20992                                                  VRR_m4(ovl), VRR_m5(ovl),
20993                                                  VRR_rxb(ovl));  goto ok;
20994    case 0xe700000000fcULL: s390_format_VRR_VVVM(s390_irgen_VMNL, VRR_v1(ovl),
20995                                                 VRR_v2(ovl), VRR_r3(ovl),
20996                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
20997    case 0xe700000000fdULL: s390_format_VRR_VVVM(s390_irgen_VMXL, VRR_v1(ovl),
20998                                                 VRR_v2(ovl), VRR_r3(ovl),
20999                                                 VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
21000    case 0xe700000000feULL: s390_format_VRR_VVVM(s390_irgen_VMN, VRR_v1(ovl),
21001                                                VRR_v2(ovl), VRR_r3(ovl),
21002                                                VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
21003    case 0xe700000000ffULL: s390_format_VRR_VVVM(s390_irgen_VMX, VRR_v1(ovl),
21004                                                VRR_v2(ovl), VRR_r3(ovl),
21005                                                VRR_m4(ovl), VRR_rxb(ovl));  goto ok;
21006    case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, RSY_r1(ovl),
21007                                                 RSY_r3(ovl), RSY_b2(ovl),
21008                                                 RSY_dl2(ovl),
21009                                                 RSY_dh2(ovl));  goto ok;
21010    case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, RSY_r1(ovl),
21011                                                 RSY_r3(ovl), RSY_b2(ovl),
21012                                                 RSY_dl2(ovl),
21013                                                 RSY_dh2(ovl));  goto ok;
21014    case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, RSY_r1(ovl),
21015                                                 RSY_r3(ovl), RSY_b2(ovl),
21016                                                 RSY_dl2(ovl),
21017                                                 RSY_dh2(ovl));  goto ok;
21018    case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, RSY_r1(ovl),
21019                                                 RSY_r3(ovl), RSY_b2(ovl),
21020                                                 RSY_dl2(ovl),
21021                                                 RSY_dh2(ovl));  goto ok;
21022    case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, RSY_r1(ovl),
21023                                                 RSY_r3(ovl), RSY_b2(ovl),
21024                                                 RSY_dl2(ovl),
21025                                                 RSY_dh2(ovl));  goto ok;
21026    case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
21027    case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, RSY_r1(ovl),
21028                                                 RSY_r3(ovl), RSY_b2(ovl),
21029                                                 RSY_dl2(ovl),
21030                                                 RSY_dh2(ovl));  goto ok;
21031    case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, RSY_r1(ovl),
21032                                                 RSY_r3(ovl), RSY_b2(ovl),
21033                                                 RSY_dl2(ovl),
21034                                                 RSY_dh2(ovl));  goto ok;
21035    case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, RSY_r1(ovl),
21036                                                 RSY_r3(ovl), RSY_b2(ovl),
21037                                                 RSY_dl2(ovl),
21038                                                 RSY_dh2(ovl));  goto ok;
21039    case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, RSY_r1(ovl),
21040                                                 RSY_r3(ovl), RSY_b2(ovl),
21041                                                 RSY_dl2(ovl),
21042                                                 RSY_dh2(ovl));  goto ok;
21043    case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, RSY_r1(ovl),
21044                                                 RSY_r3(ovl), RSY_b2(ovl),
21045                                                 RSY_dl2(ovl),
21046                                                 RSY_dh2(ovl));  goto ok;
21047    case 0xeb0000000023ULL: s390_format_RSY_RURD(s390_irgen_CLT, RSY_r1(ovl),
21048                                                 RSY_r3(ovl), RSY_b2(ovl),
21049                                                 RSY_dl2(ovl),
21050                                                 RSY_dh2(ovl));  goto ok;
21051    case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, RSY_r1(ovl),
21052                                                 RSY_r3(ovl), RSY_b2(ovl),
21053                                                 RSY_dl2(ovl),
21054                                                 RSY_dh2(ovl));  goto ok;
21055    case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
21056    case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, RSY_r1(ovl),
21057                                                 RSY_r3(ovl), RSY_b2(ovl),
21058                                                 RSY_dl2(ovl),
21059                                                 RSY_dh2(ovl));  goto ok;
21060    case 0xeb000000002bULL: s390_format_RSY_RURD(s390_irgen_CLGT, RSY_r1(ovl),
21061                                                 RSY_r3(ovl), RSY_b2(ovl),
21062                                                 RSY_dl2(ovl),
21063                                                 RSY_dh2(ovl));  goto ok;
21064    case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
21065                                                 RSY_r1(ovl), RSY_r3(ovl),
21066                                                 RSY_b2(ovl), RSY_dl2(ovl),
21067                                                 RSY_dh2(ovl));  goto ok;
21068    case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
21069                                                 RSY_r1(ovl), RSY_r3(ovl),
21070                                                 RSY_b2(ovl), RSY_dl2(ovl),
21071                                                 RSY_dh2(ovl));  goto ok;
21072    case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
21073    case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, RSY_r1(ovl),
21074                                                 RSY_r3(ovl), RSY_b2(ovl),
21075                                                 RSY_dl2(ovl),
21076                                                 RSY_dh2(ovl));  goto ok;
21077    case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, RSY_r1(ovl),
21078                                                 RSY_r3(ovl), RSY_b2(ovl),
21079                                                 RSY_dl2(ovl),
21080                                                 RSY_dh2(ovl));  goto ok;
21081    case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, RSY_r1(ovl),
21082                                                 RSY_r3(ovl), RSY_b2(ovl),
21083                                                 RSY_dl2(ovl),
21084                                                 RSY_dh2(ovl));  goto ok;
21085    case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, RSY_r1(ovl),
21086                                                 RSY_r3(ovl), RSY_b2(ovl),
21087                                                 RSY_dl2(ovl),
21088                                                 RSY_dh2(ovl));  goto ok;
21089    case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
21090                                                 RSY_r1(ovl), RSY_r3(ovl),
21091                                                 RSY_b2(ovl), RSY_dl2(ovl),
21092                                                 RSY_dh2(ovl));  goto ok;
21093    case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, RSY_r1(ovl),
21094                                                 RSY_r3(ovl), RSY_b2(ovl),
21095                                                 RSY_dl2(ovl),
21096                                                 RSY_dh2(ovl));  goto ok;
21097    case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, SIY_i2(ovl),
21098                                                SIY_b1(ovl), SIY_dl1(ovl),
21099                                                SIY_dh1(ovl));  goto ok;
21100    case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, SIY_i2(ovl),
21101                                                SIY_b1(ovl), SIY_dl1(ovl),
21102                                                SIY_dh1(ovl));  goto ok;
21103    case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, SIY_i2(ovl),
21104                                                SIY_b1(ovl), SIY_dl1(ovl),
21105                                                SIY_dh1(ovl));  goto ok;
21106    case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, SIY_i2(ovl),
21107                                                SIY_b1(ovl), SIY_dl1(ovl),
21108                                                SIY_dh1(ovl));  goto ok;
21109    case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, SIY_i2(ovl),
21110                                                SIY_b1(ovl), SIY_dl1(ovl),
21111                                                SIY_dh1(ovl));  goto ok;
21112    case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, SIY_i2(ovl),
21113                                                SIY_b1(ovl), SIY_dl1(ovl),
21114                                                SIY_dh1(ovl));  goto ok;
21115    case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, SIY_i2(ovl),
21116                                                SIY_b1(ovl), SIY_dl1(ovl),
21117                                                SIY_dh1(ovl));  goto ok;
21118    case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, SIY_i2(ovl),
21119                                                SIY_b1(ovl), SIY_dl1(ovl),
21120                                                SIY_dh1(ovl));  goto ok;
21121    case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, SIY_i2(ovl),
21122                                                SIY_b1(ovl), SIY_dl1(ovl),
21123                                                SIY_dh1(ovl));  goto ok;
21124    case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, SIY_i2(ovl),
21125                                                SIY_b1(ovl), SIY_dl1(ovl),
21126                                                SIY_dh1(ovl));  goto ok;
21127    case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, RSY_r1(ovl),
21128                                                 RSY_r3(ovl), RSY_b2(ovl),
21129                                                 RSY_dl2(ovl),
21130                                                 RSY_dh2(ovl));  goto ok;
21131    case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, RSY_r1(ovl),
21132                                                 RSY_r3(ovl), RSY_b2(ovl),
21133                                                 RSY_dl2(ovl),
21134                                                 RSY_dh2(ovl));  goto ok;
21135    case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
21136    case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
21137    case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, RSY_r1(ovl),
21138                                                 RSY_r3(ovl), RSY_b2(ovl),
21139                                                 RSY_dl2(ovl),
21140                                                 RSY_dh2(ovl));  goto ok;
21141    case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, RSY_r1(ovl),
21142                                                 RSY_r3(ovl), RSY_b2(ovl),
21143                                                 RSY_dl2(ovl),
21144                                                 RSY_dh2(ovl));  goto ok;
21145    case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, RSY_r1(ovl),
21146                                                 RSY_r3(ovl), RSY_b2(ovl),
21147                                                 RSY_dl2(ovl),
21148                                                 RSY_dh2(ovl));  goto ok;
21149    case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, RSY_r1(ovl),
21150                                                 RSY_r3(ovl), RSY_b2(ovl),
21151                                                 RSY_dl2(ovl),
21152                                                 RSY_dh2(ovl));  goto ok;
21153    case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
21154                                                 RSY_r1(ovl), RSY_r3(ovl),
21155                                                 RSY_b2(ovl), RSY_dl2(ovl),
21156                                                 RSY_dh2(ovl));  goto ok;
21157    case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
21158    case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, RSY_r1(ovl),
21159                                                 RSY_r3(ovl), RSY_b2(ovl),
21160                                                 RSY_dl2(ovl),
21161                                                 RSY_dh2(ovl));  goto ok;
21162    case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, RSY_r1(ovl),
21163                                                 RSY_r3(ovl), RSY_b2(ovl),
21164                                                 RSY_dl2(ovl),
21165                                                 RSY_dh2(ovl));  goto ok;
21166    case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, RSY_r1(ovl),
21167                                                 RSY_r3(ovl), RSY_b2(ovl),
21168                                                 RSY_dl2(ovl),
21169                                                 RSY_dh2(ovl));  goto ok;
21170    case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, RSY_r1(ovl),
21171                                                 RSY_r3(ovl), RSY_b2(ovl),
21172                                                 RSY_dl2(ovl),
21173                                                 RSY_dh2(ovl));  goto ok;
21174    case 0xeb00000000e0ULL: s390_format_RSY_RDRM(s390_irgen_LOCFH, RSY_r1(ovl),
21175                                                 RSY_r3(ovl), RSY_b2(ovl),
21176                                                 RSY_dl2(ovl),
21177                                                 RSY_dh2(ovl),
21178                                                 S390_XMNM_LOCFH);  goto ok;
21179    case 0xeb00000000e1ULL: s390_format_RSY_RDRM(s390_irgen_STOCFH, RSY_r1(ovl),
21180                                                 RSY_r3(ovl), RSY_b2(ovl),
21181                                                 RSY_dl2(ovl),
21182                                                 RSY_dh2(ovl),
21183                                                 S390_XMNM_STOCFH);  goto ok;
21184    case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, RSY_r1(ovl),
21185                                                 RSY_r3(ovl), RSY_b2(ovl),
21186                                                 RSY_dl2(ovl),
21187                                                 RSY_dh2(ovl),
21188                                                 S390_XMNM_LOCG);  goto ok;
21189    case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
21190                                                 RSY_r1(ovl), RSY_r3(ovl),
21191                                                 RSY_b2(ovl), RSY_dl2(ovl),
21192                                                 RSY_dh2(ovl),
21193                                                 S390_XMNM_STOCG);  goto ok;
21194    case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, RSY_r1(ovl),
21195                                                 RSY_r3(ovl), RSY_b2(ovl),
21196                                                 RSY_dl2(ovl),
21197                                                 RSY_dh2(ovl));  goto ok;
21198    case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, RSY_r1(ovl),
21199                                                 RSY_r3(ovl), RSY_b2(ovl),
21200                                                 RSY_dl2(ovl),
21201                                                 RSY_dh2(ovl));  goto ok;
21202    case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, RSY_r1(ovl),
21203                                                 RSY_r3(ovl), RSY_b2(ovl),
21204                                                 RSY_dl2(ovl),
21205                                                 RSY_dh2(ovl));  goto ok;
21206    case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, RSY_r1(ovl),
21207                                                 RSY_r3(ovl), RSY_b2(ovl),
21208                                                 RSY_dl2(ovl),
21209                                                 RSY_dh2(ovl));  goto ok;
21210    case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
21211                                                 RSY_r1(ovl), RSY_r3(ovl),
21212                                                 RSY_b2(ovl), RSY_dl2(ovl),
21213                                                 RSY_dh2(ovl));  goto ok;
21214    case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, RSY_r1(ovl),
21215                                                 RSY_r3(ovl), RSY_b2(ovl),
21216                                                 RSY_dl2(ovl),
21217                                                 RSY_dh2(ovl), S390_XMNM_LOC);
21218                                                 goto ok;
21219    case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, RSY_r1(ovl),
21220                                                 RSY_r3(ovl), RSY_b2(ovl),
21221                                                 RSY_dl2(ovl),
21222                                                 RSY_dh2(ovl),
21223                                                 S390_XMNM_STOC);  goto ok;
21224    case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, RSY_r1(ovl),
21225                                                 RSY_r3(ovl), RSY_b2(ovl),
21226                                                 RSY_dl2(ovl),
21227                                                 RSY_dh2(ovl));  goto ok;
21228    case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, RSY_r1(ovl),
21229                                                 RSY_r3(ovl), RSY_b2(ovl),
21230                                                 RSY_dl2(ovl),
21231                                                 RSY_dh2(ovl));  goto ok;
21232    case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, RSY_r1(ovl),
21233                                                 RSY_r3(ovl), RSY_b2(ovl),
21234                                                 RSY_dl2(ovl),
21235                                                 RSY_dh2(ovl));  goto ok;
21236    case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, RSY_r1(ovl),
21237                                                 RSY_r3(ovl), RSY_b2(ovl),
21238                                                 RSY_dl2(ovl),
21239                                                 RSY_dh2(ovl));  goto ok;
21240    case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, RSY_r1(ovl),
21241                                                 RSY_r3(ovl), RSY_b2(ovl),
21242                                                 RSY_dl2(ovl),
21243                                                 RSY_dh2(ovl));  goto ok;
21244    case 0xec0000000042ULL: s390_format_RIE_RUPIX(s390_irgen_LOCHI,
21245                                                  RIEv3_r1(ovl),
21246                                                  RIEv3_m3(ovl),
21247                                                  RIEv3_i4(ovl),
21248                                                  RIEv3_i2(ovl),
21249                                                  S390_XMNM_LOCHI);  goto ok;
21250    case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, RIE_r1(ovl),
21251                                                RIE_r3(ovl), RIE_i2(ovl));
21252                                                goto ok;
21253    case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, RIE_r1(ovl),
21254                                                RIE_r3(ovl), RIE_i2(ovl));
21255                                                goto ok;
21256    case 0xec0000000046ULL: s390_format_RIE_RUPIX(s390_irgen_LOCGHI,
21257                                                  RIEv3_r1(ovl),
21258                                                  RIEv3_m3(ovl),
21259                                                  RIEv3_i4(ovl),
21260                                                  RIEv3_i2(ovl),
21261                                                  S390_XMNM_LOCGHI);  goto ok;
21262    case 0xec000000004eULL: s390_format_RIE_RUPIX(s390_irgen_LOCHHI,
21263                                                  RIEv3_r1(ovl),
21264                                                  RIEv3_m3(ovl),
21265                                                  RIEv3_i4(ovl),
21266                                                  RIEv3_i2(ovl),
21267                                                  S390_XMNM_LOCHHI);  goto ok;
21268    case 0xec0000000051ULL: s390_format_RIE_RRUUU(s390_irgen_RISBLG,
21269                                                  RIE_RRUUU_r1(ovl),
21270                                                  RIE_RRUUU_r2(ovl),
21271                                                  RIE_RRUUU_i3(ovl),
21272                                                  RIE_RRUUU_i4(ovl),
21273                                                  RIE_RRUUU_i5(ovl));
21274                                                  goto ok;
21275    case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
21276                                                  RIE_RRUUU_r1(ovl),
21277                                                  RIE_RRUUU_r2(ovl),
21278                                                  RIE_RRUUU_i3(ovl),
21279                                                  RIE_RRUUU_i4(ovl),
21280                                                  RIE_RRUUU_i5(ovl));
21281                                                  goto ok;
21282    case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
21283                                                  RIE_RRUUU_r1(ovl),
21284                                                  RIE_RRUUU_r2(ovl),
21285                                                  RIE_RRUUU_i3(ovl),
21286                                                  RIE_RRUUU_i4(ovl),
21287                                                  RIE_RRUUU_i5(ovl));
21288                                                  goto ok;
21289    case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
21290                                                  RIE_RRUUU_r1(ovl),
21291                                                  RIE_RRUUU_r2(ovl),
21292                                                  RIE_RRUUU_i3(ovl),
21293                                                  RIE_RRUUU_i4(ovl),
21294                                                  RIE_RRUUU_i5(ovl));
21295                                                  goto ok;
21296    case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
21297                                                  RIE_RRUUU_r1(ovl),
21298                                                  RIE_RRUUU_r2(ovl),
21299                                                  RIE_RRUUU_i3(ovl),
21300                                                  RIE_RRUUU_i4(ovl),
21301                                                  RIE_RRUUU_i5(ovl));
21302                                                  goto ok;
21303    case 0xec0000000059ULL: s390_format_RIE_RRUUU(s390_irgen_RISBGN,
21304                                                  RIE_RRUUU_r1(ovl),
21305                                                  RIE_RRUUU_r2(ovl),
21306                                                  RIE_RRUUU_i3(ovl),
21307                                                  RIE_RRUUU_i4(ovl),
21308                                                  RIE_RRUUU_i5(ovl));
21309                                                  goto ok;
21310    case 0xec000000005dULL: s390_format_RIE_RRUUU(s390_irgen_RISBHG,
21311                                                  RIE_RRUUU_r1(ovl),
21312                                                  RIE_RRUUU_r2(ovl),
21313                                                  RIE_RRUUU_i3(ovl),
21314                                                  RIE_RRUUU_i4(ovl),
21315                                                  RIE_RRUUU_i5(ovl));
21316                                                  goto ok;
21317    case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
21318                                                 RIE_RRPU_r1(ovl),
21319                                                 RIE_RRPU_r2(ovl),
21320                                                 RIE_RRPU_i4(ovl),
21321                                                 RIE_RRPU_m3(ovl));  goto ok;
21322    case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
21323                                                 RIE_RRPU_r1(ovl),
21324                                                 RIE_RRPU_r2(ovl),
21325                                                 RIE_RRPU_i4(ovl),
21326                                                 RIE_RRPU_m3(ovl));  goto ok;
21327    case 0xec0000000070ULL: s390_format_RIEv1(s390_irgen_CGIT,
21328                                              RIEv1_r1(ovl),
21329                                              RIEv1_i2(ovl),
21330                                              RIEv1_m3(ovl)); goto ok;
21331    case 0xec0000000071ULL: s390_format_RIEv1(s390_irgen_CLGIT,
21332                                              RIEv1_r1(ovl),
21333                                              RIEv1_i2(ovl),
21334                                              RIEv1_m3(ovl)); goto ok;
21335    case 0xec0000000072ULL: s390_format_RIEv1(s390_irgen_CIT,
21336                                              RIEv1_r1(ovl),
21337                                              RIEv1_i2(ovl),
21338                                              RIEv1_m3(ovl)); goto ok;
21339    case 0xec0000000073ULL: s390_format_RIEv1(s390_irgen_CLFIT,
21340                                              RIEv1_r1(ovl),
21341                                              RIEv1_i2(ovl),
21342                                              RIEv1_m3(ovl)); goto ok;
21343    case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
21344                                                 RIE_RRPU_r1(ovl),
21345                                                 RIE_RRPU_r2(ovl),
21346                                                 RIE_RRPU_i4(ovl),
21347                                                 RIE_RRPU_m3(ovl));  goto ok;
21348    case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
21349                                                 RIE_RRPU_r1(ovl),
21350                                                 RIE_RRPU_r2(ovl),
21351                                                 RIE_RRPU_i4(ovl),
21352                                                 RIE_RRPU_m3(ovl));  goto ok;
21353    case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
21354                                                 RIEv3_r1(ovl),
21355                                                 RIEv3_m3(ovl),
21356                                                 RIEv3_i4(ovl),
21357                                                 RIEv3_i2(ovl));  goto ok;
21358    case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
21359                                                 RIEv3_r1(ovl),
21360                                                 RIEv3_m3(ovl),
21361                                                 RIEv3_i4(ovl),
21362                                                 RIEv3_i2(ovl));  goto ok;
21363    case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
21364                                                 RIEv3_r1(ovl),
21365                                                 RIEv3_m3(ovl),
21366                                                 RIEv3_i4(ovl),
21367                                                 RIEv3_i2(ovl));  goto ok;
21368    case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
21369                                                 RIEv3_r1(ovl),
21370                                                 RIEv3_m3(ovl),
21371                                                 RIEv3_i4(ovl),
21372                                                 RIEv3_i2(ovl));  goto ok;
21373    case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, RIE_r1(ovl),
21374                                                 RIE_r3(ovl), RIE_i2(ovl));
21375                                                 goto ok;
21376    case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
21377                                                 RIE_r1(ovl), RIE_r3(ovl),
21378                                                 RIE_i2(ovl));  goto ok;
21379    case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
21380                                                 RIE_r1(ovl), RIE_r3(ovl),
21381                                                 RIE_i2(ovl));  goto ok;
21382    case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
21383                                                 RIE_r1(ovl), RIE_r3(ovl),
21384                                                 RIE_i2(ovl));  goto ok;
21385    case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, RRS_r1(ovl),
21386                                            RRS_r2(ovl), RRS_b4(ovl),
21387                                            RRS_d4(ovl), RRS_m3(ovl));
21388                                            goto ok;
21389    case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, RRS_r1(ovl),
21390                                            RRS_r2(ovl), RRS_b4(ovl),
21391                                            RRS_d4(ovl), RRS_m3(ovl));
21392                                            goto ok;
21393    case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, RRS_r1(ovl),
21394                                            RRS_r2(ovl), RRS_b4(ovl),
21395                                            RRS_d4(ovl), RRS_m3(ovl));
21396                                            goto ok;
21397    case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, RRS_r1(ovl),
21398                                            RRS_r2(ovl), RRS_b4(ovl),
21399                                            RRS_d4(ovl), RRS_m3(ovl));
21400                                            goto ok;
21401    case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
21402                                                  RIS_r1(ovl), RIS_m3(ovl),
21403                                                  RIS_b4(ovl), RIS_d4(ovl),
21404                                                  RIS_i2(ovl));  goto ok;
21405    case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
21406                                                  RIS_r1(ovl), RIS_m3(ovl),
21407                                                  RIS_b4(ovl), RIS_d4(ovl),
21408                                                  RIS_i2(ovl));  goto ok;
21409    case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, RIS_r1(ovl),
21410                                                  RIS_m3(ovl), RIS_b4(ovl),
21411                                                  RIS_d4(ovl),
21412                                                  RIS_i2(ovl));  goto ok;
21413    case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
21414                                                  RIS_r1(ovl), RIS_m3(ovl),
21415                                                  RIS_b4(ovl), RIS_d4(ovl),
21416                                                  RIS_i2(ovl));  goto ok;
21417    case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, RXE_r1(ovl),
21418                                                 RXE_x2(ovl), RXE_b2(ovl),
21419                                                 RXE_d2(ovl));  goto ok;
21420    case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, RXE_r1(ovl),
21421                                                 RXE_x2(ovl), RXE_b2(ovl),
21422                                                 RXE_d2(ovl));  goto ok;
21423    case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, RXE_r1(ovl),
21424                                                 RXE_x2(ovl), RXE_b2(ovl),
21425                                                 RXE_d2(ovl));  goto ok;
21426    case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
21427    case 0xed0000000008ULL: /* KEB */ goto unimplemented;
21428    case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, RXE_r1(ovl),
21429                                                 RXE_x2(ovl), RXE_b2(ovl),
21430                                                 RXE_d2(ovl));  goto ok;
21431    case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, RXE_r1(ovl),
21432                                                 RXE_x2(ovl), RXE_b2(ovl),
21433                                                 RXE_d2(ovl));  goto ok;
21434    case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, RXE_r1(ovl),
21435                                                 RXE_x2(ovl), RXE_b2(ovl),
21436                                                 RXE_d2(ovl));  goto ok;
21437    case 0xed000000000cULL: /* MDEB */ goto unimplemented;
21438    case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, RXE_r1(ovl),
21439                                                 RXE_x2(ovl), RXE_b2(ovl),
21440                                                 RXE_d2(ovl));  goto ok;
21441    case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
21442                                                  RXF_r3(ovl), RXF_x2(ovl),
21443                                                  RXF_b2(ovl), RXF_d2(ovl),
21444                                                  RXF_r1(ovl));  goto ok;
21445    case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
21446                                                  RXF_r3(ovl), RXF_x2(ovl),
21447                                                  RXF_b2(ovl), RXF_d2(ovl),
21448                                                  RXF_r1(ovl));  goto ok;
21449    case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, RXE_r1(ovl),
21450                                                 RXE_x2(ovl), RXE_b2(ovl),
21451                                                 RXE_d2(ovl));  goto ok;
21452    case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, RXE_r1(ovl),
21453                                                 RXE_x2(ovl), RXE_b2(ovl),
21454                                                 RXE_d2(ovl));  goto ok;
21455    case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, RXE_r1(ovl),
21456                                                 RXE_x2(ovl), RXE_b2(ovl),
21457                                                 RXE_d2(ovl));  goto ok;
21458    case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, RXE_r1(ovl),
21459                                                 RXE_x2(ovl), RXE_b2(ovl),
21460                                                 RXE_d2(ovl));  goto ok;
21461    case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, RXE_r1(ovl),
21462                                                 RXE_x2(ovl), RXE_b2(ovl),
21463                                                 RXE_d2(ovl));  goto ok;
21464    case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, RXE_r1(ovl),
21465                                                 RXE_x2(ovl), RXE_b2(ovl),
21466                                                 RXE_d2(ovl));  goto ok;
21467    case 0xed0000000018ULL: /* KDB */ goto unimplemented;
21468    case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, RXE_r1(ovl),
21469                                                 RXE_x2(ovl), RXE_b2(ovl),
21470                                                 RXE_d2(ovl));  goto ok;
21471    case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, RXE_r1(ovl),
21472                                                 RXE_x2(ovl), RXE_b2(ovl),
21473                                                 RXE_d2(ovl));  goto ok;
21474    case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, RXE_r1(ovl),
21475                                                 RXE_x2(ovl), RXE_b2(ovl),
21476                                                 RXE_d2(ovl));  goto ok;
21477    case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, RXE_r1(ovl),
21478                                                 RXE_x2(ovl), RXE_b2(ovl),
21479                                                 RXE_d2(ovl));  goto ok;
21480    case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, RXE_r1(ovl),
21481                                                 RXE_x2(ovl), RXE_b2(ovl),
21482                                                 RXE_d2(ovl));  goto ok;
21483    case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
21484                                                  RXF_r3(ovl), RXF_x2(ovl),
21485                                                  RXF_b2(ovl), RXF_d2(ovl),
21486                                                  RXF_r1(ovl));  goto ok;
21487    case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
21488                                                  RXF_r3(ovl), RXF_x2(ovl),
21489                                                  RXF_b2(ovl), RXF_d2(ovl),
21490                                                  RXF_r1(ovl));  goto ok;
21491    case 0xed0000000024ULL: s390_format_RXE_FRRD(s390_irgen_LDE,
21492                                                 RXE_r1(ovl), RXE_x2(ovl),
21493                                                 RXE_b2(ovl),
21494                                                 RXE_d2(ovl)); goto ok;
21495    case 0xed0000000025ULL: /* LXD */ goto unimplemented;
21496    case 0xed0000000026ULL: /* LXE */ goto unimplemented;
21497    case 0xed000000002eULL: /* MAE */ goto unimplemented;
21498    case 0xed000000002fULL: /* MSE */ goto unimplemented;
21499    case 0xed0000000034ULL: /* SQE */ goto unimplemented;
21500    case 0xed0000000035ULL: /* SQD */ goto unimplemented;
21501    case 0xed0000000037ULL: /* MEE */ goto unimplemented;
21502    case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
21503    case 0xed0000000039ULL: /* MYL */ goto unimplemented;
21504    case 0xed000000003aULL: /* MAY */ goto unimplemented;
21505    case 0xed000000003bULL: /* MY */ goto unimplemented;
21506    case 0xed000000003cULL: /* MAYH */ goto unimplemented;
21507    case 0xed000000003dULL: /* MYH */ goto unimplemented;
21508    case 0xed000000003eULL: /* MAD */ goto unimplemented;
21509    case 0xed000000003fULL: /* MSD */ goto unimplemented;
21510    case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
21511                                                  RXF_r3(ovl), RXF_x2(ovl),
21512                                                  RXF_b2(ovl), RXF_d2(ovl),
21513                                                  RXF_r1(ovl));  goto ok;
21514    case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
21515                                                  RXF_r3(ovl), RXF_x2(ovl),
21516                                                  RXF_b2(ovl), RXF_d2(ovl),
21517                                                  RXF_r1(ovl));  goto ok;
21518    case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
21519                                                  RXF_r3(ovl), RXF_x2(ovl),
21520                                                  RXF_b2(ovl), RXF_d2(ovl),
21521                                                  RXF_r1(ovl));  goto ok;
21522    case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
21523                                                  RXF_r3(ovl), RXF_x2(ovl),
21524                                                  RXF_b2(ovl), RXF_d2(ovl),
21525                                                  RXF_r1(ovl));  goto ok;
21526    case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, RXE_r1(ovl),
21527                                                 RXE_x2(ovl), RXE_b2(ovl),
21528                                                 RXE_d2(ovl));  goto ok;
21529    case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, RXE_r1(ovl),
21530                                                 RXE_x2(ovl), RXE_b2(ovl),
21531                                                 RXE_d2(ovl));  goto ok;
21532    case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, RXE_r1(ovl),
21533                                                 RXE_x2(ovl), RXE_b2(ovl),
21534                                                 RXE_d2(ovl));  goto ok;
21535    case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, RXE_r1(ovl),
21536                                                 RXE_x2(ovl), RXE_b2(ovl),
21537                                                 RXE_d2(ovl));  goto ok;
21538    case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, RXE_r1(ovl),
21539                                                 RXE_x2(ovl), RXE_b2(ovl),
21540                                                 RXE_d2(ovl));  goto ok;
21541    case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, RXE_r1(ovl),
21542                                                 RXE_x2(ovl), RXE_b2(ovl),
21543                                                 RXE_d2(ovl));  goto ok;
21544    case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, RXY_r1(ovl),
21545                                                 RXY_x2(ovl), RXY_b2(ovl),
21546                                                 RXY_dl2(ovl),
21547                                                 RXY_dh2(ovl));  goto ok;
21548    case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, RXY_r1(ovl),
21549                                                 RXY_x2(ovl), RXY_b2(ovl),
21550                                                 RXY_dl2(ovl),
21551                                                 RXY_dh2(ovl));  goto ok;
21552    case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, RXY_r1(ovl),
21553                                                 RXY_x2(ovl), RXY_b2(ovl),
21554                                                 RXY_dl2(ovl),
21555                                                 RXY_dh2(ovl));  goto ok;
21556    case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, RXY_r1(ovl),
21557                                                 RXY_x2(ovl), RXY_b2(ovl),
21558                                                 RXY_dl2(ovl),
21559                                                 RXY_dh2(ovl));  goto ok;
21560    case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
21561    case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
21562    case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
21563    case 0xed00000000abULL: /* CXZT */ goto unimplemented;
21564    case 0xed00000000acULL: /* CPDT */ goto unimplemented;
21565    case 0xed00000000adULL: /* CPXT */ goto unimplemented;
21566    case 0xed00000000aeULL: /* CDPT */ goto unimplemented;
21567    case 0xed00000000afULL: /* CXPT */ goto unimplemented;
21568    }
21569 
21570    switch (((ovl >> 16) & 0xff0f00000000ULL) >> 32) {
21571    case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, RIL_r1(ovl),
21572                                       RIL_i2(ovl));  goto ok;
21573    case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, RIL_r1(ovl),
21574                                       RIL_i2(ovl));  goto ok;
21575    case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, RIL_r1(ovl),
21576                                    RIL_i2(ovl));  goto ok;
21577    case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, RIL_r1(ovl),
21578                                       RIL_i2(ovl));  goto ok;
21579    case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, RIL_r1(ovl),
21580                                       RIL_i2(ovl));  goto ok;
21581    case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, RIL_r1(ovl),
21582                                       RIL_i2(ovl));  goto ok;
21583    case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, RIL_r1(ovl),
21584                                       RIL_i2(ovl));  goto ok;
21585    case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, RIL_r1(ovl),
21586                                       RIL_i2(ovl));  goto ok;
21587    case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, RIL_r1(ovl),
21588                                       RIL_i2(ovl));  goto ok;
21589    case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, RIL_r1(ovl),
21590                                       RIL_i2(ovl));  goto ok;
21591    case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, RIL_r1(ovl),
21592                                       RIL_i2(ovl));  goto ok;
21593    case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, RIL_r1(ovl),
21594                                       RIL_i2(ovl));  goto ok;
21595    case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, RIL_r1(ovl),
21596                                       RIL_i2(ovl));  goto ok;
21597    case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, RIL_r1(ovl),
21598                                       RIL_i2(ovl));  goto ok;
21599    case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, RIL_r1(ovl),
21600                                       RIL_i2(ovl));  goto ok;
21601    case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, RIL_r1(ovl),
21602                                       RIL_i2(ovl));  goto ok;
21603    case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, RIL_r1(ovl),
21604                                       RIL_i2(ovl));  goto ok;
21605    case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, RIL_r1(ovl),
21606                                       RIL_i2(ovl));  goto ok;
21607    case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, RIL_r1(ovl),
21608                                       RIL_i2(ovl));  goto ok;
21609    case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, RIL_r1(ovl),
21610                                       RIL_i2(ovl));  goto ok;
21611    case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, RIL_r1(ovl),
21612                                       RIL_i2(ovl));  goto ok;
21613    case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, RIL_r1(ovl),
21614                                       RIL_i2(ovl));  goto ok;
21615    case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, RIL_r1(ovl),
21616                                       RIL_i2(ovl));  goto ok;
21617    case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, RIL_r1(ovl),
21618                                       RIL_i2(ovl));  goto ok;
21619    case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, RIL_r1(ovl),
21620                                       RIL_i2(ovl));  goto ok;
21621    case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, RIL_r1(ovl),
21622                                       RIL_i2(ovl));  goto ok;
21623    case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, RIL_r1(ovl),
21624                                       RIL_i2(ovl));  goto ok;
21625    case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, RIL_r1(ovl),
21626                                       RIL_i2(ovl));  goto ok;
21627    case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, RIL_r1(ovl),
21628                                       RIL_i2(ovl));  goto ok;
21629    case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, RIL_r1(ovl),
21630                                       RIL_i2(ovl));  goto ok;
21631    case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, RIL_r1(ovl),
21632                                       RIL_i2(ovl));  goto ok;
21633    case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, RIL_r1(ovl),
21634                                       RIL_i2(ovl));  goto ok;
21635    case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, RIL_r1(ovl),
21636                                       RIL_i2(ovl));  goto ok;
21637    case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, RIL_r1(ovl),
21638                                       RIL_i2(ovl));  goto ok;
21639    case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, RIL_r1(ovl),
21640                                       RIL_i2(ovl));  goto ok;
21641    case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, RIL_r1(ovl),
21642                                       RIL_i2(ovl));  goto ok;
21643    case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, RIL_r1(ovl),
21644                                       RIL_i2(ovl));  goto ok;
21645    case 0xc600ULL: exrl_bytes = bytes;
21646                    s390_format_RIL_RP(s390_irgen_EXRL, RIL_r1(ovl),
21647                                       RIL_i2(ovl));  goto ok;
21648    case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, RIL_r1(ovl),
21649                                       RIL_i2(ovl));  goto ok;
21650    case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, RIL_r1(ovl),
21651                                       RIL_i2(ovl));  goto ok;
21652    case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, RIL_r1(ovl),
21653                                       RIL_i2(ovl));  goto ok;
21654    case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, RIL_r1(ovl),
21655                                       RIL_i2(ovl));  goto ok;
21656    case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, RIL_r1(ovl),
21657                                       RIL_i2(ovl));  goto ok;
21658    case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, RIL_r1(ovl),
21659                                       RIL_i2(ovl));  goto ok;
21660    case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, RIL_r1(ovl),
21661                                       RIL_i2(ovl));  goto ok;
21662    case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, RIL_r1(ovl),
21663                                       RIL_i2(ovl));  goto ok;
21664    case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, RIL_r1(ovl),
21665                                       RIL_i2(ovl));  goto ok;
21666    case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, RIL_r1(ovl),
21667                                       RIL_i2(ovl));  goto ok;
21668    case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, RIL_r1(ovl),
21669                                       RIL_i2(ovl));  goto ok;
21670    case 0xc800ULL: /* MVCOS */ goto unimplemented;
21671    case 0xc801ULL: /* ECTG */ goto unimplemented;
21672    case 0xc802ULL: /* CSST */ goto unimplemented;
21673    case 0xc804ULL: /* LPD */ goto unimplemented;
21674    case 0xc805ULL: /* LPDG */ goto unimplemented;
21675    case 0xcc06ULL:  s390_format_RIL_RP(s390_irgen_BRCTH, RIL_r1(ovl),
21676                                        RIL_i2(ovl));  goto ok;
21677    case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, RIL_r1(ovl),
21678                                       RIL_i2(ovl));  goto ok;
21679    case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, RIL_r1(ovl),
21680                                       RIL_i2(ovl));  goto ok;
21681    case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, RIL_r1(ovl),
21682                                       RIL_i2(ovl));  goto ok;
21683    case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, RIL_r1(ovl),
21684                                       RIL_i2(ovl));  goto ok;
21685    case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, RIL_r1(ovl),
21686                                       RIL_i2(ovl));  goto ok;
21687    }
21688 
21689    switch (((ovl >> 16) & 0xff0000000000ULL) >> 40) {
21690    case 0xc5ULL: /* BPRP */ goto unimplemented;
21691    case 0xc7ULL: /* BPP */ goto unimplemented;
21692    case 0xd0ULL: /* TRTR */ goto unimplemented;
21693    case 0xd1ULL: /* MVN */ goto unimplemented;
21694    case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, SS_l(ovl),
21695                                        SS_b1(ovl), SS_d1(ovl),
21696                                        SS_b2(ovl), SS_d2(ovl));  goto ok;
21697    case 0xd3ULL: /* MVZ */ goto unimplemented;
21698    case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, SS_l(ovl),
21699                                        SS_b1(ovl), SS_d1(ovl),
21700                                        SS_b2(ovl), SS_d2(ovl));  goto ok;
21701    case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, SS_l(ovl),
21702                                        SS_b1(ovl), SS_d1(ovl),
21703                                        SS_b2(ovl), SS_d2(ovl));  goto ok;
21704    case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, SS_l(ovl),
21705                                        SS_b1(ovl), SS_d1(ovl),
21706                                        SS_b2(ovl), SS_d2(ovl));  goto ok;
21707    case 0xd7ULL:
21708       if (SS_b1(ovl) == SS_b2(ovl) && SS_d1(ovl) == SS_d2(ovl))
21709          s390_irgen_XC_sameloc(SS_l(ovl), SS_b1(ovl), SS_d1(ovl));
21710       else
21711         s390_format_SS_L0RDRD(s390_irgen_XC, SS_l(ovl),
21712                               SS_b1(ovl), SS_d1(ovl),
21713                               SS_b2(ovl), SS_d2(ovl));
21714       goto ok;
21715    case 0xd9ULL: /* MVCK */ goto unimplemented;
21716    case 0xdaULL: /* MVCP */ goto unimplemented;
21717    case 0xdbULL: /* MVCS */ goto unimplemented;
21718    case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, SS_l(ovl),
21719                                        SS_b1(ovl), SS_d1(ovl),
21720                                        SS_b2(ovl), SS_d2(ovl));  goto ok;
21721    case 0xddULL: /* TRT */ goto unimplemented;
21722    case 0xdeULL: /* ED */ goto unimplemented;
21723    case 0xdfULL: /* EDMK */ goto unimplemented;
21724    case 0xe1ULL: /* PKU */ goto unimplemented;
21725    case 0xe2ULL: /* UNPKU */ goto unimplemented;
21726    case 0xe8ULL: s390_format_SS_L0RDRD(s390_irgen_MVCIN, SS_l(ovl),
21727                                        SS_b1(ovl), SS_d1(ovl),
21728                                        SS_b2(ovl), SS_d2(ovl));  goto ok;
21729    case 0xe9ULL: /* PKA */ goto unimplemented;
21730    case 0xeaULL: /* UNPKA */ goto unimplemented;
21731    case 0xeeULL: /* PLO */ goto unimplemented;
21732    case 0xefULL: /* LMD */ goto unimplemented;
21733    case 0xf0ULL: /* SRP */ goto unimplemented;
21734    case 0xf1ULL: /* MVO */ goto unimplemented;
21735    case 0xf2ULL: /* PACK */ goto unimplemented;
21736    case 0xf3ULL: /* UNPK */ goto unimplemented;
21737    case 0xf8ULL: /* ZAP */ goto unimplemented;
21738    case 0xf9ULL: /* CP */ goto unimplemented;
21739    case 0xfaULL: /* AP */ goto unimplemented;
21740    case 0xfbULL: /* SP */ goto unimplemented;
21741    case 0xfcULL: /* MP */ goto unimplemented;
21742    case 0xfdULL: /* DP */ goto unimplemented;
21743    }
21744 
21745    switch (((ovl >> 16) & 0xffff00000000ULL) >> 32) {
21746    case 0xe500ULL: /* LASP */ goto unimplemented;
21747    case 0xe501ULL: /* TPROT */ goto unimplemented;
21748    case 0xe502ULL: /* STRAG */ goto unimplemented;
21749    case 0xe50eULL: /* MVCSK */ goto unimplemented;
21750    case 0xe50fULL: /* MVCDK */ goto unimplemented;
21751    case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, SIL_b1(ovl),
21752                                        SIL_d1(ovl), SIL_i2(ovl));
21753                                        goto ok;
21754    case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, SIL_b1(ovl),
21755                                        SIL_d1(ovl), SIL_i2(ovl));
21756                                        goto ok;
21757    case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, SIL_b1(ovl),
21758                                        SIL_d1(ovl), SIL_i2(ovl));
21759                                        goto ok;
21760    case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, SIL_b1(ovl),
21761                                        SIL_d1(ovl), SIL_i2(ovl));
21762                                        goto ok;
21763    case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, SIL_b1(ovl),
21764                                        SIL_d1(ovl), SIL_i2(ovl));
21765                                        goto ok;
21766    case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, SIL_b1(ovl),
21767                                        SIL_d1(ovl), SIL_i2(ovl));
21768                                        goto ok;
21769    case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, SIL_b1(ovl),
21770                                        SIL_d1(ovl), SIL_i2(ovl));
21771                                        goto ok;
21772    case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, SIL_b1(ovl),
21773                                        SIL_d1(ovl), SIL_i2(ovl));
21774                                        goto ok;
21775    case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, SIL_b1(ovl),
21776                                        SIL_d1(ovl), SIL_i2(ovl));
21777                                        goto ok;
21778    case 0xe560ULL: /* TBEGIN */ goto unimplemented;
21779    case 0xe561ULL: /* TBEGINC */ goto unimplemented;
21780    }
21781 
21782    return S390_DECODE_UNKNOWN_INSN;
21783 
21784 ok:
21785    return S390_DECODE_OK;
21786 
21787 unimplemented:
21788    return S390_DECODE_UNIMPLEMENTED_INSN;
21789 }
21790 
21791 /* Handle "special" instructions. */
21792 static s390_decode_t
21793 s390_decode_special_and_irgen(const UChar *bytes)
21794 {
21795    s390_decode_t status = S390_DECODE_OK;
21796 
21797    /* Got a "Special" instruction preamble.  Which one is it? */
21798    if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
21799       s390_irgen_client_request();
21800    } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
21801       s390_irgen_guest_NRADDR();
21802    } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
21803       s390_irgen_call_noredir();
21804    } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
21805       vex_inject_ir(irsb, Iend_BE);
21806 
21807       /* Invalidate the current insn. The reason is that the IRop we're
21808          injecting here can change. In which case the translation has to
21809          be redone. For ease of handling, we simply invalidate all the
21810          time. */
21811       stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
21812                       mkU64(guest_IA_curr_instr)));
21813       stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN),
21814                       mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
21815       vassert(guest_IA_next_instr - guest_IA_curr_instr ==
21816               S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
21817 
21818       put_IA(mkaddr_expr(guest_IA_next_instr));
21819       dis_res->whatNext    = Dis_StopHere;
21820       dis_res->jk_StopHere = Ijk_InvalICache;
21821    } else {
21822       /* We don't know what it is. */
21823       return S390_DECODE_UNKNOWN_SPECIAL_INSN;
21824    }
21825 
21826    dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
21827 
21828    return status;
21829 }
21830 
21831 
21832 /* Function returns # bytes that were decoded or 0 in case of failure */
21833 static UInt
21834 s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres)
21835 {
21836    s390_decode_t status;
21837 
21838    dis_res = dres;
21839 
21840    /* Spot the 8-byte preamble:   18ff lr r15,r15
21841                                   1811 lr r1,r1
21842                                   1822 lr r2,r2
21843                                   1833 lr r3,r3 */
21844    if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
21845        bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
21846        bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
21847 
21848       /* Handle special instruction that follows that preamble. */
21849       if (0) vex_printf("special function handling...\n");
21850 
21851       insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
21852       guest_IA_next_instr = guest_IA_curr_instr + insn_length;
21853 
21854       status =
21855          s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
21856    } else {
21857       /* Handle normal instructions. */
21858       switch (insn_length) {
21859       case 2:
21860          status = s390_decode_2byte_and_irgen(bytes);
21861          break;
21862 
21863       case 4:
21864          status = s390_decode_4byte_and_irgen(bytes);
21865          break;
21866 
21867       case 6:
21868          status = s390_decode_6byte_and_irgen(bytes);
21869          break;
21870 
21871       default:
21872         status = S390_DECODE_ERROR;
21873         break;
21874       }
21875    }
21876    /* If next instruction is execute, stop here */
21877    if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
21878       put_IA(mkaddr_expr(guest_IA_next_instr));
21879       dis_res->whatNext = Dis_StopHere;
21880       dis_res->jk_StopHere = Ijk_Boring;
21881    }
21882 
21883    if (status == S390_DECODE_OK) {
21884       /* Adjust status if a specification exception was indicated. */
21885       if (is_specification_exception())
21886          status = S390_DECODE_SPECIFICATION_EXCEPTION;
21887       else
21888          return insn_length;  /* OK */
21889    }
21890 
21891    /* Decoding failed somehow */
21892    if (sigill_diag) {
21893       vex_printf("vex s390->IR: ");
21894       switch (status) {
21895       case S390_DECODE_UNKNOWN_INSN:
21896          vex_printf("unknown insn: ");
21897          break;
21898 
21899       case S390_DECODE_UNIMPLEMENTED_INSN:
21900          vex_printf("unimplemented insn: ");
21901          break;
21902 
21903       case S390_DECODE_UNKNOWN_SPECIAL_INSN:
21904          vex_printf("unimplemented special insn: ");
21905          break;
21906 
21907       case S390_DECODE_SPECIFICATION_EXCEPTION:
21908          vex_printf("specification exception: ");
21909          break;
21910 
21911       case S390_DECODE_ERROR:
21912          vex_printf("decoding error: ");
21913          break;
21914 
21915       default:
21916          vpanic("s390_decode_and_irgen");
21917       }
21918 
21919       vex_printf("%02x%02x", bytes[0], bytes[1]);
21920       if (insn_length > 2) {
21921          vex_printf(" %02x%02x", bytes[2], bytes[3]);
21922       }
21923       if (insn_length > 4) {
21924          vex_printf(" %02x%02x", bytes[4], bytes[5]);
21925       }
21926       vex_printf("\n");
21927    }
21928 
21929    return 0;  /* Failed */
21930 }
21931 
21932 
21933 /* Disassemble a single instruction INSN into IR. */
21934 static DisResult
21935 disInstr_S390_WRK(const UChar *insn)
21936 {
21937    UChar byte;
21938    UInt  insn_length;
21939    DisResult dres;
21940 
21941    /* ---------------------------------------------------- */
21942    /* --- Compute instruction length                    -- */
21943    /* ---------------------------------------------------- */
21944 
21945    /* Get the first byte of the insn. */
21946    byte = insn[0];
21947 
21948    /* The leftmost two bits (0:1) encode the length of the insn in bytes.
21949       00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
21950    insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
21951 
21952    guest_IA_next_instr = guest_IA_curr_instr + insn_length;
21953 
21954    /* ---------------------------------------------------- */
21955    /* --- Initialise the DisResult data                 -- */
21956    /* ---------------------------------------------------- */
21957    dres.whatNext   = Dis_Continue;
21958    dres.len        = insn_length;
21959    dres.continueAt = 0;
21960    dres.jk_StopHere = Ijk_INVALID;
21961    dres.hint        = Dis_HintNone;
21962 
21963    /* fixs390: consider chasing of conditional jumps */
21964 
21965    /* Normal and special instruction handling starts here. */
21966    if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
21967       /* All decode failures end up here. The decoder has already issued an
21968          error message.
21969          Tell the dispatcher that this insn cannot be decoded, and so has
21970          not been executed, and (is currently) the next to be executed.
21971          The insn address in the guest state needs to be set to
21972          guest_IA_curr_instr, otherwise the complaint will report an
21973          incorrect address. */
21974       put_IA(mkaddr_expr(guest_IA_curr_instr));
21975 
21976       dres.len         = 0;
21977       dres.whatNext    = Dis_StopHere;
21978       dres.jk_StopHere = Ijk_NoDecode;
21979       dres.continueAt  = 0;
21980    } else {
21981       /* Decode success */
21982       switch (dres.whatNext) {
21983       case Dis_Continue:
21984          put_IA(mkaddr_expr(guest_IA_next_instr));
21985          break;
21986       case Dis_ResteerU:
21987       case Dis_ResteerC:
21988          put_IA(mkaddr_expr(dres.continueAt));
21989          break;
21990       case Dis_StopHere:
21991          if (dres.jk_StopHere == Ijk_EmWarn ||
21992              dres.jk_StopHere == Ijk_EmFail) {
21993             /* We assume here, that emulation warnings are not given for
21994                insns that transfer control. There is no good way to
21995                do that. */
21996             put_IA(mkaddr_expr(guest_IA_next_instr));
21997          }
21998          break;
21999       default:
22000          vpanic("disInstr_S390_WRK");
22001       }
22002    }
22003 
22004    return dres;
22005 }
22006 
22007 
22008 /*------------------------------------------------------------*/
22009 /*--- Top-level fn                                         ---*/
22010 /*------------------------------------------------------------*/
22011 
22012 /* Disassemble a single instruction into IR.  The instruction
22013    is located in host memory at &guest_code[delta]. */
22014 
22015 DisResult
22016 disInstr_S390(IRSB        *irsb_IN,
22017               Bool       (*resteerOkFn)(void *, Addr),
22018               Bool         resteerCisOk,
22019               void        *callback_opaque,
22020               const UChar *guest_code,
22021               Long         delta,
22022               Addr         guest_IP,
22023               VexArch      guest_arch,
22024               const VexArchInfo *archinfo,
22025               const VexAbiInfo  *abiinfo,
22026               VexEndness   host_endness,
22027               Bool         sigill_diag_IN)
22028 {
22029    vassert(guest_arch == VexArchS390X);
22030 
22031    /* Set globals (see top of this file) */
22032    guest_IA_curr_instr = guest_IP;
22033    irsb = irsb_IN;
22034    resteer_fn = resteerOkFn;
22035    resteer_data = callback_opaque;
22036    sigill_diag = sigill_diag_IN;
22037 
22038    return disInstr_S390_WRK(guest_code + delta);
22039 }
22040 
22041 /*---------------------------------------------------------------*/
22042 /*--- end                                   guest_s390_toIR.c ---*/
22043 /*---------------------------------------------------------------*/
22044