Bug 497723 - forgot to restore callgrind output cleanup
[valgrind.git] / VEX / priv / guest_s390_toIR.c
blob6da5996452d2de7f4710f4e34ac139c6492532cf
1 /* -*- mode: C; c-basic-offset: 3; -*- */
3 /*---------------------------------------------------------------*/
4 /*--- begin guest_s390_toIR.c ---*/
5 /*---------------------------------------------------------------*/
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
11 Copyright IBM Corp. 2010-2024
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
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.
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/>.
26 The GNU General Public License is contained in the file COPYING.
29 /* Contributed by Florian Krohm and Christian Borntraeger */
31 /* Translates s390 code to IR. */
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 */
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);
54 /*------------------------------------------------------------*/
55 /*--- Globals ---*/
56 /*------------------------------------------------------------*/
58 /* The IRSB* into which we're generating code. */
59 static IRSB *irsb;
61 /* The guest address for the instruction currently being
62 translated. */
63 static Addr64 guest_IA_curr_instr;
65 /* The guest address for the instruction following the current instruction. */
66 static Addr64 guest_IA_next_instr;
68 /* Result of disassembly step. */
69 static DisResult *dis_res;
71 /* Whether to print diagnostics for illegal instructions. */
72 static Bool sigill_diag;
74 /* The last seen execute target instruction */
75 enum { Invalid_execute_target = 1 };
76 ULong last_execute_target = Invalid_execute_target;
78 /* The guest address to be used as the base for relative addresses. */
79 Addr64 guest_IA_rel_base;
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;
92 /*------------------------------------------------------------*/
93 /*--- Instruction formats. ---*/
94 /*------------------------------------------------------------*/
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 RIE_R0xU_r1(insn) (((insn) >> 52) & 0xf)
145 #define RIE_R0xU_i2(insn) (((insn) >> 32) & 0xffff)
146 #define RIE_R0xU_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 #define VRSd_v1(insn) (((insn) >> 28) & 0xf)
256 #define VRSd_r3(insn) (((insn) >> 48) & 0xf)
257 #define VSI_i3(insn) (((insn) >> 48) & 0xff)
258 #define VSI_b2(insn) (((insn) >> 44) & 0xf)
259 #define VSI_d2(insn) (((insn) >> 32) & 0xfff)
260 #define VSI_v1(insn) (((insn) >> 28) & 0xf)
261 #define VSI_rxb(insn) (((insn) >> 24) & 0xf)
264 /*------------------------------------------------------------*/
265 /*--- Helpers for constructing IR. ---*/
266 /*------------------------------------------------------------*/
268 /* Add a statement to the current irsb. */
269 static __inline__ void
270 stmt(IRStmt *st)
272 addStmtToIRSB(irsb, st);
275 /* Allocate a new temporary of the given type. */
276 static __inline__ IRTemp
277 newTemp(IRType type)
279 vassert(isPlausibleIRType(type));
281 return newIRTemp(irsb->tyenv, type);
284 /* Create an expression node for a temporary */
285 static __inline__ IRExpr *
286 mkexpr(IRTemp tmp)
288 return IRExpr_RdTmp(tmp);
291 /* Generate an expression node for an address. */
292 static __inline__ IRExpr *
293 mkaddr_expr(Addr64 addr)
295 return IRExpr_Const(IRConst_U64(addr));
298 /* Add a statement that assigns to a temporary */
299 static __inline__ void
300 assign(IRTemp dst, IRExpr *expr)
302 stmt(IRStmt_WrTmp(dst, expr));
305 /* Write an address into the guest_IA */
306 static __inline__ void
307 put_IA(IRExpr *address)
309 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
312 /* Create a temporary of the given type and assign the expression to it */
313 static __inline__ IRTemp
314 mktemp(IRType type, IRExpr *expr)
316 IRTemp temp = newTemp(type);
318 assign(temp, expr);
320 return temp;
323 /* Create a unary expression */
324 static __inline__ IRExpr *
325 unop(IROp kind, IRExpr *op)
327 return IRExpr_Unop(kind, op);
330 /* Create a binary expression */
331 static __inline__ IRExpr *
332 binop(IROp kind, IRExpr *op1, IRExpr *op2)
334 return IRExpr_Binop(kind, op1, op2);
337 /* Create a ternary expression */
338 static __inline__ IRExpr *
339 triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
341 return IRExpr_Triop(kind, op1, op2, op3);
344 /* Create a quaternary expression */
345 static __inline__ IRExpr *
346 qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
348 return IRExpr_Qop(kind, op1, op2, op3, op4);
351 /* Create an expression node for an 8-bit integer constant */
352 static __inline__ IRExpr *
353 mkU8(UInt value)
355 vassert(value < 256);
357 return IRExpr_Const(IRConst_U8((UChar)value));
360 /* Create an expression node for a 16-bit integer constant */
361 static __inline__ IRExpr *
362 mkU16(UInt value)
364 vassert(value < 65536);
366 return IRExpr_Const(IRConst_U16((UShort)value));
369 /* Create an expression node for a 32-bit integer constant */
370 static __inline__ IRExpr *
371 mkU32(UInt value)
373 return IRExpr_Const(IRConst_U32(value));
376 /* Create an expression node for a 64-bit integer constant */
377 static __inline__ IRExpr *
378 mkU64(ULong value)
380 return IRExpr_Const(IRConst_U64(value));
383 /* Create an expression node for a 128-bit vector constant */
384 static __inline__ IRExpr *
385 mkV128(UShort value)
387 return IRExpr_Const(IRConst_V128(value));
390 /* Create an expression node for a 32-bit floating point constant
391 whose value is given by a bit pattern. */
392 static __inline__ IRExpr *
393 mkF32i(UInt value)
395 return IRExpr_Const(IRConst_F32i(value));
398 /* Create an expression node for a 32-bit floating point constant
399 whose value is given by a bit pattern. */
400 static __inline__ IRExpr *
401 mkF64i(ULong value)
403 return IRExpr_Const(IRConst_F64i(value));
406 /* Return the 64-bit address with the given 32-bit "relative long" offset from
407 the current guest instruction being translated. */
408 static __inline__ Addr64
409 addr_rel_long(UInt offset)
411 return guest_IA_rel_base + ((Addr64)(Long)(Int)offset << 1);
414 /* Return the 64-bit address with the given 16-bit "relative" offset from the
415 current guest instruction being translated. */
416 static __inline__ Addr64
417 addr_relative(UShort offset)
419 return guest_IA_rel_base + ((Addr64)(Long)(Short)offset << 1);
422 /* Little helper function for my sanity. ITE = if-then-else */
423 static IRExpr *
424 mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
426 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
428 return IRExpr_ITE(condition, iftrue, iffalse);
431 /* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
432 static __inline__ void
433 store(IRExpr *addr, IRExpr *data)
435 stmt(IRStmt_Store(Iend_BE, addr, data));
438 /* Create an expression that loads a TYPE sized value from ADDR.
439 This is a big-endian machine. */
440 static __inline__ IRExpr *
441 load(IRType type, IRExpr *addr)
443 return IRExpr_Load(Iend_BE, type, addr);
446 /* Function call */
447 static void
448 call_function(IRExpr *callee_address)
450 put_IA(callee_address);
452 dis_res->whatNext = Dis_StopHere;
453 dis_res->jk_StopHere = Ijk_Call;
456 /* Function call with known target. */
457 static void
458 call_function_and_chase(Addr64 callee_address)
460 put_IA(mkaddr_expr(callee_address));
462 dis_res->whatNext = Dis_StopHere;
463 dis_res->jk_StopHere = Ijk_Call;
466 /* Function return sequence */
467 static void
468 return_from_function(IRExpr *return_address)
470 put_IA(return_address);
472 dis_res->whatNext = Dis_StopHere;
473 dis_res->jk_StopHere = Ijk_Ret;
476 /* A conditional branch whose target is not known at instrumentation time.
478 if (condition) goto computed_target;
480 Needs to be represented as:
482 if (! condition) goto next_instruction;
483 goto computed_target;
485 static void
486 if_condition_goto_computed(IRExpr *condition, IRExpr *target)
488 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
490 condition = unop(Iop_Not1, condition);
492 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
493 S390X_GUEST_OFFSET(guest_IA)));
495 put_IA(target);
497 dis_res->whatNext = Dis_StopHere;
498 dis_res->jk_StopHere = Ijk_Boring;
501 /* A conditional branch whose target is known at instrumentation time. */
502 static void
503 if_condition_goto(IRExpr *condition, Addr64 target)
505 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
507 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
508 S390X_GUEST_OFFSET(guest_IA)));
510 put_IA(mkaddr_expr(guest_IA_next_instr));
512 dis_res->whatNext = Dis_StopHere;
513 dis_res->jk_StopHere = Ijk_Boring;
516 /* An unconditional branch. Target may or may not be known at instrumentation
517 time. */
518 static void
519 always_goto(IRExpr *target)
521 put_IA(target);
523 dis_res->whatNext = Dis_StopHere;
524 dis_res->jk_StopHere = Ijk_Boring;
528 /* An unconditional branch to a known target. */
529 // QQQQ fixme this is now the same as always_goto
530 static void
531 always_goto_and_chase(Addr64 target)
533 put_IA(mkaddr_expr(target));
535 dis_res->whatNext = Dis_StopHere;
536 dis_res->jk_StopHere = Ijk_Boring;
539 /* A system call */
540 static void
541 system_call(IRExpr *sysno)
543 /* Store the system call number in the pseudo register. */
544 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
546 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
547 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
548 mkU64(guest_IA_curr_instr)));
550 put_IA(mkaddr_expr(guest_IA_next_instr));
552 /* It's important that all ArchRegs carry their up-to-date value
553 at this point. So we declare an end-of-block here, which
554 forces any TempRegs caching ArchRegs to be flushed. */
555 dis_res->whatNext = Dis_StopHere;
556 dis_res->jk_StopHere = Ijk_Sys_syscall;
559 /* An extension */
560 static void
561 extension(ULong id, ULong variant)
563 vassert(id < (1 << S390_EXT_ID_NBITS));
564 vassert(variant <= ~((ULong) 0) >> S390_EXT_ID_NBITS);
566 /* Store the extension ID in the pseudo register. */
567 ULong ext_id = id | (variant << S390_EXT_ID_NBITS);
568 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), mkU64(ext_id)));
570 /* Store the current IA into guest_IP_AT_SYSCALL. */
571 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
572 mkU64(guest_IA_curr_instr)));
574 put_IA(mkaddr_expr(guest_IA_next_instr));
576 dis_res->whatNext = Dis_StopHere;
577 dis_res->jk_StopHere = Ijk_Extension;
580 /* A side exit that branches back to the current insn if CONDITION is
581 true. Does not set DisResult. */
582 static void
583 iterate_if(IRExpr *condition)
585 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
587 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
588 S390X_GUEST_OFFSET(guest_IA)));
591 /* A side exit that branches back to the current insn.
592 Does not set DisResult. */
593 static __inline__ void
594 iterate(void)
596 iterate_if(IRExpr_Const(IRConst_U1(True)));
599 /* A side exit that branches back to the insn immediately following the
600 current insn if CONDITION is true. Does not set DisResult. */
601 static void
602 next_insn_if(IRExpr *condition)
604 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
606 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
607 S390X_GUEST_OFFSET(guest_IA)));
610 /* Convenience function to restart the current insn */
611 static void
612 restart_if(IRExpr *condition)
614 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
616 stmt(IRStmt_Exit(condition, Ijk_InvalICache,
617 IRConst_U64(guest_IA_curr_instr),
618 S390X_GUEST_OFFSET(guest_IA)));
621 /* Convenience function to yield to thread scheduler */
622 static void
623 yield_if(IRExpr *condition)
625 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
626 S390X_GUEST_OFFSET(guest_IA)));
629 /* Convenience macro to yield a specification exception if the given condition
630 is not met. Used to pass this type of decoding error up through the call
631 chain. */
632 #define s390_insn_assert(mnm, cond) \
633 do { \
634 if (!(cond)) { \
635 dis_res->whatNext = Dis_StopHere; \
636 dis_res->jk_StopHere = Ijk_NoDecode; \
637 return (mnm); \
639 } while (0)
641 /* Convenience function to check for a specification exception. */
642 static Bool
643 is_specification_exception(void)
645 return (dis_res->whatNext == Dis_StopHere &&
646 dis_res->jk_StopHere == Ijk_NoDecode);
649 static __inline__ IRExpr *get_fpr_dw0(UInt);
650 static __inline__ void put_fpr_dw0(UInt, IRExpr *);
651 static __inline__ IRExpr *get_dpr_dw0(UInt);
652 static __inline__ void put_dpr_dw0(UInt, IRExpr *);
654 /* Read a floating point register pair and combine their contents into a
655 128-bit value */
656 static IRExpr *
657 get_fpr_pair(UInt archreg)
659 IRExpr *high = get_fpr_dw0(archreg);
660 IRExpr *low = get_fpr_dw0(archreg + 2);
662 return binop(Iop_F64HLtoF128, high, low);
665 /* Write a 128-bit floating point value into a register pair. */
666 static void
667 put_fpr_pair(UInt archreg, IRExpr *expr)
669 IRExpr *high = unop(Iop_F128HItoF64, expr);
670 IRExpr *low = unop(Iop_F128LOtoF64, expr);
672 put_fpr_dw0(archreg, high);
673 put_fpr_dw0(archreg + 2, low);
676 /* Read a floating point register pair cointaining DFP value
677 and combine their contents into a 128-bit value */
679 static IRExpr *
680 get_dpr_pair(UInt archreg)
682 IRExpr *high = get_dpr_dw0(archreg);
683 IRExpr *low = get_dpr_dw0(archreg + 2);
685 return binop(Iop_D64HLtoD128, high, low);
688 /* Write a 128-bit decimal floating point value into a register pair. */
689 static void
690 put_dpr_pair(UInt archreg, IRExpr *expr)
692 IRExpr *high = unop(Iop_D128HItoD64, expr);
693 IRExpr *low = unop(Iop_D128LOtoD64, expr);
695 put_dpr_dw0(archreg, high);
696 put_dpr_dw0(archreg + 2, low);
699 /* Terminate the current IRSB with an emulation failure. */
700 static void
701 emulation_failure_with_expr(IRExpr *emfailure)
703 vassert(typeOfIRExpr(irsb->tyenv, emfailure) == Ity_I32);
705 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emfailure));
706 dis_res->whatNext = Dis_StopHere;
707 dis_res->jk_StopHere = Ijk_EmFail;
710 static void
711 emulation_failure(VexEmNote fail_kind)
713 emulation_failure_with_expr(mkU32(fail_kind));
716 /* Terminate the current IRSB with an emulation warning. */
717 static void
718 emulation_warning_with_expr(IRExpr *emwarning)
720 vassert(typeOfIRExpr(irsb->tyenv, emwarning) == Ity_I32);
722 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emwarning));
723 dis_res->whatNext = Dis_StopHere;
724 dis_res->jk_StopHere = Ijk_EmWarn;
727 static void
728 emulation_warning(VexEmNote warn_kind)
730 emulation_warning_with_expr(mkU32(warn_kind));
733 /*------------------------------------------------------------*/
734 /*--- IR Debugging aids. ---*/
735 /*------------------------------------------------------------*/
736 #if 0
738 static ULong
739 s390_do_print(HChar *text, ULong value)
741 vex_printf("%s %llu\n", text, value);
742 return 0;
745 static void
746 s390_print(HChar *text, IRExpr *value)
748 IRDirty *d;
750 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
751 mkIRExprVec_2(mkU64((ULong)text), value));
752 stmt(IRStmt_Dirty(d));
754 #endif
757 /*------------------------------------------------------------*/
758 /*--- Build the flags thunk. ---*/
759 /*------------------------------------------------------------*/
761 /* Completely fill the flags thunk. We're always filling all fields.
762 Apparently, that is better for redundant PUT elimination. */
763 static void
764 s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
766 UInt op_off, dep1_off, dep2_off, ndep_off;
768 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
769 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
770 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
771 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
773 stmt(IRStmt_Put(op_off, op));
774 stmt(IRStmt_Put(dep1_off, dep1));
775 stmt(IRStmt_Put(dep2_off, dep2));
776 stmt(IRStmt_Put(ndep_off, ndep));
780 /* Create an expression for V and widen the result to 64 bit. */
781 static IRExpr *
782 s390_cc_widen(IRTemp v, Bool sign_extend)
784 IRExpr *expr;
786 expr = mkexpr(v);
788 switch (typeOfIRTemp(irsb->tyenv, v)) {
789 case Ity_I64:
790 break;
791 case Ity_I32:
792 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
793 break;
794 case Ity_I16:
795 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
796 break;
797 case Ity_I8:
798 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
799 break;
800 case Ity_I1:
801 expr = unop(sign_extend ? Iop_1Sto64 : Iop_1Uto64, expr);
802 break;
803 default:
804 vpanic("s390_cc_widen");
807 return expr;
810 static void
811 s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
813 IRExpr *op, *dep1, *dep2, *ndep;
815 op = mkU64(opc);
816 dep1 = s390_cc_widen(d1, sign_extend);
817 dep2 = mkU64(0);
818 ndep = mkU64(0);
820 s390_cc_thunk_fill(op, dep1, dep2, ndep);
824 static void
825 s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
827 IRExpr *op, *dep1, *dep2, *ndep;
829 op = mkU64(opc);
830 dep1 = s390_cc_widen(d1, sign_extend);
831 dep2 = s390_cc_widen(d2, sign_extend);
832 ndep = mkU64(0);
834 s390_cc_thunk_fill(op, dep1, dep2, ndep);
838 /* memcheck believes that the NDEP field in the flags thunk is always
839 defined. But for some flag computations (e.g. add with carry) that is
840 just not true. We therefore need to convey to memcheck that the value
841 of the ndep field does matter and therefore we make the DEP2 field
842 depend on it:
844 DEP2 = original_DEP2 ^ NDEP
846 In s390_calculate_cc we exploit that (a^b)^b == a
847 I.e. we xor the DEP2 value with the NDEP value to recover the
848 original_DEP2 value. */
849 static void
850 s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
852 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
854 op = mkU64(opc);
855 dep1 = s390_cc_widen(d1, sign_extend);
856 dep2 = s390_cc_widen(d2, sign_extend);
857 ndep = s390_cc_widen(nd, sign_extend);
859 dep2x = binop(Iop_Xor64, dep2, ndep);
861 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
865 /* Write one floating point value into the flags thunk */
866 static void
867 s390_cc_thunk_put1f(UInt opc, IRTemp d1)
869 IRExpr *op, *dep1, *dep2, *ndep;
871 /* Make the CC_DEP1 slot appear completely defined.
872 Otherwise, assigning a 32-bit value will cause memcheck
873 to trigger an undefinedness error.
875 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
876 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
877 stmt(IRStmt_Put(dep1_off, mkU64(0)));
879 op = mkU64(opc);
880 dep1 = mkexpr(d1);
881 dep2 = mkU64(0);
882 ndep = mkU64(0);
884 s390_cc_thunk_fill(op, dep1, dep2, ndep);
888 /* Write a floating point value and an integer into the flags thunk. The
889 integer value is zero-extended first. */
890 static void
891 s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
893 IRExpr *op, *dep1, *dep2, *ndep;
895 /* Make the CC_DEP1 slot appear completely defined.
896 Otherwise, assigning a 32-bit value will cause memcheck
897 to trigger an undefinedness error.
899 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
900 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
901 stmt(IRStmt_Put(dep1_off, mkU64(0)));
903 op = mkU64(opc);
904 dep1 = mkexpr(d1);
905 dep2 = s390_cc_widen(d2, False);
906 ndep = mkU64(0);
908 s390_cc_thunk_fill(op, dep1, dep2, ndep);
912 /* Write a 128-bit floating point value into the flags thunk. This is
913 done by splitting the value into two 64-bits values. */
914 static void
915 s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
917 IRExpr *op, *hi, *lo, *ndep;
919 op = mkU64(opc);
920 hi = unop(Iop_F128HItoF64, mkexpr(d1));
921 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
922 ndep = mkU64(0);
924 s390_cc_thunk_fill(op, hi, lo, ndep);
928 /* Write a 128-bit floating point value and an integer into the flags thunk.
929 The integer value is zero-extended first. */
930 static void
931 s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
933 IRExpr *op, *hi, *lo, *lox, *ndep;
935 op = mkU64(opc);
936 hi = unop(Iop_F128HItoF64, mkexpr(d1));
937 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
938 ndep = s390_cc_widen(nd, False);
940 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
942 s390_cc_thunk_fill(op, hi, lox, ndep);
946 /* Write a 128-bit decimal floating point value into the flags thunk.
947 This is done by splitting the value into two 64-bits values. */
948 static void
949 s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
951 IRExpr *op, *hi, *lo, *ndep;
953 op = mkU64(opc);
954 hi = unop(Iop_D128HItoD64, mkexpr(d1));
955 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
956 ndep = mkU64(0);
958 s390_cc_thunk_fill(op, hi, lo, ndep);
962 /* Write a 128-bit decimal floating point value and an integer into the flags
963 thunk. The integer value is zero-extended first. */
964 static void
965 s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
967 IRExpr *op, *hi, *lo, *lox, *ndep;
969 op = mkU64(opc);
970 hi = unop(Iop_D128HItoD64, mkexpr(d1));
971 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
972 ndep = s390_cc_widen(nd, False);
974 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
976 s390_cc_thunk_fill(op, hi, lox, ndep);
979 static void
980 s390_cc_set(IRTemp cc)
982 vassert(typeOfIRTemp(irsb->tyenv, cc) == Ity_I64);
984 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
987 static void
988 s390_cc_set_val(UInt val)
990 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkU64(val), mkU64(0), mkU64(0));
993 /* Build IR to calculate the condition code from flags thunk.
994 Returns an expression of type Ity_I32 */
995 static IRExpr *
996 s390_call_calculate_cc(void)
998 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
1000 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
1001 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
1002 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
1003 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
1005 args = mkIRExprVec_4(op, dep1, dep2, ndep);
1006 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
1007 "s390_calculate_cc", &s390_calculate_cc, args);
1009 /* Exclude OP and NDEP from definedness checking. We're only
1010 interested in DEP1 and DEP2. */
1011 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
1013 return call;
1016 /* Build IR to calculate the internal condition code for a "compare and branch"
1017 insn. Returns an expression of type Ity_I32 */
1018 static IRExpr *
1019 s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
1021 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
1023 switch (opc) {
1024 case S390_CC_OP_SIGNED_COMPARE:
1025 dep1 = s390_cc_widen(op1, True);
1026 dep2 = s390_cc_widen(op2, True);
1027 break;
1029 case S390_CC_OP_UNSIGNED_COMPARE:
1030 dep1 = s390_cc_widen(op1, False);
1031 dep2 = s390_cc_widen(op2, False);
1032 break;
1034 default:
1035 vpanic("s390_call_calculate_icc");
1038 mask = mkU64(m);
1039 op = mkU64(opc);
1041 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
1042 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
1043 "s390_calculate_cond", &s390_calculate_cond, args);
1045 /* Exclude the requested condition, OP and NDEP from definedness
1046 checking. We're only interested in DEP1 and DEP2. */
1047 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
1049 return call;
1052 /* Build IR to calculate the condition code from flags thunk.
1053 Returns an expression of type Ity_I32 */
1054 static IRExpr *
1055 s390_call_calculate_cond(UInt m)
1057 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
1059 mask = mkU64(m);
1060 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
1061 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
1062 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
1063 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
1065 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
1066 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
1067 "s390_calculate_cond", &s390_calculate_cond, args);
1069 /* Exclude the requested condition, OP and NDEP from definedness
1070 checking. We're only interested in DEP1 and DEP2. */
1071 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
1073 return call;
1076 #define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
1077 #define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
1078 #define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
1079 #define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
1080 #define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
1081 #define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
1082 #define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
1083 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
1084 #define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
1085 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
1090 /*------------------------------------------------------------*/
1091 /*--- Guest register access ---*/
1092 /*------------------------------------------------------------*/
1095 /*------------------------------------------------------------*/
1096 /*--- ar registers ---*/
1097 /*------------------------------------------------------------*/
1099 /* Return the guest state offset of a ar register. */
1100 static UInt
1101 ar_offset(UInt archreg)
1103 static const UInt offset[16] = {
1104 S390X_GUEST_OFFSET(guest_a0),
1105 S390X_GUEST_OFFSET(guest_a1),
1106 S390X_GUEST_OFFSET(guest_a2),
1107 S390X_GUEST_OFFSET(guest_a3),
1108 S390X_GUEST_OFFSET(guest_a4),
1109 S390X_GUEST_OFFSET(guest_a5),
1110 S390X_GUEST_OFFSET(guest_a6),
1111 S390X_GUEST_OFFSET(guest_a7),
1112 S390X_GUEST_OFFSET(guest_a8),
1113 S390X_GUEST_OFFSET(guest_a9),
1114 S390X_GUEST_OFFSET(guest_a10),
1115 S390X_GUEST_OFFSET(guest_a11),
1116 S390X_GUEST_OFFSET(guest_a12),
1117 S390X_GUEST_OFFSET(guest_a13),
1118 S390X_GUEST_OFFSET(guest_a14),
1119 S390X_GUEST_OFFSET(guest_a15),
1122 vassert(archreg < 16);
1124 return offset[archreg];
1128 /* Return the guest state offset of word #0 of a ar register. */
1129 static __inline__ UInt
1130 ar_w0_offset(UInt archreg)
1132 return ar_offset(archreg) + 0;
1135 /* Write word #0 of a ar to the guest state. */
1136 static __inline__ void
1137 put_ar_w0(UInt archreg, IRExpr *expr)
1139 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1141 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
1144 /* Read word #0 of a ar register. */
1145 static __inline__ IRExpr *
1146 get_ar_w0(UInt archreg)
1148 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
1152 /*------------------------------------------------------------*/
1153 /*--- fpr registers ---*/
1154 /*------------------------------------------------------------*/
1156 /* Return the guest state offset of a fpr register.
1157 FPRs are maped to first doubleword of VRs.
1159 static UInt
1160 fpr_offset(UInt archreg)
1162 static const UInt offset[16] = {
1163 S390X_GUEST_OFFSET(guest_v0),
1164 S390X_GUEST_OFFSET(guest_v1),
1165 S390X_GUEST_OFFSET(guest_v2),
1166 S390X_GUEST_OFFSET(guest_v3),
1167 S390X_GUEST_OFFSET(guest_v4),
1168 S390X_GUEST_OFFSET(guest_v5),
1169 S390X_GUEST_OFFSET(guest_v6),
1170 S390X_GUEST_OFFSET(guest_v7),
1171 S390X_GUEST_OFFSET(guest_v8),
1172 S390X_GUEST_OFFSET(guest_v9),
1173 S390X_GUEST_OFFSET(guest_v10),
1174 S390X_GUEST_OFFSET(guest_v11),
1175 S390X_GUEST_OFFSET(guest_v12),
1176 S390X_GUEST_OFFSET(guest_v13),
1177 S390X_GUEST_OFFSET(guest_v14),
1178 S390X_GUEST_OFFSET(guest_v15),
1181 vassert(archreg < 16);
1183 return offset[archreg];
1187 /* Return the guest state offset of word #0 of a fpr register. */
1188 static __inline__ UInt
1189 fpr_w0_offset(UInt archreg)
1191 return fpr_offset(archreg) + 0;
1194 /* Write word #0 of a fpr to the guest state. */
1195 static __inline__ void
1196 put_fpr_w0(UInt archreg, IRExpr *expr)
1198 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
1200 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
1203 /* Read word #0 of a fpr register. */
1204 static __inline__ IRExpr *
1205 get_fpr_w0(UInt archreg)
1207 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
1210 /* Return the guest state offset of double word #0 of a fpr register. */
1211 static __inline__ UInt
1212 fpr_dw0_offset(UInt archreg)
1214 return fpr_offset(archreg) + 0;
1217 /* Write double word #0 of a fpr to the guest state. */
1218 static __inline__ void
1219 put_fpr_dw0(UInt archreg, IRExpr *expr)
1221 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
1223 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1226 /* Read double word #0 of a fpr register. */
1227 static __inline__ IRExpr *
1228 get_fpr_dw0(UInt archreg)
1230 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
1233 /* Write word #0 of a dpr to the guest state. */
1234 static __inline__ void
1235 put_dpr_w0(UInt archreg, IRExpr *expr)
1237 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
1239 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
1242 /* Read word #0 of a dpr register. */
1243 static __inline__ IRExpr *
1244 get_dpr_w0(UInt archreg)
1246 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
1249 /* Write double word #0 of a fpr containg DFP value to the guest state. */
1250 static __inline__ void
1251 put_dpr_dw0(UInt archreg, IRExpr *expr)
1253 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
1255 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1258 /* Read double word #0 of a fpr register containing DFP value. */
1259 static __inline__ IRExpr *
1260 get_dpr_dw0(UInt archreg)
1262 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1265 /* Read a float of given type from an fpr. */
1266 static IRExpr *
1267 get_fpr_float(UInt archreg, IRType type)
1269 if (type == Ity_F128)
1270 return get_fpr_pair(archreg);
1271 else
1272 return IRExpr_Get(fpr_offset(archreg), type);
1275 /*------------------------------------------------------------*/
1276 /*--- gpr registers ---*/
1277 /*------------------------------------------------------------*/
1279 /* Return the guest state offset of a gpr register. */
1280 static UInt
1281 gpr_offset(UInt archreg)
1283 static const UInt offset[16] = {
1284 S390X_GUEST_OFFSET(guest_r0),
1285 S390X_GUEST_OFFSET(guest_r1),
1286 S390X_GUEST_OFFSET(guest_r2),
1287 S390X_GUEST_OFFSET(guest_r3),
1288 S390X_GUEST_OFFSET(guest_r4),
1289 S390X_GUEST_OFFSET(guest_r5),
1290 S390X_GUEST_OFFSET(guest_r6),
1291 S390X_GUEST_OFFSET(guest_r7),
1292 S390X_GUEST_OFFSET(guest_r8),
1293 S390X_GUEST_OFFSET(guest_r9),
1294 S390X_GUEST_OFFSET(guest_r10),
1295 S390X_GUEST_OFFSET(guest_r11),
1296 S390X_GUEST_OFFSET(guest_r12),
1297 S390X_GUEST_OFFSET(guest_r13),
1298 S390X_GUEST_OFFSET(guest_r14),
1299 S390X_GUEST_OFFSET(guest_r15),
1302 vassert(archreg < 16);
1304 return offset[archreg];
1308 /* Return the guest state offset of word #0 of a gpr register. */
1309 static __inline__ UInt
1310 gpr_w0_offset(UInt archreg)
1312 return gpr_offset(archreg) + 0;
1315 /* Read an integer of given type from a gpr. */
1316 static __inline__ IRExpr *
1317 get_gpr_int(UInt archreg, IRType ty)
1319 return IRExpr_Get(gpr_offset(archreg) + 8 - sizeofIRType(ty), ty);
1322 /* Write word #0 of a gpr to the guest state. */
1323 static __inline__ void
1324 put_gpr_w0(UInt archreg, IRExpr *expr)
1326 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1328 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1331 /* Read word #0 of a gpr register. */
1332 static __inline__ IRExpr *
1333 get_gpr_w0(UInt archreg)
1335 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1338 /* Return the guest state offset of double word #0 of a gpr register. */
1339 static __inline__ UInt
1340 gpr_dw0_offset(UInt archreg)
1342 return gpr_offset(archreg) + 0;
1345 /* Write double word #0 of a gpr to the guest state. */
1346 static __inline__ void
1347 put_gpr_dw0(UInt archreg, IRExpr *expr)
1349 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1351 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1354 /* Read double word #0 of a gpr register. */
1355 static __inline__ IRExpr *
1356 get_gpr_dw0(UInt archreg)
1358 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1361 /* Return the guest state offset of half word #1 of a gpr register. */
1362 static __inline__ UInt
1363 gpr_hw1_offset(UInt archreg)
1365 return gpr_offset(archreg) + 2;
1368 /* Write half word #1 of a gpr to the guest state. */
1369 static __inline__ void
1370 put_gpr_hw1(UInt archreg, IRExpr *expr)
1372 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1374 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1377 /* Read half word #1 of a gpr register. */
1378 static __inline__ IRExpr *
1379 get_gpr_hw1(UInt archreg)
1381 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1384 /* Return the guest state offset of byte #6 of a gpr register. */
1385 static __inline__ UInt
1386 gpr_b6_offset(UInt archreg)
1388 return gpr_offset(archreg) + 6;
1391 /* Write byte #6 of a gpr to the guest state. */
1392 static __inline__ void
1393 put_gpr_b6(UInt archreg, IRExpr *expr)
1395 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1397 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1400 /* Read byte #6 of a gpr register. */
1401 static __inline__ IRExpr *
1402 get_gpr_b6(UInt archreg)
1404 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1407 /* Return the guest state offset of byte #3 of a gpr register. */
1408 static __inline__ UInt
1409 gpr_b3_offset(UInt archreg)
1411 return gpr_offset(archreg) + 3;
1414 /* Write byte #3 of a gpr to the guest state. */
1415 static __inline__ void
1416 put_gpr_b3(UInt archreg, IRExpr *expr)
1418 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1420 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1423 /* Read byte #3 of a gpr register. */
1424 static __inline__ IRExpr *
1425 get_gpr_b3(UInt archreg)
1427 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1430 /* Return the guest state offset of byte #0 of a gpr register. */
1431 static __inline__ UInt
1432 gpr_b0_offset(UInt archreg)
1434 return gpr_offset(archreg) + 0;
1437 /* Write byte #0 of a gpr to the guest state. */
1438 static __inline__ void
1439 put_gpr_b0(UInt archreg, IRExpr *expr)
1441 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1443 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1446 /* Read byte #0 of a gpr register. */
1447 static __inline__ IRExpr *
1448 get_gpr_b0(UInt archreg)
1450 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1453 /* Return the guest state offset of word #1 of a gpr register. */
1454 static __inline__ UInt
1455 gpr_w1_offset(UInt archreg)
1457 return gpr_offset(archreg) + 4;
1460 /* Write word #1 of a gpr to the guest state. */
1461 static __inline__ void
1462 put_gpr_w1(UInt archreg, IRExpr *expr)
1464 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1466 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1469 /* Read word #1 of a gpr register. */
1470 static __inline__ IRExpr *
1471 get_gpr_w1(UInt archreg)
1473 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1476 /* Return the guest state offset of half word #3 of a gpr register. */
1477 static __inline__ UInt
1478 gpr_hw3_offset(UInt archreg)
1480 return gpr_offset(archreg) + 6;
1483 /* Write half word #3 of a gpr to the guest state. */
1484 static __inline__ void
1485 put_gpr_hw3(UInt archreg, IRExpr *expr)
1487 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1489 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1492 /* Read half word #3 of a gpr register. */
1493 static __inline__ IRExpr *
1494 get_gpr_hw3(UInt archreg)
1496 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1499 /* Return the guest state offset of byte #7 of a gpr register. */
1500 static __inline__ UInt
1501 gpr_b7_offset(UInt archreg)
1503 return gpr_offset(archreg) + 7;
1506 /* Write byte #7 of a gpr to the guest state. */
1507 static __inline__ void
1508 put_gpr_b7(UInt archreg, IRExpr *expr)
1510 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1512 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1515 /* Read byte #7 of a gpr register. */
1516 static __inline__ IRExpr *
1517 get_gpr_b7(UInt archreg)
1519 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1522 /* Return the guest state offset of half word #0 of a gpr register. */
1523 static __inline__ UInt
1524 gpr_hw0_offset(UInt archreg)
1526 return gpr_offset(archreg) + 0;
1529 /* Write half word #0 of a gpr to the guest state. */
1530 static __inline__ void
1531 put_gpr_hw0(UInt archreg, IRExpr *expr)
1533 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1535 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1538 /* Read half word #0 of a gpr register. */
1539 static __inline__ IRExpr *
1540 get_gpr_hw0(UInt archreg)
1542 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1545 /* Return the guest state offset of byte #4 of a gpr register. */
1546 static __inline__ UInt
1547 gpr_b4_offset(UInt archreg)
1549 return gpr_offset(archreg) + 4;
1552 /* Write byte #4 of a gpr to the guest state. */
1553 static __inline__ void
1554 put_gpr_b4(UInt archreg, IRExpr *expr)
1556 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1558 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1561 /* Read byte #4 of a gpr register. */
1562 static __inline__ IRExpr *
1563 get_gpr_b4(UInt archreg)
1565 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1568 /* Return the guest state offset of byte #1 of a gpr register. */
1569 static __inline__ UInt
1570 gpr_b1_offset(UInt archreg)
1572 return gpr_offset(archreg) + 1;
1575 /* Write byte #1 of a gpr to the guest state. */
1576 static __inline__ void
1577 put_gpr_b1(UInt archreg, IRExpr *expr)
1579 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1581 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1584 /* Read byte #1 of a gpr register. */
1585 static __inline__ IRExpr *
1586 get_gpr_b1(UInt archreg)
1588 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1591 /* Return the guest state offset of half word #2 of a gpr register. */
1592 static __inline__ UInt
1593 gpr_hw2_offset(UInt archreg)
1595 return gpr_offset(archreg) + 4;
1598 /* Write half word #2 of a gpr to the guest state. */
1599 static __inline__ void
1600 put_gpr_hw2(UInt archreg, IRExpr *expr)
1602 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1604 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1607 /* Read half word #2 of a gpr register. */
1608 static __inline__ IRExpr *
1609 get_gpr_hw2(UInt archreg)
1611 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1614 /* Return the guest state offset of byte #5 of a gpr register. */
1615 static __inline__ UInt
1616 gpr_b5_offset(UInt archreg)
1618 return gpr_offset(archreg) + 5;
1621 /* Write byte #5 of a gpr to the guest state. */
1622 static __inline__ void
1623 put_gpr_b5(UInt archreg, IRExpr *expr)
1625 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1627 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1630 /* Read byte #5 of a gpr register. */
1631 static __inline__ IRExpr *
1632 get_gpr_b5(UInt archreg)
1634 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1637 /* Return the guest state offset of byte #2 of a gpr register. */
1638 static __inline__ UInt
1639 gpr_b2_offset(UInt archreg)
1641 return gpr_offset(archreg) + 2;
1644 /* Write byte #2 of a gpr to the guest state. */
1645 static __inline__ void
1646 put_gpr_b2(UInt archreg, IRExpr *expr)
1648 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1650 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1653 /* Read byte #2 of a gpr register. */
1654 static __inline__ IRExpr *
1655 get_gpr_b2(UInt archreg)
1657 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1660 /* Return the guest state offset of the counter register. */
1661 static UInt
1662 counter_offset(void)
1664 return S390X_GUEST_OFFSET(guest_counter);
1667 /* Return the guest state offset of double word #0 of the counter register. */
1668 static __inline__ UInt
1669 counter_dw0_offset(void)
1671 return counter_offset() + 0;
1674 /* Write double word #0 of the counter to the guest state. */
1675 static __inline__ void
1676 put_counter_dw0(IRExpr *expr)
1678 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1680 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1683 /* Read double word #0 of the counter register. */
1684 static __inline__ IRExpr *
1685 get_counter_dw0(void)
1687 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1690 /* Return the guest state offset of word #0 of the counter register. */
1691 static __inline__ UInt
1692 counter_w0_offset(void)
1694 return counter_offset() + 0;
1697 /* Return the guest state offset of word #1 of the counter register. */
1698 static __inline__ UInt
1699 counter_w1_offset(void)
1701 return counter_offset() + 4;
1704 /* Write word #0 of the counter to the guest state. */
1705 static __inline__ void
1706 put_counter_w0(IRExpr *expr)
1708 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1710 stmt(IRStmt_Put(counter_w0_offset(), expr));
1713 /* Read word #0 of the counter register. */
1714 static __inline__ IRExpr *
1715 get_counter_w0(void)
1717 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1720 /* Write word #1 of the counter to the guest state. */
1721 static __inline__ void
1722 put_counter_w1(IRExpr *expr)
1724 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1726 stmt(IRStmt_Put(counter_w1_offset(), expr));
1729 /* Read word #1 of the counter register. */
1730 static __inline__ IRExpr *
1731 get_counter_w1(void)
1733 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1736 /* Return the guest state offset of the fpc register. */
1737 static UInt
1738 fpc_offset(void)
1740 return S390X_GUEST_OFFSET(guest_fpc);
1743 /* Return the guest state offset of word #0 of the fpc register. */
1744 static __inline__ UInt
1745 fpc_w0_offset(void)
1747 return fpc_offset() + 0;
1750 /* Write word #0 of the fpc to the guest state. */
1751 static __inline__ void
1752 put_fpc_w0(IRExpr *expr)
1754 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1756 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1759 /* Read word #0 of the fpc register. */
1760 static __inline__ IRExpr *
1761 get_fpc_w0(void)
1763 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1767 /*------------------------------------------------------------*/
1768 /*--- vr registers ---*/
1769 /*------------------------------------------------------------*/
1771 /* Return the guest state offset of a vr register. */
1772 static UInt
1773 vr_offset(const UInt archreg)
1775 static const UInt offset[32] = {
1776 S390X_GUEST_OFFSET(guest_v0),
1777 S390X_GUEST_OFFSET(guest_v1),
1778 S390X_GUEST_OFFSET(guest_v2),
1779 S390X_GUEST_OFFSET(guest_v3),
1780 S390X_GUEST_OFFSET(guest_v4),
1781 S390X_GUEST_OFFSET(guest_v5),
1782 S390X_GUEST_OFFSET(guest_v6),
1783 S390X_GUEST_OFFSET(guest_v7),
1784 S390X_GUEST_OFFSET(guest_v8),
1785 S390X_GUEST_OFFSET(guest_v9),
1786 S390X_GUEST_OFFSET(guest_v10),
1787 S390X_GUEST_OFFSET(guest_v11),
1788 S390X_GUEST_OFFSET(guest_v12),
1789 S390X_GUEST_OFFSET(guest_v13),
1790 S390X_GUEST_OFFSET(guest_v14),
1791 S390X_GUEST_OFFSET(guest_v15),
1792 S390X_GUEST_OFFSET(guest_v16),
1793 S390X_GUEST_OFFSET(guest_v17),
1794 S390X_GUEST_OFFSET(guest_v18),
1795 S390X_GUEST_OFFSET(guest_v19),
1796 S390X_GUEST_OFFSET(guest_v20),
1797 S390X_GUEST_OFFSET(guest_v21),
1798 S390X_GUEST_OFFSET(guest_v22),
1799 S390X_GUEST_OFFSET(guest_v23),
1800 S390X_GUEST_OFFSET(guest_v24),
1801 S390X_GUEST_OFFSET(guest_v25),
1802 S390X_GUEST_OFFSET(guest_v26),
1803 S390X_GUEST_OFFSET(guest_v27),
1804 S390X_GUEST_OFFSET(guest_v28),
1805 S390X_GUEST_OFFSET(guest_v29),
1806 S390X_GUEST_OFFSET(guest_v30),
1807 S390X_GUEST_OFFSET(guest_v31),
1810 vassert(archreg < 32);
1812 return offset[archreg];
1815 /* Return the guest state offset of quadword of a vr register. */
1816 static UInt
1817 vr_qw_offset(const UInt archreg)
1819 return vr_offset(archreg) + 0;
1822 /* Write quadword of a vr to the guest state. */
1823 static void
1824 put_vr_qw(const UInt archreg, IRExpr *expr)
1826 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_V128);
1828 stmt(IRStmt_Put(vr_qw_offset(archreg), expr));
1831 /* Read quadword of a vr register. */
1832 static IRExpr *
1833 get_vr_qw(const UInt archreg)
1835 return IRExpr_Get(vr_qw_offset(archreg), Ity_V128);
1838 /* Return the guest state offset of double word #0 of a gpr register. */
1839 static UInt
1840 vr_dw0_offset(UInt archreg)
1842 return vr_offset(archreg) + 0;
1845 /* Read doubleword #0 of a vr register. */
1846 static IRExpr *
1847 get_vr_dw0(UInt archreg)
1849 return IRExpr_Get(vr_dw0_offset(archreg), Ity_I64);
1852 /* Write double word #0 of a vr to the guest state. */
1853 static void
1854 put_vr_dw0(UInt archreg, IRExpr *expr)
1856 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1858 stmt(IRStmt_Put(vr_dw0_offset(archreg), expr));
1861 /* Return the guest state offset of double word #1 of a gpr register. */
1862 static UInt
1863 vr_dw1_offset(UInt archreg)
1865 return vr_offset(archreg) + 8;
1868 /* Read doubleword #1 of a vr register. */
1869 static IRExpr *
1870 get_vr_dw1(UInt archreg)
1872 return IRExpr_Get(vr_dw1_offset(archreg), Ity_I64);
1875 /* Write double word #0 of a vr to the guest state. */
1876 static void
1877 put_vr_dw1(UInt archreg, IRExpr *expr)
1879 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1881 stmt(IRStmt_Put(vr_dw1_offset(archreg), expr));
1884 /* Return the guest state offset of word #1 of a gpr register. */
1885 static UInt
1886 vr_w1_offset(UInt archreg)
1888 return vr_offset(archreg) + 4;
1891 /* Return the guest state offset of word #3 of a gpr register. */
1892 static UInt
1893 vr_w3_offset(UInt archreg)
1895 return vr_offset(archreg) + 12;
1898 /* Read word #0 of a vr register. */
1899 static IRExpr *
1900 get_vr_w0(UInt archreg)
1902 return IRExpr_Get(vr_dw0_offset(archreg), Ity_I32);
1905 /* Read word #1 of a vr register. */
1906 static IRExpr *
1907 get_vr_w1(UInt archreg)
1909 return IRExpr_Get(vr_w1_offset(archreg), Ity_I32);
1912 /* Read word #2 of a vr register. */
1913 static IRExpr *
1914 get_vr_w2(UInt archreg)
1916 return IRExpr_Get(vr_dw1_offset(archreg), Ity_I32);
1919 /* Read word #3 of a vr register. */
1920 static IRExpr *
1921 get_vr_w3(UInt archreg)
1923 return IRExpr_Get(vr_w3_offset(archreg), Ity_I32);
1926 /* Return the guest state offset of halfword #3 of a gpr register. */
1927 static UInt
1928 vr_hw3_offset(UInt archreg)
1930 return vr_offset(archreg) + 6;
1933 /* Read halfword #3 of a vr register. */
1934 static IRExpr *
1935 get_vr_hw3(UInt archreg)
1937 return IRExpr_Get(vr_hw3_offset(archreg), Ity_I16);
1940 /* Return the guest state offset of halfword #7 of a gpr register. */
1941 static UInt
1942 vr_hw7_offset(UInt archreg)
1944 return vr_offset(archreg) + 14;
1947 /* Read halfword #7 of a vr register. */
1948 static IRExpr *
1949 get_vr_hw7(UInt archreg)
1951 return IRExpr_Get(vr_hw7_offset(archreg), Ity_I16);
1954 /* Return the guest state offset of byte #7 of a vr register. */
1955 static UInt
1956 vr_b7_offset(UInt archreg)
1958 return vr_offset(archreg) + 7;
1961 /* Read byte #7 of a vr register. */
1962 static IRExpr *
1963 get_vr_b7(UInt archreg)
1965 return IRExpr_Get(vr_b7_offset(archreg), Ity_I8);
1968 /* Return the guest state offset of byte #15 of a vr register. */
1969 static UInt
1970 vr_b15_offset(UInt archreg)
1972 return vr_offset(archreg) + 15;
1975 /* Read byte #15 of a vr register. */
1976 static IRExpr *
1977 get_vr_b15(UInt archreg)
1979 return IRExpr_Get(vr_b15_offset(archreg), Ity_I8);
1982 /* Determine IRType by instruction's m3 field */
1983 static IRType
1984 s390_vr_get_type(const UChar m)
1986 static const IRType results[] = {Ity_I8, Ity_I16, Ity_I32, Ity_I64, Ity_V128};
1987 if (m > 4) {
1988 vex_printf("s390_vr_get_type: m=%x\n", m);
1989 vpanic("s390_vr_get_type: reserved m value");
1992 return results[m];
1995 /* Determine IRType from instruction's floating-point format field */
1996 static IRType
1997 s390_vr_get_ftype(const UChar m)
1999 static const IRType results[] = {Ity_F32, Ity_F64, Ity_F128};
2000 if (m >= 2 && m <= 4)
2001 return results[m - 2];
2002 return Ity_INVALID;
2005 /* Determine number of elements from instruction's floating-point format
2006 field */
2007 static UChar
2008 s390_vr_get_n_elem(const UChar m)
2010 if (m >= 2 && m <= 4)
2011 return 1 << (4 - m);
2012 return 0;
2015 /* Determine if Condition Code Set (CS) flag is set in m field */
2016 #define s390_vr_is_cs_set(m) (((m) & 0x1) != 0)
2018 /* Determine if Zero Search (ZS) flag is set in m field */
2019 #define s390_vr_is_zs_set(m) (((m) & 0b0010) != 0)
2021 /* Check if the "Single-Element-Control" bit is set.
2022 Used in vector FP instructions.
2024 #define s390_vr_is_single_element_control_set(m) (((m) & 0x8) != 0)
2026 /* Generates arg1 < arg2 (or arg1 <= arg2 if allow_equal == True) expression.
2027 Arguments must have V128 type and are treated as unsigned 128-bit numbers.
2029 static IRExpr*
2030 s390_V128_compareLT128x1(IRExpr* arg1, IRExpr* arg2, Bool allow_equal)
2032 /* If high halves are equal
2033 then we compare lower ones
2034 otherwise we compare high halves.
2036 IRExpr* result;
2037 result = mkite(binop(Iop_CmpEQ64,
2038 unop(Iop_V128HIto64, arg1),
2039 unop(Iop_V128HIto64, arg2)
2041 unop(Iop_1Uto64,
2042 binop(allow_equal ? Iop_CmpLE64U : Iop_CmpLT64U,
2043 unop(Iop_V128to64, arg1),
2044 unop(Iop_V128to64, arg2)
2047 unop(Iop_1Uto64,
2048 binop(Iop_CmpLT64U,
2049 unop(Iop_V128HIto64, arg1),
2050 unop(Iop_V128HIto64, arg2)
2055 return result;
2058 /* Generates arg1 == 0 expression.
2059 Argument must have V128 type and is treated as unsigned 128-bit number.
2061 static IRExpr*
2062 s390_V128_isZero(IRExpr* arg)
2064 IRExpr* high_or_low = binop(Iop_Or64,
2065 unop(Iop_V128to64, arg),
2066 unop(Iop_V128HIto64, arg)
2069 return unop(Iop_1Uto64, binop(Iop_CmpEQ64, high_or_low, mkU64(0ULL)));
2072 /* Generate the two's complement for arg.
2073 Arg should be V128.
2075 static IRExpr*
2076 s390_V128_get_complement(IRExpr* arg, IRType type)
2078 IRExpr* notArg = unop(Iop_NotV128, arg);
2079 IRExpr* ones;
2080 IRExpr* result;
2081 switch(type) {
2082 case Ity_I8:
2083 ones = unop(Iop_Dup8x16, mkU8(0x01));
2084 result = binop(Iop_Add8x16, notArg, ones);
2085 break;
2086 case Ity_I16:
2087 ones = unop(Iop_Dup16x8, mkU16(0x0001));
2088 result = binop(Iop_Add16x8, notArg, ones);
2089 break;
2090 case Ity_I32:
2091 ones = unop(Iop_Dup32x4, mkU32(0x00000001));
2092 result = binop(Iop_Add32x4, notArg, ones);
2093 break;
2094 case Ity_I64:
2095 ones = binop(Iop_64HLtoV128, mkU64(0x1ULL), mkU64(0x1ULL));
2096 result = binop(Iop_Add64x2, notArg, ones);
2097 break;
2098 case Ity_V128:
2099 ones = binop(Iop_64HLtoV128, mkU64(0x0ULL), mkU64(0x1ULL));
2100 result = binop(Iop_Add128x1, notArg, ones);
2101 break;
2102 default:
2103 vpanic("s390_V128_get_complement: unknown type");
2106 return result;
2109 /* # Elements are treated as 128-bit unsigned integers
2110 For i = 0; i < elemCount; i++ do:
2111 sum = arg1[i] + arg2[i]
2112 result[i] = carry_out_bit(sum)
2114 return result
2116 static IRExpr*
2117 s390_V128_calculate_carry_out(IRExpr* arg1, IRExpr* arg2, IRType type,
2118 Bool allow_equal)
2120 IRTemp sum = newTemp(Ity_V128);
2121 IRExpr* mask;
2122 IRExpr* comparison;
2123 IRExpr* result;
2124 switch(type){
2125 case Ity_I8:
2126 assign(sum, binop(Iop_Add8x16, arg1, arg2));
2127 mask = unop(Iop_Dup8x16, mkU8(0x1));
2128 comparison = binop(Iop_CmpGT8Ux16, arg1, mkexpr(sum));
2129 if(allow_equal) {
2130 comparison = binop(Iop_OrV128, binop(Iop_CmpEQ8x16, arg1, mkexpr(sum)),
2131 comparison);
2133 result = binop(Iop_AndV128, comparison, mask);
2134 break;
2135 case Ity_I16:
2136 assign(sum, binop(Iop_Add16x8, arg1, arg2));
2137 mask = unop(Iop_Dup16x8, mkU16(0x1));
2138 comparison = binop(Iop_CmpGT16Ux8, arg1, mkexpr(sum));
2139 if(allow_equal) {
2140 comparison = binop(Iop_OrV128, binop(Iop_CmpEQ16x8, arg1, mkexpr(sum)),
2141 comparison);
2143 result = binop(Iop_AndV128, comparison, mask);
2144 break;
2145 case Ity_I32:
2146 assign(sum, binop(Iop_Add32x4, arg1, arg2));
2147 mask = unop(Iop_Dup32x4, mkU32(0x1));
2148 comparison = binop(Iop_CmpGT32Ux4, arg1, mkexpr(sum));
2149 if(allow_equal) {
2150 comparison = binop(Iop_OrV128, binop(Iop_CmpEQ32x4, arg1, mkexpr(sum)),
2151 comparison);
2153 result = binop(Iop_AndV128, comparison, mask);
2154 break;
2155 case Ity_I64:
2156 assign(sum, binop(Iop_Add64x2, arg1, arg2));
2157 mask = binop(Iop_64HLtoV128, mkU64(0x1), mkU64(0x1));
2158 comparison = binop(Iop_CmpGT64Ux2, arg1, mkexpr(sum));
2159 if(allow_equal) {
2160 comparison = binop(Iop_OrV128, binop(Iop_CmpEQ64x2, arg1, mkexpr(sum)),
2161 comparison);
2163 result = binop(Iop_AndV128, comparison, mask);
2164 break;
2165 case Ity_V128:
2166 assign(sum, binop(Iop_Add128x1, arg1, arg2));
2167 comparison = s390_V128_compareLT128x1(mkexpr(sum), arg1, allow_equal);
2168 result = binop(Iop_64HLtoV128, mkU64(0x0), comparison);
2169 break;
2170 default:
2171 ppIRType(type);
2172 vpanic("s390_V128_calculate_carry_out: unknown type");
2175 return result;
2178 /* # elemCount = 1 for now (elements are 128-bit unsigned integers)
2179 For i = 0; i < elemCount; i++ do:
2180 sum = arg1[i] + arg2[i] + arg3[i] & 0x1
2181 result[i] = carry_out_bit(sum)
2183 return result
2185 static IRExpr*
2186 s390_V128_calculate_carry_out_with_carry(IRExpr* arg1, IRExpr* arg2, IRExpr* arg3)
2188 IRTemp sum = newTemp(Ity_V128);
2189 assign(sum, binop(Iop_Add128x1, arg1, arg2));
2191 IRTemp overflow_before = newTemp(Ity_I64);
2192 assign(overflow_before, s390_V128_compareLT128x1(mkexpr(sum), arg1, False));
2194 IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0), mkU64(1));
2195 IRTemp carry_in = newTemp(Ity_V128);
2196 assign(carry_in, binop(Iop_AndV128, arg3, mask));
2198 IRExpr* carry_is_not_zero = unop(Iop_1Uto64,
2199 binop(Iop_CmpNE64,
2200 unop(Iop_V128to64, mkexpr(carry_in)),
2201 mkU64(0ULL)
2205 IRTemp sum_plus_carry = newTemp(Ity_V128);
2206 assign(sum_plus_carry, binop(Iop_Add128x1, mkexpr(sum), mkexpr(carry_in)));
2208 IRExpr* overflow_after = binop(Iop_And64,
2209 carry_is_not_zero,
2210 s390_V128_isZero(mkexpr(sum_plus_carry))
2213 IRExpr* result = binop(Iop_Or64, mkexpr(overflow_before), overflow_after);
2214 result = binop(Iop_64HLtoV128, mkU64(0Ull), result);
2215 return result;
2218 /* Performs "arg1 + arg2 + carry_out_bit(arg1 + arg2)".
2219 Arguments and result are Ity_I32.
2221 static IRTemp
2222 s390_checksum_add(IRExpr* arg1, IRExpr* arg2)
2224 IRTemp sum = newTemp(Ity_I32);
2225 IRTemp res = newTemp(Ity_I32);
2227 assign(sum, binop(Iop_Add32, arg1, arg2));
2228 assign(res,
2229 mkite(binop(Iop_CmpLT32U, mkexpr(sum), arg1),
2230 binop(Iop_Add32, mkexpr(sum), mkU32(1)),
2231 mkexpr(sum))
2234 return res;
2237 /* Return the guest state offset of element with type's size and given index
2238 of a vr register.
2240 static UInt
2241 s390_vr_offset_by_index(UInt archreg,IRType type, UChar index)
2243 switch (type) {
2244 case Ity_I8:
2245 if(index > 15) {
2246 goto invalidIndex;
2248 return vr_offset(archreg) + sizeof(UChar) * index;
2250 case Ity_I16:
2251 if(index > 7) {
2252 goto invalidIndex;
2254 return vr_offset(archreg) + sizeof(UShort) * index;
2256 case Ity_I32:
2257 case Ity_F32:
2258 if(index > 3) {
2259 goto invalidIndex;
2261 return vr_offset(archreg) + sizeof(UInt) * index;
2263 case Ity_I64:
2264 case Ity_F64:
2265 if(index > 1) {
2266 goto invalidIndex;
2268 return vr_offset(archreg) + sizeof(ULong) * index;
2270 case Ity_V128:
2271 case Ity_F128:
2272 if(index == 0) {
2273 return vr_qw_offset(archreg);
2274 } else {
2275 goto invalidIndex;
2278 default:
2279 vpanic("s390_vr_offset_by_index: unknown type");
2282 invalidIndex:
2283 vex_printf("s390_vr_offset_by_index: index = %d ; type = ", index);
2284 ppIRType(type);
2285 vpanic("s390_vr_offset_by_index: invalid index for given type");
2288 /* Write type sized element to indexed part of vr to the guest state. */
2289 static void
2290 put_vr(UInt archreg, IRType type, UChar index, IRExpr *expr)
2292 UInt offset = s390_vr_offset_by_index(archreg, type, index);
2293 vassert(typeOfIRExpr(irsb->tyenv, expr) == type);
2295 if (type == Ity_F128) {
2296 IRTemp val = newTemp(Ity_F128);
2297 assign(val, expr);
2298 stmt(IRStmt_Put(offset, unop(Iop_F128HItoF64, mkexpr(val))));
2299 stmt(IRStmt_Put(offset + 8, unop(Iop_F128LOtoF64, mkexpr(val))));
2300 } else {
2301 stmt(IRStmt_Put(offset, expr));
2305 /* Read type sized part specified by index of a vr register. */
2306 static IRExpr *
2307 get_vr(UInt archreg, IRType type, UChar index)
2309 UInt offset = s390_vr_offset_by_index(archreg, type, index);
2310 if (type == Ity_F128) {
2311 return binop(Iop_F64HLtoF128,
2312 IRExpr_Get(offset, Ity_F64),
2313 IRExpr_Get(offset + 8, Ity_F64));
2315 return IRExpr_Get(offset, type);
2318 /* Calculates vr index according to instruction's rxb field
2319 and position of vr in instruction.
2320 Index of first argument must be 1 (not zero) */
2321 static UChar
2322 s390_vr_getVRindex(UChar v,UChar argNumber, UChar rxb)
2324 vassert(argNumber > 0 && argNumber <= 4);
2325 vassert(rxb < 16);
2326 return v | (((rxb) << argNumber) & 0b00010000);
2329 static void
2330 s390_vr_fill(UChar v1, IRExpr *o2)
2332 IRType o2type = typeOfIRExpr(irsb->tyenv, o2);
2333 switch (o2type) {
2334 case Ity_I8:
2335 put_vr_qw(v1, unop(Iop_Dup8x16, o2));
2336 break;
2337 case Ity_I16:
2338 put_vr_qw(v1, unop(Iop_Dup16x8, o2));
2339 break;
2340 case Ity_I32:
2341 put_vr_qw(v1, unop(Iop_Dup32x4, o2));
2342 break;
2343 case Ity_I64: {
2344 IRTemp val = newTemp(Ity_I64);
2345 assign(val, o2);
2346 put_vr_qw(v1, binop(Iop_64HLtoV128, mkexpr(val), mkexpr(val)));
2347 break;
2349 default:
2350 ppIRType(o2type);
2351 vpanic("s390_vr_fill: invalid IRType");
2355 /* Returns Ity_I32 number of bytes till block boundary specified by m */
2356 static IRExpr*
2357 s390_getCountToBlockBoundary(IRTemp op2addr, UChar m)
2359 IRTemp boundary = newTemp(Ity_I32);
2360 IRTemp sixteen = newTemp(Ity_I32);
2361 IRTemp divisionResult = newTemp(Ity_I64);
2362 IRTemp mod_result = newTemp(Ity_I32);
2363 IRTemp output = newTemp(Ity_I32);
2365 switch (m) {
2366 case 0: assign(boundary, mkU32(64)); break;
2367 case 1: assign(boundary, mkU32(128)); break;
2368 case 2: assign(boundary, mkU32(256)); break;
2369 case 3: assign(boundary, mkU32(512)); break;
2370 case 4: assign(boundary, mkU32(1024)); break;
2371 case 5: assign(boundary, mkU32(2048)); break;
2372 case 6: assign(boundary, mkU32(4096)); break;
2373 default:
2374 vex_printf("m = %d\n", m);
2375 vpanic("s390_getCountToBlockBoundary: invalid m");
2377 assign(sixteen, mkU32(16));
2378 assign(divisionResult,
2379 binop(Iop_DivModU64to32, mkexpr(op2addr), mkexpr(boundary)));
2380 assign(mod_result,
2381 binop(Iop_Sub32,mkexpr(boundary),
2382 unop(Iop_64HIto32, mkexpr(divisionResult))));
2384 assign(output,
2385 mkite(binop(Iop_CmpLE32U, mkexpr(sixteen), mkexpr(mod_result)),
2386 mkexpr(sixteen),
2387 mkexpr(mod_result)
2390 return mkexpr(output);
2393 /* Starting from addr, load at most maxIndex + 1 bytes into v1. Fill the
2394 leftmost or rightmost bytes of v1, depending on whether `rightmost' is set.
2395 If maxIndex >= 15, load all 16 bytes; otherwise clear the remaining bytes. */
2396 static void
2397 s390_vr_loadWithLength(UChar v1, IRTemp addr, IRExpr *maxIndex, Bool rightmost)
2399 IRTemp maxIdx = newTemp(Ity_I32);
2400 IRTemp cappedMax = newTemp(Ity_I64);
2401 IRTemp offset = newTemp(Ity_I64);
2402 IRTemp zeroed = newTemp(Ity_I64);
2403 IRTemp back = newTemp(Ity_I64);
2405 /* Implement the insn with a single 16-byte load, to allow memcheck's
2406 "partial-loads-OK" heuristic to apply. Ensure that a page boundary is
2407 crossed if and only if the real insn would have crossed it as well.
2408 Thus, if the bytes to load are fully contained in an aligned 16-byte
2409 chunk, load the whole 16-byte aligned chunk, and otherwise load 16 bytes
2410 from the unaligned address. Then shift the loaded data left- or
2411 right-aligned into the target vector register. */
2413 assign(maxIdx, maxIndex);
2414 assign(cappedMax, mkite(binop(Iop_CmpLT32U, mkexpr(maxIdx), mkU32(15)),
2415 unop(Iop_32Uto64, mkexpr(maxIdx)), mkU64(15)));
2416 /* 'offset': addr's offset from last 16-byte aligned address
2417 'zeroed': number of bytes to be zeroed in the target vector
2418 'back': how much to subtract from addr before loading 16 bytes */
2419 assign(offset, binop(Iop_And64, mkexpr(addr), mkU64(15)));
2420 assign(zeroed, binop(Iop_Sub64, mkU64(15), mkexpr(cappedMax)));
2421 assign(back, mkite(binop(Iop_CmpLE64U, mkexpr(offset), mkexpr(zeroed)),
2422 mkexpr(offset), mkU64(0)));
2424 IRExpr* chunk = load(Ity_V128, binop(Iop_Sub64, mkexpr(addr), mkexpr(back)));
2426 /* Shift the loaded 16-byte vector to the right, then to the left, or vice
2427 versa, where each shift amount ranges from 0 to 120. */
2428 IRExpr* shift1;
2429 IRExpr* shift2 = unop(Iop_64to8, binop(Iop_Shl64, mkexpr(zeroed), mkU8(3)));
2431 if (rightmost) {
2432 shift1 = unop(Iop_64to8, binop(Iop_Shl64, mkexpr(back), mkU8(3)));
2433 put_vr_qw(v1, binop(Iop_ShrV128,
2434 binop(Iop_ShlV128, chunk, shift1),
2435 shift2));
2436 } else {
2437 shift1 = unop(Iop_64to8,
2438 binop(Iop_Shl64,
2439 binop(Iop_Sub64, mkexpr(zeroed), mkexpr(back)),
2440 mkU8(3)));
2441 put_vr_qw(v1, binop(Iop_ShlV128,
2442 binop(Iop_ShrV128, chunk, shift1),
2443 shift2));
2447 /* Store at most maxIndex + 1 bytes from v1 to addr. Store the leftmost or
2448 rightmost bytes of v1, depending on whether `rightmost' is set. If maxIndex
2449 >= 15, store all 16 bytes. */
2450 static void
2451 s390_vr_storeWithLength(UChar v1, IRTemp addr, IRExpr *maxIndex, Bool rightmost)
2453 IRTemp maxIdx = newTemp(Ity_I32);
2454 IRTemp cappedMax = newTemp(Ity_I64);
2455 IRTemp counter = newTemp(Ity_I64);
2456 IRExpr* offset;
2458 assign(maxIdx, maxIndex);
2459 assign(cappedMax, mkite(binop(Iop_CmpLT32U, mkexpr(maxIdx), mkU32(15)),
2460 unop(Iop_32Uto64, mkexpr(maxIdx)), mkU64(15)));
2462 assign(counter, get_counter_dw0());
2464 if (rightmost)
2465 offset = binop(Iop_Add64,
2466 binop(Iop_Sub64, mkU64(15), mkexpr(cappedMax)),
2467 mkexpr(counter));
2468 else
2469 offset = mkexpr(counter);
2471 store(binop(Iop_Add64, mkexpr(addr), mkexpr(counter)),
2472 binop(Iop_GetElem8x16, get_vr_qw(v1), unop(Iop_64to8, offset)));
2474 /* Check for end of field */
2475 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
2476 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(cappedMax)));
2477 put_counter_dw0(mkU64(0));
2480 /* Bitwise vCond ? v1 : v2
2481 All args are V128.
2483 static IRExpr*
2484 s390_V128_bitwiseITE(IRExpr* vCond, IRExpr* v1, IRExpr* v2)
2486 IRTemp vc = newTemp(Ity_V128);
2487 assign(vc, vCond);
2488 /* result = (v1 & vCond) | (v2 & ~vCond) */
2489 return binop(Iop_OrV128,
2490 binop(Iop_AndV128, v1, mkexpr(vc)),
2491 binop(Iop_AndV128, v2, unop(Iop_NotV128, mkexpr(vc))));
2494 /*------------------------------------------------------------*/
2495 /*--- Rounding modes ---*/
2496 /*------------------------------------------------------------*/
2498 /* Extract the bfp rounding mode from the guest FPC reg and encode it as an
2499 IRRoundingMode:
2501 rounding mode | s390 | IR
2502 -------------------------
2503 to nearest | 00 | 00
2504 to zero | 01 | 11
2505 to +infinity | 10 | 10
2506 to -infinity | 11 | 01
2508 So: IR = (4 - s390) & 3
2510 static IRExpr *
2511 get_bfp_rounding_mode_from_fpc(void)
2513 IRTemp fpc_bits = newTemp(Ity_I32);
2515 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
2516 Prior to that bits [30:31] contained the bfp rounding mode with
2517 bit 29 being unused and having a value of 0. So we can always
2518 extract the least significant 3 bits. */
2519 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
2521 /* fixs390:
2524 if (! s390_host_has_fpext && rounding_mode > 3) {
2525 emulation warning @ runtime and
2526 set fpc to round nearest
2530 /* For now silently adjust an unsupported rounding mode to "nearest" */
2531 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
2532 mkexpr(fpc_bits),
2533 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
2535 // rm_IR = (4 - rm_s390) & 3;
2536 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
2539 /* Encode the s390 rounding mode as it appears in the m3 field of certain
2540 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
2541 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
2542 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
2543 considers the default rounding mode (4.3.3). */
2544 static IRTemp
2545 encode_bfp_rounding_mode(UChar mode)
2547 IRExpr *rm;
2549 switch (mode) {
2550 case S390_BFP_ROUND_PER_FPC:
2551 rm = get_bfp_rounding_mode_from_fpc();
2552 break;
2553 case S390_BFP_ROUND_NEAREST_AWAY: rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
2554 case S390_BFP_ROUND_PREPARE_SHORT: rm = mkU32(Irrm_PREPARE_SHORTER); break;
2555 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
2556 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
2557 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
2558 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
2559 default:
2560 vpanic("encode_bfp_rounding_mode");
2563 return mktemp(Ity_I32, rm);
2566 /* Extract the DFP rounding mode from the guest FPC reg and encode it as an
2567 IRRoundingMode:
2569 rounding mode | s390 | IR
2570 ------------------------------------------------
2571 to nearest, ties to even | 000 | 000
2572 to zero | 001 | 011
2573 to +infinity | 010 | 010
2574 to -infinity | 011 | 001
2575 to nearest, ties away from 0 | 100 | 100
2576 to nearest, ties toward 0 | 101 | 111
2577 to away from 0 | 110 | 110
2578 to prepare for shorter precision | 111 | 101
2580 So: IR = (s390 ^ ((s390 << 1) & 2))
2582 static IRExpr *
2583 get_dfp_rounding_mode_from_fpc(void)
2585 IRTemp fpc_bits = newTemp(Ity_I32);
2587 /* The dfp rounding mode is stored in bits [25:27].
2588 extract the bits at 25:27 and right shift 4 times. */
2589 assign(fpc_bits, binop(Iop_Shr32,
2590 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
2591 mkU8(4)));
2593 IRExpr *rm_s390 = mkexpr(fpc_bits);
2594 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
2596 return binop(Iop_Xor32, rm_s390,
2597 binop( Iop_And32,
2598 binop(Iop_Shl32, rm_s390, mkU8(1)),
2599 mkU32(2)));
2602 /* Encode the s390 rounding mode as it appears in the m3 field of certain
2603 instructions to VEX's IRRoundingMode. */
2604 static IRTemp
2605 encode_dfp_rounding_mode(UChar mode)
2607 IRExpr *rm;
2609 switch (mode) {
2610 case S390_DFP_ROUND_PER_FPC_0:
2611 case S390_DFP_ROUND_PER_FPC_2:
2612 rm = get_dfp_rounding_mode_from_fpc(); break;
2613 case S390_DFP_ROUND_NEAREST_EVEN_4:
2614 case S390_DFP_ROUND_NEAREST_EVEN_8:
2615 rm = mkU32(Irrm_NEAREST); break;
2616 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
2617 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
2618 rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
2619 case S390_DFP_ROUND_PREPARE_SHORT_3:
2620 case S390_DFP_ROUND_PREPARE_SHORT_15:
2621 rm = mkU32(Irrm_PREPARE_SHORTER); break;
2622 case S390_DFP_ROUND_ZERO_5:
2623 case S390_DFP_ROUND_ZERO_9:
2624 rm = mkU32(Irrm_ZERO ); break;
2625 case S390_DFP_ROUND_POSINF_6:
2626 case S390_DFP_ROUND_POSINF_10:
2627 rm = mkU32(Irrm_PosINF); break;
2628 case S390_DFP_ROUND_NEGINF_7:
2629 case S390_DFP_ROUND_NEGINF_11:
2630 rm = mkU32(Irrm_NegINF); break;
2631 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
2632 rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
2633 case S390_DFP_ROUND_AWAY_0:
2634 rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
2635 default:
2636 vpanic("encode_dfp_rounding_mode");
2639 return mktemp(Ity_I32, rm);
2643 /*------------------------------------------------------------*/
2644 /*--- Condition code helpers ---*/
2645 /*------------------------------------------------------------*/
2647 /* The result of a Iop_CmpFxx operation is a condition code. It is
2648 encoded using the values defined in type IRCmpFxxResult.
2649 Before we can store the condition code into the guest state (or do
2650 anything else with it for that matter) we need to convert it to
2651 the encoding that s390 uses. This is what this function does.
2653 s390 VEX b6 b2 b0 cc.1 cc.0
2654 0 0x40 EQ 1 0 0 0 0
2655 1 0x01 LT 0 0 1 0 1
2656 2 0x00 GT 0 0 0 1 0
2657 3 0x45 Unordered 1 1 1 1 1
2659 The following bits from the VEX encoding are interesting:
2660 b0, b2, b6 with b0 being the LSB. We observe:
2662 cc.0 = b0;
2663 cc.1 = b2 | (~b0 & ~b6)
2665 with cc being the s390 condition code.
2667 static IRExpr *
2668 convert_vex_bfpcc_to_s390(IRTemp vex_cc)
2670 IRTemp cc0 = newTemp(Ity_I32);
2671 IRTemp cc1 = newTemp(Ity_I32);
2672 IRTemp b0 = newTemp(Ity_I32);
2673 IRTemp b2 = newTemp(Ity_I32);
2674 IRTemp b6 = newTemp(Ity_I32);
2676 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
2677 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
2678 mkU32(1)));
2679 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
2680 mkU32(1)));
2682 assign(cc0, mkexpr(b0));
2683 assign(cc1, binop(Iop_Or32, mkexpr(b2),
2684 binop(Iop_And32,
2685 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
2686 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
2687 )));
2689 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
2693 /* The result of a Iop_CmpDxx operation is a condition code. It is
2694 encoded using the values defined in type IRCmpDxxResult.
2695 Before we can store the condition code into the guest state (or do
2696 anything else with it for that matter) we need to convert it to
2697 the encoding that s390 uses. This is what this function does. */
2698 static IRExpr *
2699 convert_vex_dfpcc_to_s390(IRTemp vex_cc)
2701 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
2702 same. currently. */
2703 return convert_vex_bfpcc_to_s390(vex_cc);
2707 /*------------------------------------------------------------*/
2708 /*--- Build IR for formats ---*/
2709 /*------------------------------------------------------------*/
2710 static void
2711 s390_format_I(const HChar *(*irgen)(UChar i),
2712 UChar i)
2714 const HChar *mnm = irgen(i);
2716 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2717 s390_disasm(ENC2(MNM, UINT), mnm, i);
2720 static void
2721 s390_format_E(const HChar *(*irgen)(void))
2723 const HChar *mnm = irgen();
2725 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2726 s390_disasm(ENC1(MNM), mnm);
2729 static void
2730 s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
2731 UChar r1, UShort i2)
2733 irgen(r1, i2);
2736 static void
2737 s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
2738 UChar r1, UShort i2)
2740 const HChar *mnm = irgen(r1, i2);
2742 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2743 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
2746 static void
2747 s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
2748 UChar r1, UShort i2)
2750 const HChar *mnm = irgen(r1, i2);
2752 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2753 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
2756 static void
2757 s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
2758 UChar r1, UShort i2)
2760 const HChar *mnm = irgen(r1, i2);
2762 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2763 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
2766 static void
2767 s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
2768 UChar r1, UChar r3, UShort i2)
2770 const HChar *mnm = irgen(r1, r3, i2);
2772 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2773 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2776 static void
2777 s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
2778 UChar r1, UChar r3, UShort i2)
2780 const HChar *mnm = irgen(r1, r3, i2);
2782 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2783 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
2786 static void
2787 s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
2788 UChar i4, UChar i5),
2789 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
2791 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
2793 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2794 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
2795 i5);
2798 static void
2799 s390_format_R0UU(const HChar *(*irgen)(UChar r1, UShort i2, UChar m3),
2800 UChar r1, UShort i2, UChar m3)
2802 const HChar *mnm = irgen(r1, i2, m3);
2804 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2805 s390_disasm(ENC4(XMNM, GPR, INT, CABM), S390_XMNM_CAB, mnm, m3, r1,
2806 i2, m3);
2809 static void
2810 s390_format_R0IU(const HChar *(*irgen)(UChar r1, UShort i2, UChar m3),
2811 UChar r1, UShort i2, UChar m3)
2813 const HChar *mnm = irgen(r1, i2, m3);
2815 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2816 s390_disasm(ENC4(XMNM, GPR, INT, CABM), S390_XMNM_CAB, mnm, m3, r1,
2817 (Int)(Short)i2, m3);
2820 static void
2821 s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
2822 UChar m3),
2823 UChar r1, UChar r2, UShort i4, UChar m3)
2825 const HChar *mnm = irgen(r1, r2, i4, m3);
2827 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2828 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
2829 r2, m3, (Int)(Short)i4);
2832 static void
2833 s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
2834 UChar i2),
2835 UChar r1, UChar m3, UShort i4, UChar i2)
2837 const HChar *mnm = irgen(r1, m3, i4, i2);
2839 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2840 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
2841 r1, i2, m3, (Int)(Short)i4);
2844 static void
2845 s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
2846 UChar i2),
2847 UChar r1, UChar m3, UShort i4, UChar i2)
2849 const HChar *mnm = irgen(r1, m3, i4, i2);
2851 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2852 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
2853 (Int)(Char)i2, m3, (Int)(Short)i4);
2856 static void
2857 s390_format_RIE_RUPIX(const HChar *(*irgen)(UChar r1, UChar m3, UShort i2),
2858 UChar r1, UChar m3, UShort i2)
2860 const HChar *mnm = irgen(r1, m3, i2);
2862 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2863 s390_disasm(ENC3(XMNM, GPR, INT), S390_XMNM_CLS, mnm, m3, r1,
2864 (Int)(Short)i2);
2867 static void
2868 s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
2869 UChar r1, UInt i2)
2871 irgen(r1, i2);
2874 static void
2875 s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
2876 UChar r1, UInt i2)
2878 const HChar *mnm = irgen(r1, i2);
2880 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2881 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
2884 static void
2885 s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
2886 UChar r1, UInt i2)
2888 const HChar *mnm = irgen(r1, i2);
2890 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2891 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
2894 static void
2895 s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
2896 UChar r1, UInt i2)
2898 const HChar *mnm = irgen(r1, i2);
2900 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2901 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
2904 static void
2905 s390_format_RIL_UP(const HChar *(*irgen)(void),
2906 UChar r1, UInt i2)
2908 const HChar *mnm = irgen();
2910 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2911 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
2914 static void
2915 s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
2916 IRTemp op4addr),
2917 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
2919 const HChar *mnm;
2920 IRTemp op4addr = newTemp(Ity_I64);
2922 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2923 mkU64(0)));
2925 mnm = irgen(r1, m3, i2, op4addr);
2927 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2928 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2929 (Int)(Char)i2, m3, d4, 0, b4);
2932 static void
2933 s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
2934 IRTemp op4addr),
2935 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
2937 const HChar *mnm;
2938 IRTemp op4addr = newTemp(Ity_I64);
2940 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2941 mkU64(0)));
2943 mnm = irgen(r1, m3, i2, op4addr);
2945 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2946 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2947 i2, m3, d4, 0, b4);
2950 static void
2951 s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
2952 UChar r1, UChar r2)
2954 irgen(r1, r2);
2957 static void
2958 s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
2959 UChar r1, UChar r2)
2961 const HChar *mnm = irgen(r1, r2);
2963 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2964 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
2967 static void
2968 s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
2969 UChar r1, UChar r2)
2971 const HChar *mnm = irgen(r1, r2);
2973 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2974 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
2977 static void
2978 s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
2979 UChar r1, UChar r2)
2981 irgen(r1, r2);
2984 static void
2985 s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
2986 UChar r1, UChar r2)
2988 const HChar *mnm = irgen(r1, r2);
2990 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2991 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
2994 static void
2995 s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
2996 UChar r1, UChar r2)
2998 const HChar *mnm = irgen(r1, r2);
3000 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3001 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
3004 static void
3005 s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
3006 UChar r1, UChar r2)
3008 const HChar *mnm = irgen(r1, r2);
3010 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3011 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
3014 static void
3015 s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
3016 UChar r1, UChar r2)
3018 const HChar *mnm = irgen(r1, r2);
3020 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3021 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
3024 static void
3025 s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
3026 UChar r1)
3028 const HChar *mnm = irgen(r1);
3030 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3031 s390_disasm(ENC2(MNM, GPR), mnm, r1);
3034 static void
3035 s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
3036 UChar r1)
3038 const HChar *mnm = irgen(r1);
3040 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3041 s390_disasm(ENC2(MNM, FPR), mnm, r1);
3044 static void
3045 s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
3046 UChar m3, UChar r1, UChar r2)
3048 const HChar *mnm = irgen(m3, r1, r2);
3050 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3051 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
3054 static void
3055 s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
3056 UChar r1, UChar r3, UChar r2)
3058 const HChar *mnm = irgen(r1, r3, r2);
3060 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3061 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
3064 static void
3065 s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
3066 UChar r3, UChar r1, UChar r2)
3068 const HChar *mnm = irgen(r3, r1, r2);
3070 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3071 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
3074 static void
3075 s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
3076 UChar r2),
3077 UChar m3, UChar m4, UChar r1, UChar r2)
3079 const HChar *mnm = irgen(m3, m4, r1, r2);
3081 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3082 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
3085 static void
3086 s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
3087 UChar m4, UChar r1, UChar r2)
3089 const HChar *mnm = irgen(m4, r1, r2);
3091 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3092 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
3095 static void
3096 s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
3097 UChar r2),
3098 UChar m3, UChar m4, UChar r1, UChar r2)
3100 const HChar *mnm = irgen(m3, m4, r1, r2);
3102 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3103 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
3106 static void
3107 s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
3108 UChar r2),
3109 UChar m3, UChar m4, UChar r1, UChar r2)
3111 const HChar *mnm = irgen(m3, m4, r1, r2);
3113 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3114 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
3118 static void
3119 s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
3120 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
3122 const HChar *mnm = irgen(m3, r1, r2);
3124 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3125 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, mnm, m3, r1, r2);
3128 static void
3129 s390_format_RRFa_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
3130 UChar m3, UChar r1, UChar r2)
3132 const HChar *mnm = irgen(m3, r1, r2);
3134 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) {
3135 if (m3 != 0)
3136 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
3137 else
3138 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
3142 static void
3143 s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
3144 UChar r3, UChar r1, UChar r2)
3146 const HChar *mnm = irgen(r3, r1, r2);
3148 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3149 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
3152 static void
3153 s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
3154 UChar r3, UChar m4, UChar r1, UChar r2)
3156 const HChar *mnm = irgen(r3, m4, r1, r2);
3158 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3159 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
3162 static void
3163 s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
3164 UChar r3, UChar m4, UChar r1, UChar r2)
3166 const HChar *mnm = irgen(r3, m4, r1, r2);
3168 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3169 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
3172 static void
3173 s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
3174 UChar r3, UChar m4, UChar r1, UChar r2)
3176 const HChar *mnm = irgen(r3, m4, r1, r2);
3178 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3179 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
3182 static void
3183 s390_format_RRF_RURR(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
3184 UChar r3, UChar m4, UChar r1, UChar r2)
3186 const HChar *mnm = irgen(r3, m4, r1, r2);
3188 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3189 s390_disasm(ENC4(XMNM, GPR, GPR, GPR), S390_XMNM_CLS, mnm, m4, r1, r2, r3);
3192 static void
3193 s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
3194 UChar r3, UChar r1, UChar r2)
3196 const HChar *mnm = irgen(r3, r1, r2);
3198 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3199 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
3202 static void
3203 s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
3204 IRTemp op4addr),
3205 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
3207 const HChar *mnm;
3208 IRTemp op4addr = newTemp(Ity_I64);
3210 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
3211 mkU64(0)));
3213 mnm = irgen(r1, r2, m3, op4addr);
3215 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3216 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
3217 r2, m3, d4, 0, b4);
3220 static void
3221 s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3222 UChar r1, UChar b2, UShort d2)
3224 const HChar *mnm;
3225 IRTemp op2addr = newTemp(Ity_I64);
3227 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3228 mkU64(0)));
3230 mnm = irgen(r1, op2addr);
3232 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3233 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
3236 static void
3237 s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
3238 UChar r1, UChar r3, UChar b2, UShort d2)
3240 const HChar *mnm;
3241 IRTemp op2addr = newTemp(Ity_I64);
3243 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3244 mkU64(0)));
3246 mnm = irgen(r1, r3, op2addr);
3248 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3249 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
3252 static void
3253 s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
3254 UChar r1, UChar r3, UChar b2, UShort d2)
3256 const HChar *mnm;
3257 IRTemp op2addr = newTemp(Ity_I64);
3259 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3260 mkU64(0)));
3262 mnm = irgen(r1, r3, op2addr);
3264 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3265 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
3268 static void
3269 s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
3270 UChar r1, UChar r3, UChar b2, UShort d2)
3272 const HChar *mnm;
3273 IRTemp op2addr = newTemp(Ity_I64);
3275 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3276 mkU64(0)));
3278 mnm = irgen(r1, r3, op2addr);
3280 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3281 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
3284 static void
3285 s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
3286 UChar r1, UChar r3, UShort i2)
3288 const HChar *mnm = irgen(r1, r3, i2);
3290 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3291 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
3294 static void
3295 s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
3296 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
3298 const HChar *mnm;
3299 IRTemp op2addr = newTemp(Ity_I64);
3300 IRTemp d2 = newTemp(Ity_I64);
3302 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3303 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
3304 mkU64(0)));
3306 mnm = irgen(r1, r3, op2addr);
3308 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3309 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
3312 static void
3313 s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
3314 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
3316 const HChar *mnm;
3317 IRTemp op2addr = newTemp(Ity_I64);
3318 IRTemp d2 = newTemp(Ity_I64);
3320 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3321 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
3322 mkU64(0)));
3324 mnm = irgen(r1, r3, op2addr);
3326 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3327 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
3330 static void
3331 s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
3332 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
3334 const HChar *mnm;
3335 IRTemp op2addr = newTemp(Ity_I64);
3336 IRTemp d2 = newTemp(Ity_I64);
3338 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3339 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
3340 mkU64(0)));
3342 mnm = irgen(r1, r3, op2addr);
3344 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3345 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
3348 static void
3349 s390_format_RSY_R0RD(const HChar *(*irgen)(UChar r1, UChar m3, IRTemp op2addr),
3350 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2)
3352 const HChar *mnm;
3353 IRTemp op2addr = newTemp(Ity_I64);
3354 IRTemp d2 = newTemp(Ity_I64);
3356 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3357 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
3358 mkU64(0)));
3360 mnm = irgen(r1, m3, op2addr);
3362 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3363 s390_disasm(ENC4(XMNM, GPR, CABM, SDXB), S390_XMNM_CAB, mnm, m3, r1, m3,
3364 dh2, dl2, 0, b2);
3367 static void
3368 s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3369 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2)
3371 IRTemp op2addr = newTemp(Ity_I64);
3372 IRTemp d2 = newTemp(Ity_I64);
3374 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
3376 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3377 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
3378 mkU64(0)));
3380 const HChar *mnm = irgen(r1, op2addr);
3382 vassert(dis_res->whatNext == Dis_Continue);
3384 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3385 s390_disasm(ENC3(XMNM, GPR, SDXB), S390_XMNM_CLS, mnm, m3, r1,
3386 dh2, dl2, 0, b2);
3389 static void
3390 s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
3391 IRTemp op2addr),
3392 UChar r1, UChar x2, UChar b2, UShort d2)
3394 IRTemp op2addr = newTemp(Ity_I64);
3396 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3397 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3398 mkU64(0)));
3400 irgen(r1, x2, b2, d2, op2addr);
3403 static void
3404 s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3405 UChar r1, UChar x2, UChar b2, UShort d2)
3407 const HChar *mnm;
3408 IRTemp op2addr = newTemp(Ity_I64);
3410 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3411 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3412 mkU64(0)));
3414 mnm = irgen(r1, op2addr);
3416 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3417 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
3420 static void
3421 s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3422 UChar r1, UChar x2, UChar b2, UShort d2)
3424 const HChar *mnm;
3425 IRTemp op2addr = newTemp(Ity_I64);
3427 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3428 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3429 mkU64(0)));
3431 mnm = irgen(r1, op2addr);
3433 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3434 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
3437 static void
3438 s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3439 UChar r1, UChar x2, UChar b2, UShort d2)
3441 const HChar *mnm;
3442 IRTemp op2addr = newTemp(Ity_I64);
3444 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3445 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3446 mkU64(0)));
3448 mnm = irgen(r1, op2addr);
3450 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3451 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
3454 static void
3455 s390_format_RXE_RRRDR(const HChar *(*irgen)(UChar r1, IRTemp op2addr, UChar m3),
3456 UChar r1, UChar x2, UChar b2, UShort d2, UChar m3)
3458 const HChar *mnm;
3459 IRTemp op2addr = newTemp(Ity_I64);
3461 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3462 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3463 mkU64(0)));
3465 mnm = irgen(r1, op2addr, m3);
3467 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3468 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
3471 static void
3472 s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
3473 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
3475 const HChar *mnm;
3476 IRTemp op2addr = newTemp(Ity_I64);
3478 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3479 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3480 mkU64(0)));
3482 mnm = irgen(r3, op2addr, r1);
3484 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3485 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
3488 static void
3489 s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3490 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3492 const HChar *mnm;
3493 IRTemp op2addr = newTemp(Ity_I64);
3494 IRTemp d2 = newTemp(Ity_I64);
3496 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3497 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
3498 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3499 mkU64(0)));
3501 mnm = irgen(r1, op2addr);
3503 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) {
3504 if (irgen == s390_irgen_BIC)
3505 s390_disasm(ENC2(XMNM, SDXB), S390_XMNM_BIC, r1, dh2, dl2, x2, b2);
3506 else
3507 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
3511 static void
3512 s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
3513 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3515 const HChar *mnm;
3516 IRTemp op2addr = newTemp(Ity_I64);
3517 IRTemp d2 = newTemp(Ity_I64);
3519 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3520 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
3521 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3522 mkU64(0)));
3524 mnm = irgen(r1, op2addr);
3526 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3527 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
3530 static void
3531 s390_format_RXY_URRD(const HChar *(*irgen)(void),
3532 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
3534 const HChar *mnm;
3535 IRTemp op2addr = newTemp(Ity_I64);
3536 IRTemp d2 = newTemp(Ity_I64);
3538 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
3539 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
3540 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3541 mkU64(0)));
3543 mnm = irgen();
3545 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3546 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
3549 static void
3550 s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
3551 UChar b2, UShort d2)
3553 const HChar *mnm;
3554 IRTemp op2addr = newTemp(Ity_I64);
3556 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3557 mkU64(0)));
3559 mnm = irgen(op2addr);
3561 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3562 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
3565 static void
3566 s390_format_S_RD_raw(const HChar *(*irgen)(UChar b2, UShort d2),
3567 UChar b2, UShort d2)
3569 const HChar *mnm;
3571 mnm = irgen(b2, d2);
3573 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3574 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
3577 static void
3578 s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
3579 UChar i2, UChar b1, UShort d1)
3581 const HChar *mnm;
3582 IRTemp op1addr = newTemp(Ity_I64);
3584 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3585 mkU64(0)));
3587 mnm = irgen(i2, op1addr);
3589 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3590 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
3593 static void
3594 s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
3595 UChar i2, UChar b1, UShort dl1, UChar dh1)
3597 const HChar *mnm;
3598 IRTemp op1addr = newTemp(Ity_I64);
3599 IRTemp d1 = newTemp(Ity_I64);
3601 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
3602 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
3603 mkU64(0)));
3605 mnm = irgen(i2, op1addr);
3607 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3608 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
3611 static void
3612 s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
3613 UChar i2, UChar b1, UShort dl1, UChar dh1)
3615 const HChar *mnm;
3616 IRTemp op1addr = newTemp(Ity_I64);
3617 IRTemp d1 = newTemp(Ity_I64);
3619 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
3620 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
3621 mkU64(0)));
3623 mnm = irgen(i2, op1addr);
3625 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3626 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
3629 static void
3630 s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
3631 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
3633 const HChar *mnm;
3634 IRTemp op1addr = newTemp(Ity_I64);
3635 IRTemp op2addr = newTemp(Ity_I64);
3637 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3638 mkU64(0)));
3639 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3640 mkU64(0)));
3642 mnm = irgen(l, op1addr, op2addr);
3644 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3645 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
3648 static void
3649 s390_format_SSE_RDRD(const HChar *(*irgen)(IRTemp, IRTemp),
3650 UChar b1, UShort d1, UChar b2, UShort d2)
3652 const HChar *mnm;
3653 IRTemp op1addr = newTemp(Ity_I64);
3654 IRTemp op2addr = newTemp(Ity_I64);
3656 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3657 mkU64(0)));
3658 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3659 mkU64(0)));
3661 mnm = irgen(op1addr, op2addr);
3663 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3664 s390_disasm(ENC2(UDXB, UDXB), mnm, d1, 0, b1, d2, 0, b2);
3667 static void
3668 s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
3669 UChar b1, UShort d1, UShort i2)
3671 const HChar *mnm;
3672 IRTemp op1addr = newTemp(Ity_I64);
3674 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3675 mkU64(0)));
3677 mnm = irgen(i2, op1addr);
3679 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3680 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
3683 static void
3684 s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
3685 UChar b1, UShort d1, UShort i2)
3687 const HChar *mnm;
3688 IRTemp op1addr = newTemp(Ity_I64);
3690 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
3691 mkU64(0)));
3693 mnm = irgen(i2, op1addr);
3695 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3696 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
3699 static void
3700 s390_format_VRX_VRRD(const HChar *(*irgen)(UChar v1, IRTemp op2addr),
3701 UChar v1, UChar x2, UChar b2, UShort d2, UChar rxb)
3703 const HChar *mnm;
3704 IRTemp op2addr = newTemp(Ity_I64);
3706 if (! s390_host_has_vx) {
3707 emulation_failure(EmFail_S390X_vx);
3708 return;
3711 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3712 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3713 mkU64(0)));
3715 v1 = s390_vr_getVRindex(v1, 1, rxb);
3716 mnm = irgen(v1, op2addr);
3718 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3719 s390_disasm(ENC3(MNM, VR, UDXB), mnm, v1, d2, x2, b2);
3723 static void
3724 s390_format_VRX_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3),
3725 UChar v1, UChar x2, UChar b2, UShort d2, UChar m3, UChar rxb)
3727 const HChar *mnm;
3728 IRTemp op2addr = newTemp(Ity_I64);
3730 if (! s390_host_has_vx) {
3731 emulation_failure(EmFail_S390X_vx);
3732 return;
3735 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
3736 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
3737 mkU64(0)));
3739 v1 = s390_vr_getVRindex(v1, 1, rxb);
3740 mnm = irgen(v1, op2addr, m3);
3742 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3743 s390_disasm(ENC3(MNM, VR, UDXB), mnm, v1, d2, x2, b2);
3747 static void
3748 s390_format_VRR_VV(const HChar *(*irgen)(UChar v1, UChar v2),
3749 UChar v1, UChar v2, UChar rxb)
3751 const HChar *mnm;
3753 if (! s390_host_has_vx) {
3754 emulation_failure(EmFail_S390X_vx);
3755 return;
3758 v1 = s390_vr_getVRindex(v1, 1, rxb);
3759 v2 = s390_vr_getVRindex(v2, 2, rxb);
3760 mnm = irgen(v1, v2);
3762 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3763 s390_disasm(ENC3(MNM, VR, VR), mnm, v1, v2);
3767 static void
3768 s390_format_VRR_VVV(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3),
3769 UChar v1, UChar v2, UChar v3, UChar rxb)
3771 const HChar *mnm;
3773 if (! s390_host_has_vx) {
3774 emulation_failure(EmFail_S390X_vx);
3775 return;
3778 v1 = s390_vr_getVRindex(v1, 1, rxb);
3779 v2 = s390_vr_getVRindex(v2, 2, rxb);
3780 v3 = s390_vr_getVRindex(v3, 3, rxb);
3781 mnm = irgen(v1, v2, v3);
3783 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3784 s390_disasm(ENC4(MNM, VR, VR, VR), mnm, v1, v2, v3);
3788 static void
3789 s390_format_VRR_VVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m4),
3790 UChar v1, UChar v2, UChar v3, UChar m4, UChar rxb)
3792 const HChar *mnm;
3794 if (! s390_host_has_vx) {
3795 emulation_failure(EmFail_S390X_vx);
3796 return;
3799 v1 = s390_vr_getVRindex(v1, 1, rxb);
3800 v2 = s390_vr_getVRindex(v2, 2, rxb);
3801 v3 = s390_vr_getVRindex(v3, 3, rxb);
3802 mnm = irgen(v1, v2, v3, m4);
3804 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3805 s390_disasm(ENC5(MNM, VR, VR, VR, UINT), mnm, v1, v2, v3, m4);
3809 static void
3810 s390_format_VRR_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5),
3811 UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar rxb)
3813 const HChar *mnm;
3815 if (! s390_host_has_vx) {
3816 emulation_failure(EmFail_S390X_vx);
3817 return;
3820 v1 = s390_vr_getVRindex(v1, 1, rxb);
3821 v2 = s390_vr_getVRindex(v2, 2, rxb);
3822 v3 = s390_vr_getVRindex(v3, 3, rxb);
3823 mnm = irgen(v1, v2, v3, m4, m5);
3825 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3826 s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), mnm, v1, v2, v3, m4, m5);
3830 static void
3831 s390_format_VRR_VVVV(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar v4),
3832 UChar v1, UChar v2, UChar v3, UChar v4, UChar rxb)
3834 const HChar *mnm;
3836 if (! s390_host_has_vx) {
3837 emulation_failure(EmFail_S390X_vx);
3838 return;
3841 v1 = s390_vr_getVRindex(v1, 1, rxb);
3842 v2 = s390_vr_getVRindex(v2, 2, rxb);
3843 v3 = s390_vr_getVRindex(v3, 3, rxb);
3844 v4 = s390_vr_getVRindex(v4, 4, rxb);
3845 mnm = irgen(v1, v2, v3, v4);
3847 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3848 s390_disasm(ENC5(MNM, VR, VR, VR, VR), mnm, v1, v2, v3, v4);
3852 static void
3853 s390_format_VRR_VRR(const HChar *(*irgen)(UChar v1, UChar r2, UChar r3),
3854 UChar v1, UChar r2, UChar r3, UChar rxb)
3856 const HChar *mnm;
3858 if (! s390_host_has_vx) {
3859 emulation_failure(EmFail_S390X_vx);
3860 return;
3863 v1 = s390_vr_getVRindex(v1, 1, rxb);
3864 mnm = irgen(v1, r2, r3);
3866 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3867 s390_disasm(ENC4(MNM, VR, GPR, GPR), mnm, v1, r2, r3);
3871 static void
3872 s390_format_VRR_VVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3),
3873 UChar v1, UChar v2, UChar m3, UChar rxb)
3875 const HChar *mnm;
3877 if (! s390_host_has_vx) {
3878 emulation_failure(EmFail_S390X_vx);
3879 return;
3882 v1 = s390_vr_getVRindex(v1, 1, rxb);
3883 v2 = s390_vr_getVRindex(v2, 2, rxb);
3884 mnm = irgen(v1, v2, m3);
3886 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3887 s390_disasm(ENC4(MNM, VR, VR, UINT), mnm, v1, v2, m3);
3891 static void
3892 s390_format_VRI_VIM(const HChar *(*irgen)(UChar v1, UShort i2, UChar m3),
3893 UChar v1, UShort i2, UChar m3, UChar rxb)
3895 const HChar *mnm;
3897 if (! s390_host_has_vx) {
3898 emulation_failure(EmFail_S390X_vx);
3899 return;
3902 v1 = s390_vr_getVRindex(v1, 1, rxb);
3903 mnm = irgen(v1, i2, m3);
3905 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3906 s390_disasm(ENC4(MNM, VR, UINT, UINT), mnm, v1, i2, m3);
3910 static void
3911 s390_format_VRI_VVIM(const HChar *(*irgen)(UChar v1, UChar v3, UShort i2, UChar m4),
3912 UChar v1, UChar v3, UShort i2, UChar m4, UChar rxb)
3914 const HChar *mnm;
3916 if (! s390_host_has_vx) {
3917 emulation_failure(EmFail_S390X_vx);
3918 return;
3921 v1 = s390_vr_getVRindex(v1, 1, rxb);
3922 v3 = s390_vr_getVRindex(v3, 2, rxb);
3923 mnm = irgen(v1, v3, i2, m4);
3925 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3926 s390_disasm(ENC5(MNM, VR, VR, UINT, UINT), mnm, v1, v3, i2, m4);
3929 static void
3930 s390_format_VRI_VVIMM(const HChar *(*irgen)(UChar v1, UChar v2, UShort i3,
3931 UChar m4, UChar m5),
3932 UChar v1, UChar v2, UShort i3, UChar m4, UChar m5,
3933 UChar rxb)
3935 const HChar *mnm;
3937 if (!s390_host_has_vx) {
3938 emulation_failure(EmFail_S390X_vx);
3939 return;
3942 v1 = s390_vr_getVRindex(v1, 1, rxb);
3943 v2 = s390_vr_getVRindex(v2, 2, rxb);
3944 mnm = irgen(v1, v2, i3, m4, m5);
3946 if (vex_traceflags & VEX_TRACE_FE)
3947 s390_disasm(ENC6(MNM, VR, VR, UINT, UINT, UINT), mnm, v1, v2, i3, m4, m5);
3950 static void
3951 s390_format_VRS_RRDVM(const HChar *(*irgen)(UChar r1, IRTemp op2addr, UChar v3,
3952 UChar m4), UChar r1, UChar b2, UShort d2, UChar v3,
3953 UChar m4, UChar rxb)
3955 const HChar *mnm;
3956 IRTemp op2addr = newTemp(Ity_I64);
3958 if (! s390_host_has_vx) {
3959 emulation_failure(EmFail_S390X_vx);
3960 return;
3963 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3964 mkU64(0)));
3966 v3 = s390_vr_getVRindex(v3, 2, rxb);
3967 mnm = irgen(r1, op2addr, v3, m4);
3969 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3970 s390_disasm(ENC5(MNM, GPR, UDXB, VR, UINT), mnm, r1, d2, 0, b2, v3, m4);
3973 static void
3974 s390_format_VRS_RRDV(const HChar *(*irgen)(UChar v1, UChar r3, IRTemp op2addr),
3975 UChar v1, UChar r3, UChar b2, UShort d2, UChar rxb)
3977 const HChar *mnm;
3978 IRTemp op2addr = newTemp(Ity_I64);
3980 if (! s390_host_has_vx) {
3981 emulation_failure(EmFail_S390X_vx);
3982 return;
3985 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
3986 mkU64(0)));
3988 v1 = s390_vr_getVRindex(v1, 4, rxb);
3989 mnm = irgen(v1, r3, op2addr);
3991 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
3992 s390_disasm(ENC4(MNM, VR, GPR, UDXB), mnm, v1, r3, d2, 0, b2);
3996 static void
3997 s390_format_VRS_VRDVM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3,
3998 UChar m4), UChar v1, UChar b2, UShort d2, UChar v3,
3999 UChar m4, UChar rxb)
4001 const HChar *mnm;
4002 IRTemp op2addr = newTemp(Ity_I64);
4004 if (! s390_host_has_vx) {
4005 emulation_failure(EmFail_S390X_vx);
4006 return;
4009 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
4010 mkU64(0)));
4012 v1 = s390_vr_getVRindex(v1, 1, rxb);
4013 v3 = s390_vr_getVRindex(v3, 2, rxb);
4014 mnm = irgen(v1, op2addr, v3, m4);
4016 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4017 s390_disasm(ENC5(MNM, VR, UDXB, VR, UINT), mnm, v1, d2, 0, b2, v3, m4);
4021 static void
4022 s390_format_VRS_VRDV(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3),
4023 UChar v1, UChar b2, UShort d2, UChar v3, UChar rxb)
4025 const HChar *mnm;
4026 IRTemp op2addr = newTemp(Ity_I64);
4028 if (! s390_host_has_vx) {
4029 emulation_failure(EmFail_S390X_vx);
4030 return;
4033 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
4034 mkU64(0)));
4036 v1 = s390_vr_getVRindex(v1, 1, rxb);
4037 v3 = s390_vr_getVRindex(v3, 2, rxb);
4038 mnm = irgen(v1, op2addr, v3);
4040 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4041 s390_disasm(ENC4(MNM, VR, UDXB, VR), mnm, v1, d2, 0, b2, v3);
4045 static void
4046 s390_format_VRS_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar r3,
4047 UChar m4),
4048 UChar v1, UChar b2, UShort d2, UChar r3, UChar m4, UChar rxb)
4050 const HChar *mnm;
4051 IRTemp op2addr = newTemp(Ity_I64);
4053 if (! s390_host_has_vx) {
4054 emulation_failure(EmFail_S390X_vx);
4055 return;
4058 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
4059 mkU64(0)));
4061 v1 = s390_vr_getVRindex(v1, 1, rxb);
4062 mnm = irgen(v1, op2addr, r3, m4);
4064 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4065 s390_disasm(ENC5(MNM, VR, GPR, UDXB, UINT), mnm, v1, r3, d2, 0, b2, m4);
4069 static void
4070 s390_format_VRS_VRRD(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar r3),
4071 UChar v1, UChar b2, UShort d2, UChar r3, UChar rxb)
4073 const HChar *mnm;
4074 IRTemp op2addr = newTemp(Ity_I64);
4076 if (! s390_host_has_vx) {
4077 emulation_failure(EmFail_S390X_vx);
4078 return;
4081 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
4082 mkU64(0)));
4084 v1 = s390_vr_getVRindex(v1, 1, rxb);
4085 mnm = irgen(v1, op2addr, r3);
4087 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4088 s390_disasm(ENC4(MNM, VR, GPR, UDXB), mnm, v1, r3, d2, 0, b2);
4092 static void
4093 s390_format_VRV_VVRDMT(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3),
4094 UChar v1, UChar v2, UChar b2, UShort d2, UChar m3, UChar rxb,
4095 IRType type)
4097 const HChar *mnm;
4098 IRTemp op2addr = newTemp(Ity_I64);
4100 if (! s390_host_has_vx) {
4101 emulation_failure(EmFail_S390X_vx);
4102 return;
4105 v1 = s390_vr_getVRindex(v1, 1, rxb);
4106 v2 = s390_vr_getVRindex(v2, 2, rxb);
4108 vassert(type == Ity_I32 || type == Ity_I64);
4109 IRExpr *x2;
4110 if(type == Ity_I32) {
4111 x2 = unop(Iop_32Uto64, get_vr(v2, type, m3));
4112 } else {
4113 x2 = get_vr(v2, type, m3);
4116 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
4117 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2));
4119 mnm = irgen(v1, op2addr, m3);
4121 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4122 s390_disasm(ENC4(MNM, VR, UDVB, UINT), mnm, v1, d2, v2, b2, m3);
4126 static void
4127 s390_format_VRR_VVVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
4128 UChar v4, UChar m5, UChar m6),
4129 UChar v1, UChar v2, UChar v3, UChar v4, UChar m5,
4130 UChar m6, UChar rxb)
4132 const HChar *mnm;
4134 if (! s390_host_has_vx) {
4135 emulation_failure(EmFail_S390X_vx);
4136 return;
4139 v1 = s390_vr_getVRindex(v1, 1, rxb);
4140 v2 = s390_vr_getVRindex(v2, 2, rxb);
4141 v3 = s390_vr_getVRindex(v3, 3, rxb);
4142 v4 = s390_vr_getVRindex(v4, 4, rxb);
4143 mnm = irgen(v1, v2, v3, v4, m5, m6);
4145 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4146 s390_disasm(ENC7(MNM, VR, VR, VR, VR, UINT, UINT),
4147 mnm, v1, v2, v3, v4, m5, m6);
4151 static void
4152 s390_format_VRR_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3,
4153 UChar m5),
4154 UChar v1, UChar v2, UChar m3, UChar m5, UChar rxb)
4156 const HChar *mnm;
4158 if (! s390_host_has_vx) {
4159 emulation_failure(EmFail_S390X_vx);
4160 return;
4163 v1 = s390_vr_getVRindex(v1, 1, rxb);
4164 v2 = s390_vr_getVRindex(v2, 2, rxb);
4165 mnm = irgen(v1, v2, m3, m5);
4167 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4168 s390_disasm(ENC5(MNM, VR, VR, UINT, UINT), mnm, v1, v2, m3, m5);
4172 static void
4173 s390_format_VRId_VVVIM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
4174 UChar i4, UChar m5),
4175 UChar v1, UChar v2, UChar v3, UChar i4, UChar m5,
4176 UChar rxb)
4178 const HChar *mnm;
4180 if (! s390_host_has_vx) {
4181 emulation_failure(EmFail_S390X_vx);
4182 return;
4185 v1 = s390_vr_getVRindex(v1, 1, rxb);
4186 v2 = s390_vr_getVRindex(v2, 2, rxb);
4187 v3 = s390_vr_getVRindex(v3, 3, rxb);
4188 mnm = irgen(v1, v2, v3, i4, m5);
4190 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4191 s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), mnm, v1, v2, v3, i4, m5);
4195 static void
4196 s390_format_VRId_VVVI(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
4197 UChar i4),
4198 UChar v1, UChar v2, UChar v3, UChar i4, UChar rxb)
4200 const HChar *mnm;
4202 if (! s390_host_has_vx) {
4203 emulation_failure(EmFail_S390X_vx);
4204 return;
4207 v1 = s390_vr_getVRindex(v1, 1, rxb);
4208 v2 = s390_vr_getVRindex(v2, 2, rxb);
4209 v3 = s390_vr_getVRindex(v3, 3, rxb);
4210 mnm = irgen(v1, v2, v3, i4);
4212 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4213 s390_disasm(ENC5(MNM, VR, VR, VR, UINT), mnm, v1, v2, v3, i4);
4217 static void
4218 s390_format_VRRd_VVVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
4219 UChar v4, UChar m5),
4220 UChar v1, UChar v2, UChar v3, UChar v4, UChar m5,
4221 UChar rxb)
4223 const HChar *mnm;
4225 if (! s390_host_has_vx) {
4226 emulation_failure(EmFail_S390X_vx);
4227 return;
4230 v1 = s390_vr_getVRindex(v1, 1, rxb);
4231 v2 = s390_vr_getVRindex(v2, 2, rxb);
4232 v3 = s390_vr_getVRindex(v3, 3, rxb);
4233 v4 = s390_vr_getVRindex(v4, 4, rxb);
4234 mnm = irgen(v1, v2, v3, v4, m5);
4236 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
4237 s390_disasm(ENC6(MNM, VR, VR, VR, VR, UINT), mnm, v1, v2, v3, v4, m5);
4241 static void
4242 s390_format_VRRa_VVMMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3,
4243 UChar m4, UChar m5),
4244 UChar v1, UChar v2, UChar m3, UChar m4, UChar m5,
4245 UChar rxb)
4247 const HChar *mnm;
4249 if (!s390_host_has_vx) {
4250 emulation_failure(EmFail_S390X_vx);
4251 return;
4254 v1 = s390_vr_getVRindex(v1, 1, rxb);
4255 v2 = s390_vr_getVRindex(v2, 2, rxb);
4256 mnm = irgen(v1, v2, m3, m4, m5);
4258 if (vex_traceflags & VEX_TRACE_FE)
4259 s390_disasm(ENC6(MNM, VR, VR, UINT, UINT, UINT), mnm, v1, v2, m3, m4, m5);
4262 static void
4263 s390_format_VRRa_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
4264 UChar m4, UChar m5),
4265 UChar v1, UChar v2, UChar v3, UChar m4, UChar m5,
4266 UChar rxb)
4268 const HChar *mnm;
4270 if (!s390_host_has_vx) {
4271 emulation_failure(EmFail_S390X_vx);
4272 return;
4275 v1 = s390_vr_getVRindex(v1, 1, rxb);
4276 v2 = s390_vr_getVRindex(v2, 2, rxb);
4277 v3 = s390_vr_getVRindex(v3, 3, rxb);
4278 mnm = irgen(v1, v2, v3, m4, m5);
4280 if (vex_traceflags & VEX_TRACE_FE)
4281 s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), mnm, v1, v2, v3, m4, m5);
4284 static void
4285 s390_format_VRRa_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3,
4286 UChar m4),
4287 UChar v1, UChar v2, UChar m3, UChar m4, UChar rxb)
4289 const HChar *mnm;
4291 if (!s390_host_has_vx) {
4292 emulation_failure(EmFail_S390X_vx);
4293 return;
4296 v1 = s390_vr_getVRindex(v1, 1, rxb);
4297 v2 = s390_vr_getVRindex(v2, 2, rxb);
4298 mnm = irgen(v1, v2, m3, m4);
4300 if (vex_traceflags & VEX_TRACE_FE)
4301 s390_disasm(ENC5(MNM, VR, VR, UINT, UINT), mnm, v1, v2, m3, m4);
4304 static void
4305 s390_format_VRRa_VVVMMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3,
4306 UChar m4, UChar m5, UChar m6),
4307 UChar v1, UChar v2, UChar v3, UChar m4, UChar m5,
4308 UChar m6, UChar rxb)
4310 const HChar *mnm;
4312 if (!s390_host_has_vx) {
4313 emulation_failure(EmFail_S390X_vx);
4314 return;
4317 v1 = s390_vr_getVRindex(v1, 1, rxb);
4318 v2 = s390_vr_getVRindex(v2, 2, rxb);
4319 v3 = s390_vr_getVRindex(v3, 3, rxb);
4320 mnm = irgen(v1, v2, v3, m4, m5, m6);
4322 if (vex_traceflags & VEX_TRACE_FE)
4323 s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT),
4324 mnm, v1, v2, v3, m4, m5, m6);
4327 static void
4328 s390_format_VSI_URDV(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar i3),
4329 UChar v1, UChar b2, UChar d2, UChar i3, UChar rxb)
4331 const HChar *mnm;
4332 IRTemp op2addr = newTemp(Ity_I64);
4334 if (!s390_host_has_vx) {
4335 emulation_failure(EmFail_S390X_vx);
4336 return;
4339 v1 = s390_vr_getVRindex(v1, 4, rxb);
4341 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
4342 mkU64(0)));
4344 mnm = irgen(v1, op2addr, i3);
4346 if (vex_traceflags & VEX_TRACE_FE)
4347 s390_disasm(ENC4(MNM, VR, UDXB, UINT), mnm, v1, d2, 0, b2, i3);
4350 /*------------------------------------------------------------*/
4351 /*--- Build IR for opcodes ---*/
4352 /*------------------------------------------------------------*/
4354 static const HChar *
4355 s390_irgen_AR(UChar r1, UChar r2)
4357 IRTemp op1 = newTemp(Ity_I32);
4358 IRTemp op2 = newTemp(Ity_I32);
4359 IRTemp result = newTemp(Ity_I32);
4361 assign(op1, get_gpr_w1(r1));
4362 assign(op2, get_gpr_w1(r2));
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));
4367 return "ar";
4370 static const HChar *
4371 s390_irgen_AGR(UChar r1, UChar r2)
4373 IRTemp op1 = newTemp(Ity_I64);
4374 IRTemp op2 = newTemp(Ity_I64);
4375 IRTemp result = newTemp(Ity_I64);
4377 assign(op1, get_gpr_dw0(r1));
4378 assign(op2, get_gpr_dw0(r2));
4379 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4380 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
4381 put_gpr_dw0(r1, mkexpr(result));
4383 return "agr";
4386 static const HChar *
4387 s390_irgen_AGFR(UChar r1, UChar r2)
4389 IRTemp op1 = newTemp(Ity_I64);
4390 IRTemp op2 = newTemp(Ity_I64);
4391 IRTemp result = newTemp(Ity_I64);
4393 assign(op1, get_gpr_dw0(r1));
4394 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
4395 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4396 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
4397 put_gpr_dw0(r1, mkexpr(result));
4399 return "agfr";
4402 static const HChar *
4403 s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
4405 IRTemp op2 = newTemp(Ity_I32);
4406 IRTemp op3 = newTemp(Ity_I32);
4407 IRTemp result = newTemp(Ity_I32);
4409 assign(op2, get_gpr_w1(r2));
4410 assign(op3, get_gpr_w1(r3));
4411 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4412 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
4413 put_gpr_w1(r1, mkexpr(result));
4415 return "ark";
4418 static const HChar *
4419 s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
4421 IRTemp op2 = newTemp(Ity_I64);
4422 IRTemp op3 = newTemp(Ity_I64);
4423 IRTemp result = newTemp(Ity_I64);
4425 assign(op2, get_gpr_dw0(r2));
4426 assign(op3, get_gpr_dw0(r3));
4427 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
4428 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
4429 put_gpr_dw0(r1, mkexpr(result));
4431 return "agrk";
4434 static const HChar *
4435 s390_irgen_A(UChar r1, IRTemp op2addr)
4437 IRTemp op1 = newTemp(Ity_I32);
4438 IRTemp op2 = newTemp(Ity_I32);
4439 IRTemp result = newTemp(Ity_I32);
4441 assign(op1, get_gpr_w1(r1));
4442 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4443 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4444 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4445 put_gpr_w1(r1, mkexpr(result));
4447 return "a";
4450 static const HChar *
4451 s390_irgen_AY(UChar r1, IRTemp op2addr)
4453 IRTemp op1 = newTemp(Ity_I32);
4454 IRTemp op2 = newTemp(Ity_I32);
4455 IRTemp result = newTemp(Ity_I32);
4457 assign(op1, get_gpr_w1(r1));
4458 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4459 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4460 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4461 put_gpr_w1(r1, mkexpr(result));
4463 return "ay";
4466 static const HChar *
4467 s390_irgen_AG(UChar r1, IRTemp op2addr)
4469 IRTemp op1 = newTemp(Ity_I64);
4470 IRTemp op2 = newTemp(Ity_I64);
4471 IRTemp result = newTemp(Ity_I64);
4473 assign(op1, get_gpr_dw0(r1));
4474 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4475 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4476 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
4477 put_gpr_dw0(r1, mkexpr(result));
4479 return "ag";
4482 static const HChar *
4483 s390_irgen_AGF(UChar r1, IRTemp op2addr)
4485 IRTemp op1 = newTemp(Ity_I64);
4486 IRTemp op2 = newTemp(Ity_I64);
4487 IRTemp result = newTemp(Ity_I64);
4489 assign(op1, get_gpr_dw0(r1));
4490 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
4491 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4492 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
4493 put_gpr_dw0(r1, mkexpr(result));
4495 return "agf";
4498 static const HChar *
4499 s390_irgen_AFI(UChar r1, UInt i2)
4501 IRTemp op1 = newTemp(Ity_I32);
4502 Int op2;
4503 IRTemp result = newTemp(Ity_I32);
4505 assign(op1, get_gpr_w1(r1));
4506 op2 = (Int)i2;
4507 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
4508 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
4509 mkU32((UInt)op2)));
4510 put_gpr_w1(r1, mkexpr(result));
4512 return "afi";
4515 static const HChar *
4516 s390_irgen_AGFI(UChar r1, UInt i2)
4518 IRTemp op1 = newTemp(Ity_I64);
4519 Long op2;
4520 IRTemp result = newTemp(Ity_I64);
4522 assign(op1, get_gpr_dw0(r1));
4523 op2 = (Long)(Int)i2;
4524 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
4525 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
4526 mkU64((ULong)op2)));
4527 put_gpr_dw0(r1, mkexpr(result));
4529 return "agfi";
4532 static const HChar *
4533 s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
4535 Int op2;
4536 IRTemp op3 = newTemp(Ity_I32);
4537 IRTemp result = newTemp(Ity_I32);
4539 op2 = (Int)(Short)i2;
4540 assign(op3, get_gpr_w1(r3));
4541 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
4542 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
4543 op2)), op3);
4544 put_gpr_w1(r1, mkexpr(result));
4546 return "ahik";
4549 static const HChar *
4550 s390_irgen_AGH(UChar r1, IRTemp op2addr)
4552 IRTemp op1 = newTemp(Ity_I64);
4553 IRTemp op2 = newTemp(Ity_I64);
4554 IRTemp result = newTemp(Ity_I64);
4556 assign(op1, get_gpr_dw0(r1));
4557 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4558 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4559 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
4560 put_gpr_dw0(r1, mkexpr(result));
4562 return "agh";
4565 static const HChar *
4566 s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
4568 Long op2;
4569 IRTemp op3 = newTemp(Ity_I64);
4570 IRTemp result = newTemp(Ity_I64);
4572 op2 = (Long)(Short)i2;
4573 assign(op3, get_gpr_dw0(r3));
4574 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
4575 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
4576 op2)), op3);
4577 put_gpr_dw0(r1, mkexpr(result));
4579 return "aghik";
4582 static const HChar *
4583 s390_irgen_ASI(UChar i2, IRTemp op1addr)
4585 IRTemp op1 = newTemp(Ity_I32);
4586 Int op2;
4587 IRTemp result = newTemp(Ity_I32);
4589 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4590 op2 = (Int)(Char)i2;
4591 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
4592 store(mkexpr(op1addr), mkexpr(result));
4593 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
4594 mkU32((UInt)op2)));
4596 return "asi";
4599 static const HChar *
4600 s390_irgen_AGSI(UChar i2, IRTemp op1addr)
4602 IRTemp op1 = newTemp(Ity_I64);
4603 Long op2;
4604 IRTemp result = newTemp(Ity_I64);
4606 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4607 op2 = (Long)(Char)i2;
4608 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
4609 store(mkexpr(op1addr), mkexpr(result));
4610 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
4611 mkU64((ULong)op2)));
4613 return "agsi";
4616 static const HChar *
4617 s390_irgen_AH(UChar r1, IRTemp op2addr)
4619 IRTemp op1 = newTemp(Ity_I32);
4620 IRTemp op2 = newTemp(Ity_I32);
4621 IRTemp result = newTemp(Ity_I32);
4623 assign(op1, get_gpr_w1(r1));
4624 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4625 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4626 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4627 put_gpr_w1(r1, mkexpr(result));
4629 return "ah";
4632 static const HChar *
4633 s390_irgen_AHY(UChar r1, IRTemp op2addr)
4635 IRTemp op1 = newTemp(Ity_I32);
4636 IRTemp op2 = newTemp(Ity_I32);
4637 IRTemp result = newTemp(Ity_I32);
4639 assign(op1, get_gpr_w1(r1));
4640 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4641 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4642 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
4643 put_gpr_w1(r1, mkexpr(result));
4645 return "ahy";
4648 static const HChar *
4649 s390_irgen_AHI(UChar r1, UShort i2)
4651 IRTemp op1 = newTemp(Ity_I32);
4652 Int op2;
4653 IRTemp result = newTemp(Ity_I32);
4655 assign(op1, get_gpr_w1(r1));
4656 op2 = (Int)(Short)i2;
4657 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
4658 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
4659 mkU32((UInt)op2)));
4660 put_gpr_w1(r1, mkexpr(result));
4662 return "ahi";
4665 static const HChar *
4666 s390_irgen_AGHI(UChar r1, UShort i2)
4668 IRTemp op1 = newTemp(Ity_I64);
4669 Long op2;
4670 IRTemp result = newTemp(Ity_I64);
4672 assign(op1, get_gpr_dw0(r1));
4673 op2 = (Long)(Short)i2;
4674 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
4675 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
4676 mkU64((ULong)op2)));
4677 put_gpr_dw0(r1, mkexpr(result));
4679 return "aghi";
4682 static const HChar *
4683 s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
4685 IRTemp op2 = newTemp(Ity_I32);
4686 IRTemp op3 = newTemp(Ity_I32);
4687 IRTemp result = newTemp(Ity_I32);
4689 assign(op2, get_gpr_w0(r2));
4690 assign(op3, get_gpr_w0(r3));
4691 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4692 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
4693 put_gpr_w0(r1, mkexpr(result));
4695 return "ahhhr";
4698 static const HChar *
4699 s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
4701 IRTemp op2 = newTemp(Ity_I32);
4702 IRTemp op3 = newTemp(Ity_I32);
4703 IRTemp result = newTemp(Ity_I32);
4705 assign(op2, get_gpr_w0(r2));
4706 assign(op3, get_gpr_w1(r3));
4707 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4708 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
4709 put_gpr_w0(r1, mkexpr(result));
4711 return "ahhlr";
4714 static const HChar *
4715 s390_irgen_AIH(UChar r1, UInt i2)
4717 IRTemp op1 = newTemp(Ity_I32);
4718 Int op2;
4719 IRTemp result = newTemp(Ity_I32);
4721 assign(op1, get_gpr_w0(r1));
4722 op2 = (Int)i2;
4723 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
4724 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
4725 mkU32((UInt)op2)));
4726 put_gpr_w0(r1, mkexpr(result));
4728 return "aih";
4731 static const HChar *
4732 s390_irgen_ALR(UChar r1, UChar r2)
4734 IRTemp op1 = newTemp(Ity_I32);
4735 IRTemp op2 = newTemp(Ity_I32);
4736 IRTemp result = newTemp(Ity_I32);
4738 assign(op1, get_gpr_w1(r1));
4739 assign(op2, get_gpr_w1(r2));
4740 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4741 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
4742 put_gpr_w1(r1, mkexpr(result));
4744 return "alr";
4747 static const HChar *
4748 s390_irgen_ALGR(UChar r1, UChar r2)
4750 IRTemp op1 = newTemp(Ity_I64);
4751 IRTemp op2 = newTemp(Ity_I64);
4752 IRTemp result = newTemp(Ity_I64);
4754 assign(op1, get_gpr_dw0(r1));
4755 assign(op2, get_gpr_dw0(r2));
4756 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4757 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
4758 put_gpr_dw0(r1, mkexpr(result));
4760 return "algr";
4763 static const HChar *
4764 s390_irgen_ALGFR(UChar r1, UChar r2)
4766 IRTemp op1 = newTemp(Ity_I64);
4767 IRTemp op2 = newTemp(Ity_I64);
4768 IRTemp result = newTemp(Ity_I64);
4770 assign(op1, get_gpr_dw0(r1));
4771 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4772 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4773 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
4774 put_gpr_dw0(r1, mkexpr(result));
4776 return "algfr";
4779 static const HChar *
4780 s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
4782 IRTemp op2 = newTemp(Ity_I32);
4783 IRTemp op3 = newTemp(Ity_I32);
4784 IRTemp result = newTemp(Ity_I32);
4786 assign(op2, get_gpr_w1(r2));
4787 assign(op3, get_gpr_w1(r3));
4788 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4789 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
4790 put_gpr_w1(r1, mkexpr(result));
4792 return "alrk";
4795 static const HChar *
4796 s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
4798 IRTemp op2 = newTemp(Ity_I64);
4799 IRTemp op3 = newTemp(Ity_I64);
4800 IRTemp result = newTemp(Ity_I64);
4802 assign(op2, get_gpr_dw0(r2));
4803 assign(op3, get_gpr_dw0(r3));
4804 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
4805 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
4806 put_gpr_dw0(r1, mkexpr(result));
4808 return "algrk";
4811 static const HChar *
4812 s390_irgen_AL(UChar r1, IRTemp op2addr)
4814 IRTemp op1 = newTemp(Ity_I32);
4815 IRTemp op2 = newTemp(Ity_I32);
4816 IRTemp result = newTemp(Ity_I32);
4818 assign(op1, get_gpr_w1(r1));
4819 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4820 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4821 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
4822 put_gpr_w1(r1, mkexpr(result));
4824 return "al";
4827 static const HChar *
4828 s390_irgen_ALY(UChar r1, IRTemp op2addr)
4830 IRTemp op1 = newTemp(Ity_I32);
4831 IRTemp op2 = newTemp(Ity_I32);
4832 IRTemp result = newTemp(Ity_I32);
4834 assign(op1, get_gpr_w1(r1));
4835 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4836 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
4837 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
4838 put_gpr_w1(r1, mkexpr(result));
4840 return "aly";
4843 static const HChar *
4844 s390_irgen_ALG(UChar r1, IRTemp op2addr)
4846 IRTemp op1 = newTemp(Ity_I64);
4847 IRTemp op2 = newTemp(Ity_I64);
4848 IRTemp result = newTemp(Ity_I64);
4850 assign(op1, get_gpr_dw0(r1));
4851 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4852 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4853 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
4854 put_gpr_dw0(r1, mkexpr(result));
4856 return "alg";
4859 static const HChar *
4860 s390_irgen_ALGF(UChar r1, IRTemp op2addr)
4862 IRTemp op1 = newTemp(Ity_I64);
4863 IRTemp op2 = newTemp(Ity_I64);
4864 IRTemp result = newTemp(Ity_I64);
4866 assign(op1, get_gpr_dw0(r1));
4867 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4868 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
4869 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
4870 put_gpr_dw0(r1, mkexpr(result));
4872 return "algf";
4875 static const HChar *
4876 s390_irgen_ALFI(UChar r1, UInt i2)
4878 IRTemp op1 = newTemp(Ity_I32);
4879 UInt op2;
4880 IRTemp result = newTemp(Ity_I32);
4882 assign(op1, get_gpr_w1(r1));
4883 op2 = i2;
4884 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
4885 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
4886 mkU32(op2)));
4887 put_gpr_w1(r1, mkexpr(result));
4889 return "alfi";
4892 static const HChar *
4893 s390_irgen_ALGFI(UChar r1, UInt i2)
4895 IRTemp op1 = newTemp(Ity_I64);
4896 ULong op2;
4897 IRTemp result = newTemp(Ity_I64);
4899 assign(op1, get_gpr_dw0(r1));
4900 op2 = (ULong)i2;
4901 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
4902 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
4903 mkU64(op2)));
4904 put_gpr_dw0(r1, mkexpr(result));
4906 return "algfi";
4909 static const HChar *
4910 s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
4912 IRTemp op2 = newTemp(Ity_I32);
4913 IRTemp op3 = newTemp(Ity_I32);
4914 IRTemp result = newTemp(Ity_I32);
4916 assign(op2, get_gpr_w0(r2));
4917 assign(op3, get_gpr_w0(r3));
4918 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4919 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
4920 put_gpr_w0(r1, mkexpr(result));
4922 return "alhhhr";
4925 static const HChar *
4926 s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
4928 IRTemp op2 = newTemp(Ity_I32);
4929 IRTemp op3 = newTemp(Ity_I32);
4930 IRTemp result = newTemp(Ity_I32);
4932 assign(op2, get_gpr_w0(r2));
4933 assign(op3, get_gpr_w1(r3));
4934 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
4935 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
4936 put_gpr_w0(r1, mkexpr(result));
4938 return "alhhlr";
4941 static const HChar *
4942 s390_irgen_ALCR(UChar r1, UChar r2)
4944 IRTemp op1 = newTemp(Ity_I32);
4945 IRTemp op2 = newTemp(Ity_I32);
4946 IRTemp result = newTemp(Ity_I32);
4947 IRTemp carry_in = newTemp(Ity_I32);
4949 assign(op1, get_gpr_w1(r1));
4950 assign(op2, get_gpr_w1(r2));
4951 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
4952 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
4953 mkexpr(carry_in)));
4954 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
4955 put_gpr_w1(r1, mkexpr(result));
4957 return "alcr";
4960 static const HChar *
4961 s390_irgen_ALCGR(UChar r1, UChar r2)
4963 IRTemp op1 = newTemp(Ity_I64);
4964 IRTemp op2 = newTemp(Ity_I64);
4965 IRTemp result = newTemp(Ity_I64);
4966 IRTemp carry_in = newTemp(Ity_I64);
4968 assign(op1, get_gpr_dw0(r1));
4969 assign(op2, get_gpr_dw0(r2));
4970 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
4971 mkU8(1))));
4972 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
4973 mkexpr(carry_in)));
4974 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
4975 put_gpr_dw0(r1, mkexpr(result));
4977 return "alcgr";
4980 static const HChar *
4981 s390_irgen_ALC(UChar r1, IRTemp op2addr)
4983 IRTemp op1 = newTemp(Ity_I32);
4984 IRTemp op2 = newTemp(Ity_I32);
4985 IRTemp result = newTemp(Ity_I32);
4986 IRTemp carry_in = newTemp(Ity_I32);
4988 assign(op1, get_gpr_w1(r1));
4989 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4990 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
4991 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
4992 mkexpr(carry_in)));
4993 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
4994 put_gpr_w1(r1, mkexpr(result));
4996 return "alc";
4999 static const HChar *
5000 s390_irgen_ALCG(UChar r1, IRTemp op2addr)
5002 IRTemp op1 = newTemp(Ity_I64);
5003 IRTemp op2 = newTemp(Ity_I64);
5004 IRTemp result = newTemp(Ity_I64);
5005 IRTemp carry_in = newTemp(Ity_I64);
5007 assign(op1, get_gpr_dw0(r1));
5008 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5009 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
5010 mkU8(1))));
5011 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
5012 mkexpr(carry_in)));
5013 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
5014 put_gpr_dw0(r1, mkexpr(result));
5016 return "alcg";
5019 static const HChar *
5020 s390_irgen_ALSI(UChar i2, IRTemp op1addr)
5022 IRTemp op1 = newTemp(Ity_I32);
5023 UInt op2;
5024 IRTemp result = newTemp(Ity_I32);
5026 assign(op1, load(Ity_I32, mkexpr(op1addr)));
5027 op2 = (UInt)(Int)(Char)i2;
5028 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
5029 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
5030 mkU32(op2)));
5031 store(mkexpr(op1addr), mkexpr(result));
5033 return "alsi";
5036 static const HChar *
5037 s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
5039 IRTemp op1 = newTemp(Ity_I64);
5040 ULong op2;
5041 IRTemp result = newTemp(Ity_I64);
5043 assign(op1, load(Ity_I64, mkexpr(op1addr)));
5044 op2 = (ULong)(Long)(Char)i2;
5045 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
5046 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
5047 mkU64(op2)));
5048 store(mkexpr(op1addr), mkexpr(result));
5050 return "algsi";
5053 static const HChar *
5054 s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
5056 UInt op2;
5057 IRTemp op3 = newTemp(Ity_I32);
5058 IRTemp result = newTemp(Ity_I32);
5060 op2 = (UInt)(Int)(Short)i2;
5061 assign(op3, get_gpr_w1(r3));
5062 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
5063 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
5064 op3);
5065 put_gpr_w1(r1, mkexpr(result));
5067 return "alhsik";
5070 static const HChar *
5071 s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
5073 ULong op2;
5074 IRTemp op3 = newTemp(Ity_I64);
5075 IRTemp result = newTemp(Ity_I64);
5077 op2 = (ULong)(Long)(Short)i2;
5078 assign(op3, get_gpr_dw0(r3));
5079 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
5080 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
5081 op3);
5082 put_gpr_dw0(r1, mkexpr(result));
5084 return "alghsik";
5087 static const HChar *
5088 s390_irgen_ALSIH(UChar r1, UInt i2)
5090 IRTemp op1 = newTemp(Ity_I32);
5091 UInt op2;
5092 IRTemp result = newTemp(Ity_I32);
5094 assign(op1, get_gpr_w0(r1));
5095 op2 = i2;
5096 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
5097 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
5098 mkU32(op2)));
5099 put_gpr_w0(r1, mkexpr(result));
5101 return "alsih";
5104 static const HChar *
5105 s390_irgen_ALSIHN(UChar r1, UInt i2)
5107 IRTemp op1 = newTemp(Ity_I32);
5108 UInt op2;
5109 IRTemp result = newTemp(Ity_I32);
5111 assign(op1, get_gpr_w0(r1));
5112 op2 = i2;
5113 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
5114 put_gpr_w0(r1, mkexpr(result));
5116 return "alsihn";
5119 static const HChar *
5120 s390_irgen_NR(UChar r1, UChar r2)
5122 IRTemp op1 = newTemp(Ity_I32);
5123 IRTemp op2 = newTemp(Ity_I32);
5124 IRTemp result = newTemp(Ity_I32);
5126 assign(op1, get_gpr_w1(r1));
5127 assign(op2, get_gpr_w1(r2));
5128 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
5129 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5130 put_gpr_w1(r1, mkexpr(result));
5132 return "nr";
5135 static const HChar *
5136 s390_irgen_NGR(UChar r1, UChar r2)
5138 IRTemp op1 = newTemp(Ity_I64);
5139 IRTemp op2 = newTemp(Ity_I64);
5140 IRTemp result = newTemp(Ity_I64);
5142 assign(op1, get_gpr_dw0(r1));
5143 assign(op2, get_gpr_dw0(r2));
5144 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
5145 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5146 put_gpr_dw0(r1, mkexpr(result));
5148 return "ngr";
5151 /* Helper for bitwise logical instructions with two 32-bit input operands and a
5152 32-bit output operand. `inv3' and `inv' indicate whether to invert (build
5153 bitwise complement of) operand 3 or the result, respectively. */
5154 static const HChar *
5155 s390_irgen_logicalK32(UChar r3, UChar r1, UChar r2,
5156 const HChar *mnem, IROp op, Bool inv3, Bool inv)
5158 IRTemp op2 = newTemp(Ity_I32);
5159 IRTemp op3 = newTemp(Ity_I32);
5160 IRTemp result = newTemp(Ity_I32);
5162 assign(op2, get_gpr_w1(r2));
5163 assign(op3, get_gpr_w1(r3));
5164 IRExpr* tmp = binop(op, mkexpr(op2),
5165 inv3 ? unop(Iop_Not32, mkexpr(op3)) : mkexpr(op3));
5166 assign(result, inv ? unop(Iop_Not32, tmp) : tmp);
5167 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5168 put_gpr_w1(r1, mkexpr(result));
5170 return mnem;
5173 /* Same as s390_irgen_logicalK32, but for 64-bit operands. */
5174 static const HChar *
5175 s390_irgen_logicalK64(UChar r3, UChar r1, UChar r2,
5176 const HChar *mnem, IROp op, Bool inv3, Bool inv)
5178 IRTemp op2 = newTemp(Ity_I64);
5179 IRTemp op3 = newTemp(Ity_I64);
5180 IRTemp result = newTemp(Ity_I64);
5182 assign(op2, get_gpr_dw0(r2));
5183 assign(op3, get_gpr_dw0(r3));
5184 IRExpr* tmp = binop(op, mkexpr(op2),
5185 inv3 ? unop(Iop_Not64, mkexpr(op3)) : mkexpr(op3));
5186 assign(result, inv ? unop(Iop_Not64, tmp) : tmp);
5187 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5188 put_gpr_dw0(r1, mkexpr(result));
5190 return mnem;
5193 static const HChar *
5194 s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
5196 return s390_irgen_logicalK32(r3, r1, r2, "nrk", Iop_And32, False, False);
5199 static const HChar *
5200 s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
5202 return s390_irgen_logicalK64(r3, r1, r2, "ngrk", Iop_And64, False, False);
5205 static const HChar *
5206 s390_irgen_NCRK(UChar r3, UChar r1, UChar r2)
5208 return s390_irgen_logicalK32(r3, r1, r2, "ncrk", Iop_And32, True, False);
5211 static const HChar *
5212 s390_irgen_NCGRK(UChar r3, UChar r1, UChar r2)
5214 return s390_irgen_logicalK64(r3, r1, r2, "ncgrk", Iop_And64, True, False);
5217 static const HChar *
5218 s390_irgen_NNRK(UChar r3, UChar r1, UChar r2)
5220 return s390_irgen_logicalK32(r3, r1, r2, "nnrk", Iop_And32, False, True);
5223 static const HChar *
5224 s390_irgen_NNGRK(UChar r3, UChar r1, UChar r2)
5226 return s390_irgen_logicalK64(r3, r1, r2, "nngrk", Iop_And64, False, True);
5229 static const HChar *
5230 s390_irgen_N(UChar r1, IRTemp op2addr)
5232 IRTemp op1 = newTemp(Ity_I32);
5233 IRTemp op2 = newTemp(Ity_I32);
5234 IRTemp result = newTemp(Ity_I32);
5236 assign(op1, get_gpr_w1(r1));
5237 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5238 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
5239 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5240 put_gpr_w1(r1, mkexpr(result));
5242 return "n";
5245 static const HChar *
5246 s390_irgen_NY(UChar r1, IRTemp op2addr)
5248 IRTemp op1 = newTemp(Ity_I32);
5249 IRTemp op2 = newTemp(Ity_I32);
5250 IRTemp result = newTemp(Ity_I32);
5252 assign(op1, get_gpr_w1(r1));
5253 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5254 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
5255 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5256 put_gpr_w1(r1, mkexpr(result));
5258 return "ny";
5261 static const HChar *
5262 s390_irgen_NG(UChar r1, IRTemp op2addr)
5264 IRTemp op1 = newTemp(Ity_I64);
5265 IRTemp op2 = newTemp(Ity_I64);
5266 IRTemp result = newTemp(Ity_I64);
5268 assign(op1, get_gpr_dw0(r1));
5269 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5270 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
5271 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5272 put_gpr_dw0(r1, mkexpr(result));
5274 return "ng";
5277 static const HChar *
5278 s390_irgen_NI(UChar i2, IRTemp op1addr)
5280 IRTemp op1 = newTemp(Ity_I8);
5281 UChar op2;
5282 IRTemp result = newTemp(Ity_I8);
5284 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5285 op2 = i2;
5286 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
5287 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5288 store(mkexpr(op1addr), mkexpr(result));
5290 return "ni";
5293 static const HChar *
5294 s390_irgen_NIY(UChar i2, IRTemp op1addr)
5296 IRTemp op1 = newTemp(Ity_I8);
5297 UChar op2;
5298 IRTemp result = newTemp(Ity_I8);
5300 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5301 op2 = i2;
5302 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
5303 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5304 store(mkexpr(op1addr), mkexpr(result));
5306 return "niy";
5309 static const HChar *
5310 s390_irgen_NIHF(UChar r1, UInt i2)
5312 IRTemp op1 = newTemp(Ity_I32);
5313 UInt op2;
5314 IRTemp result = newTemp(Ity_I32);
5316 assign(op1, get_gpr_w0(r1));
5317 op2 = i2;
5318 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
5319 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5320 put_gpr_w0(r1, mkexpr(result));
5322 return "nihf";
5325 static const HChar *
5326 s390_irgen_NIHH(UChar r1, UShort i2)
5328 IRTemp op1 = newTemp(Ity_I16);
5329 UShort op2;
5330 IRTemp result = newTemp(Ity_I16);
5332 assign(op1, get_gpr_hw0(r1));
5333 op2 = i2;
5334 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
5335 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5336 put_gpr_hw0(r1, mkexpr(result));
5338 return "nihh";
5341 static const HChar *
5342 s390_irgen_NIHL(UChar r1, UShort i2)
5344 IRTemp op1 = newTemp(Ity_I16);
5345 UShort op2;
5346 IRTemp result = newTemp(Ity_I16);
5348 assign(op1, get_gpr_hw1(r1));
5349 op2 = i2;
5350 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
5351 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5352 put_gpr_hw1(r1, mkexpr(result));
5354 return "nihl";
5357 static const HChar *
5358 s390_irgen_NILF(UChar r1, UInt i2)
5360 IRTemp op1 = newTemp(Ity_I32);
5361 UInt op2;
5362 IRTemp result = newTemp(Ity_I32);
5364 assign(op1, get_gpr_w1(r1));
5365 op2 = i2;
5366 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
5367 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5368 put_gpr_w1(r1, mkexpr(result));
5370 return "nilf";
5373 static const HChar *
5374 s390_irgen_NILH(UChar r1, UShort i2)
5376 IRTemp op1 = newTemp(Ity_I16);
5377 UShort op2;
5378 IRTemp result = newTemp(Ity_I16);
5380 assign(op1, get_gpr_hw2(r1));
5381 op2 = i2;
5382 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
5383 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5384 put_gpr_hw2(r1, mkexpr(result));
5386 return "nilh";
5389 static const HChar *
5390 s390_irgen_NILL(UChar r1, UShort i2)
5392 IRTemp op1 = newTemp(Ity_I16);
5393 UShort op2;
5394 IRTemp result = newTemp(Ity_I16);
5396 assign(op1, get_gpr_hw3(r1));
5397 op2 = i2;
5398 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
5399 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5400 put_gpr_hw3(r1, mkexpr(result));
5402 return "nill";
5405 static const HChar *
5406 s390_irgen_BASR(UChar r1, UChar r2)
5408 IRTemp target = newTemp(Ity_I64);
5410 if (r2 == 0) {
5411 put_gpr_dw0(r1, mkU64(guest_IA_next_instr));
5412 } else {
5413 if (r1 != r2) {
5414 put_gpr_dw0(r1, mkU64(guest_IA_next_instr));
5415 call_function(get_gpr_dw0(r2));
5416 } else {
5417 assign(target, get_gpr_dw0(r2));
5418 put_gpr_dw0(r1, mkU64(guest_IA_next_instr));
5419 call_function(mkexpr(target));
5423 return "basr";
5426 static const HChar *
5427 s390_irgen_BAS(UChar r1, IRTemp op2addr)
5429 IRTemp target = newTemp(Ity_I64);
5431 put_gpr_dw0(r1, mkU64(guest_IA_next_instr));
5432 assign(target, mkexpr(op2addr));
5433 call_function(mkexpr(target));
5435 return "bas";
5438 static const HChar *
5439 s390_irgen_BCR(UChar r1, UChar r2)
5441 IRTemp cond = newTemp(Ity_I32);
5443 if (r2 == 0 && (r1 >= 14)) { /* serialization */
5444 stmt(IRStmt_MBE(Imbe_Fence));
5447 if ((r2 == 0) || (r1 == 0)) {
5448 } else {
5449 if (r1 == 15) {
5450 return_from_function(get_gpr_dw0(r2));
5451 } else {
5452 assign(cond, s390_call_calculate_cond(r1));
5453 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5454 get_gpr_dw0(r2));
5457 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5458 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
5460 return "bcr";
5463 static const HChar *
5464 s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
5466 IRTemp cond = newTemp(Ity_I32);
5468 if (r1 == 0) {
5469 } else {
5470 if (r1 == 15) {
5471 always_goto(mkexpr(op2addr));
5472 } else {
5473 assign(cond, s390_call_calculate_cond(r1));
5474 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5475 mkexpr(op2addr));
5478 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5479 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
5481 return "bc";
5484 static const HChar *
5485 s390_irgen_BCTR(UChar r1, UChar r2)
5487 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
5488 if (r2 != 0) {
5489 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
5490 get_gpr_dw0(r2));
5493 return "bctr";
5496 static const HChar *
5497 s390_irgen_BCTGR(UChar r1, UChar r2)
5499 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
5500 if (r2 != 0) {
5501 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
5502 get_gpr_dw0(r2));
5505 return "bctgr";
5508 static const HChar *
5509 s390_irgen_BCT(UChar r1, IRTemp op2addr)
5511 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
5512 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
5513 mkexpr(op2addr));
5515 return "bct";
5518 static const HChar *
5519 s390_irgen_BCTG(UChar r1, IRTemp op2addr)
5521 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
5522 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
5523 mkexpr(op2addr));
5525 return "bctg";
5528 static const HChar *
5529 s390_irgen_BIC(UChar r1, IRTemp op2addr)
5531 IRTemp cond = newTemp(Ity_I32);
5533 if (r1 == 0) {
5534 /* nothing */
5535 } else if (r1 == 15) {
5536 always_goto(load(Ity_I64, mkexpr(op2addr)));
5537 } else {
5538 assign(cond, s390_call_calculate_cond(r1));
5539 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5540 load(Ity_I64, mkexpr(op2addr)));
5543 return "bic";
5546 static const HChar *
5547 s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
5549 IRTemp value = newTemp(Ity_I32);
5551 assign(value, get_gpr_w1(r3 | 1));
5552 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
5553 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
5554 get_gpr_w1(r1)), mkexpr(op2addr));
5556 return "bxh";
5559 static const HChar *
5560 s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
5562 IRTemp value = newTemp(Ity_I64);
5564 assign(value, get_gpr_dw0(r3 | 1));
5565 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
5566 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
5567 get_gpr_dw0(r1)), mkexpr(op2addr));
5569 return "bxhg";
5572 static const HChar *
5573 s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
5575 IRTemp value = newTemp(Ity_I32);
5577 assign(value, get_gpr_w1(r3 | 1));
5578 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
5579 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
5580 mkexpr(value)), mkexpr(op2addr));
5582 return "bxle";
5585 static const HChar *
5586 s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
5588 IRTemp value = newTemp(Ity_I64);
5590 assign(value, get_gpr_dw0(r3 | 1));
5591 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
5592 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
5593 mkexpr(value)), mkexpr(op2addr));
5595 return "bxleg";
5598 static const HChar *
5599 s390_irgen_BRAS(UChar r1, UShort i2)
5601 put_gpr_dw0(r1, mkU64(guest_IA_next_instr));
5602 call_function_and_chase(addr_relative(i2));
5604 return "bras";
5607 static const HChar *
5608 s390_irgen_BRASL(UChar r1, UInt i2)
5610 put_gpr_dw0(r1, mkU64(guest_IA_next_instr));
5611 call_function_and_chase(addr_rel_long(i2));
5613 return "brasl";
5616 static const HChar *
5617 s390_irgen_BRC(UChar r1, UShort i2)
5619 IRTemp cond = newTemp(Ity_I32);
5621 if (r1 == 0) {
5622 } else {
5623 if (r1 == 15) {
5624 always_goto_and_chase(addr_relative(i2));
5625 } else {
5626 assign(cond, s390_call_calculate_cond(r1));
5627 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5628 addr_relative(i2));
5632 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5633 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
5635 return "brc";
5638 static const HChar *
5639 s390_irgen_BRCL(UChar r1, UInt i2)
5641 IRTemp cond = newTemp(Ity_I32);
5643 if (r1 == 0) {
5644 } else {
5645 if (r1 == 15) {
5646 always_goto_and_chase(addr_rel_long(i2));
5647 } else {
5648 assign(cond, s390_call_calculate_cond(r1));
5649 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5650 addr_rel_long(i2));
5653 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
5654 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
5656 return "brcl";
5659 static const HChar *
5660 s390_irgen_BRCT(UChar r1, UShort i2)
5662 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
5663 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
5664 addr_relative(i2));
5666 return "brct";
5669 static const HChar *
5670 s390_irgen_BRCTH(UChar r1, UInt i2)
5672 put_gpr_w0(r1, binop(Iop_Sub32, get_gpr_w0(r1), mkU32(1)));
5673 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w0(r1), mkU32(0)),
5674 addr_relative(i2));
5676 return "brcth";
5679 static const HChar *
5680 s390_irgen_BRCTG(UChar r1, UShort i2)
5682 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
5683 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
5684 addr_relative(i2));
5686 return "brctg";
5689 static const HChar *
5690 s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
5692 IRTemp value = newTemp(Ity_I32);
5694 assign(value, get_gpr_w1(r3 | 1));
5695 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
5696 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
5697 addr_relative(i2));
5699 return "brxh";
5702 static const HChar *
5703 s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
5705 IRTemp value = newTemp(Ity_I64);
5707 assign(value, get_gpr_dw0(r3 | 1));
5708 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
5709 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
5710 addr_relative(i2));
5712 return "brxhg";
5715 static const HChar *
5716 s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
5718 IRTemp value = newTemp(Ity_I32);
5720 assign(value, get_gpr_w1(r3 | 1));
5721 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
5722 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
5723 addr_relative(i2));
5725 return "brxle";
5728 static const HChar *
5729 s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
5731 IRTemp value = newTemp(Ity_I64);
5733 assign(value, get_gpr_dw0(r3 | 1));
5734 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
5735 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
5736 addr_relative(i2));
5738 return "brxlg";
5741 static const HChar *
5742 s390_irgen_CR(UChar r1, UChar r2)
5744 IRTemp op1 = newTemp(Ity_I32);
5745 IRTemp op2 = newTemp(Ity_I32);
5747 assign(op1, get_gpr_w1(r1));
5748 assign(op2, get_gpr_w1(r2));
5749 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5751 return "cr";
5754 static const HChar *
5755 s390_irgen_CGR(UChar r1, UChar r2)
5757 IRTemp op1 = newTemp(Ity_I64);
5758 IRTemp op2 = newTemp(Ity_I64);
5760 assign(op1, get_gpr_dw0(r1));
5761 assign(op2, get_gpr_dw0(r2));
5762 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5764 return "cgr";
5767 static const HChar *
5768 s390_irgen_CGFR(UChar r1, UChar r2)
5770 IRTemp op1 = newTemp(Ity_I64);
5771 IRTemp op2 = newTemp(Ity_I64);
5773 assign(op1, get_gpr_dw0(r1));
5774 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5775 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5777 return "cgfr";
5780 static const HChar *
5781 s390_irgen_C(UChar r1, IRTemp op2addr)
5783 IRTemp op1 = newTemp(Ity_I32);
5784 IRTemp op2 = newTemp(Ity_I32);
5786 assign(op1, get_gpr_w1(r1));
5787 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5788 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5790 return "c";
5793 static const HChar *
5794 s390_irgen_CY(UChar r1, IRTemp op2addr)
5796 IRTemp op1 = newTemp(Ity_I32);
5797 IRTemp op2 = newTemp(Ity_I32);
5799 assign(op1, get_gpr_w1(r1));
5800 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5801 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5803 return "cy";
5806 static const HChar *
5807 s390_irgen_CG(UChar r1, IRTemp op2addr)
5809 IRTemp op1 = newTemp(Ity_I64);
5810 IRTemp op2 = newTemp(Ity_I64);
5812 assign(op1, get_gpr_dw0(r1));
5813 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5814 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5816 return "cg";
5819 static const HChar *
5820 s390_irgen_CGF(UChar r1, IRTemp op2addr)
5822 IRTemp op1 = newTemp(Ity_I64);
5823 IRTemp op2 = newTemp(Ity_I64);
5825 assign(op1, get_gpr_dw0(r1));
5826 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5827 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5829 return "cgf";
5832 static const HChar *
5833 s390_irgen_CFI(UChar r1, UInt i2)
5835 IRTemp op1 = newTemp(Ity_I32);
5836 Int op2;
5838 assign(op1, get_gpr_w1(r1));
5839 op2 = (Int)i2;
5840 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
5841 mkU32((UInt)op2)));
5843 return "cfi";
5846 static const HChar *
5847 s390_irgen_CGFI(UChar r1, UInt i2)
5849 IRTemp op1 = newTemp(Ity_I64);
5850 Long op2;
5852 assign(op1, get_gpr_dw0(r1));
5853 op2 = (Long)(Int)i2;
5854 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
5855 mkU64((ULong)op2)));
5857 return "cgfi";
5860 static const HChar *
5861 s390_irgen_CRL(UChar r1, UInt i2)
5863 IRTemp op1 = newTemp(Ity_I32);
5864 IRTemp op2 = newTemp(Ity_I32);
5866 assign(op1, get_gpr_w1(r1));
5867 assign(op2, load(Ity_I32, mkU64(addr_rel_long(i2))));
5868 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5870 return "crl";
5873 static const HChar *
5874 s390_irgen_CGRL(UChar r1, UInt i2)
5876 IRTemp op1 = newTemp(Ity_I64);
5877 IRTemp op2 = newTemp(Ity_I64);
5879 assign(op1, get_gpr_dw0(r1));
5880 assign(op2, load(Ity_I64, mkU64(addr_rel_long(i2))));
5881 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5883 return "cgrl";
5886 static const HChar *
5887 s390_irgen_CGFRL(UChar r1, UInt i2)
5889 IRTemp op1 = newTemp(Ity_I64);
5890 IRTemp op2 = newTemp(Ity_I64);
5892 assign(op1, get_gpr_dw0(r1));
5893 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(addr_rel_long(i2)))));
5894 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
5896 return "cgfrl";
5899 static const HChar *
5900 s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
5902 IRTemp op1 = newTemp(Ity_I32);
5903 IRTemp op2 = newTemp(Ity_I32);
5904 IRTemp cond = newTemp(Ity_I32);
5906 if (m3 == 0) {
5907 } else {
5908 if (m3 == 14) {
5909 always_goto(mkexpr(op4addr));
5910 } else {
5911 assign(op1, get_gpr_w1(r1));
5912 assign(op2, get_gpr_w1(r2));
5913 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
5914 op1, op2));
5915 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
5916 mkU32(0)), mkexpr(op4addr));
5920 return "crb";
5923 static const HChar *
5924 s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
5926 IRTemp op1 = newTemp(Ity_I64);
5927 IRTemp op2 = newTemp(Ity_I64);
5928 IRTemp cond = newTemp(Ity_I32);
5930 if (m3 == 0) {
5931 } else {
5932 if (m3 == 14) {
5933 always_goto(mkexpr(op4addr));
5934 } else {
5935 assign(op1, get_gpr_dw0(r1));
5936 assign(op2, get_gpr_dw0(r2));
5937 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
5938 op1, op2));
5939 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
5940 mkU32(0)), mkexpr(op4addr));
5944 return "cgrb";
5947 static const HChar *
5948 s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
5950 IRTemp op1 = newTemp(Ity_I32);
5951 IRTemp op2 = newTemp(Ity_I32);
5952 IRTemp cond = newTemp(Ity_I32);
5954 if (m3 == 0) {
5955 } else {
5956 if (m3 == 14) {
5957 always_goto_and_chase(addr_relative(i4));
5958 } else {
5959 assign(op1, get_gpr_w1(r1));
5960 assign(op2, get_gpr_w1(r2));
5961 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
5962 op1, op2));
5963 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5964 addr_relative(i4));
5969 return "crj";
5972 static const HChar *
5973 s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
5975 IRTemp op1 = newTemp(Ity_I64);
5976 IRTemp op2 = newTemp(Ity_I64);
5977 IRTemp cond = newTemp(Ity_I32);
5979 if (m3 == 0) {
5980 } else {
5981 if (m3 == 14) {
5982 always_goto_and_chase(addr_relative(i4));
5983 } else {
5984 assign(op1, get_gpr_dw0(r1));
5985 assign(op2, get_gpr_dw0(r2));
5986 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
5987 op1, op2));
5988 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
5989 addr_relative(i4));
5994 return "cgrj";
5997 static const HChar *
5998 s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
6000 IRTemp op1 = newTemp(Ity_I32);
6001 Int op2;
6002 IRTemp cond = newTemp(Ity_I32);
6004 if (m3 == 0) {
6005 } else {
6006 if (m3 == 14) {
6007 always_goto(mkexpr(op4addr));
6008 } else {
6009 assign(op1, get_gpr_w1(r1));
6010 op2 = (Int)(Char)i2;
6011 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
6012 mktemp(Ity_I32, mkU32((UInt)op2))));
6013 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6014 mkexpr(op4addr));
6018 return "cib";
6021 static const HChar *
6022 s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
6024 IRTemp op1 = newTemp(Ity_I64);
6025 Long op2;
6026 IRTemp cond = newTemp(Ity_I32);
6028 if (m3 == 0) {
6029 } else {
6030 if (m3 == 14) {
6031 always_goto(mkexpr(op4addr));
6032 } else {
6033 assign(op1, get_gpr_dw0(r1));
6034 op2 = (Long)(Char)i2;
6035 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
6036 mktemp(Ity_I64, mkU64((ULong)op2))));
6037 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6038 mkexpr(op4addr));
6042 return "cgib";
6045 static const HChar *
6046 s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
6048 IRTemp op1 = newTemp(Ity_I32);
6049 Int op2;
6050 IRTemp cond = newTemp(Ity_I32);
6052 if (m3 == 0) {
6053 } else {
6054 if (m3 == 14) {
6055 always_goto_and_chase(addr_relative(i4));
6056 } else {
6057 assign(op1, get_gpr_w1(r1));
6058 op2 = (Int)(Char)i2;
6059 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
6060 mktemp(Ity_I32, mkU32((UInt)op2))));
6061 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6062 addr_relative(i4));
6067 return "cij";
6070 static const HChar *
6071 s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
6073 IRTemp op1 = newTemp(Ity_I64);
6074 Long op2;
6075 IRTemp cond = newTemp(Ity_I32);
6077 if (m3 == 0) {
6078 } else {
6079 if (m3 == 14) {
6080 always_goto_and_chase(addr_relative(i4));
6081 } else {
6082 assign(op1, get_gpr_dw0(r1));
6083 op2 = (Long)(Char)i2;
6084 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
6085 mktemp(Ity_I64, mkU64((ULong)op2))));
6086 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6087 addr_relative(i4));
6092 return "cgij";
6095 static const HChar *
6096 s390_irgen_CH(UChar r1, IRTemp op2addr)
6098 IRTemp op1 = newTemp(Ity_I32);
6099 IRTemp op2 = newTemp(Ity_I32);
6101 assign(op1, get_gpr_w1(r1));
6102 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6103 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
6105 return "ch";
6108 static const HChar *
6109 s390_irgen_CHY(UChar r1, IRTemp op2addr)
6111 IRTemp op1 = newTemp(Ity_I32);
6112 IRTemp op2 = newTemp(Ity_I32);
6114 assign(op1, get_gpr_w1(r1));
6115 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6116 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
6118 return "chy";
6121 static const HChar *
6122 s390_irgen_CGH(UChar r1, IRTemp op2addr)
6124 IRTemp op1 = newTemp(Ity_I64);
6125 IRTemp op2 = newTemp(Ity_I64);
6127 assign(op1, get_gpr_dw0(r1));
6128 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6129 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
6131 return "cgh";
6134 static const HChar *
6135 s390_irgen_CHI(UChar r1, UShort i2)
6137 IRTemp op1 = newTemp(Ity_I32);
6138 Int op2;
6140 assign(op1, get_gpr_w1(r1));
6141 op2 = (Int)(Short)i2;
6142 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
6143 mkU32((UInt)op2)));
6145 return "chi";
6148 static const HChar *
6149 s390_irgen_CGHI(UChar r1, UShort i2)
6151 IRTemp op1 = newTemp(Ity_I64);
6152 Long op2;
6154 assign(op1, get_gpr_dw0(r1));
6155 op2 = (Long)(Short)i2;
6156 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
6157 mkU64((ULong)op2)));
6159 return "cghi";
6162 static const HChar *
6163 s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
6165 IRTemp op1 = newTemp(Ity_I16);
6166 Short op2;
6168 assign(op1, load(Ity_I16, mkexpr(op1addr)));
6169 op2 = (Short)i2;
6170 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
6171 mkU16((UShort)op2)));
6173 return "chhsi";
6176 static const HChar *
6177 s390_irgen_CHSI(UShort i2, IRTemp op1addr)
6179 IRTemp op1 = newTemp(Ity_I32);
6180 Int op2;
6182 assign(op1, load(Ity_I32, mkexpr(op1addr)));
6183 op2 = (Int)(Short)i2;
6184 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
6185 mkU32((UInt)op2)));
6187 return "chsi";
6190 static const HChar *
6191 s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
6193 IRTemp op1 = newTemp(Ity_I64);
6194 Long op2;
6196 assign(op1, load(Ity_I64, mkexpr(op1addr)));
6197 op2 = (Long)(Short)i2;
6198 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
6199 mkU64((ULong)op2)));
6201 return "cghsi";
6204 static const HChar *
6205 s390_irgen_CHRL(UChar r1, UInt i2)
6207 IRTemp op1 = newTemp(Ity_I32);
6208 IRTemp op2 = newTemp(Ity_I32);
6210 assign(op1, get_gpr_w1(r1));
6211 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(addr_rel_long(i2)))));
6212 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
6214 return "chrl";
6217 static const HChar *
6218 s390_irgen_CGHRL(UChar r1, UInt i2)
6220 IRTemp op1 = newTemp(Ity_I64);
6221 IRTemp op2 = newTemp(Ity_I64);
6223 assign(op1, get_gpr_dw0(r1));
6224 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(addr_rel_long(i2)))));
6225 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
6227 return "cghrl";
6230 static const HChar *
6231 s390_irgen_CHHR(UChar r1, UChar r2)
6233 IRTemp op1 = newTemp(Ity_I32);
6234 IRTemp op2 = newTemp(Ity_I32);
6236 assign(op1, get_gpr_w0(r1));
6237 assign(op2, get_gpr_w0(r2));
6238 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
6240 return "chhr";
6243 static const HChar *
6244 s390_irgen_CHLR(UChar r1, UChar r2)
6246 IRTemp op1 = newTemp(Ity_I32);
6247 IRTemp op2 = newTemp(Ity_I32);
6249 assign(op1, get_gpr_w0(r1));
6250 assign(op2, get_gpr_w1(r2));
6251 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
6253 return "chlr";
6256 static const HChar *
6257 s390_irgen_CHF(UChar r1, IRTemp op2addr)
6259 IRTemp op1 = newTemp(Ity_I32);
6260 IRTemp op2 = newTemp(Ity_I32);
6262 assign(op1, get_gpr_w0(r1));
6263 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6264 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
6266 return "chf";
6269 static const HChar *
6270 s390_irgen_CIH(UChar r1, UInt i2)
6272 IRTemp op1 = newTemp(Ity_I32);
6273 Int op2;
6275 assign(op1, get_gpr_w0(r1));
6276 op2 = (Int)i2;
6277 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
6278 mkU32((UInt)op2)));
6280 return "cih";
6283 static const HChar *
6284 s390_irgen_CLR(UChar r1, UChar r2)
6286 IRTemp op1 = newTemp(Ity_I32);
6287 IRTemp op2 = newTemp(Ity_I32);
6289 assign(op1, get_gpr_w1(r1));
6290 assign(op2, get_gpr_w1(r2));
6291 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6293 return "clr";
6296 static const HChar *
6297 s390_irgen_CLGR(UChar r1, UChar r2)
6299 IRTemp op1 = newTemp(Ity_I64);
6300 IRTemp op2 = newTemp(Ity_I64);
6302 assign(op1, get_gpr_dw0(r1));
6303 assign(op2, get_gpr_dw0(r2));
6304 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6306 return "clgr";
6309 static const HChar *
6310 s390_irgen_CLGFR(UChar r1, UChar r2)
6312 IRTemp op1 = newTemp(Ity_I64);
6313 IRTemp op2 = newTemp(Ity_I64);
6315 assign(op1, get_gpr_dw0(r1));
6316 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
6317 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6319 return "clgfr";
6322 static const HChar *
6323 s390_irgen_CL(UChar r1, IRTemp op2addr)
6325 IRTemp op1 = newTemp(Ity_I32);
6326 IRTemp op2 = newTemp(Ity_I32);
6328 assign(op1, get_gpr_w1(r1));
6329 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6330 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6332 return "cl";
6335 static const HChar *
6336 s390_irgen_CLY(UChar r1, IRTemp op2addr)
6338 IRTemp op1 = newTemp(Ity_I32);
6339 IRTemp op2 = newTemp(Ity_I32);
6341 assign(op1, get_gpr_w1(r1));
6342 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6343 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6345 return "cly";
6348 static const HChar *
6349 s390_irgen_CLG(UChar r1, IRTemp op2addr)
6351 IRTemp op1 = newTemp(Ity_I64);
6352 IRTemp op2 = newTemp(Ity_I64);
6354 assign(op1, get_gpr_dw0(r1));
6355 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6356 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6358 return "clg";
6361 static const HChar *
6362 s390_irgen_CLGF(UChar r1, IRTemp op2addr)
6364 IRTemp op1 = newTemp(Ity_I64);
6365 IRTemp op2 = newTemp(Ity_I64);
6367 assign(op1, get_gpr_dw0(r1));
6368 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6369 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6371 return "clgf";
6374 static const HChar *
6375 s390_irgen_CLFI(UChar r1, UInt i2)
6377 IRTemp op1 = newTemp(Ity_I32);
6378 UInt op2;
6380 assign(op1, get_gpr_w1(r1));
6381 op2 = i2;
6382 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
6383 mkU32(op2)));
6385 return "clfi";
6388 static const HChar *
6389 s390_irgen_CLGFI(UChar r1, UInt i2)
6391 IRTemp op1 = newTemp(Ity_I64);
6392 ULong op2;
6394 assign(op1, get_gpr_dw0(r1));
6395 op2 = (ULong)i2;
6396 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
6397 mkU64(op2)));
6399 return "clgfi";
6402 static const HChar *
6403 s390_irgen_CLI(UChar i2, IRTemp op1addr)
6405 IRTemp op1 = newTemp(Ity_I8);
6406 UChar op2;
6408 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6409 op2 = i2;
6410 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
6411 mkU8(op2)));
6413 return "cli";
6416 static const HChar *
6417 s390_irgen_CLIY(UChar i2, IRTemp op1addr)
6419 IRTemp op1 = newTemp(Ity_I8);
6420 UChar op2;
6422 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6423 op2 = i2;
6424 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
6425 mkU8(op2)));
6427 return "cliy";
6430 static const HChar *
6431 s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
6433 IRTemp op1 = newTemp(Ity_I32);
6434 UInt op2;
6436 assign(op1, load(Ity_I32, mkexpr(op1addr)));
6437 op2 = (UInt)i2;
6438 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
6439 mkU32(op2)));
6441 return "clfhsi";
6444 static const HChar *
6445 s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
6447 IRTemp op1 = newTemp(Ity_I64);
6448 ULong op2;
6450 assign(op1, load(Ity_I64, mkexpr(op1addr)));
6451 op2 = (ULong)i2;
6452 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
6453 mkU64(op2)));
6455 return "clghsi";
6458 static const HChar *
6459 s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
6461 IRTemp op1 = newTemp(Ity_I16);
6462 UShort op2;
6464 assign(op1, load(Ity_I16, mkexpr(op1addr)));
6465 op2 = i2;
6466 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
6467 mkU16(op2)));
6469 return "clhhsi";
6472 static const HChar *
6473 s390_irgen_CLRL(UChar r1, UInt i2)
6475 IRTemp op1 = newTemp(Ity_I32);
6476 IRTemp op2 = newTemp(Ity_I32);
6478 assign(op1, get_gpr_w1(r1));
6479 assign(op2, load(Ity_I32, mkU64(addr_rel_long(i2))));
6480 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6482 return "clrl";
6485 static const HChar *
6486 s390_irgen_CLGRL(UChar r1, UInt i2)
6488 IRTemp op1 = newTemp(Ity_I64);
6489 IRTemp op2 = newTemp(Ity_I64);
6491 assign(op1, get_gpr_dw0(r1));
6492 assign(op2, load(Ity_I64, mkU64(addr_rel_long(i2))));
6493 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6495 return "clgrl";
6498 static const HChar *
6499 s390_irgen_CLGFRL(UChar r1, UInt i2)
6501 IRTemp op1 = newTemp(Ity_I64);
6502 IRTemp op2 = newTemp(Ity_I64);
6504 assign(op1, get_gpr_dw0(r1));
6505 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(addr_rel_long(i2)))));
6506 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6508 return "clgfrl";
6511 static const HChar *
6512 s390_irgen_CLHRL(UChar r1, UInt i2)
6514 IRTemp op1 = newTemp(Ity_I32);
6515 IRTemp op2 = newTemp(Ity_I32);
6517 assign(op1, get_gpr_w1(r1));
6518 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(addr_rel_long(i2)))));
6519 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6521 return "clhrl";
6524 static const HChar *
6525 s390_irgen_CLGHRL(UChar r1, UInt i2)
6527 IRTemp op1 = newTemp(Ity_I64);
6528 IRTemp op2 = newTemp(Ity_I64);
6530 assign(op1, get_gpr_dw0(r1));
6531 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(addr_rel_long(i2)))));
6532 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
6534 return "clghrl";
6537 static const HChar *
6538 s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
6540 IRTemp op1 = newTemp(Ity_I32);
6541 IRTemp op2 = newTemp(Ity_I32);
6542 IRTemp cond = newTemp(Ity_I32);
6544 if (m3 == 0) {
6545 } else {
6546 if (m3 == 14) {
6547 always_goto(mkexpr(op4addr));
6548 } else {
6549 assign(op1, get_gpr_w1(r1));
6550 assign(op2, get_gpr_w1(r2));
6551 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
6552 op1, op2));
6553 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6554 mkexpr(op4addr));
6558 return "clrb";
6561 static const HChar *
6562 s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
6564 IRTemp op1 = newTemp(Ity_I64);
6565 IRTemp op2 = newTemp(Ity_I64);
6566 IRTemp cond = newTemp(Ity_I32);
6568 if (m3 == 0) {
6569 } else {
6570 if (m3 == 14) {
6571 always_goto(mkexpr(op4addr));
6572 } else {
6573 assign(op1, get_gpr_dw0(r1));
6574 assign(op2, get_gpr_dw0(r2));
6575 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
6576 op1, op2));
6577 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6578 mkexpr(op4addr));
6582 return "clgrb";
6585 /* Raise the appropriate signal for a compare-and-trap-instruction data
6586 exception if the condition is true. */
6587 static void
6588 s390_trap_on_condition(IRExpr *cond)
6590 stmt(IRStmt_Exit(cond, Ijk_SigFPE, IRConst_U64(guest_IA_next_instr),
6591 S390X_GUEST_OFFSET(guest_IA)));
6594 /* Handle the various flavors of compare (logical) and trap. */
6595 static void
6596 s390_irgen_CxRT(UChar m3, UChar r1, UChar r2, IRType type, UInt opc)
6598 IRExpr *cond;
6600 if (m3 == 0) {
6601 /* Trap never (NOP) */
6602 return;
6603 } else if (m3 == 14) {
6604 /* Trap always */
6605 cond = IRExpr_Const(IRConst_U1 (True));
6606 } else {
6607 IRTemp op1 = newTemp(type);
6608 IRTemp op2 = newTemp(type);
6610 assign(op1, get_gpr_int(r1, type));
6611 assign(op2, get_gpr_int(r2, type));
6612 cond = binop(Iop_CmpNE32,
6613 s390_call_calculate_icc(m3, opc, op1, op2), mkU32(0));
6615 s390_trap_on_condition(cond);
6618 static const HChar *
6619 s390_irgen_CGRT(UChar m3, UChar r1, UChar r2)
6621 s390_irgen_CxRT(m3, r1, r2, Ity_I64, S390_CC_OP_SIGNED_COMPARE);
6622 return "cgrt";
6625 static const HChar *
6626 s390_irgen_CRT(UChar m3, UChar r1, UChar r2)
6628 s390_irgen_CxRT(m3, r1, r2, Ity_I32, S390_CC_OP_SIGNED_COMPARE);
6629 return "crt";
6632 static const HChar *
6633 s390_irgen_CLGRT(UChar m3, UChar r1, UChar r2)
6635 s390_irgen_CxRT(m3, r1, r2, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE);
6636 return "clgrt";
6639 static const HChar *
6640 s390_irgen_CLRT(UChar m3, UChar r1, UChar r2)
6642 s390_irgen_CxRT(m3, r1, r2, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE);
6643 return "clrt";
6646 /* Handle the various flavors of compare (logical) immediate and trap. */
6647 static void
6648 s390_irgen_CxIT(UChar m3, UChar r1, UShort i2, IRType type, UInt opc)
6650 IRExpr *cond;
6652 if (m3 == 0) {
6653 /* Trap never (NOP) */
6654 return;
6655 } else if (m3 == 14) {
6656 /* Trap always */
6657 cond = IRExpr_Const(IRConst_U1 (True));
6658 } else {
6659 IRTemp op1 = newTemp(type);
6660 IRTemp op2 = newTemp(type);
6662 assign(op1, get_gpr_int(r1, type));
6663 if (opc == S390_CC_OP_SIGNED_COMPARE) {
6664 assign(op2, type == Ity_I64 ?
6665 mkU64((ULong)(Short)i2) : mkU32((UInt)(Short)i2));
6666 } else {
6667 assign(op2, type == Ity_I64 ?
6668 mkU64((ULong)i2) : mkU32((UInt)i2));
6670 cond = binop(Iop_CmpNE32,
6671 s390_call_calculate_icc(m3, opc, op1, op2), mkU32(0));
6673 s390_trap_on_condition(cond);
6676 static const HChar *
6677 s390_irgen_CGIT(UChar r1, UShort i2, UChar m3)
6679 s390_irgen_CxIT(m3, r1, i2, Ity_I64, S390_CC_OP_SIGNED_COMPARE);
6680 return "cgit";
6683 static const HChar *
6684 s390_irgen_CIT(UChar r1, UShort i2, UChar m3)
6686 s390_irgen_CxIT(m3, r1, i2, Ity_I32, S390_CC_OP_SIGNED_COMPARE);
6687 return "cit";
6690 static const HChar *
6691 s390_irgen_CLGIT(UChar r1, UShort i2, UChar m3)
6693 s390_irgen_CxIT(m3, r1, i2, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE);
6694 return "clgit";
6697 static const HChar *
6698 s390_irgen_CLFIT(UChar r1, UShort i2, UChar m3)
6700 s390_irgen_CxIT(m3, r1, i2, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE);
6701 return "clfit";
6704 /* Handle the variants of compare logical and trap with memory operand. */
6705 static void
6706 s390_irgen_CLxT(UChar r1, UChar m3, IRTemp op2addr, IRType type, UInt opc)
6708 IRExpr *cond;
6710 if (m3 == 0) {
6711 /* Trap never (NOP) */
6712 return;
6713 } else if (m3 == 14) {
6714 /* Trap always */
6715 cond = IRExpr_Const(IRConst_U1 (True));
6716 } else {
6717 IRTemp op1 = newTemp(type);
6718 IRTemp op2 = newTemp(type);
6720 assign(op1, get_gpr_int(r1, type));
6721 assign(op2, load(type, mkexpr(op2addr)));
6722 cond = binop(Iop_CmpNE32,
6723 s390_call_calculate_icc(m3, opc, op1, op2), mkU32(0));
6725 s390_trap_on_condition(cond);
6728 static const HChar *
6729 s390_irgen_CLT(UChar r1, UChar m3, IRTemp op2addr)
6731 s390_irgen_CLxT(r1, m3, op2addr, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE);
6732 return "clt";
6735 static const HChar *
6736 s390_irgen_CLGT(UChar r1, UChar m3, IRTemp op2addr)
6738 s390_irgen_CLxT(r1, m3, op2addr, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE);
6739 return "clgt";
6742 static const HChar *
6743 s390_irgen_LAT(UChar r1, IRTemp op2addr)
6745 IRTemp val = newTemp(Ity_I32);
6746 assign(val, load(Ity_I32, mkexpr(op2addr)));
6747 put_gpr_w1(r1, mkexpr(val));
6748 s390_trap_on_condition(binop(Iop_CmpEQ32, mkexpr(val), mkU32(0)));
6749 return "lat";
6752 static const HChar *
6753 s390_irgen_LGAT(UChar r1, IRTemp op2addr)
6755 IRTemp val = newTemp(Ity_I64);
6756 assign(val, load(Ity_I64, mkexpr(op2addr)));
6757 put_gpr_dw0(r1, mkexpr(val));
6758 s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0)));
6759 return "lgat";
6762 static const HChar *
6763 s390_irgen_LFHAT(UChar r1, IRTemp op2addr)
6765 IRTemp val = newTemp(Ity_I32);
6766 assign(val, load(Ity_I32, mkexpr(op2addr)));
6767 put_gpr_w0(r1, mkexpr(val));
6768 s390_trap_on_condition(binop(Iop_CmpEQ32, mkexpr(val), mkU32(0)));
6769 return "lfhat";
6772 static const HChar *
6773 s390_irgen_LLGFAT(UChar r1, IRTemp op2addr)
6775 IRTemp val = newTemp(Ity_I64);
6776 assign(val, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6777 put_gpr_dw0(r1, mkexpr(val));
6778 s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0)));
6779 return "llgfat";
6782 static const HChar *
6783 s390_irgen_LLGTAT(UChar r1, IRTemp op2addr)
6785 IRTemp val = newTemp(Ity_I64);
6786 assign(val, binop(Iop_And64, mkU64(0x7fffffff),
6787 unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr)))));
6788 put_gpr_dw0(r1, mkexpr(val));
6789 s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0)));
6790 return "llgtat";
6793 static const HChar *
6794 s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
6796 IRTemp op1 = newTemp(Ity_I32);
6797 IRTemp op2 = newTemp(Ity_I32);
6798 IRTemp cond = newTemp(Ity_I32);
6800 if (m3 == 0) {
6801 } else {
6802 if (m3 == 14) {
6803 always_goto_and_chase(addr_relative(i4));
6804 } else {
6805 assign(op1, get_gpr_w1(r1));
6806 assign(op2, get_gpr_w1(r2));
6807 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
6808 op1, op2));
6809 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6810 addr_relative(i4));
6815 return "clrj";
6818 static const HChar *
6819 s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
6821 IRTemp op1 = newTemp(Ity_I64);
6822 IRTemp op2 = newTemp(Ity_I64);
6823 IRTemp cond = newTemp(Ity_I32);
6825 if (m3 == 0) {
6826 } else {
6827 if (m3 == 14) {
6828 always_goto_and_chase(addr_relative(i4));
6829 } else {
6830 assign(op1, get_gpr_dw0(r1));
6831 assign(op2, get_gpr_dw0(r2));
6832 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
6833 op1, op2));
6834 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6835 addr_relative(i4));
6840 return "clgrj";
6843 static const HChar *
6844 s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
6846 IRTemp op1 = newTemp(Ity_I32);
6847 UInt op2;
6848 IRTemp cond = newTemp(Ity_I32);
6850 if (m3 == 0) {
6851 } else {
6852 if (m3 == 14) {
6853 always_goto(mkexpr(op4addr));
6854 } else {
6855 assign(op1, get_gpr_w1(r1));
6856 op2 = (UInt)i2;
6857 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
6858 mktemp(Ity_I32, mkU32(op2))));
6859 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6860 mkexpr(op4addr));
6864 return "clib";
6867 static const HChar *
6868 s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
6870 IRTemp op1 = newTemp(Ity_I64);
6871 ULong op2;
6872 IRTemp cond = newTemp(Ity_I32);
6874 if (m3 == 0) {
6875 } else {
6876 if (m3 == 14) {
6877 always_goto(mkexpr(op4addr));
6878 } else {
6879 assign(op1, get_gpr_dw0(r1));
6880 op2 = (ULong)i2;
6881 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
6882 mktemp(Ity_I64, mkU64(op2))));
6883 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6884 mkexpr(op4addr));
6888 return "clgib";
6891 static const HChar *
6892 s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
6894 IRTemp op1 = newTemp(Ity_I32);
6895 UInt op2;
6896 IRTemp cond = newTemp(Ity_I32);
6898 if (m3 == 0) {
6899 } else {
6900 if (m3 == 14) {
6901 always_goto_and_chase(addr_relative(i4));
6902 } else {
6903 assign(op1, get_gpr_w1(r1));
6904 op2 = (UInt)i2;
6905 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
6906 mktemp(Ity_I32, mkU32(op2))));
6907 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6908 addr_relative(i4));
6913 return "clij";
6916 static const HChar *
6917 s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
6919 IRTemp op1 = newTemp(Ity_I64);
6920 ULong op2;
6921 IRTemp cond = newTemp(Ity_I32);
6923 if (m3 == 0) {
6924 } else {
6925 if (m3 == 14) {
6926 always_goto_and_chase(addr_relative(i4));
6927 } else {
6928 assign(op1, get_gpr_dw0(r1));
6929 op2 = (ULong)i2;
6930 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
6931 mktemp(Ity_I64, mkU64(op2))));
6932 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
6933 addr_relative(i4));
6938 return "clgij";
6941 static const HChar *
6942 s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
6944 IRTemp op1 = newTemp(Ity_I32);
6945 IRTemp op2 = newTemp(Ity_I32);
6946 IRTemp b0 = newTemp(Ity_I32);
6947 IRTemp b1 = newTemp(Ity_I32);
6948 IRTemp b2 = newTemp(Ity_I32);
6949 IRTemp b3 = newTemp(Ity_I32);
6950 IRTemp c0 = newTemp(Ity_I32);
6951 IRTemp c1 = newTemp(Ity_I32);
6952 IRTemp c2 = newTemp(Ity_I32);
6953 IRTemp c3 = newTemp(Ity_I32);
6954 UChar n;
6956 n = 0;
6957 if ((r3 & 8) != 0) {
6958 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
6959 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6960 n = n + 1;
6961 } else {
6962 assign(b0, mkU32(0));
6963 assign(c0, mkU32(0));
6965 if ((r3 & 4) != 0) {
6966 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
6967 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6968 mkU64(n)))));
6969 n = n + 1;
6970 } else {
6971 assign(b1, mkU32(0));
6972 assign(c1, mkU32(0));
6974 if ((r3 & 2) != 0) {
6975 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
6976 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6977 mkU64(n)))));
6978 n = n + 1;
6979 } else {
6980 assign(b2, mkU32(0));
6981 assign(c2, mkU32(0));
6983 if ((r3 & 1) != 0) {
6984 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
6985 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
6986 mkU64(n)))));
6987 n = n + 1;
6988 } else {
6989 assign(b3, mkU32(0));
6990 assign(c3, mkU32(0));
6992 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6993 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
6994 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
6995 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
6996 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
6997 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
6998 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
7000 return "clm";
7003 static const HChar *
7004 s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
7006 IRTemp op1 = newTemp(Ity_I32);
7007 IRTemp op2 = newTemp(Ity_I32);
7008 IRTemp b0 = newTemp(Ity_I32);
7009 IRTemp b1 = newTemp(Ity_I32);
7010 IRTemp b2 = newTemp(Ity_I32);
7011 IRTemp b3 = newTemp(Ity_I32);
7012 IRTemp c0 = newTemp(Ity_I32);
7013 IRTemp c1 = newTemp(Ity_I32);
7014 IRTemp c2 = newTemp(Ity_I32);
7015 IRTemp c3 = newTemp(Ity_I32);
7016 UChar n;
7018 n = 0;
7019 if ((r3 & 8) != 0) {
7020 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
7021 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
7022 n = n + 1;
7023 } else {
7024 assign(b0, mkU32(0));
7025 assign(c0, mkU32(0));
7027 if ((r3 & 4) != 0) {
7028 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
7029 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
7030 mkU64(n)))));
7031 n = n + 1;
7032 } else {
7033 assign(b1, mkU32(0));
7034 assign(c1, mkU32(0));
7036 if ((r3 & 2) != 0) {
7037 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
7038 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
7039 mkU64(n)))));
7040 n = n + 1;
7041 } else {
7042 assign(b2, mkU32(0));
7043 assign(c2, mkU32(0));
7045 if ((r3 & 1) != 0) {
7046 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
7047 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
7048 mkU64(n)))));
7049 n = n + 1;
7050 } else {
7051 assign(b3, mkU32(0));
7052 assign(c3, mkU32(0));
7054 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
7055 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
7056 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
7057 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
7058 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
7059 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
7060 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
7062 return "clmy";
7065 static const HChar *
7066 s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
7068 IRTemp op1 = newTemp(Ity_I32);
7069 IRTemp op2 = newTemp(Ity_I32);
7070 IRTemp b0 = newTemp(Ity_I32);
7071 IRTemp b1 = newTemp(Ity_I32);
7072 IRTemp b2 = newTemp(Ity_I32);
7073 IRTemp b3 = newTemp(Ity_I32);
7074 IRTemp c0 = newTemp(Ity_I32);
7075 IRTemp c1 = newTemp(Ity_I32);
7076 IRTemp c2 = newTemp(Ity_I32);
7077 IRTemp c3 = newTemp(Ity_I32);
7078 UChar n;
7080 n = 0;
7081 if ((r3 & 8) != 0) {
7082 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
7083 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
7084 n = n + 1;
7085 } else {
7086 assign(b0, mkU32(0));
7087 assign(c0, mkU32(0));
7089 if ((r3 & 4) != 0) {
7090 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
7091 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
7092 mkU64(n)))));
7093 n = n + 1;
7094 } else {
7095 assign(b1, mkU32(0));
7096 assign(c1, mkU32(0));
7098 if ((r3 & 2) != 0) {
7099 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
7100 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
7101 mkU64(n)))));
7102 n = n + 1;
7103 } else {
7104 assign(b2, mkU32(0));
7105 assign(c2, mkU32(0));
7107 if ((r3 & 1) != 0) {
7108 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
7109 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
7110 mkU64(n)))));
7111 n = n + 1;
7112 } else {
7113 assign(b3, mkU32(0));
7114 assign(c3, mkU32(0));
7116 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
7117 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
7118 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
7119 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
7120 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
7121 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
7122 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
7124 return "clmh";
7127 static const HChar *
7128 s390_irgen_CLHHR(UChar r1, UChar r2)
7130 IRTemp op1 = newTemp(Ity_I32);
7131 IRTemp op2 = newTemp(Ity_I32);
7133 assign(op1, get_gpr_w0(r1));
7134 assign(op2, get_gpr_w0(r2));
7135 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
7137 return "clhhr";
7140 static const HChar *
7141 s390_irgen_CLHLR(UChar r1, UChar r2)
7143 IRTemp op1 = newTemp(Ity_I32);
7144 IRTemp op2 = newTemp(Ity_I32);
7146 assign(op1, get_gpr_w0(r1));
7147 assign(op2, get_gpr_w1(r2));
7148 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
7150 return "clhlr";
7153 static const HChar *
7154 s390_irgen_CLHF(UChar r1, IRTemp op2addr)
7156 IRTemp op1 = newTemp(Ity_I32);
7157 IRTemp op2 = newTemp(Ity_I32);
7159 assign(op1, get_gpr_w0(r1));
7160 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7161 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
7163 return "clhf";
7166 static const HChar *
7167 s390_irgen_CLIH(UChar r1, UInt i2)
7169 IRTemp op1 = newTemp(Ity_I32);
7170 UInt op2;
7172 assign(op1, get_gpr_w0(r1));
7173 op2 = i2;
7174 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
7175 mkU32(op2)));
7177 return "clih";
7180 static const HChar *
7181 s390_irgen_CPYA(UChar r1, UChar r2)
7183 put_ar_w0(r1, get_ar_w0(r2));
7184 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
7185 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
7187 return "cpya";
7190 static const HChar *
7191 s390_irgen_XR(UChar r1, UChar r2)
7193 IRTemp op1 = newTemp(Ity_I32);
7194 IRTemp op2 = newTemp(Ity_I32);
7195 IRTemp result = newTemp(Ity_I32);
7197 if (r1 == r2) {
7198 assign(result, mkU32(0));
7199 } else {
7200 assign(op1, get_gpr_w1(r1));
7201 assign(op2, get_gpr_w1(r2));
7202 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
7204 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7205 put_gpr_w1(r1, mkexpr(result));
7207 return "xr";
7210 static const HChar *
7211 s390_irgen_XGR(UChar r1, UChar r2)
7213 IRTemp op1 = newTemp(Ity_I64);
7214 IRTemp op2 = newTemp(Ity_I64);
7215 IRTemp result = newTemp(Ity_I64);
7217 if (r1 == r2) {
7218 assign(result, mkU64(0));
7219 } else {
7220 assign(op1, get_gpr_dw0(r1));
7221 assign(op2, get_gpr_dw0(r2));
7222 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
7224 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7225 put_gpr_dw0(r1, mkexpr(result));
7227 return "xgr";
7230 static const HChar *
7231 s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
7233 return s390_irgen_logicalK32(r3, r1, r2, "xrk", Iop_Xor32, False, False);
7236 static const HChar *
7237 s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
7239 return s390_irgen_logicalK64(r3, r1, r2, "xgrk", Iop_Xor64, False, False);
7242 static const HChar *
7243 s390_irgen_NXRK(UChar r3, UChar r1, UChar r2)
7245 return s390_irgen_logicalK32(r3, r1, r2, "nxrk", Iop_Xor32, False, True);
7248 static const HChar *
7249 s390_irgen_NXGRK(UChar r3, UChar r1, UChar r2)
7251 return s390_irgen_logicalK64(r3, r1, r2, "nxgrk", Iop_Xor64, False, True);
7254 static const HChar *
7255 s390_irgen_X(UChar r1, IRTemp op2addr)
7257 IRTemp op1 = newTemp(Ity_I32);
7258 IRTemp op2 = newTemp(Ity_I32);
7259 IRTemp result = newTemp(Ity_I32);
7261 assign(op1, get_gpr_w1(r1));
7262 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7263 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
7264 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7265 put_gpr_w1(r1, mkexpr(result));
7267 return "x";
7270 static const HChar *
7271 s390_irgen_XY(UChar r1, IRTemp op2addr)
7273 IRTemp op1 = newTemp(Ity_I32);
7274 IRTemp op2 = newTemp(Ity_I32);
7275 IRTemp result = newTemp(Ity_I32);
7277 assign(op1, get_gpr_w1(r1));
7278 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7279 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
7280 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7281 put_gpr_w1(r1, mkexpr(result));
7283 return "xy";
7286 static const HChar *
7287 s390_irgen_XG(UChar r1, IRTemp op2addr)
7289 IRTemp op1 = newTemp(Ity_I64);
7290 IRTemp op2 = newTemp(Ity_I64);
7291 IRTemp result = newTemp(Ity_I64);
7293 assign(op1, get_gpr_dw0(r1));
7294 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7295 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
7296 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7297 put_gpr_dw0(r1, mkexpr(result));
7299 return "xg";
7302 static const HChar *
7303 s390_irgen_XI(UChar i2, IRTemp op1addr)
7305 IRTemp op1 = newTemp(Ity_I8);
7306 UChar op2;
7307 IRTemp result = newTemp(Ity_I8);
7309 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7310 op2 = i2;
7311 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
7312 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7313 store(mkexpr(op1addr), mkexpr(result));
7315 return "xi";
7318 static const HChar *
7319 s390_irgen_XIY(UChar i2, IRTemp op1addr)
7321 IRTemp op1 = newTemp(Ity_I8);
7322 UChar op2;
7323 IRTemp result = newTemp(Ity_I8);
7325 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7326 op2 = i2;
7327 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
7328 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7329 store(mkexpr(op1addr), mkexpr(result));
7331 return "xiy";
7334 static const HChar *
7335 s390_irgen_XIHF(UChar r1, UInt i2)
7337 IRTemp op1 = newTemp(Ity_I32);
7338 UInt op2;
7339 IRTemp result = newTemp(Ity_I32);
7341 assign(op1, get_gpr_w0(r1));
7342 op2 = i2;
7343 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
7344 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7345 put_gpr_w0(r1, mkexpr(result));
7347 return "xihf";
7350 static const HChar *
7351 s390_irgen_XILF(UChar r1, UInt i2)
7353 IRTemp op1 = newTemp(Ity_I32);
7354 UInt op2;
7355 IRTemp result = newTemp(Ity_I32);
7357 assign(op1, get_gpr_w1(r1));
7358 op2 = i2;
7359 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
7360 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7361 put_gpr_w1(r1, mkexpr(result));
7363 return "xilf";
7366 static const HChar *
7367 s390_irgen_EAR(UChar r1, UChar r2)
7369 put_gpr_w1(r1, get_ar_w0(r2));
7370 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
7371 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
7373 return "ear";
7376 static const HChar *
7377 s390_irgen_IC(UChar r1, IRTemp op2addr)
7379 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
7381 return "ic";
7384 static const HChar *
7385 s390_irgen_ICY(UChar r1, IRTemp op2addr)
7387 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
7389 return "icy";
7392 static const HChar *
7393 s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
7395 UChar n;
7396 IRTemp result = newTemp(Ity_I32);
7397 UInt mask;
7399 n = 0;
7400 mask = (UInt)r3;
7401 if ((mask & 8) != 0) {
7402 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
7403 n = n + 1;
7405 if ((mask & 4) != 0) {
7406 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7408 n = n + 1;
7410 if ((mask & 2) != 0) {
7411 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7413 n = n + 1;
7415 if ((mask & 1) != 0) {
7416 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7418 n = n + 1;
7420 assign(result, get_gpr_w1(r1));
7421 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
7422 mkU32(mask)));
7424 return "icm";
7427 static const HChar *
7428 s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
7430 UChar n;
7431 IRTemp result = newTemp(Ity_I32);
7432 UInt mask;
7434 n = 0;
7435 mask = (UInt)r3;
7436 if ((mask & 8) != 0) {
7437 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
7438 n = n + 1;
7440 if ((mask & 4) != 0) {
7441 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7443 n = n + 1;
7445 if ((mask & 2) != 0) {
7446 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7448 n = n + 1;
7450 if ((mask & 1) != 0) {
7451 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7453 n = n + 1;
7455 assign(result, get_gpr_w1(r1));
7456 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
7457 mkU32(mask)));
7459 return "icmy";
7462 static const HChar *
7463 s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
7465 UChar n;
7466 IRTemp result = newTemp(Ity_I32);
7467 UInt mask;
7469 n = 0;
7470 mask = (UInt)r3;
7471 if ((mask & 8) != 0) {
7472 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
7473 n = n + 1;
7475 if ((mask & 4) != 0) {
7476 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7478 n = n + 1;
7480 if ((mask & 2) != 0) {
7481 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7483 n = n + 1;
7485 if ((mask & 1) != 0) {
7486 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
7488 n = n + 1;
7490 assign(result, get_gpr_w0(r1));
7491 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
7492 mkU32(mask)));
7494 return "icmh";
7497 static const HChar *
7498 s390_irgen_IIHF(UChar r1, UInt i2)
7500 put_gpr_w0(r1, mkU32(i2));
7502 return "iihf";
7505 static const HChar *
7506 s390_irgen_IIHH(UChar r1, UShort i2)
7508 put_gpr_hw0(r1, mkU16(i2));
7510 return "iihh";
7513 static const HChar *
7514 s390_irgen_IIHL(UChar r1, UShort i2)
7516 put_gpr_hw1(r1, mkU16(i2));
7518 return "iihl";
7521 static const HChar *
7522 s390_irgen_IILF(UChar r1, UInt i2)
7524 put_gpr_w1(r1, mkU32(i2));
7526 return "iilf";
7529 static const HChar *
7530 s390_irgen_IILH(UChar r1, UShort i2)
7532 put_gpr_hw2(r1, mkU16(i2));
7534 return "iilh";
7537 static const HChar *
7538 s390_irgen_IILL(UChar r1, UShort i2)
7540 put_gpr_hw3(r1, mkU16(i2));
7542 return "iill";
7545 static const HChar *
7546 s390_irgen_LR(UChar r1, UChar r2)
7548 put_gpr_w1(r1, get_gpr_w1(r2));
7550 return "lr";
7553 static const HChar *
7554 s390_irgen_LGR(UChar r1, UChar r2)
7556 put_gpr_dw0(r1, get_gpr_dw0(r2));
7558 return "lgr";
7561 static const HChar *
7562 s390_irgen_LGFR(UChar r1, UChar r2)
7564 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
7566 return "lgfr";
7569 static const HChar *
7570 s390_irgen_L(UChar r1, IRTemp op2addr)
7572 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
7574 return "l";
7577 static const HChar *
7578 s390_irgen_LY(UChar r1, IRTemp op2addr)
7580 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
7582 return "ly";
7585 static const HChar *
7586 s390_irgen_LG(UChar r1, IRTemp op2addr)
7588 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
7590 return "lg";
7593 static const HChar *
7594 s390_irgen_LGF(UChar r1, IRTemp op2addr)
7596 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7598 return "lgf";
7601 static const HChar *
7602 s390_irgen_LGFI(UChar r1, UInt i2)
7604 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
7606 return "lgfi";
7609 static const HChar *
7610 s390_irgen_LRL(UChar r1, UInt i2)
7612 put_gpr_w1(r1, load(Ity_I32, mkU64(addr_rel_long(i2))));
7614 return "lrl";
7617 static const HChar *
7618 s390_irgen_LGRL(UChar r1, UInt i2)
7620 put_gpr_dw0(r1, load(Ity_I64, mkU64(addr_rel_long(i2))));
7622 return "lgrl";
7625 static const HChar *
7626 s390_irgen_LGFRL(UChar r1, UInt i2)
7628 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(addr_rel_long(i2)))));
7630 return "lgfrl";
7633 static const HChar *
7634 s390_irgen_LA(UChar r1, IRTemp op2addr)
7636 put_gpr_dw0(r1, mkexpr(op2addr));
7638 return "la";
7641 static const HChar *
7642 s390_irgen_LAY(UChar r1, IRTemp op2addr)
7644 put_gpr_dw0(r1, mkexpr(op2addr));
7646 return "lay";
7649 static const HChar *
7650 s390_irgen_LAE(UChar r1, IRTemp op2addr)
7652 put_gpr_dw0(r1, mkexpr(op2addr));
7654 return "lae";
7657 static const HChar *
7658 s390_irgen_LAEY(UChar r1, IRTemp op2addr)
7660 put_gpr_dw0(r1, mkexpr(op2addr));
7662 return "laey";
7665 static const HChar *
7666 s390_irgen_LARL(UChar r1, UInt i2)
7668 put_gpr_dw0(r1, mkU64(addr_rel_long(i2)));
7670 return "larl";
7673 /* The IR representation of LAA and friends is an approximation of what
7674 happens natively. Essentially a loop containing a compare-and-swap is
7675 constructed which will iterate until the CAS succeeds. As a consequence,
7676 instrumenters may see more memory accesses than happen natively. See also
7677 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
7678 static void
7679 s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
7681 IRCAS *cas;
7682 IRTemp old_mem = newTemp(Ity_I32);
7683 IRTemp op2 = newTemp(Ity_I32);
7684 IRTemp op3 = newTemp(Ity_I32);
7685 IRTemp result = newTemp(Ity_I32);
7687 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7688 assign(op3, get_gpr_w1(r3));
7689 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
7691 /* Place the addition of second operand and third operand at the
7692 second-operand location everytime */
7693 cas = mkIRCAS(IRTemp_INVALID, old_mem,
7694 Iend_BE, mkexpr(op2addr),
7695 NULL, mkexpr(op2), /* expected value */
7696 NULL, mkexpr(result) /* new value */);
7697 stmt(IRStmt_CAS(cas));
7699 /* Set CC according to 32-bit addition */
7700 if (is_signed) {
7701 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
7702 } else {
7703 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
7706 /* If old_mem contains the expected value, then the CAS succeeded.
7707 Otherwise, it did not */
7708 yield_if(binop(Iop_CasCmpNE32, mkexpr(old_mem), mkexpr(op2)));
7709 put_gpr_w1(r1, mkexpr(old_mem));
7712 static void
7713 s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
7715 IRCAS *cas;
7716 IRTemp old_mem = newTemp(Ity_I64);
7717 IRTemp op2 = newTemp(Ity_I64);
7718 IRTemp op3 = newTemp(Ity_I64);
7719 IRTemp result = newTemp(Ity_I64);
7721 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7722 assign(op3, get_gpr_dw0(r3));
7723 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
7725 /* Place the addition of second operand and third operand at the
7726 second-operand location everytime */
7727 cas = mkIRCAS(IRTemp_INVALID, old_mem,
7728 Iend_BE, mkexpr(op2addr),
7729 NULL, mkexpr(op2), /* expected value */
7730 NULL, mkexpr(result) /* new value */);
7731 stmt(IRStmt_CAS(cas));
7733 /* Set CC according to 64-bit addition */
7734 if (is_signed) {
7735 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
7736 } else {
7737 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
7740 /* If old_mem contains the expected value, then the CAS succeeded.
7741 Otherwise, it did not */
7742 yield_if(binop(Iop_CasCmpNE64, mkexpr(old_mem), mkexpr(op2)));
7743 put_gpr_dw0(r1, mkexpr(old_mem));
7746 static void
7747 s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
7749 IRCAS *cas;
7750 IRTemp old_mem = newTemp(Ity_I32);
7751 IRTemp op2 = newTemp(Ity_I32);
7752 IRTemp op3 = newTemp(Ity_I32);
7753 IRTemp result = newTemp(Ity_I32);
7755 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7756 assign(op3, get_gpr_w1(r3));
7757 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
7759 /* Place the addition of second operand and third operand at the
7760 second-operand location everytime */
7761 cas = mkIRCAS(IRTemp_INVALID, old_mem,
7762 Iend_BE, mkexpr(op2addr),
7763 NULL, mkexpr(op2), /* expected value */
7764 NULL, mkexpr(result) /* new value */);
7765 stmt(IRStmt_CAS(cas));
7767 /* Set CC according to bitwise operation */
7768 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7770 /* If old_mem contains the expected value, then the CAS succeeded.
7771 Otherwise, it did not */
7772 yield_if(binop(Iop_CasCmpNE32, mkexpr(old_mem), mkexpr(op2)));
7773 put_gpr_w1(r1, mkexpr(old_mem));
7776 static void
7777 s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
7779 IRCAS *cas;
7780 IRTemp old_mem = newTemp(Ity_I64);
7781 IRTemp op2 = newTemp(Ity_I64);
7782 IRTemp op3 = newTemp(Ity_I64);
7783 IRTemp result = newTemp(Ity_I64);
7785 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7786 assign(op3, get_gpr_dw0(r3));
7787 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
7789 /* Place the addition of second operand and third operand at the
7790 second-operand location everytime */
7791 cas = mkIRCAS(IRTemp_INVALID, old_mem,
7792 Iend_BE, mkexpr(op2addr),
7793 NULL, mkexpr(op2), /* expected value */
7794 NULL, mkexpr(result) /* new value */);
7795 stmt(IRStmt_CAS(cas));
7797 /* Set CC according to bitwise operation */
7798 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7800 /* If old_mem contains the expected value, then the CAS succeeded.
7801 Otherwise, it did not */
7802 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
7803 put_gpr_dw0(r1, mkexpr(old_mem));
7806 static const HChar *
7807 s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
7809 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
7811 return "laa";
7814 static const HChar *
7815 s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
7817 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
7819 return "laag";
7822 static const HChar *
7823 s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
7825 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
7827 return "laal";
7830 static const HChar *
7831 s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
7833 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
7835 return "laalg";
7838 static const HChar *
7839 s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
7841 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
7843 return "lan";
7846 static const HChar *
7847 s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
7849 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
7851 return "lang";
7854 static const HChar *
7855 s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
7857 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
7859 return "lax";
7862 static const HChar *
7863 s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
7865 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
7867 return "laxg";
7870 static const HChar *
7871 s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
7873 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
7875 return "lao";
7878 static const HChar *
7879 s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
7881 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
7883 return "laog";
7886 static const HChar *
7887 s390_irgen_LTR(UChar r1, UChar r2)
7889 IRTemp op2 = newTemp(Ity_I32);
7891 assign(op2, get_gpr_w1(r2));
7892 put_gpr_w1(r1, mkexpr(op2));
7893 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7895 return "ltr";
7898 static const HChar *
7899 s390_irgen_LTGR(UChar r1, UChar r2)
7901 IRTemp op2 = newTemp(Ity_I64);
7903 assign(op2, get_gpr_dw0(r2));
7904 put_gpr_dw0(r1, mkexpr(op2));
7905 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7907 return "ltgr";
7910 static const HChar *
7911 s390_irgen_LTGFR(UChar r1, UChar r2)
7913 IRTemp op2 = newTemp(Ity_I64);
7915 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7916 put_gpr_dw0(r1, mkexpr(op2));
7917 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7919 return "ltgfr";
7922 static const HChar *
7923 s390_irgen_LT(UChar r1, IRTemp op2addr)
7925 IRTemp op2 = newTemp(Ity_I32);
7927 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7928 put_gpr_w1(r1, mkexpr(op2));
7929 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7931 return "lt";
7934 static const HChar *
7935 s390_irgen_LTG(UChar r1, IRTemp op2addr)
7937 IRTemp op2 = newTemp(Ity_I64);
7939 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7940 put_gpr_dw0(r1, mkexpr(op2));
7941 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7943 return "ltg";
7946 static const HChar *
7947 s390_irgen_LTGF(UChar r1, IRTemp op2addr)
7949 IRTemp op2 = newTemp(Ity_I64);
7951 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7952 put_gpr_dw0(r1, mkexpr(op2));
7953 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7955 return "ltgf";
7958 static const HChar *
7959 s390_irgen_LBR(UChar r1, UChar r2)
7961 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
7963 return "lbr";
7966 static const HChar *
7967 s390_irgen_LGBR(UChar r1, UChar r2)
7969 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
7971 return "lgbr";
7974 static const HChar *
7975 s390_irgen_LB(UChar r1, IRTemp op2addr)
7977 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
7979 return "lb";
7982 static const HChar *
7983 s390_irgen_LGB(UChar r1, IRTemp op2addr)
7985 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
7987 return "lgb";
7990 static const HChar *
7991 s390_irgen_LBH(UChar r1, IRTemp op2addr)
7993 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
7995 return "lbh";
7998 static const HChar *
7999 s390_irgen_LCR(UChar r1, UChar r2)
8001 Int op1;
8002 IRTemp op2 = newTemp(Ity_I32);
8003 IRTemp result = newTemp(Ity_I32);
8005 op1 = 0;
8006 assign(op2, get_gpr_w1(r2));
8007 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
8008 put_gpr_w1(r1, mkexpr(result));
8009 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
8010 op1)), op2);
8012 return "lcr";
8015 static const HChar *
8016 s390_irgen_LCGR(UChar r1, UChar r2)
8018 Long op1;
8019 IRTemp op2 = newTemp(Ity_I64);
8020 IRTemp result = newTemp(Ity_I64);
8022 op1 = 0ULL;
8023 assign(op2, get_gpr_dw0(r2));
8024 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
8025 put_gpr_dw0(r1, mkexpr(result));
8026 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
8027 op1)), op2);
8029 return "lcgr";
8032 static const HChar *
8033 s390_irgen_LCGFR(UChar r1, UChar r2)
8035 Long op1;
8036 IRTemp op2 = newTemp(Ity_I64);
8037 IRTemp result = newTemp(Ity_I64);
8039 op1 = 0ULL;
8040 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8041 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
8042 put_gpr_dw0(r1, mkexpr(result));
8043 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
8044 op1)), op2);
8046 return "lcgfr";
8049 static const HChar *
8050 s390_irgen_LHR(UChar r1, UChar r2)
8052 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
8054 return "lhr";
8057 static const HChar *
8058 s390_irgen_LGHR(UChar r1, UChar r2)
8060 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
8062 return "lghr";
8065 static const HChar *
8066 s390_irgen_LH(UChar r1, IRTemp op2addr)
8068 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8070 return "lh";
8073 static const HChar *
8074 s390_irgen_LHY(UChar r1, IRTemp op2addr)
8076 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8078 return "lhy";
8081 static const HChar *
8082 s390_irgen_LGH(UChar r1, IRTemp op2addr)
8084 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
8086 return "lgh";
8089 static const HChar *
8090 s390_irgen_LHI(UChar r1, UShort i2)
8092 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
8094 return "lhi";
8097 static const HChar *
8098 s390_irgen_LGHI(UChar r1, UShort i2)
8100 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
8102 return "lghi";
8105 static const HChar *
8106 s390_irgen_LHRL(UChar r1, UInt i2)
8108 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(addr_rel_long(i2)))));
8110 return "lhrl";
8113 static const HChar *
8114 s390_irgen_LGHRL(UChar r1, UInt i2)
8116 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(addr_rel_long(i2)))));
8118 return "lghrl";
8121 static const HChar *
8122 s390_irgen_LHH(UChar r1, IRTemp op2addr)
8124 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8126 return "lhh";
8129 static const HChar *
8130 s390_irgen_LFH(UChar r1, IRTemp op2addr)
8132 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
8134 return "lfh";
8137 static const HChar *
8138 s390_irgen_LLGFR(UChar r1, UChar r2)
8140 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
8142 return "llgfr";
8145 static const HChar *
8146 s390_irgen_LLGF(UChar r1, IRTemp op2addr)
8148 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8150 return "llgf";
8153 static const HChar *
8154 s390_irgen_LLGFRL(UChar r1, UInt i2)
8156 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(addr_rel_long(i2)))));
8158 return "llgfrl";
8161 static const HChar *
8162 s390_irgen_LLCR(UChar r1, UChar r2)
8164 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
8166 return "llcr";
8169 static const HChar *
8170 s390_irgen_LLGCR(UChar r1, UChar r2)
8172 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
8174 return "llgcr";
8177 static const HChar *
8178 s390_irgen_LLC(UChar r1, IRTemp op2addr)
8180 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
8182 return "llc";
8185 static const HChar *
8186 s390_irgen_LLGC(UChar r1, IRTemp op2addr)
8188 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
8190 return "llgc";
8193 static const HChar *
8194 s390_irgen_LLCH(UChar r1, IRTemp op2addr)
8196 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
8198 return "llch";
8201 static const HChar *
8202 s390_irgen_LLHR(UChar r1, UChar r2)
8204 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
8206 return "llhr";
8209 static const HChar *
8210 s390_irgen_LLGHR(UChar r1, UChar r2)
8212 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
8214 return "llghr";
8217 static const HChar *
8218 s390_irgen_LLH(UChar r1, IRTemp op2addr)
8220 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
8222 return "llh";
8225 static const HChar *
8226 s390_irgen_LLGH(UChar r1, IRTemp op2addr)
8228 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
8230 return "llgh";
8233 static const HChar *
8234 s390_irgen_LLHRL(UChar r1, UInt i2)
8236 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(addr_rel_long(i2)))));
8238 return "llhrl";
8241 static const HChar *
8242 s390_irgen_LLGHRL(UChar r1, UInt i2)
8244 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(addr_rel_long(i2)))));
8246 return "llghrl";
8249 static const HChar *
8250 s390_irgen_LLHH(UChar r1, IRTemp op2addr)
8252 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
8254 return "llhh";
8257 static const HChar *
8258 s390_irgen_LLIHF(UChar r1, UInt i2)
8260 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
8262 return "llihf";
8265 static const HChar *
8266 s390_irgen_LLIHH(UChar r1, UShort i2)
8268 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
8270 return "llihh";
8273 static const HChar *
8274 s390_irgen_LLIHL(UChar r1, UShort i2)
8276 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
8278 return "llihl";
8281 static const HChar *
8282 s390_irgen_LLILF(UChar r1, UInt i2)
8284 put_gpr_dw0(r1, mkU64(i2));
8286 return "llilf";
8289 static const HChar *
8290 s390_irgen_LLILH(UChar r1, UShort i2)
8292 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
8294 return "llilh";
8297 static const HChar *
8298 s390_irgen_LLILL(UChar r1, UShort i2)
8300 put_gpr_dw0(r1, mkU64(i2));
8302 return "llill";
8305 static const HChar *
8306 s390_irgen_LLGTR(UChar r1, UChar r2)
8308 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
8309 mkU32(2147483647))));
8311 return "llgtr";
8314 static const HChar *
8315 s390_irgen_LLGT(UChar r1, IRTemp op2addr)
8317 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
8318 mkexpr(op2addr)), mkU32(2147483647))));
8320 return "llgt";
8323 static const HChar *
8324 s390_irgen_LNR(UChar r1, UChar r2)
8326 IRTemp op2 = newTemp(Ity_I32);
8327 IRTemp result = newTemp(Ity_I32);
8329 assign(op2, get_gpr_w1(r2));
8330 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
8331 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
8332 put_gpr_w1(r1, mkexpr(result));
8333 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
8335 return "lnr";
8338 static const HChar *
8339 s390_irgen_LNGR(UChar r1, UChar r2)
8341 IRTemp op2 = newTemp(Ity_I64);
8342 IRTemp result = newTemp(Ity_I64);
8344 assign(op2, get_gpr_dw0(r2));
8345 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
8346 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
8347 put_gpr_dw0(r1, mkexpr(result));
8348 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
8350 return "lngr";
8353 static const HChar *
8354 s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
8356 IRTemp op2 = newTemp(Ity_I64);
8357 IRTemp result = newTemp(Ity_I64);
8359 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
8360 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
8361 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
8362 put_gpr_dw0(r1, mkexpr(result));
8363 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
8365 return "lngfr";
8368 static const HChar *
8369 s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
8371 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
8372 put_gpr_w1(r1, get_gpr_w1(r2));
8374 return "locr";
8377 static const HChar *
8378 s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
8380 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
8381 put_gpr_dw0(r1, get_gpr_dw0(r2));
8383 return "locgr";
8386 static const HChar *
8387 s390_irgen_LOC(UChar r1, IRTemp op2addr)
8389 /* condition is checked in format handler */
8390 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
8392 return "loc";
8395 static const HChar *
8396 s390_irgen_LOCG(UChar r1, IRTemp op2addr)
8398 /* condition is checked in format handler */
8399 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
8401 return "locg";
8404 static const HChar *
8405 s390_irgen_LPQ(UChar r1, IRTemp op2addr)
8407 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
8408 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
8411 return "lpq";
8414 static const HChar *
8415 s390_irgen_LPR(UChar r1, UChar r2)
8417 IRTemp op2 = newTemp(Ity_I32);
8418 IRTemp result = newTemp(Ity_I32);
8420 assign(op2, get_gpr_w1(r2));
8421 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
8422 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
8423 put_gpr_w1(r1, mkexpr(result));
8424 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
8426 return "lpr";
8429 static const HChar *
8430 s390_irgen_LPGR(UChar r1, UChar r2)
8432 IRTemp op2 = newTemp(Ity_I64);
8433 IRTemp result = newTemp(Ity_I64);
8435 assign(op2, get_gpr_dw0(r2));
8436 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
8437 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
8438 put_gpr_dw0(r1, mkexpr(result));
8439 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
8441 return "lpgr";
8444 static const HChar *
8445 s390_irgen_LPGFR(UChar r1, UChar r2)
8447 IRTemp op2 = newTemp(Ity_I64);
8448 IRTemp result = newTemp(Ity_I64);
8450 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8451 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
8452 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
8453 put_gpr_dw0(r1, mkexpr(result));
8454 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
8456 return "lpgfr";
8459 static const HChar *
8460 s390_irgen_LRVR(UChar r1, UChar r2)
8462 IRTemp b0 = newTemp(Ity_I8);
8463 IRTemp b1 = newTemp(Ity_I8);
8464 IRTemp b2 = newTemp(Ity_I8);
8465 IRTemp b3 = newTemp(Ity_I8);
8467 assign(b3, get_gpr_b7(r2));
8468 assign(b2, get_gpr_b6(r2));
8469 assign(b1, get_gpr_b5(r2));
8470 assign(b0, get_gpr_b4(r2));
8471 put_gpr_b4(r1, mkexpr(b3));
8472 put_gpr_b5(r1, mkexpr(b2));
8473 put_gpr_b6(r1, mkexpr(b1));
8474 put_gpr_b7(r1, mkexpr(b0));
8476 return "lrvr";
8479 static const HChar *
8480 s390_irgen_LRVGR(UChar r1, UChar r2)
8482 IRTemp b0 = newTemp(Ity_I8);
8483 IRTemp b1 = newTemp(Ity_I8);
8484 IRTemp b2 = newTemp(Ity_I8);
8485 IRTemp b3 = newTemp(Ity_I8);
8486 IRTemp b4 = newTemp(Ity_I8);
8487 IRTemp b5 = newTemp(Ity_I8);
8488 IRTemp b6 = newTemp(Ity_I8);
8489 IRTemp b7 = newTemp(Ity_I8);
8491 assign(b7, get_gpr_b7(r2));
8492 assign(b6, get_gpr_b6(r2));
8493 assign(b5, get_gpr_b5(r2));
8494 assign(b4, get_gpr_b4(r2));
8495 assign(b3, get_gpr_b3(r2));
8496 assign(b2, get_gpr_b2(r2));
8497 assign(b1, get_gpr_b1(r2));
8498 assign(b0, get_gpr_b0(r2));
8499 put_gpr_b0(r1, mkexpr(b7));
8500 put_gpr_b1(r1, mkexpr(b6));
8501 put_gpr_b2(r1, mkexpr(b5));
8502 put_gpr_b3(r1, mkexpr(b4));
8503 put_gpr_b4(r1, mkexpr(b3));
8504 put_gpr_b5(r1, mkexpr(b2));
8505 put_gpr_b6(r1, mkexpr(b1));
8506 put_gpr_b7(r1, mkexpr(b0));
8508 return "lrvgr";
8511 static const HChar *
8512 s390_irgen_LRVH(UChar r1, IRTemp op2addr)
8514 IRTemp op2 = newTemp(Ity_I16);
8516 assign(op2, load(Ity_I16, mkexpr(op2addr)));
8517 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
8518 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
8520 return "lrvh";
8523 static const HChar *
8524 s390_irgen_LRV(UChar r1, IRTemp op2addr)
8526 IRTemp op2 = newTemp(Ity_I32);
8528 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8529 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
8530 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
8531 mkU8(8)), mkU32(255))));
8532 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
8533 mkU8(16)), mkU32(255))));
8534 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
8535 mkU8(24)), mkU32(255))));
8537 return "lrv";
8540 static const HChar *
8541 s390_irgen_LRVG(UChar r1, IRTemp op2addr)
8543 IRTemp op2 = newTemp(Ity_I64);
8545 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8546 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
8547 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8548 mkU8(8)), mkU64(255))));
8549 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8550 mkU8(16)), mkU64(255))));
8551 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8552 mkU8(24)), mkU64(255))));
8553 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8554 mkU8(32)), mkU64(255))));
8555 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8556 mkU8(40)), mkU64(255))));
8557 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8558 mkU8(48)), mkU64(255))));
8559 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
8560 mkU8(56)), mkU64(255))));
8562 return "lrvg";
8565 static const HChar *
8566 s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
8568 store(mkexpr(op1addr), mkU16(i2));
8570 return "mvhhi";
8573 static const HChar *
8574 s390_irgen_MVHI(UShort i2, IRTemp op1addr)
8576 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
8578 return "mvhi";
8581 static const HChar *
8582 s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
8584 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
8586 return "mvghi";
8589 static const HChar *
8590 s390_irgen_MVI(UChar i2, IRTemp op1addr)
8592 store(mkexpr(op1addr), mkU8(i2));
8594 return "mvi";
8597 static const HChar *
8598 s390_irgen_MVIY(UChar i2, IRTemp op1addr)
8600 store(mkexpr(op1addr), mkU8(i2));
8602 return "mviy";
8605 static const HChar *
8606 s390_irgen_MR(UChar r1, UChar r2)
8608 IRTemp op1 = newTemp(Ity_I32);
8609 IRTemp op2 = newTemp(Ity_I32);
8610 IRTemp result = newTemp(Ity_I64);
8612 assign(op1, get_gpr_w1(r1 + 1));
8613 assign(op2, get_gpr_w1(r2));
8614 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8615 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8616 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8618 return "mr";
8621 static const HChar *
8622 s390_irgen_M(UChar r1, IRTemp op2addr)
8624 IRTemp op1 = newTemp(Ity_I32);
8625 IRTemp op2 = newTemp(Ity_I32);
8626 IRTemp result = newTemp(Ity_I64);
8628 assign(op1, get_gpr_w1(r1 + 1));
8629 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8630 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8631 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8632 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8634 return "m";
8637 static const HChar *
8638 s390_irgen_MFY(UChar r1, IRTemp op2addr)
8640 IRTemp op1 = newTemp(Ity_I32);
8641 IRTemp op2 = newTemp(Ity_I32);
8642 IRTemp result = newTemp(Ity_I64);
8644 assign(op1, get_gpr_w1(r1 + 1));
8645 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8646 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8647 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8648 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8650 return "mfy";
8653 static const HChar *
8654 s390_irgen_MG(UChar r1, IRTemp op2addr)
8656 IRTemp op1 = newTemp(Ity_I64);
8657 IRTemp op2 = newTemp(Ity_I64);
8658 IRTemp result = newTemp(Ity_I128);
8660 assign(op1, get_gpr_dw0(r1 + 1));
8661 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8662 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
8663 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
8664 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
8666 return "mg";
8669 static const HChar *
8670 s390_irgen_MGH(UChar r1, IRTemp op2addr)
8672 IRTemp op1 = newTemp(Ity_I64);
8673 IRTemp op2 = newTemp(Ity_I16);
8674 IRTemp result = newTemp(Ity_I128);
8676 assign(op1, get_gpr_dw0(r1));
8677 assign(op2, load(Ity_I16, mkexpr(op2addr)));
8678 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64, mkexpr(op2))
8680 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8682 return "mgh";
8685 static const HChar *
8686 s390_irgen_MGRK(UChar r3, UChar r1, UChar r2)
8688 IRTemp op2 = newTemp(Ity_I64);
8689 IRTemp op3 = newTemp(Ity_I64);
8690 IRTemp result = newTemp(Ity_I128);
8692 assign(op2, get_gpr_dw0(r2));
8693 assign(op3, get_gpr_dw0(r3));
8694 assign(result, binop(Iop_MullS64, mkexpr(op2), mkexpr(op3)));
8695 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
8696 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
8698 return "mgrk";
8701 static const HChar *
8702 s390_irgen_MH(UChar r1, IRTemp op2addr)
8704 IRTemp op1 = newTemp(Ity_I32);
8705 IRTemp op2 = newTemp(Ity_I16);
8706 IRTemp result = newTemp(Ity_I64);
8708 assign(op1, get_gpr_w1(r1));
8709 assign(op2, load(Ity_I16, mkexpr(op2addr)));
8710 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
8712 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8714 return "mh";
8717 static const HChar *
8718 s390_irgen_MHY(UChar r1, IRTemp op2addr)
8720 IRTemp op1 = newTemp(Ity_I32);
8721 IRTemp op2 = newTemp(Ity_I16);
8722 IRTemp result = newTemp(Ity_I64);
8724 assign(op1, get_gpr_w1(r1));
8725 assign(op2, load(Ity_I16, mkexpr(op2addr)));
8726 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
8728 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8730 return "mhy";
8733 static const HChar *
8734 s390_irgen_MHI(UChar r1, UShort i2)
8736 IRTemp op1 = newTemp(Ity_I32);
8737 Short op2;
8738 IRTemp result = newTemp(Ity_I64);
8740 assign(op1, get_gpr_w1(r1));
8741 op2 = (Short)i2;
8742 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
8743 mkU16((UShort)op2))));
8744 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8746 return "mhi";
8749 static const HChar *
8750 s390_irgen_MGHI(UChar r1, UShort i2)
8752 IRTemp op1 = newTemp(Ity_I64);
8753 Short op2;
8754 IRTemp result = newTemp(Ity_I128);
8756 assign(op1, get_gpr_dw0(r1));
8757 op2 = (Short)i2;
8758 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
8759 mkU16((UShort)op2))));
8760 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8762 return "mghi";
8765 static const HChar *
8766 s390_irgen_MLR(UChar r1, UChar r2)
8768 IRTemp op1 = newTemp(Ity_I32);
8769 IRTemp op2 = newTemp(Ity_I32);
8770 IRTemp result = newTemp(Ity_I64);
8772 assign(op1, get_gpr_w1(r1 + 1));
8773 assign(op2, get_gpr_w1(r2));
8774 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
8775 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8776 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8778 return "mlr";
8781 static const HChar *
8782 s390_irgen_MLGR(UChar r1, UChar r2)
8784 IRTemp op1 = newTemp(Ity_I64);
8785 IRTemp op2 = newTemp(Ity_I64);
8786 IRTemp result = newTemp(Ity_I128);
8788 assign(op1, get_gpr_dw0(r1 + 1));
8789 assign(op2, get_gpr_dw0(r2));
8790 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
8791 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
8792 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
8794 return "mlgr";
8797 static const HChar *
8798 s390_irgen_ML(UChar r1, IRTemp op2addr)
8800 IRTemp op1 = newTemp(Ity_I32);
8801 IRTemp op2 = newTemp(Ity_I32);
8802 IRTemp result = newTemp(Ity_I64);
8804 assign(op1, get_gpr_w1(r1 + 1));
8805 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8806 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
8807 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
8808 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
8810 return "ml";
8813 static const HChar *
8814 s390_irgen_MLG(UChar r1, IRTemp op2addr)
8816 IRTemp op1 = newTemp(Ity_I64);
8817 IRTemp op2 = newTemp(Ity_I64);
8818 IRTemp result = newTemp(Ity_I128);
8820 assign(op1, get_gpr_dw0(r1 + 1));
8821 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8822 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
8823 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
8824 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
8826 return "mlg";
8829 static const HChar *
8830 s390_irgen_MSR(UChar r1, UChar r2)
8832 IRTemp op1 = newTemp(Ity_I32);
8833 IRTemp op2 = newTemp(Ity_I32);
8834 IRTemp result = newTemp(Ity_I64);
8836 assign(op1, get_gpr_w1(r1));
8837 assign(op2, get_gpr_w1(r2));
8838 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8839 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8841 return "msr";
8844 static const HChar *
8845 s390_irgen_MSGR(UChar r1, UChar r2)
8847 IRTemp op1 = newTemp(Ity_I64);
8848 IRTemp op2 = newTemp(Ity_I64);
8849 IRTemp result = newTemp(Ity_I128);
8851 assign(op1, get_gpr_dw0(r1));
8852 assign(op2, get_gpr_dw0(r2));
8853 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
8854 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8856 return "msgr";
8859 static const HChar *
8860 s390_irgen_MSGFR(UChar r1, UChar r2)
8862 IRTemp op1 = newTemp(Ity_I64);
8863 IRTemp op2 = newTemp(Ity_I32);
8864 IRTemp result = newTemp(Ity_I128);
8866 assign(op1, get_gpr_dw0(r1));
8867 assign(op2, get_gpr_w1(r2));
8868 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
8870 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8872 return "msgfr";
8875 static const HChar *
8876 s390_irgen_MS(UChar r1, IRTemp op2addr)
8878 IRTemp op1 = newTemp(Ity_I32);
8879 IRTemp op2 = newTemp(Ity_I32);
8880 IRTemp result = newTemp(Ity_I64);
8882 assign(op1, get_gpr_w1(r1));
8883 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8884 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8885 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8887 return "ms";
8890 static const HChar *
8891 s390_irgen_MSC(UChar r1, IRTemp op2addr)
8893 IRTemp op1 = newTemp(Ity_I32);
8894 IRTemp op2 = newTemp(Ity_I32);
8895 IRTemp result = newTemp(Ity_I64);
8897 assign(op1, get_gpr_w1(r1));
8898 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8899 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8900 s390_cc_thunk_putSS(S390_CC_OP_MUL_32, op1, op2);
8901 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8903 return "msc";
8906 static const HChar *
8907 s390_irgen_MSRKC(UChar r3, UChar r1, UChar r2)
8909 IRTemp op2 = newTemp(Ity_I32);
8910 IRTemp op3 = newTemp(Ity_I32);
8911 IRTemp result = newTemp(Ity_I64);
8913 assign(op2, get_gpr_w1(r2));
8914 assign(op3, get_gpr_w1(r3));
8915 assign(result, binop(Iop_MullS32, mkexpr(op2), mkexpr(op3)));
8916 s390_cc_thunk_putSS(S390_CC_OP_MUL_32, op2, op3);
8917 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8919 return "msrkc";
8922 static const HChar *
8923 s390_irgen_MSY(UChar r1, IRTemp op2addr)
8925 IRTemp op1 = newTemp(Ity_I32);
8926 IRTemp op2 = newTemp(Ity_I32);
8927 IRTemp result = newTemp(Ity_I64);
8929 assign(op1, get_gpr_w1(r1));
8930 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8931 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
8932 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8934 return "msy";
8937 static const HChar *
8938 s390_irgen_MSG(UChar r1, IRTemp op2addr)
8940 IRTemp op1 = newTemp(Ity_I64);
8941 IRTemp op2 = newTemp(Ity_I64);
8942 IRTemp result = newTemp(Ity_I128);
8944 assign(op1, get_gpr_dw0(r1));
8945 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8946 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
8947 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8949 return "msg";
8952 static const HChar *
8953 s390_irgen_MSGC(UChar r1, IRTemp op2addr)
8955 IRTemp op1 = newTemp(Ity_I64);
8956 IRTemp op2 = newTemp(Ity_I64);
8957 IRTemp result = newTemp(Ity_I128);
8959 assign(op1, get_gpr_dw0(r1));
8960 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8961 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
8962 s390_cc_thunk_putSS(S390_CC_OP_MUL_64, op1, op2);
8963 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8965 return "msgc";
8968 static const HChar *
8969 s390_irgen_MSGF(UChar r1, IRTemp op2addr)
8971 IRTemp op1 = newTemp(Ity_I64);
8972 IRTemp op2 = newTemp(Ity_I32);
8973 IRTemp result = newTemp(Ity_I128);
8975 assign(op1, get_gpr_dw0(r1));
8976 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8977 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
8979 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
8981 return "msgf";
8984 static const HChar *
8985 s390_irgen_MSFI(UChar r1, UInt i2)
8987 IRTemp op1 = newTemp(Ity_I32);
8988 Int op2;
8989 IRTemp result = newTemp(Ity_I64);
8991 assign(op1, get_gpr_w1(r1));
8992 op2 = (Int)i2;
8993 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
8994 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
8996 return "msfi";
8999 static const HChar *
9000 s390_irgen_MSGFI(UChar r1, UInt i2)
9002 IRTemp op1 = newTemp(Ity_I64);
9003 Int op2;
9004 IRTemp result = newTemp(Ity_I128);
9006 assign(op1, get_gpr_dw0(r1));
9007 op2 = (Int)i2;
9008 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
9009 op2))));
9010 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
9012 return "msgfi";
9015 static const HChar *
9016 s390_irgen_MSGRKC(UChar r3, UChar r1, UChar r2)
9018 IRTemp op2 = newTemp(Ity_I64);
9019 IRTemp op3 = newTemp(Ity_I64);
9020 IRTemp result = newTemp(Ity_I128);
9022 assign(op2, get_gpr_dw0(r2));
9023 assign(op3, get_gpr_dw0(r3));
9024 assign(result, binop(Iop_MullS64, mkexpr(op2), mkexpr(op3)));
9025 s390_cc_thunk_putSS(S390_CC_OP_MUL_64, op2, op3);
9026 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
9028 return "msgrkc";
9031 static const HChar *
9032 s390_irgen_OR(UChar r1, UChar r2)
9034 IRTemp op1 = newTemp(Ity_I32);
9035 IRTemp op2 = newTemp(Ity_I32);
9036 IRTemp result = newTemp(Ity_I32);
9038 assign(op1, get_gpr_w1(r1));
9039 assign(op2, get_gpr_w1(r2));
9040 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
9041 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9042 put_gpr_w1(r1, mkexpr(result));
9044 return "or";
9047 static const HChar *
9048 s390_irgen_OGR(UChar r1, UChar r2)
9050 IRTemp op1 = newTemp(Ity_I64);
9051 IRTemp op2 = newTemp(Ity_I64);
9052 IRTemp result = newTemp(Ity_I64);
9054 assign(op1, get_gpr_dw0(r1));
9055 assign(op2, get_gpr_dw0(r2));
9056 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
9057 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9058 put_gpr_dw0(r1, mkexpr(result));
9060 return "ogr";
9063 static const HChar *
9064 s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
9066 return s390_irgen_logicalK32(r3, r1, r2, "ork", Iop_Or32, False, False);
9069 static const HChar *
9070 s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
9072 return s390_irgen_logicalK64(r3, r1, r2, "ogrk", Iop_Or64, False, False);
9075 static const HChar *
9076 s390_irgen_OCRK(UChar r3, UChar r1, UChar r2)
9078 return s390_irgen_logicalK32(r3, r1, r2, "ocrk", Iop_Or32, True, False);
9081 static const HChar *
9082 s390_irgen_OCGRK(UChar r3, UChar r1, UChar r2)
9084 return s390_irgen_logicalK64(r3, r1, r2, "ocgrk", Iop_Or64, True, False);
9087 static const HChar *
9088 s390_irgen_NORK(UChar r3, UChar r1, UChar r2)
9090 return s390_irgen_logicalK32(r3, r1, r2, "nork", Iop_Or32, False, True);
9093 static const HChar *
9094 s390_irgen_NOGRK(UChar r3, UChar r1, UChar r2)
9096 return s390_irgen_logicalK64(r3, r1, r2, "nogrk", Iop_Or64, False, True);
9099 static const HChar *
9100 s390_irgen_O(UChar r1, IRTemp op2addr)
9102 IRTemp op1 = newTemp(Ity_I32);
9103 IRTemp op2 = newTemp(Ity_I32);
9104 IRTemp result = newTemp(Ity_I32);
9106 assign(op1, get_gpr_w1(r1));
9107 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9108 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
9109 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9110 put_gpr_w1(r1, mkexpr(result));
9112 return "o";
9115 static const HChar *
9116 s390_irgen_OY(UChar r1, IRTemp op2addr)
9118 IRTemp op1 = newTemp(Ity_I32);
9119 IRTemp op2 = newTemp(Ity_I32);
9120 IRTemp result = newTemp(Ity_I32);
9122 assign(op1, get_gpr_w1(r1));
9123 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9124 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
9125 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9126 put_gpr_w1(r1, mkexpr(result));
9128 return "oy";
9131 static const HChar *
9132 s390_irgen_OG(UChar r1, IRTemp op2addr)
9134 IRTemp op1 = newTemp(Ity_I64);
9135 IRTemp op2 = newTemp(Ity_I64);
9136 IRTemp result = newTemp(Ity_I64);
9138 assign(op1, get_gpr_dw0(r1));
9139 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9140 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
9141 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9142 put_gpr_dw0(r1, mkexpr(result));
9144 return "og";
9147 static const HChar *
9148 s390_irgen_OI(UChar i2, IRTemp op1addr)
9150 IRTemp op1 = newTemp(Ity_I8);
9151 UChar op2;
9152 IRTemp result = newTemp(Ity_I8);
9154 assign(op1, load(Ity_I8, mkexpr(op1addr)));
9155 op2 = i2;
9156 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
9157 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9158 store(mkexpr(op1addr), mkexpr(result));
9160 return "oi";
9163 static const HChar *
9164 s390_irgen_OIY(UChar i2, IRTemp op1addr)
9166 IRTemp op1 = newTemp(Ity_I8);
9167 UChar op2;
9168 IRTemp result = newTemp(Ity_I8);
9170 assign(op1, load(Ity_I8, mkexpr(op1addr)));
9171 op2 = i2;
9172 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
9173 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9174 store(mkexpr(op1addr), mkexpr(result));
9176 return "oiy";
9179 static const HChar *
9180 s390_irgen_OIHF(UChar r1, UInt i2)
9182 IRTemp op1 = newTemp(Ity_I32);
9183 UInt op2;
9184 IRTemp result = newTemp(Ity_I32);
9186 assign(op1, get_gpr_w0(r1));
9187 op2 = i2;
9188 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
9189 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9190 put_gpr_w0(r1, mkexpr(result));
9192 return "oihf";
9195 static const HChar *
9196 s390_irgen_OIHH(UChar r1, UShort i2)
9198 IRTemp op1 = newTemp(Ity_I16);
9199 UShort op2;
9200 IRTemp result = newTemp(Ity_I16);
9202 assign(op1, get_gpr_hw0(r1));
9203 op2 = i2;
9204 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
9205 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9206 put_gpr_hw0(r1, mkexpr(result));
9208 return "oihh";
9211 static const HChar *
9212 s390_irgen_OIHL(UChar r1, UShort i2)
9214 IRTemp op1 = newTemp(Ity_I16);
9215 UShort op2;
9216 IRTemp result = newTemp(Ity_I16);
9218 assign(op1, get_gpr_hw1(r1));
9219 op2 = i2;
9220 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
9221 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9222 put_gpr_hw1(r1, mkexpr(result));
9224 return "oihl";
9227 static const HChar *
9228 s390_irgen_OILF(UChar r1, UInt i2)
9230 IRTemp op1 = newTemp(Ity_I32);
9231 UInt op2;
9232 IRTemp result = newTemp(Ity_I32);
9234 assign(op1, get_gpr_w1(r1));
9235 op2 = i2;
9236 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
9237 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9238 put_gpr_w1(r1, mkexpr(result));
9240 return "oilf";
9243 static const HChar *
9244 s390_irgen_OILH(UChar r1, UShort i2)
9246 IRTemp op1 = newTemp(Ity_I16);
9247 UShort op2;
9248 IRTemp result = newTemp(Ity_I16);
9250 assign(op1, get_gpr_hw2(r1));
9251 op2 = i2;
9252 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
9253 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9254 put_gpr_hw2(r1, mkexpr(result));
9256 return "oilh";
9259 static const HChar *
9260 s390_irgen_OILL(UChar r1, UShort i2)
9262 IRTemp op1 = newTemp(Ity_I16);
9263 UShort op2;
9264 IRTemp result = newTemp(Ity_I16);
9266 assign(op1, get_gpr_hw3(r1));
9267 op2 = i2;
9268 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
9269 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9270 put_gpr_hw3(r1, mkexpr(result));
9272 return "oill";
9275 static const HChar *
9276 s390_irgen_PFD(void)
9279 return "pfd";
9282 static const HChar *
9283 s390_irgen_PFDRL(void)
9286 return "pfdrl";
9289 static IRExpr *
9290 get_rounding_mode_from_gr0(void)
9292 IRTemp rm_bits = newTemp(Ity_I32);
9293 IRExpr *s390rm;
9294 IRExpr *irrm;
9296 /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
9297 when PFPO insn is called. So, extract the bits at [60:63] */
9298 assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
9299 s390rm = mkexpr(rm_bits);
9300 irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
9301 mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
9302 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
9303 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
9304 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
9305 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
9306 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
9307 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
9308 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
9309 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
9310 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
9311 mkexpr(encode_dfp_rounding_mode(
9312 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
9313 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
9314 mkexpr(encode_dfp_rounding_mode(
9315 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
9316 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
9317 mkexpr(encode_dfp_rounding_mode(
9318 S390_DFP_ROUND_AWAY_0)),
9319 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
9320 mkexpr(encode_dfp_rounding_mode(
9321 S390_DFP_ROUND_PREPARE_SHORT_15)),
9322 /* if rounding mode is 0 or invalid (2-7)
9323 set S390_DFP_ROUND_PER_FPC_0 */
9324 mkexpr(encode_dfp_rounding_mode(
9325 S390_DFP_ROUND_PER_FPC_0)))))))))));
9327 return irrm;
9330 static IRExpr *
9331 s390_call_pfpo_helper(IRExpr *gr0)
9333 IRExpr **args, *call;
9335 args = mkIRExprVec_1(gr0);
9336 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
9337 "s390_do_pfpo", &s390_do_pfpo, args);
9338 /* Nothing is excluded from definedness checking. */
9339 call->Iex.CCall.cee->mcx_mask = 0;
9341 return call;
9344 static const HChar *
9345 s390_irgen_PFPO(void)
9347 IRTemp gr0 = newTemp(Ity_I32); /* word 1 [32:63] of GR 0 */
9348 IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
9349 IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */
9350 IRTemp ef = newTemp(Ity_I32); /* Emulation Failure */
9351 IRTemp src1 = newTemp(Ity_F32);
9352 IRTemp dst1 = newTemp(Ity_D32);
9353 IRTemp src2 = newTemp(Ity_F32);
9354 IRTemp dst2 = newTemp(Ity_D64);
9355 IRTemp src3 = newTemp(Ity_F32);
9356 IRTemp dst3 = newTemp(Ity_D128);
9357 IRTemp src4 = newTemp(Ity_F64);
9358 IRTemp dst4 = newTemp(Ity_D32);
9359 IRTemp src5 = newTemp(Ity_F64);
9360 IRTemp dst5 = newTemp(Ity_D64);
9361 IRTemp src6 = newTemp(Ity_F64);
9362 IRTemp dst6 = newTemp(Ity_D128);
9363 IRTemp src7 = newTemp(Ity_F128);
9364 IRTemp dst7 = newTemp(Ity_D32);
9365 IRTemp src8 = newTemp(Ity_F128);
9366 IRTemp dst8 = newTemp(Ity_D64);
9367 IRTemp src9 = newTemp(Ity_F128);
9368 IRTemp dst9 = newTemp(Ity_D128);
9369 IRTemp src10 = newTemp(Ity_D32);
9370 IRTemp dst10 = newTemp(Ity_F32);
9371 IRTemp src11 = newTemp(Ity_D32);
9372 IRTemp dst11 = newTemp(Ity_F64);
9373 IRTemp src12 = newTemp(Ity_D32);
9374 IRTemp dst12 = newTemp(Ity_F128);
9375 IRTemp src13 = newTemp(Ity_D64);
9376 IRTemp dst13 = newTemp(Ity_F32);
9377 IRTemp src14 = newTemp(Ity_D64);
9378 IRTemp dst14 = newTemp(Ity_F64);
9379 IRTemp src15 = newTemp(Ity_D64);
9380 IRTemp dst15 = newTemp(Ity_F128);
9381 IRTemp src16 = newTemp(Ity_D128);
9382 IRTemp dst16 = newTemp(Ity_F32);
9383 IRTemp src17 = newTemp(Ity_D128);
9384 IRTemp dst17 = newTemp(Ity_F64);
9385 IRTemp src18 = newTemp(Ity_D128);
9386 IRTemp dst18 = newTemp(Ity_F128);
9387 IRExpr *irrm;
9389 if (! s390_host_has_pfpo) {
9390 emulation_failure(EmFail_S390X_pfpo);
9391 goto done;
9394 assign(gr0, get_gpr_w1(0));
9395 /* get function code */
9396 assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
9397 mkU32(0x7fffff)));
9398 /* get validity test bit */
9399 assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
9400 mkU32(0x1)));
9401 irrm = get_rounding_mode_from_gr0();
9403 /* test_bit is 1 */
9404 assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
9405 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
9407 /* Return code set in GR1 is usually 0. Non-zero value is set only
9408 when exceptions are raised. See Programming Notes point 5 in the
9409 instrcution description of pfpo in POP. Since valgrind does not
9410 model exception, it might be safe to just set 0 to GR 1. */
9411 put_gpr_w1(1, mkU32(0x0));
9412 next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
9414 /* Check validity of function code in GR 0 */
9415 assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
9416 emulation_failure_with_expr(mkexpr(ef));
9418 stmt(
9419 IRStmt_Exit(
9420 binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
9421 Ijk_EmFail,
9422 IRConst_U64(guest_IA_next_instr),
9423 S390X_GUEST_OFFSET(guest_IA)
9427 /* F32 -> D32 */
9428 /* get source from FPR 4,6 - already set in src1 */
9429 assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
9430 put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
9431 put_gpr_w1(1, mkU32(0x0));
9432 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
9433 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
9435 /* F32 -> D64 */
9436 assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
9437 assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
9438 put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
9439 put_gpr_w1(1, mkU32(0x0));
9440 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
9441 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
9443 /* F32 -> D128 */
9444 assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
9445 assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
9446 put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
9447 put_gpr_w1(1, mkU32(0x0));
9448 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
9449 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
9451 /* F64 -> D32 */
9452 assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
9453 assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
9454 put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
9455 put_gpr_w1(1, mkU32(0x0));
9456 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
9457 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
9459 /* F64 -> D64 */
9460 assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
9461 assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
9462 put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
9463 put_gpr_w1(1, mkU32(0x0));
9464 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
9465 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
9467 /* F64 -> D128 */
9468 assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
9469 assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
9470 put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
9471 put_gpr_w1(1, mkU32(0x0));
9472 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
9473 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
9475 /* F128 -> D32 */
9476 assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
9477 assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
9478 put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
9479 put_gpr_w1(1, mkU32(0x0));
9480 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
9481 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
9483 /* F128 -> D64 */
9484 assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
9485 assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
9486 put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
9487 put_gpr_w1(1, mkU32(0x0));
9488 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
9489 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
9491 /* F128 -> D128 */
9492 assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
9493 assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
9494 put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
9495 put_gpr_w1(1, mkU32(0x0));
9496 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
9497 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
9499 /* D32 -> F32 */
9500 assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
9501 assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
9502 put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
9503 put_gpr_w1(1, mkU32(0x0));
9504 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
9505 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
9507 /* D32 -> F64 */
9508 assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
9509 assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
9510 put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
9511 put_gpr_w1(1, mkU32(0x0));
9512 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
9513 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
9515 /* D32 -> F128 */
9516 assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
9517 assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
9518 put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
9519 put_gpr_w1(1, mkU32(0x0));
9520 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
9521 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
9523 /* D64 -> F32 */
9524 assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
9525 assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
9526 put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
9527 put_gpr_w1(1, mkU32(0x0));
9528 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
9529 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
9531 /* D64 -> F64 */
9532 assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
9533 assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
9534 put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
9535 put_gpr_w1(1, mkU32(0x0));
9536 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
9537 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
9539 /* D64 -> F128 */
9540 assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
9541 assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
9542 put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
9543 put_gpr_w1(1, mkU32(0x0));
9544 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
9545 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
9547 /* D128 -> F32 */
9548 assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
9549 assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
9550 put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
9551 put_gpr_w1(1, mkU32(0x0));
9552 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
9553 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
9555 /* D128 -> F64 */
9556 assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
9557 assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
9558 put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
9559 put_gpr_w1(1, mkU32(0x0));
9560 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
9561 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
9563 /* D128 -> F128 */
9564 assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
9565 assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
9566 put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
9567 put_gpr_w1(1, mkU32(0x0));
9568 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
9569 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
9571 done:
9572 return "pfpo";
9575 static const HChar *
9576 s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
9578 IRTemp amount = newTemp(Ity_I64);
9579 IRTemp op = newTemp(Ity_I32);
9581 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
9582 assign(op, get_gpr_w1(r3));
9583 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
9584 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
9585 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
9587 return "rll";
9590 static const HChar *
9591 s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
9593 IRTemp amount = newTemp(Ity_I64);
9594 IRTemp op = newTemp(Ity_I64);
9596 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9597 assign(op, get_gpr_dw0(r3));
9598 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
9599 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
9600 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
9602 return "rllg";
9605 static const HChar *
9606 s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9608 UChar from;
9609 UChar to;
9610 UChar rot;
9611 UChar t_bit;
9612 ULong mask;
9613 ULong maskc;
9614 IRTemp result = newTemp(Ity_I64);
9615 IRTemp op2 = newTemp(Ity_I64);
9617 from = i3 & 63;
9618 to = i4 & 63;
9619 rot = i5 & 63;
9620 t_bit = i3 & 128;
9621 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
9622 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
9623 mkU8(64 - rot))));
9624 if (from <= to) {
9625 mask = ~0ULL;
9626 mask = (mask >> from) & (mask << (63 - to));
9627 maskc = ~mask;
9628 } else {
9629 maskc = ~0ULL;
9630 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
9631 mask = ~maskc;
9633 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
9634 ), mkU64(mask)));
9635 if (t_bit == 0) {
9636 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
9637 mkU64(maskc)), mkexpr(result)));
9639 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9641 return "rnsbg";
9644 static const HChar *
9645 s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9647 UChar from;
9648 UChar to;
9649 UChar rot;
9650 UChar t_bit;
9651 ULong mask;
9652 ULong maskc;
9653 IRTemp result = newTemp(Ity_I64);
9654 IRTemp op2 = newTemp(Ity_I64);
9656 from = i3 & 63;
9657 to = i4 & 63;
9658 rot = i5 & 63;
9659 t_bit = i3 & 128;
9660 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
9661 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
9662 mkU8(64 - rot))));
9663 if (from <= to) {
9664 mask = ~0ULL;
9665 mask = (mask >> from) & (mask << (63 - to));
9666 maskc = ~mask;
9667 } else {
9668 maskc = ~0ULL;
9669 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
9670 mask = ~maskc;
9672 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
9673 ), mkU64(mask)));
9674 if (t_bit == 0) {
9675 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
9676 mkU64(maskc)), mkexpr(result)));
9678 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9680 return "rxsbg";
9683 static const HChar *
9684 s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9686 UChar from;
9687 UChar to;
9688 UChar rot;
9689 UChar t_bit;
9690 ULong mask;
9691 ULong maskc;
9692 IRTemp result = newTemp(Ity_I64);
9693 IRTemp op2 = newTemp(Ity_I64);
9695 from = i3 & 63;
9696 to = i4 & 63;
9697 rot = i5 & 63;
9698 t_bit = i3 & 128;
9699 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
9700 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
9701 mkU8(64 - rot))));
9702 if (from <= to) {
9703 mask = ~0ULL;
9704 mask = (mask >> from) & (mask << (63 - to));
9705 maskc = ~mask;
9706 } else {
9707 maskc = ~0ULL;
9708 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
9709 mask = ~maskc;
9711 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
9712 ), mkU64(mask)));
9713 if (t_bit == 0) {
9714 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
9715 mkU64(maskc)), mkexpr(result)));
9717 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
9719 return "rosbg";
9722 static const HChar *
9723 s390_irgen_RISBGx(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
9724 Bool set_cc)
9726 UChar from;
9727 UChar to;
9728 UChar rot;
9729 UChar z_bit;
9730 ULong mask;
9731 ULong maskc;
9732 IRTemp op2 = newTemp(Ity_I64);
9733 IRTemp result = newTemp(Ity_I64);
9735 from = i3 & 63;
9736 to = i4 & 63;
9737 rot = i5 & 63;
9738 z_bit = i4 & 128;
9739 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
9740 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
9741 mkU8(64 - rot))));
9742 if (from <= to) {
9743 mask = ~0ULL;
9744 mask = (mask >> from) & (mask << (63 - to));
9745 maskc = ~mask;
9746 } else {
9747 maskc = ~0ULL;
9748 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
9749 mask = ~maskc;
9751 if (z_bit == 0) {
9752 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
9753 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
9754 } else {
9755 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
9757 assign(result, get_gpr_dw0(r1));
9758 if (set_cc) {
9759 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
9760 return "risbg";
9763 return "risbgn";
9766 static const HChar *
9767 s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9769 return s390_irgen_RISBGx(r1, r2, i3, i4, i5, True);
9772 static const HChar *
9773 s390_irgen_RISBGN(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9775 return s390_irgen_RISBGx(r1, r2, i3, i4, i5, False);
9778 static IRExpr *
9779 s390_irgen_RISBxG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
9780 Bool high)
9782 UChar from;
9783 UChar to;
9784 UChar rot;
9785 UChar z_bit;
9786 UInt mask;
9787 UInt maskc;
9788 IRTemp op2 = newTemp(Ity_I32);
9790 from = i3 & 31;
9791 to = i4 & 31;
9792 rot = i5 & 63;
9793 z_bit = i4 & 128;
9794 if (rot == 0) {
9795 assign(op2, high ? get_gpr_w0(r2) : get_gpr_w1(r2));
9796 } else if (rot == 32) {
9797 assign(op2, high ? get_gpr_w1(r2) : get_gpr_w0(r2));
9798 } else {
9799 assign(op2,
9800 unop(high ? Iop_64HIto32 : Iop_64to32,
9801 binop(Iop_Or64,
9802 binop(Iop_Shl64, get_gpr_dw0(r2), mkU8(rot)),
9803 binop(Iop_Shr64, get_gpr_dw0(r2), mkU8(64 - rot)))));
9805 if (from <= to) {
9806 mask = ~0U;
9807 mask = (mask >> from) & (mask << (31 - to));
9808 maskc = ~mask;
9809 } else {
9810 maskc = ~0U;
9811 maskc = (maskc >> (to + 1)) & (maskc << (32 - from));
9812 mask = ~maskc;
9814 if (z_bit) {
9815 return binop(Iop_And32, mkexpr(op2), mkU32(mask));
9817 return binop(Iop_Or32,
9818 binop(Iop_And32, high ? get_gpr_w0(r1) : get_gpr_w1(r1),
9819 mkU32(maskc)),
9820 binop(Iop_And32, mkexpr(op2), mkU32(mask)));
9823 static const HChar *
9824 s390_irgen_RISBHG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9826 put_gpr_w0(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, True));
9827 return "risbhg";
9830 static const HChar *
9831 s390_irgen_RISBLG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
9833 put_gpr_w1(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, False));
9834 return "risblg";
9837 static const HChar *
9838 s390_irgen_SAR(UChar r1, UChar r2)
9840 put_ar_w0(r1, get_gpr_w1(r2));
9841 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
9842 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
9844 return "sar";
9847 static const HChar *
9848 s390_irgen_SLDA(UChar r1, IRTemp op2addr)
9850 IRTemp p1 = newTemp(Ity_I64);
9851 IRTemp p2 = newTemp(Ity_I64);
9852 IRTemp op = newTemp(Ity_I64);
9853 IRTemp result = newTemp(Ity_I64);
9854 ULong sign_mask;
9855 IRTemp shift_amount = newTemp(Ity_I64);
9857 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
9858 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
9859 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
9861 sign_mask = 1ULL << 63;
9862 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9863 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
9864 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
9865 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
9866 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
9867 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
9868 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
9870 return "slda";
9873 static const HChar *
9874 s390_irgen_SLDL(UChar r1, IRTemp op2addr)
9876 IRTemp p1 = newTemp(Ity_I64);
9877 IRTemp p2 = newTemp(Ity_I64);
9878 IRTemp result = newTemp(Ity_I64);
9880 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
9881 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
9882 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
9883 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
9884 mkexpr(op2addr), mkU64(63)))));
9885 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
9886 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
9888 return "sldl";
9891 static const HChar *
9892 s390_irgen_SLA(UChar r1, IRTemp op2addr)
9894 IRTemp uop = newTemp(Ity_I32);
9895 IRTemp result = newTemp(Ity_I32);
9896 UInt sign_mask;
9897 IRTemp shift_amount = newTemp(Ity_I64);
9898 IRTemp op = newTemp(Ity_I32);
9900 assign(op, get_gpr_w1(r1));
9901 assign(uop, get_gpr_w1(r1));
9902 sign_mask = 2147483648U;
9903 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9904 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
9905 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
9906 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
9907 put_gpr_w1(r1, mkexpr(result));
9908 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
9910 return "sla";
9913 static const HChar *
9914 s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
9916 IRTemp uop = newTemp(Ity_I32);
9917 IRTemp result = newTemp(Ity_I32);
9918 UInt sign_mask;
9919 IRTemp shift_amount = newTemp(Ity_I64);
9920 IRTemp op = newTemp(Ity_I32);
9922 assign(op, get_gpr_w1(r3));
9923 assign(uop, get_gpr_w1(r3));
9924 sign_mask = 2147483648U;
9925 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9926 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
9927 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
9928 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
9929 put_gpr_w1(r1, mkexpr(result));
9930 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
9932 return "slak";
9935 static const HChar *
9936 s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
9938 IRTemp uop = newTemp(Ity_I64);
9939 IRTemp result = newTemp(Ity_I64);
9940 ULong sign_mask;
9941 IRTemp shift_amount = newTemp(Ity_I64);
9942 IRTemp op = newTemp(Ity_I64);
9944 assign(op, get_gpr_dw0(r3));
9945 assign(uop, get_gpr_dw0(r3));
9946 sign_mask = 9223372036854775808ULL;
9947 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
9948 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
9949 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
9950 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
9951 put_gpr_dw0(r1, mkexpr(result));
9952 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
9954 return "slag";
9957 static const HChar *
9958 s390_irgen_SLL(UChar r1, IRTemp op2addr)
9960 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
9961 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9963 return "sll";
9966 static const HChar *
9967 s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
9969 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
9970 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9972 return "sllk";
9975 static const HChar *
9976 s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
9978 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
9979 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9981 return "sllg";
9984 static const HChar *
9985 s390_irgen_SRDA(UChar r1, IRTemp op2addr)
9987 IRTemp p1 = newTemp(Ity_I64);
9988 IRTemp p2 = newTemp(Ity_I64);
9989 IRTemp result = newTemp(Ity_I64);
9991 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
9992 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
9993 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
9994 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
9995 mkexpr(op2addr), mkU64(63)))));
9996 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
9997 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
9998 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
10000 return "srda";
10003 static const HChar *
10004 s390_irgen_SRDL(UChar r1, IRTemp op2addr)
10006 IRTemp p1 = newTemp(Ity_I64);
10007 IRTemp p2 = newTemp(Ity_I64);
10008 IRTemp result = newTemp(Ity_I64);
10010 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
10011 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
10012 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
10013 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
10014 mkexpr(op2addr), mkU64(63)))));
10015 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
10016 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
10018 return "srdl";
10021 static const HChar *
10022 s390_irgen_SRA(UChar r1, IRTemp op2addr)
10024 IRTemp result = newTemp(Ity_I32);
10025 IRTemp op = newTemp(Ity_I32);
10027 assign(op, get_gpr_w1(r1));
10028 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
10029 mkexpr(op2addr), mkU64(63)))));
10030 put_gpr_w1(r1, mkexpr(result));
10031 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
10033 return "sra";
10036 static const HChar *
10037 s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
10039 IRTemp result = newTemp(Ity_I32);
10040 IRTemp op = newTemp(Ity_I32);
10042 assign(op, get_gpr_w1(r3));
10043 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
10044 mkexpr(op2addr), mkU64(63)))));
10045 put_gpr_w1(r1, mkexpr(result));
10046 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
10048 return "srak";
10051 static const HChar *
10052 s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
10054 IRTemp result = newTemp(Ity_I64);
10055 IRTemp op = newTemp(Ity_I64);
10057 assign(op, get_gpr_dw0(r3));
10058 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
10059 mkexpr(op2addr), mkU64(63)))));
10060 put_gpr_dw0(r1, mkexpr(result));
10061 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
10063 return "srag";
10066 static const HChar *
10067 s390_irgen_SRL(UChar r1, IRTemp op2addr)
10069 IRTemp op = newTemp(Ity_I32);
10071 assign(op, get_gpr_w1(r1));
10072 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
10073 mkexpr(op2addr), mkU64(63)))));
10075 return "srl";
10078 static const HChar *
10079 s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
10081 IRTemp op = newTemp(Ity_I32);
10083 assign(op, get_gpr_w1(r3));
10084 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
10085 mkexpr(op2addr), mkU64(63)))));
10087 return "srlk";
10090 static const HChar *
10091 s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
10093 IRTemp op = newTemp(Ity_I64);
10095 assign(op, get_gpr_dw0(r3));
10096 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
10097 mkexpr(op2addr), mkU64(63)))));
10099 return "srlg";
10102 static const HChar *
10103 s390_irgen_ST(UChar r1, IRTemp op2addr)
10105 store(mkexpr(op2addr), get_gpr_w1(r1));
10107 return "st";
10110 static const HChar *
10111 s390_irgen_STY(UChar r1, IRTemp op2addr)
10113 store(mkexpr(op2addr), get_gpr_w1(r1));
10115 return "sty";
10118 static const HChar *
10119 s390_irgen_STG(UChar r1, IRTemp op2addr)
10121 store(mkexpr(op2addr), get_gpr_dw0(r1));
10123 return "stg";
10126 static const HChar *
10127 s390_irgen_STRL(UChar r1, UInt i2)
10129 store(mkU64(addr_rel_long(i2)), get_gpr_w1(r1));
10131 return "strl";
10134 static const HChar *
10135 s390_irgen_STGRL(UChar r1, UInt i2)
10137 store(mkU64(addr_rel_long(i2)), get_gpr_dw0(r1));
10139 return "stgrl";
10142 static const HChar *
10143 s390_irgen_STC(UChar r1, IRTemp op2addr)
10145 store(mkexpr(op2addr), get_gpr_b7(r1));
10147 return "stc";
10150 static const HChar *
10151 s390_irgen_STCY(UChar r1, IRTemp op2addr)
10153 store(mkexpr(op2addr), get_gpr_b7(r1));
10155 return "stcy";
10158 static const HChar *
10159 s390_irgen_STCH(UChar r1, IRTemp op2addr)
10161 store(mkexpr(op2addr), get_gpr_b3(r1));
10163 return "stch";
10166 static const HChar *
10167 s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
10169 UChar mask;
10170 UChar n;
10172 mask = (UChar)r3;
10173 n = 0;
10174 if ((mask & 8) != 0) {
10175 store(mkexpr(op2addr), get_gpr_b4(r1));
10176 n = n + 1;
10178 if ((mask & 4) != 0) {
10179 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
10180 n = n + 1;
10182 if ((mask & 2) != 0) {
10183 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
10184 n = n + 1;
10186 if ((mask & 1) != 0) {
10187 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
10190 return "stcm";
10193 static const HChar *
10194 s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
10196 UChar mask;
10197 UChar n;
10199 mask = (UChar)r3;
10200 n = 0;
10201 if ((mask & 8) != 0) {
10202 store(mkexpr(op2addr), get_gpr_b4(r1));
10203 n = n + 1;
10205 if ((mask & 4) != 0) {
10206 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
10207 n = n + 1;
10209 if ((mask & 2) != 0) {
10210 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
10211 n = n + 1;
10213 if ((mask & 1) != 0) {
10214 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
10217 return "stcmy";
10220 static const HChar *
10221 s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
10223 UChar mask;
10224 UChar n;
10226 mask = (UChar)r3;
10227 n = 0;
10228 if ((mask & 8) != 0) {
10229 store(mkexpr(op2addr), get_gpr_b0(r1));
10230 n = n + 1;
10232 if ((mask & 4) != 0) {
10233 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
10234 n = n + 1;
10236 if ((mask & 2) != 0) {
10237 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
10238 n = n + 1;
10240 if ((mask & 1) != 0) {
10241 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
10244 return "stcmh";
10247 static const HChar *
10248 s390_irgen_STH(UChar r1, IRTemp op2addr)
10250 store(mkexpr(op2addr), get_gpr_hw3(r1));
10252 return "sth";
10255 static const HChar *
10256 s390_irgen_STHY(UChar r1, IRTemp op2addr)
10258 store(mkexpr(op2addr), get_gpr_hw3(r1));
10260 return "sthy";
10263 static const HChar *
10264 s390_irgen_STHRL(UChar r1, UInt i2)
10266 store(mkU64(addr_rel_long(i2)), get_gpr_hw3(r1));
10268 return "sthrl";
10271 static const HChar *
10272 s390_irgen_STHH(UChar r1, IRTemp op2addr)
10274 store(mkexpr(op2addr), get_gpr_hw1(r1));
10276 return "sthh";
10279 static const HChar *
10280 s390_irgen_STFH(UChar r1, IRTemp op2addr)
10282 store(mkexpr(op2addr), get_gpr_w0(r1));
10284 return "stfh";
10287 static const HChar *
10288 s390_irgen_STOC(UChar r1, IRTemp op2addr)
10290 /* condition is checked in format handler */
10291 store(mkexpr(op2addr), get_gpr_w1(r1));
10293 return "stoc";
10296 static const HChar *
10297 s390_irgen_STOCG(UChar r1, IRTemp op2addr)
10299 /* condition is checked in format handler */
10300 store(mkexpr(op2addr), get_gpr_dw0(r1));
10302 return "stocg";
10305 static const HChar *
10306 s390_irgen_STPQ(UChar r1, IRTemp op2addr)
10308 store(mkexpr(op2addr), get_gpr_dw0(r1));
10309 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
10311 return "stpq";
10314 static const HChar *
10315 s390_irgen_STRVH(UChar r1, IRTemp op2addr)
10317 store(mkexpr(op2addr), get_gpr_b7(r1));
10318 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
10320 return "strvh";
10323 static const HChar *
10324 s390_irgen_STRV(UChar r1, IRTemp op2addr)
10326 store(mkexpr(op2addr), get_gpr_b7(r1));
10327 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
10328 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
10329 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
10331 return "strv";
10334 static const HChar *
10335 s390_irgen_STRVG(UChar r1, IRTemp op2addr)
10337 store(mkexpr(op2addr), get_gpr_b7(r1));
10338 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
10339 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
10340 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
10341 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
10342 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
10343 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
10344 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
10346 return "strvg";
10349 static const HChar *
10350 s390_irgen_SR(UChar r1, UChar r2)
10352 IRTemp op1 = newTemp(Ity_I32);
10353 IRTemp op2 = newTemp(Ity_I32);
10354 IRTemp result = newTemp(Ity_I32);
10356 assign(op1, get_gpr_w1(r1));
10357 assign(op2, get_gpr_w1(r2));
10358 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10359 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
10360 put_gpr_w1(r1, mkexpr(result));
10362 return "sr";
10365 static const HChar *
10366 s390_irgen_SGR(UChar r1, UChar r2)
10368 IRTemp op1 = newTemp(Ity_I64);
10369 IRTemp op2 = newTemp(Ity_I64);
10370 IRTemp result = newTemp(Ity_I64);
10372 assign(op1, get_gpr_dw0(r1));
10373 assign(op2, get_gpr_dw0(r2));
10374 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10375 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
10376 put_gpr_dw0(r1, mkexpr(result));
10378 return "sgr";
10381 static const HChar *
10382 s390_irgen_SGFR(UChar r1, UChar r2)
10384 IRTemp op1 = newTemp(Ity_I64);
10385 IRTemp op2 = newTemp(Ity_I64);
10386 IRTemp result = newTemp(Ity_I64);
10388 assign(op1, get_gpr_dw0(r1));
10389 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10390 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10391 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
10392 put_gpr_dw0(r1, mkexpr(result));
10394 return "sgfr";
10397 static const HChar *
10398 s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
10400 IRTemp op2 = newTemp(Ity_I32);
10401 IRTemp op3 = newTemp(Ity_I32);
10402 IRTemp result = newTemp(Ity_I32);
10404 assign(op2, get_gpr_w1(r2));
10405 assign(op3, get_gpr_w1(r3));
10406 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10407 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
10408 put_gpr_w1(r1, mkexpr(result));
10410 return "srk";
10413 static const HChar *
10414 s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
10416 IRTemp op2 = newTemp(Ity_I64);
10417 IRTemp op3 = newTemp(Ity_I64);
10418 IRTemp result = newTemp(Ity_I64);
10420 assign(op2, get_gpr_dw0(r2));
10421 assign(op3, get_gpr_dw0(r3));
10422 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
10423 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
10424 put_gpr_dw0(r1, mkexpr(result));
10426 return "sgrk";
10429 static const HChar *
10430 s390_irgen_S(UChar r1, IRTemp op2addr)
10432 IRTemp op1 = newTemp(Ity_I32);
10433 IRTemp op2 = newTemp(Ity_I32);
10434 IRTemp result = newTemp(Ity_I32);
10436 assign(op1, get_gpr_w1(r1));
10437 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10438 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10439 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
10440 put_gpr_w1(r1, mkexpr(result));
10442 return "s";
10445 static const HChar *
10446 s390_irgen_SY(UChar r1, IRTemp op2addr)
10448 IRTemp op1 = newTemp(Ity_I32);
10449 IRTemp op2 = newTemp(Ity_I32);
10450 IRTemp result = newTemp(Ity_I32);
10452 assign(op1, get_gpr_w1(r1));
10453 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10454 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10455 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
10456 put_gpr_w1(r1, mkexpr(result));
10458 return "sy";
10461 static const HChar *
10462 s390_irgen_SG(UChar r1, IRTemp op2addr)
10464 IRTemp op1 = newTemp(Ity_I64);
10465 IRTemp op2 = newTemp(Ity_I64);
10466 IRTemp result = newTemp(Ity_I64);
10468 assign(op1, get_gpr_dw0(r1));
10469 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10470 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10471 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
10472 put_gpr_dw0(r1, mkexpr(result));
10474 return "sg";
10477 static const HChar *
10478 s390_irgen_SGF(UChar r1, IRTemp op2addr)
10480 IRTemp op1 = newTemp(Ity_I64);
10481 IRTemp op2 = newTemp(Ity_I64);
10482 IRTemp result = newTemp(Ity_I64);
10484 assign(op1, get_gpr_dw0(r1));
10485 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10486 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10487 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
10488 put_gpr_dw0(r1, mkexpr(result));
10490 return "sgf";
10493 static const HChar *
10494 s390_irgen_SGH(UChar r1, IRTemp op2addr)
10496 IRTemp op1 = newTemp(Ity_I64);
10497 IRTemp op2 = newTemp(Ity_I64);
10498 IRTemp result = newTemp(Ity_I64);
10500 assign(op1, get_gpr_dw0(r1));
10501 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
10502 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10503 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
10504 put_gpr_dw0(r1, mkexpr(result));
10506 return "sgh";
10509 static const HChar *
10510 s390_irgen_SH(UChar r1, IRTemp op2addr)
10512 IRTemp op1 = newTemp(Ity_I32);
10513 IRTemp op2 = newTemp(Ity_I32);
10514 IRTemp result = newTemp(Ity_I32);
10516 assign(op1, get_gpr_w1(r1));
10517 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
10518 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10519 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
10520 put_gpr_w1(r1, mkexpr(result));
10522 return "sh";
10525 static const HChar *
10526 s390_irgen_SHY(UChar r1, IRTemp op2addr)
10528 IRTemp op1 = newTemp(Ity_I32);
10529 IRTemp op2 = newTemp(Ity_I32);
10530 IRTemp result = newTemp(Ity_I32);
10532 assign(op1, get_gpr_w1(r1));
10533 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
10534 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10535 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
10536 put_gpr_w1(r1, mkexpr(result));
10538 return "shy";
10541 static const HChar *
10542 s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
10544 IRTemp op2 = newTemp(Ity_I32);
10545 IRTemp op3 = newTemp(Ity_I32);
10546 IRTemp result = newTemp(Ity_I32);
10548 assign(op2, get_gpr_w0(r1));
10549 assign(op3, get_gpr_w0(r2));
10550 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10551 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
10552 put_gpr_w0(r1, mkexpr(result));
10554 return "shhhr";
10557 static const HChar *
10558 s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
10560 IRTemp op2 = newTemp(Ity_I32);
10561 IRTemp op3 = newTemp(Ity_I32);
10562 IRTemp result = newTemp(Ity_I32);
10564 assign(op2, get_gpr_w0(r1));
10565 assign(op3, get_gpr_w1(r2));
10566 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10567 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
10568 put_gpr_w0(r1, mkexpr(result));
10570 return "shhlr";
10573 static const HChar *
10574 s390_irgen_SLR(UChar r1, UChar r2)
10576 IRTemp op1 = newTemp(Ity_I32);
10577 IRTemp op2 = newTemp(Ity_I32);
10578 IRTemp result = newTemp(Ity_I32);
10580 assign(op1, get_gpr_w1(r1));
10581 assign(op2, get_gpr_w1(r2));
10582 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10583 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
10584 put_gpr_w1(r1, mkexpr(result));
10586 return "slr";
10589 static const HChar *
10590 s390_irgen_SLGR(UChar r1, UChar r2)
10592 IRTemp op1 = newTemp(Ity_I64);
10593 IRTemp op2 = newTemp(Ity_I64);
10594 IRTemp result = newTemp(Ity_I64);
10596 assign(op1, get_gpr_dw0(r1));
10597 assign(op2, get_gpr_dw0(r2));
10598 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10599 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
10600 put_gpr_dw0(r1, mkexpr(result));
10602 return "slgr";
10605 static const HChar *
10606 s390_irgen_SLGFR(UChar r1, UChar r2)
10608 IRTemp op1 = newTemp(Ity_I64);
10609 IRTemp op2 = newTemp(Ity_I64);
10610 IRTemp result = newTemp(Ity_I64);
10612 assign(op1, get_gpr_dw0(r1));
10613 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
10614 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10615 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
10616 put_gpr_dw0(r1, mkexpr(result));
10618 return "slgfr";
10621 static const HChar *
10622 s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
10624 IRTemp op2 = newTemp(Ity_I32);
10625 IRTemp op3 = newTemp(Ity_I32);
10626 IRTemp result = newTemp(Ity_I32);
10628 assign(op2, get_gpr_w1(r2));
10629 assign(op3, get_gpr_w1(r3));
10630 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10631 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
10632 put_gpr_w1(r1, mkexpr(result));
10634 return "slrk";
10637 static const HChar *
10638 s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
10640 IRTemp op2 = newTemp(Ity_I64);
10641 IRTemp op3 = newTemp(Ity_I64);
10642 IRTemp result = newTemp(Ity_I64);
10644 assign(op2, get_gpr_dw0(r2));
10645 assign(op3, get_gpr_dw0(r3));
10646 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
10647 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
10648 put_gpr_dw0(r1, mkexpr(result));
10650 return "slgrk";
10653 static const HChar *
10654 s390_irgen_SL(UChar r1, IRTemp op2addr)
10656 IRTemp op1 = newTemp(Ity_I32);
10657 IRTemp op2 = newTemp(Ity_I32);
10658 IRTemp result = newTemp(Ity_I32);
10660 assign(op1, get_gpr_w1(r1));
10661 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10662 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10663 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
10664 put_gpr_w1(r1, mkexpr(result));
10666 return "sl";
10669 static const HChar *
10670 s390_irgen_SLY(UChar r1, IRTemp op2addr)
10672 IRTemp op1 = newTemp(Ity_I32);
10673 IRTemp op2 = newTemp(Ity_I32);
10674 IRTemp result = newTemp(Ity_I32);
10676 assign(op1, get_gpr_w1(r1));
10677 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10678 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
10679 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
10680 put_gpr_w1(r1, mkexpr(result));
10682 return "sly";
10685 static const HChar *
10686 s390_irgen_SLG(UChar r1, IRTemp op2addr)
10688 IRTemp op1 = newTemp(Ity_I64);
10689 IRTemp op2 = newTemp(Ity_I64);
10690 IRTemp result = newTemp(Ity_I64);
10692 assign(op1, get_gpr_dw0(r1));
10693 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10694 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10695 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
10696 put_gpr_dw0(r1, mkexpr(result));
10698 return "slg";
10701 static const HChar *
10702 s390_irgen_SLGF(UChar r1, IRTemp op2addr)
10704 IRTemp op1 = newTemp(Ity_I64);
10705 IRTemp op2 = newTemp(Ity_I64);
10706 IRTemp result = newTemp(Ity_I64);
10708 assign(op1, get_gpr_dw0(r1));
10709 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
10710 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
10711 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
10712 put_gpr_dw0(r1, mkexpr(result));
10714 return "slgf";
10717 static const HChar *
10718 s390_irgen_SLFI(UChar r1, UInt i2)
10720 IRTemp op1 = newTemp(Ity_I32);
10721 UInt op2;
10722 IRTemp result = newTemp(Ity_I32);
10724 assign(op1, get_gpr_w1(r1));
10725 op2 = i2;
10726 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
10727 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
10728 mkU32(op2)));
10729 put_gpr_w1(r1, mkexpr(result));
10731 return "slfi";
10734 static const HChar *
10735 s390_irgen_SLGFI(UChar r1, UInt i2)
10737 IRTemp op1 = newTemp(Ity_I64);
10738 ULong op2;
10739 IRTemp result = newTemp(Ity_I64);
10741 assign(op1, get_gpr_dw0(r1));
10742 op2 = (ULong)i2;
10743 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
10744 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
10745 mkU64(op2)));
10746 put_gpr_dw0(r1, mkexpr(result));
10748 return "slgfi";
10751 static const HChar *
10752 s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
10754 IRTemp op2 = newTemp(Ity_I32);
10755 IRTemp op3 = newTemp(Ity_I32);
10756 IRTemp result = newTemp(Ity_I32);
10758 assign(op2, get_gpr_w0(r1));
10759 assign(op3, get_gpr_w0(r2));
10760 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10761 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
10762 put_gpr_w0(r1, mkexpr(result));
10764 return "slhhhr";
10767 static const HChar *
10768 s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
10770 IRTemp op2 = newTemp(Ity_I32);
10771 IRTemp op3 = newTemp(Ity_I32);
10772 IRTemp result = newTemp(Ity_I32);
10774 assign(op2, get_gpr_w0(r1));
10775 assign(op3, get_gpr_w1(r2));
10776 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
10777 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
10778 put_gpr_w0(r1, mkexpr(result));
10780 return "slhhlr";
10783 static const HChar *
10784 s390_irgen_SLBR(UChar r1, UChar r2)
10786 IRTemp op1 = newTemp(Ity_I32);
10787 IRTemp op2 = newTemp(Ity_I32);
10788 IRTemp result = newTemp(Ity_I32);
10789 IRTemp borrow_in = newTemp(Ity_I32);
10791 assign(op1, get_gpr_w1(r1));
10792 assign(op2, get_gpr_w1(r2));
10793 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
10794 s390_call_calculate_cc(), mkU8(1))));
10795 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
10796 mkexpr(borrow_in)));
10797 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
10798 put_gpr_w1(r1, mkexpr(result));
10800 return "slbr";
10803 static const HChar *
10804 s390_irgen_SLBGR(UChar r1, UChar r2)
10806 IRTemp op1 = newTemp(Ity_I64);
10807 IRTemp op2 = newTemp(Ity_I64);
10808 IRTemp result = newTemp(Ity_I64);
10809 IRTemp borrow_in = newTemp(Ity_I64);
10811 assign(op1, get_gpr_dw0(r1));
10812 assign(op2, get_gpr_dw0(r2));
10813 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
10814 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
10815 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
10816 mkexpr(borrow_in)));
10817 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
10818 put_gpr_dw0(r1, mkexpr(result));
10820 return "slbgr";
10823 static const HChar *
10824 s390_irgen_SLB(UChar r1, IRTemp op2addr)
10826 IRTemp op1 = newTemp(Ity_I32);
10827 IRTemp op2 = newTemp(Ity_I32);
10828 IRTemp result = newTemp(Ity_I32);
10829 IRTemp borrow_in = newTemp(Ity_I32);
10831 assign(op1, get_gpr_w1(r1));
10832 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10833 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
10834 s390_call_calculate_cc(), mkU8(1))));
10835 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
10836 mkexpr(borrow_in)));
10837 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
10838 put_gpr_w1(r1, mkexpr(result));
10840 return "slb";
10843 static const HChar *
10844 s390_irgen_SLBG(UChar r1, IRTemp op2addr)
10846 IRTemp op1 = newTemp(Ity_I64);
10847 IRTemp op2 = newTemp(Ity_I64);
10848 IRTemp result = newTemp(Ity_I64);
10849 IRTemp borrow_in = newTemp(Ity_I64);
10851 assign(op1, get_gpr_dw0(r1));
10852 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10853 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
10854 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
10855 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
10856 mkexpr(borrow_in)));
10857 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
10858 put_gpr_dw0(r1, mkexpr(result));
10860 return "slbg";
10863 static const HChar *
10864 s390_irgen_SVC(UChar i)
10866 IRTemp sysno = newTemp(Ity_I64);
10868 if (i != 0) {
10869 assign(sysno, mkU64(i));
10870 } else {
10871 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
10873 system_call(mkexpr(sysno));
10875 return "svc";
10878 static const HChar *
10879 s390_irgen_TM(UChar i2, IRTemp op1addr)
10881 UChar mask;
10882 IRTemp value = newTemp(Ity_I8);
10884 mask = i2;
10885 assign(value, load(Ity_I8, mkexpr(op1addr)));
10886 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
10887 mkU8(mask)));
10889 return "tm";
10892 static const HChar *
10893 s390_irgen_TMY(UChar i2, IRTemp op1addr)
10895 UChar mask;
10896 IRTemp value = newTemp(Ity_I8);
10898 mask = i2;
10899 assign(value, load(Ity_I8, mkexpr(op1addr)));
10900 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
10901 mkU8(mask)));
10903 return "tmy";
10906 static const HChar *
10907 s390_irgen_TMHH(UChar r1, UShort i2)
10909 UShort mask;
10910 IRTemp value = newTemp(Ity_I16);
10912 mask = i2;
10913 assign(value, get_gpr_hw0(r1));
10914 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
10915 mkU16(mask)));
10917 return "tmhh";
10920 static const HChar *
10921 s390_irgen_TMHL(UChar r1, UShort i2)
10923 UShort mask;
10924 IRTemp value = newTemp(Ity_I16);
10926 mask = i2;
10927 assign(value, get_gpr_hw1(r1));
10928 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
10929 mkU16(mask)));
10931 return "tmhl";
10934 static const HChar *
10935 s390_irgen_TMLH(UChar r1, UShort i2)
10937 UShort mask;
10938 IRTemp value = newTemp(Ity_I16);
10940 mask = i2;
10941 assign(value, get_gpr_hw2(r1));
10942 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
10943 mkU16(mask)));
10945 return "tmlh";
10948 static const HChar *
10949 s390_irgen_TMLL(UChar r1, UShort i2)
10951 UShort mask;
10952 IRTemp value = newTemp(Ity_I16);
10954 mask = i2;
10955 assign(value, get_gpr_hw3(r1));
10956 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
10957 mkU16(mask)));
10959 return "tmll";
10962 static const HChar *
10963 s390_irgen_EFPC(UChar r1)
10965 put_gpr_w1(r1, get_fpc_w0());
10967 return "efpc";
10970 static const HChar *
10971 s390_irgen_LER(UChar r1, UChar r2)
10973 put_fpr_w0(r1, get_fpr_w0(r2));
10975 return "ler";
10978 static const HChar *
10979 s390_irgen_LDR(UChar r1, UChar r2)
10981 put_fpr_dw0(r1, get_fpr_dw0(r2));
10983 return "ldr";
10986 static const HChar *
10987 s390_irgen_LDER(UChar r1, UChar r2)
10989 put_fpr_dw0(r1, mkF64i(0x0));
10990 put_fpr_w0(r1, get_fpr_w0(r2));
10992 return "lder";
10995 static const HChar *
10996 s390_irgen_LXR(UChar r1, UChar r2)
10998 put_fpr_dw0(r1, get_fpr_dw0(r2));
10999 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
11001 return "lxr";
11004 static const HChar *
11005 s390_irgen_LE(UChar r1, IRTemp op2addr)
11007 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
11009 return "le";
11012 static const HChar *
11013 s390_irgen_LD(UChar r1, IRTemp op2addr)
11015 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
11017 return "ld";
11020 static const HChar *
11021 s390_irgen_LDE(UChar r1, IRTemp op2addr)
11023 put_fpr_dw0(r1, mkF64i(0x0));
11024 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
11026 return "lde";
11029 static const HChar *
11030 s390_irgen_LEY(UChar r1, IRTemp op2addr)
11032 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
11034 return "ley";
11037 static const HChar *
11038 s390_irgen_LDY(UChar r1, IRTemp op2addr)
11040 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
11042 return "ldy";
11045 static const HChar *
11046 s390_irgen_LFPC(IRTemp op2addr)
11048 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
11050 return "lfpc";
11053 static const HChar *
11054 s390_irgen_LZER(UChar r1)
11056 put_fpr_w0(r1, mkF32i(0x0));
11058 return "lzer";
11061 static const HChar *
11062 s390_irgen_LZDR(UChar r1)
11064 put_fpr_dw0(r1, mkF64i(0x0));
11066 return "lzdr";
11069 static const HChar *
11070 s390_irgen_LZXR(UChar r1)
11072 put_fpr_dw0(r1, mkF64i(0x0));
11073 put_fpr_dw0(r1 + 2, mkF64i(0x0));
11075 return "lzxr";
11078 static const HChar *
11079 s390_irgen_SRNM(IRTemp op2addr)
11081 UInt input_mask, fpc_mask;
11083 input_mask = 3;
11084 fpc_mask = s390_host_has_fpext ? 7 : 3;
11086 put_fpc_w0(binop(Iop_Or32,
11087 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
11088 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
11089 mkU32(input_mask))));
11090 return "srnm";
11093 static const HChar *
11094 s390_irgen_SRNMB(IRTemp op2addr)
11096 UInt input_mask, fpc_mask;
11098 input_mask = 7;
11099 fpc_mask = 7;
11101 put_fpc_w0(binop(Iop_Or32,
11102 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
11103 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
11104 mkU32(input_mask))));
11105 return "srnmb";
11108 static void
11109 s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
11111 if (b2 == 0) { /* This is the typical case */
11112 if (d2 > 3) {
11113 if (s390_host_has_fpext && d2 == 7) {
11114 /* ok */
11115 } else {
11116 emulation_warning(EmWarn_S390X_invalid_rounding);
11117 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
11122 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
11125 /* Wrapper to validate the parameter as in SRNMB is not required, as all
11126 the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
11127 static const HChar *
11128 s390_irgen_SRNMT(IRTemp op2addr)
11130 UInt input_mask, fpc_mask;
11132 input_mask = 7;
11133 fpc_mask = 0x70;
11135 /* fpc[25:27] <- op2addr[61:63]
11136 fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
11137 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
11138 binop(Iop_Shl32, binop(Iop_And32,
11139 unop(Iop_64to32, mkexpr(op2addr)),
11140 mkU32(input_mask)), mkU8(4))));
11141 return "srnmt";
11145 static const HChar *
11146 s390_irgen_SFPC(UChar r1)
11148 put_fpc_w0(get_gpr_w1(r1));
11150 return "sfpc";
11153 static const HChar *
11154 s390_irgen_STE(UChar r1, IRTemp op2addr)
11156 store(mkexpr(op2addr), get_fpr_w0(r1));
11158 return "ste";
11161 static const HChar *
11162 s390_irgen_STD(UChar r1, IRTemp op2addr)
11164 store(mkexpr(op2addr), get_fpr_dw0(r1));
11166 return "std";
11169 static const HChar *
11170 s390_irgen_STEY(UChar r1, IRTemp op2addr)
11172 store(mkexpr(op2addr), get_fpr_w0(r1));
11174 return "stey";
11177 static const HChar *
11178 s390_irgen_STDY(UChar r1, IRTemp op2addr)
11180 store(mkexpr(op2addr), get_fpr_dw0(r1));
11182 return "stdy";
11185 static const HChar *
11186 s390_irgen_STFPC(IRTemp op2addr)
11188 store(mkexpr(op2addr), get_fpc_w0());
11190 return "stfpc";
11193 static const HChar *
11194 s390_irgen_AEBR(UChar r1, UChar r2)
11196 IRTemp op1 = newTemp(Ity_F32);
11197 IRTemp op2 = newTemp(Ity_F32);
11198 IRTemp result = newTemp(Ity_F32);
11199 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11201 assign(op1, get_fpr_w0(r1));
11202 assign(op2, get_fpr_w0(r2));
11203 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
11204 mkexpr(op2)));
11205 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11206 put_fpr_w0(r1, mkexpr(result));
11208 return "aebr";
11211 static const HChar *
11212 s390_irgen_ADBR(UChar r1, UChar r2)
11214 IRTemp op1 = newTemp(Ity_F64);
11215 IRTemp op2 = newTemp(Ity_F64);
11216 IRTemp result = newTemp(Ity_F64);
11217 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11219 assign(op1, get_fpr_dw0(r1));
11220 assign(op2, get_fpr_dw0(r2));
11221 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
11222 mkexpr(op2)));
11223 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11224 put_fpr_dw0(r1, mkexpr(result));
11226 return "adbr";
11229 static const HChar *
11230 s390_irgen_AEB(UChar r1, IRTemp op2addr)
11232 IRTemp op1 = newTemp(Ity_F32);
11233 IRTemp op2 = newTemp(Ity_F32);
11234 IRTemp result = newTemp(Ity_F32);
11235 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11237 assign(op1, get_fpr_w0(r1));
11238 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11239 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
11240 mkexpr(op2)));
11241 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11242 put_fpr_w0(r1, mkexpr(result));
11244 return "aeb";
11247 static const HChar *
11248 s390_irgen_ADB(UChar r1, IRTemp op2addr)
11250 IRTemp op1 = newTemp(Ity_F64);
11251 IRTemp op2 = newTemp(Ity_F64);
11252 IRTemp result = newTemp(Ity_F64);
11253 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11255 assign(op1, get_fpr_dw0(r1));
11256 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11257 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
11258 mkexpr(op2)));
11259 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11260 put_fpr_dw0(r1, mkexpr(result));
11262 return "adb";
11265 static const HChar *
11266 s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
11267 UChar r1, UChar r2)
11269 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
11270 emulation_warning(EmWarn_S390X_fpext_rounding);
11271 m3 = S390_BFP_ROUND_PER_FPC;
11273 IRTemp op2 = newTemp(Ity_I32);
11275 assign(op2, get_gpr_w1(r2));
11276 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
11277 mkexpr(op2)));
11279 return "cefbr";
11282 static const HChar *
11283 s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
11284 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11286 IRTemp op2 = newTemp(Ity_I32);
11288 assign(op2, get_gpr_w1(r2));
11289 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
11291 return "cdfbr";
11294 static const HChar *
11295 s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
11296 UChar r1, UChar r2)
11298 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
11299 emulation_warning(EmWarn_S390X_fpext_rounding);
11300 m3 = S390_BFP_ROUND_PER_FPC;
11302 IRTemp op2 = newTemp(Ity_I64);
11304 assign(op2, get_gpr_dw0(r2));
11305 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
11306 mkexpr(op2)));
11308 return "cegbr";
11311 static const HChar *
11312 s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
11313 UChar r1, UChar r2)
11315 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
11316 emulation_warning(EmWarn_S390X_fpext_rounding);
11317 m3 = S390_BFP_ROUND_PER_FPC;
11319 IRTemp op2 = newTemp(Ity_I64);
11321 assign(op2, get_gpr_dw0(r2));
11322 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
11323 mkexpr(op2)));
11325 return "cdgbr";
11328 static const HChar *
11329 s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
11330 UChar r1, UChar r2)
11332 if (! s390_host_has_fpext) {
11333 emulation_failure(EmFail_S390X_fpext);
11334 } else {
11335 IRTemp op2 = newTemp(Ity_I32);
11337 assign(op2, get_gpr_w1(r2));
11338 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
11339 mkexpr(op2)));
11341 return "celfbr";
11344 static const HChar *
11345 s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
11346 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11348 if (! s390_host_has_fpext) {
11349 emulation_failure(EmFail_S390X_fpext);
11350 } else {
11351 IRTemp op2 = newTemp(Ity_I32);
11353 assign(op2, get_gpr_w1(r2));
11354 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
11356 return "cdlfbr";
11359 static const HChar *
11360 s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
11361 UChar r1, UChar r2)
11363 if (! s390_host_has_fpext) {
11364 emulation_failure(EmFail_S390X_fpext);
11365 } else {
11366 IRTemp op2 = newTemp(Ity_I64);
11368 assign(op2, get_gpr_dw0(r2));
11369 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
11370 mkexpr(op2)));
11372 return "celgbr";
11375 static const HChar *
11376 s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
11377 UChar r1, UChar r2)
11379 if (! s390_host_has_fpext) {
11380 emulation_failure(EmFail_S390X_fpext);
11381 } else {
11382 IRTemp op2 = newTemp(Ity_I64);
11384 assign(op2, get_gpr_dw0(r2));
11385 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
11386 mkexpr(encode_bfp_rounding_mode(m3)),
11387 mkexpr(op2)));
11389 return "cdlgbr";
11392 static const HChar *
11393 s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
11394 UChar r1, UChar r2)
11396 if (! s390_host_has_fpext) {
11397 emulation_failure(EmFail_S390X_fpext);
11398 } else {
11399 IRTemp op = newTemp(Ity_F32);
11400 IRTemp result = newTemp(Ity_I32);
11401 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11403 assign(op, get_fpr_w0(r2));
11404 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
11405 mkexpr(op)));
11406 put_gpr_w1(r1, mkexpr(result));
11407 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
11409 return "clfebr";
11412 static const HChar *
11413 s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
11414 UChar r1, UChar r2)
11416 if (! s390_host_has_fpext) {
11417 emulation_failure(EmFail_S390X_fpext);
11418 } else {
11419 IRTemp op = newTemp(Ity_F64);
11420 IRTemp result = newTemp(Ity_I32);
11421 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11423 assign(op, get_fpr_dw0(r2));
11424 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
11425 mkexpr(op)));
11426 put_gpr_w1(r1, mkexpr(result));
11427 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
11429 return "clfdbr";
11432 static const HChar *
11433 s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
11434 UChar r1, UChar r2)
11436 if (! s390_host_has_fpext) {
11437 emulation_failure(EmFail_S390X_fpext);
11438 } else {
11439 IRTemp op = newTemp(Ity_F32);
11440 IRTemp result = newTemp(Ity_I64);
11441 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11443 assign(op, get_fpr_w0(r2));
11444 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
11445 mkexpr(op)));
11446 put_gpr_dw0(r1, mkexpr(result));
11447 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
11449 return "clgebr";
11452 static const HChar *
11453 s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
11454 UChar r1, UChar r2)
11456 if (! s390_host_has_fpext) {
11457 emulation_failure(EmFail_S390X_fpext);
11458 } else {
11459 IRTemp op = newTemp(Ity_F64);
11460 IRTemp result = newTemp(Ity_I64);
11461 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11463 assign(op, get_fpr_dw0(r2));
11464 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
11465 mkexpr(op)));
11466 put_gpr_dw0(r1, mkexpr(result));
11467 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
11469 return "clgdbr";
11472 static const HChar *
11473 s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
11474 UChar r1, UChar r2)
11476 IRTemp op = newTemp(Ity_F32);
11477 IRTemp result = newTemp(Ity_I32);
11478 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11480 assign(op, get_fpr_w0(r2));
11481 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
11482 mkexpr(op)));
11483 put_gpr_w1(r1, mkexpr(result));
11484 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
11486 return "cfebr";
11489 static const HChar *
11490 s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
11491 UChar r1, UChar r2)
11493 IRTemp op = newTemp(Ity_F64);
11494 IRTemp result = newTemp(Ity_I32);
11495 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11497 assign(op, get_fpr_dw0(r2));
11498 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
11499 mkexpr(op)));
11500 put_gpr_w1(r1, mkexpr(result));
11501 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
11503 return "cfdbr";
11506 static const HChar *
11507 s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
11508 UChar r1, UChar r2)
11510 IRTemp op = newTemp(Ity_F32);
11511 IRTemp result = newTemp(Ity_I64);
11512 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11514 assign(op, get_fpr_w0(r2));
11515 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
11516 mkexpr(op)));
11517 put_gpr_dw0(r1, mkexpr(result));
11518 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
11520 return "cgebr";
11523 static const HChar *
11524 s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
11525 UChar r1, UChar r2)
11527 IRTemp op = newTemp(Ity_F64);
11528 IRTemp result = newTemp(Ity_I64);
11529 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
11531 assign(op, get_fpr_dw0(r2));
11532 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
11533 mkexpr(op)));
11534 put_gpr_dw0(r1, mkexpr(result));
11535 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
11537 return "cgdbr";
11540 static const HChar *
11541 s390_irgen_DEBR(UChar r1, UChar r2)
11543 IRTemp op1 = newTemp(Ity_F32);
11544 IRTemp op2 = newTemp(Ity_F32);
11545 IRTemp result = newTemp(Ity_F32);
11546 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11548 assign(op1, get_fpr_w0(r1));
11549 assign(op2, get_fpr_w0(r2));
11550 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
11551 mkexpr(op2)));
11552 put_fpr_w0(r1, mkexpr(result));
11554 return "debr";
11557 static const HChar *
11558 s390_irgen_DDBR(UChar r1, UChar r2)
11560 IRTemp op1 = newTemp(Ity_F64);
11561 IRTemp op2 = newTemp(Ity_F64);
11562 IRTemp result = newTemp(Ity_F64);
11563 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11565 assign(op1, get_fpr_dw0(r1));
11566 assign(op2, get_fpr_dw0(r2));
11567 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
11568 mkexpr(op2)));
11569 put_fpr_dw0(r1, mkexpr(result));
11571 return "ddbr";
11574 static const HChar *
11575 s390_irgen_DEB(UChar r1, IRTemp op2addr)
11577 IRTemp op1 = newTemp(Ity_F32);
11578 IRTemp op2 = newTemp(Ity_F32);
11579 IRTemp result = newTemp(Ity_F32);
11580 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11582 assign(op1, get_fpr_w0(r1));
11583 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11584 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
11585 mkexpr(op2)));
11586 put_fpr_w0(r1, mkexpr(result));
11588 return "deb";
11591 static const HChar *
11592 s390_irgen_DDB(UChar r1, IRTemp op2addr)
11594 IRTemp op1 = newTemp(Ity_F64);
11595 IRTemp op2 = newTemp(Ity_F64);
11596 IRTemp result = newTemp(Ity_F64);
11597 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11599 assign(op1, get_fpr_dw0(r1));
11600 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11601 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
11602 mkexpr(op2)));
11603 put_fpr_dw0(r1, mkexpr(result));
11605 return "ddb";
11608 static const HChar *
11609 s390_irgen_LTEBR(UChar r1, UChar r2)
11611 IRTemp result = newTemp(Ity_F32);
11613 assign(result, get_fpr_w0(r2));
11614 put_fpr_w0(r1, mkexpr(result));
11615 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11617 return "ltebr";
11620 static const HChar *
11621 s390_irgen_LTDBR(UChar r1, UChar r2)
11623 IRTemp result = newTemp(Ity_F64);
11625 assign(result, get_fpr_dw0(r2));
11626 put_fpr_dw0(r1, mkexpr(result));
11627 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11629 return "ltdbr";
11632 static const HChar *
11633 s390_irgen_LCEBR(UChar r1, UChar r2)
11635 IRTemp result = newTemp(Ity_F32);
11637 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
11638 put_fpr_w0(r1, mkexpr(result));
11639 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11641 return "lcebr";
11644 static const HChar *
11645 s390_irgen_LCDBR(UChar r1, UChar r2)
11647 IRTemp result = newTemp(Ity_F64);
11649 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11650 put_fpr_dw0(r1, mkexpr(result));
11651 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11653 return "lcdbr";
11656 static const HChar *
11657 s390_irgen_LDEBR(UChar r1, UChar r2)
11659 IRTemp op = newTemp(Ity_F32);
11661 assign(op, get_fpr_w0(r2));
11662 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
11664 return "ldebr";
11667 static const HChar *
11668 s390_irgen_LDEB(UChar r1, IRTemp op2addr)
11670 IRTemp op = newTemp(Ity_F32);
11672 assign(op, load(Ity_F32, mkexpr(op2addr)));
11673 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
11675 return "ldeb";
11678 static const HChar *
11679 s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
11680 UChar r1, UChar r2)
11682 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
11683 emulation_warning(EmWarn_S390X_fpext_rounding);
11684 m3 = S390_BFP_ROUND_PER_FPC;
11686 IRTemp op = newTemp(Ity_F64);
11688 assign(op, get_fpr_dw0(r2));
11689 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
11690 mkexpr(op)));
11692 return "ledbr";
11695 static const HChar *
11696 s390_irgen_MEEBR(UChar r1, UChar r2)
11698 IRTemp op1 = newTemp(Ity_F32);
11699 IRTemp op2 = newTemp(Ity_F32);
11700 IRTemp result = newTemp(Ity_F32);
11701 IRRoundingMode rounding_mode =
11702 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11704 assign(op1, get_fpr_w0(r1));
11705 assign(op2, get_fpr_w0(r2));
11706 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
11707 mkexpr(op2)));
11708 put_fpr_w0(r1, mkexpr(result));
11710 return "meebr";
11713 static const HChar *
11714 s390_irgen_MDBR(UChar r1, UChar r2)
11716 IRTemp op1 = newTemp(Ity_F64);
11717 IRTemp op2 = newTemp(Ity_F64);
11718 IRTemp result = newTemp(Ity_F64);
11719 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11721 assign(op1, get_fpr_dw0(r1));
11722 assign(op2, get_fpr_dw0(r2));
11723 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
11724 mkexpr(op2)));
11725 put_fpr_dw0(r1, mkexpr(result));
11727 return "mdbr";
11730 static const HChar *
11731 s390_irgen_MEEB(UChar r1, IRTemp op2addr)
11733 IRTemp op1 = newTemp(Ity_F32);
11734 IRTemp op2 = newTemp(Ity_F32);
11735 IRTemp result = newTemp(Ity_F32);
11736 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11738 assign(op1, get_fpr_w0(r1));
11739 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11740 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
11741 mkexpr(op2)));
11742 put_fpr_w0(r1, mkexpr(result));
11744 return "meeb";
11747 static const HChar *
11748 s390_irgen_MDB(UChar r1, IRTemp op2addr)
11750 IRTemp op1 = newTemp(Ity_F64);
11751 IRTemp op2 = newTemp(Ity_F64);
11752 IRTemp result = newTemp(Ity_F64);
11753 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11755 assign(op1, get_fpr_dw0(r1));
11756 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11757 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
11758 mkexpr(op2)));
11759 put_fpr_dw0(r1, mkexpr(result));
11761 return "mdb";
11764 static const HChar *
11765 s390_irgen_SEBR(UChar r1, UChar r2)
11767 IRTemp op1 = newTemp(Ity_F32);
11768 IRTemp op2 = newTemp(Ity_F32);
11769 IRTemp result = newTemp(Ity_F32);
11770 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11772 assign(op1, get_fpr_w0(r1));
11773 assign(op2, get_fpr_w0(r2));
11774 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
11775 mkexpr(op2)));
11776 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11777 put_fpr_w0(r1, mkexpr(result));
11779 return "sebr";
11782 static const HChar *
11783 s390_irgen_SDBR(UChar r1, UChar r2)
11785 IRTemp op1 = newTemp(Ity_F64);
11786 IRTemp op2 = newTemp(Ity_F64);
11787 IRTemp result = newTemp(Ity_F64);
11788 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11790 assign(op1, get_fpr_dw0(r1));
11791 assign(op2, get_fpr_dw0(r2));
11792 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
11793 mkexpr(op2)));
11794 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11795 put_fpr_dw0(r1, mkexpr(result));
11797 return "sdbr";
11800 static const HChar *
11801 s390_irgen_SEB(UChar r1, IRTemp op2addr)
11803 IRTemp op1 = newTemp(Ity_F32);
11804 IRTemp op2 = newTemp(Ity_F32);
11805 IRTemp result = newTemp(Ity_F32);
11806 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11808 assign(op1, get_fpr_w0(r1));
11809 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11810 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
11811 mkexpr(op2)));
11812 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
11813 put_fpr_w0(r1, mkexpr(result));
11815 return "seb";
11818 static const HChar *
11819 s390_irgen_SDB(UChar r1, IRTemp op2addr)
11821 IRTemp op1 = newTemp(Ity_F64);
11822 IRTemp op2 = newTemp(Ity_F64);
11823 IRTemp result = newTemp(Ity_F64);
11824 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
11826 assign(op1, get_fpr_dw0(r1));
11827 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11828 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
11829 mkexpr(op2)));
11830 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
11831 put_fpr_dw0(r1, mkexpr(result));
11833 return "sdb";
11836 static const HChar *
11837 s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
11839 if (! s390_host_has_dfp) {
11840 emulation_failure(EmFail_S390X_DFP_insn);
11841 } else {
11842 IRTemp op1 = newTemp(Ity_D64);
11843 IRTemp op2 = newTemp(Ity_D64);
11844 IRTemp result = newTemp(Ity_D64);
11845 IRTemp rounding_mode;
11847 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
11848 emulation_warning(EmWarn_S390X_fpext_rounding);
11849 m4 = S390_DFP_ROUND_PER_FPC_0;
11852 rounding_mode = encode_dfp_rounding_mode(m4);
11853 assign(op1, get_dpr_dw0(r2));
11854 assign(op2, get_dpr_dw0(r3));
11855 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
11856 mkexpr(op2)));
11857 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
11858 put_dpr_dw0(r1, mkexpr(result));
11860 return (m4 == 0) ? "adtr" : "adtra";
11863 static const HChar *
11864 s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
11866 if (! s390_host_has_dfp) {
11867 emulation_failure(EmFail_S390X_DFP_insn);
11868 } else {
11869 IRTemp op1 = newTemp(Ity_D128);
11870 IRTemp op2 = newTemp(Ity_D128);
11871 IRTemp result = newTemp(Ity_D128);
11872 IRTemp rounding_mode;
11874 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
11875 emulation_warning(EmWarn_S390X_fpext_rounding);
11876 m4 = S390_DFP_ROUND_PER_FPC_0;
11879 rounding_mode = encode_dfp_rounding_mode(m4);
11880 assign(op1, get_dpr_pair(r2));
11881 assign(op2, get_dpr_pair(r3));
11882 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
11883 mkexpr(op2)));
11884 put_dpr_pair(r1, mkexpr(result));
11886 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
11888 return (m4 == 0) ? "axtr" : "axtra";
11891 static const HChar *
11892 s390_irgen_CDTR(UChar r1, UChar r2)
11894 IRTemp op1 = newTemp(Ity_D64);
11895 IRTemp op2 = newTemp(Ity_D64);
11896 IRTemp cc_vex = newTemp(Ity_I32);
11897 IRTemp cc_s390 = newTemp(Ity_I32);
11899 assign(op1, get_dpr_dw0(r1));
11900 assign(op2, get_dpr_dw0(r2));
11901 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
11903 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
11904 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11906 return "cdtr";
11909 static const HChar *
11910 s390_irgen_CXTR(UChar r1, UChar r2)
11912 IRTemp op1 = newTemp(Ity_D128);
11913 IRTemp op2 = newTemp(Ity_D128);
11914 IRTemp cc_vex = newTemp(Ity_I32);
11915 IRTemp cc_s390 = newTemp(Ity_I32);
11917 assign(op1, get_dpr_pair(r1));
11918 assign(op2, get_dpr_pair(r2));
11919 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
11921 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
11922 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11924 return "cxtr";
11927 static const HChar *
11928 s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
11929 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11931 if (! s390_host_has_dfp) {
11932 emulation_failure(EmFail_S390X_DFP_insn);
11933 } else {
11934 if (! s390_host_has_fpext) {
11935 emulation_failure(EmFail_S390X_fpext);
11936 } else {
11937 IRTemp op2 = newTemp(Ity_I32);
11939 assign(op2, get_gpr_w1(r2));
11940 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
11943 return "cdftr";
11946 static const HChar *
11947 s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
11948 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11950 if (! s390_host_has_dfp) {
11951 emulation_failure(EmFail_S390X_DFP_insn);
11952 } else {
11953 if (! s390_host_has_fpext) {
11954 emulation_failure(EmFail_S390X_fpext);
11955 } else {
11956 IRTemp op2 = newTemp(Ity_I32);
11958 assign(op2, get_gpr_w1(r2));
11959 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
11962 return "cxftr";
11965 static const HChar *
11966 s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
11967 UChar r1, UChar r2)
11969 if (! s390_host_has_dfp) {
11970 emulation_failure(EmFail_S390X_DFP_insn);
11971 } else {
11972 IRTemp op2 = newTemp(Ity_I64);
11974 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
11975 emulation_warning(EmWarn_S390X_fpext_rounding);
11976 m3 = S390_DFP_ROUND_PER_FPC_0;
11979 assign(op2, get_gpr_dw0(r2));
11980 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
11981 mkexpr(op2)));
11983 return (m3 == 0) ? "cdgtr" : "cdgtra";
11986 static const HChar *
11987 s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
11988 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
11990 if (! s390_host_has_dfp) {
11991 emulation_failure(EmFail_S390X_DFP_insn);
11992 } else {
11993 IRTemp op2 = newTemp(Ity_I64);
11995 /* No emulation warning here about an non-zero m3 on hosts without
11996 floating point extension facility. No rounding is performed */
11998 assign(op2, get_gpr_dw0(r2));
11999 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
12001 return "cxgtr";
12004 static const HChar *
12005 s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
12006 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12008 if (! s390_host_has_dfp) {
12009 emulation_failure(EmFail_S390X_DFP_insn);
12010 } else {
12011 if (! s390_host_has_fpext) {
12012 emulation_failure(EmFail_S390X_fpext);
12013 } else {
12014 IRTemp op2 = newTemp(Ity_I32);
12016 assign(op2, get_gpr_w1(r2));
12017 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
12020 return "cdlftr";
12023 static const HChar *
12024 s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
12025 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12027 if (! s390_host_has_dfp) {
12028 emulation_failure(EmFail_S390X_DFP_insn);
12029 } else {
12030 if (! s390_host_has_fpext) {
12031 emulation_failure(EmFail_S390X_fpext);
12032 } else {
12033 IRTemp op2 = newTemp(Ity_I32);
12035 assign(op2, get_gpr_w1(r2));
12036 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
12039 return "cxlftr";
12042 static const HChar *
12043 s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
12044 UChar r1, UChar r2)
12046 if (! s390_host_has_dfp) {
12047 emulation_failure(EmFail_S390X_DFP_insn);
12048 } else {
12049 if (! s390_host_has_fpext) {
12050 emulation_failure(EmFail_S390X_fpext);
12051 } else {
12052 IRTemp op2 = newTemp(Ity_I64);
12054 assign(op2, get_gpr_dw0(r2));
12055 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
12056 mkexpr(encode_dfp_rounding_mode(m3)),
12057 mkexpr(op2)));
12060 return "cdlgtr";
12063 static const HChar *
12064 s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
12065 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12067 if (! s390_host_has_dfp) {
12068 emulation_failure(EmFail_S390X_DFP_insn);
12069 } else {
12070 if (! s390_host_has_fpext) {
12071 emulation_failure(EmFail_S390X_fpext);
12072 } else {
12073 IRTemp op2 = newTemp(Ity_I64);
12075 assign(op2, get_gpr_dw0(r2));
12076 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
12079 return "cxlgtr";
12082 static const HChar *
12083 s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
12084 UChar r1, UChar r2)
12086 if (! s390_host_has_dfp) {
12087 emulation_failure(EmFail_S390X_DFP_insn);
12088 } else {
12089 if (! s390_host_has_fpext) {
12090 emulation_failure(EmFail_S390X_fpext);
12091 } else {
12092 IRTemp op = newTemp(Ity_D64);
12093 IRTemp result = newTemp(Ity_I32);
12094 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
12096 assign(op, get_dpr_dw0(r2));
12097 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
12098 mkexpr(op)));
12099 put_gpr_w1(r1, mkexpr(result));
12100 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
12103 return "cfdtr";
12106 static const HChar *
12107 s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
12108 UChar r1, UChar r2)
12110 if (! s390_host_has_dfp) {
12111 emulation_failure(EmFail_S390X_DFP_insn);
12112 } else {
12113 if (! s390_host_has_fpext) {
12114 emulation_failure(EmFail_S390X_fpext);
12115 } else {
12116 IRTemp op = newTemp(Ity_D128);
12117 IRTemp result = newTemp(Ity_I32);
12118 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
12120 assign(op, get_dpr_pair(r2));
12121 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
12122 mkexpr(op)));
12123 put_gpr_w1(r1, mkexpr(result));
12124 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op,
12125 rounding_mode);
12128 return "cfxtr";
12131 static const HChar *
12132 s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
12133 UChar r1, UChar r2)
12135 if (! s390_host_has_dfp) {
12136 emulation_failure(EmFail_S390X_DFP_insn);
12137 } else {
12138 IRTemp op = newTemp(Ity_D64);
12139 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
12141 /* If fpext is not installed and m3 is in 1:7,
12142 rounding mode performed is unpredictable */
12143 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
12144 emulation_warning(EmWarn_S390X_fpext_rounding);
12145 m3 = S390_DFP_ROUND_PER_FPC_0;
12148 assign(op, get_dpr_dw0(r2));
12149 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
12150 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
12152 return "cgdtr";
12155 static const HChar *
12156 s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
12157 UChar r1, UChar r2)
12159 if (! s390_host_has_dfp) {
12160 emulation_failure(EmFail_S390X_DFP_insn);
12161 } else {
12162 IRTemp op = newTemp(Ity_D128);
12163 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
12165 /* If fpext is not installed and m3 is in 1:7,
12166 rounding mode performed is unpredictable */
12167 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
12168 emulation_warning(EmWarn_S390X_fpext_rounding);
12169 m3 = S390_DFP_ROUND_PER_FPC_0;
12171 assign(op, get_dpr_pair(r2));
12172 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
12173 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
12175 return "cgxtr";
12178 static const HChar *
12179 s390_irgen_CEDTR(UChar r1, UChar r2)
12181 if (! s390_host_has_dfp) {
12182 emulation_failure(EmFail_S390X_DFP_insn);
12183 } else {
12184 IRTemp op1 = newTemp(Ity_D64);
12185 IRTemp op2 = newTemp(Ity_D64);
12186 IRTemp cc_vex = newTemp(Ity_I32);
12187 IRTemp cc_s390 = newTemp(Ity_I32);
12189 assign(op1, get_dpr_dw0(r1));
12190 assign(op2, get_dpr_dw0(r2));
12191 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
12193 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
12194 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12196 return "cedtr";
12199 static const HChar *
12200 s390_irgen_CEXTR(UChar r1, UChar r2)
12202 if (! s390_host_has_dfp) {
12203 emulation_failure(EmFail_S390X_DFP_insn);
12204 } else {
12205 IRTemp op1 = newTemp(Ity_D128);
12206 IRTemp op2 = newTemp(Ity_D128);
12207 IRTemp cc_vex = newTemp(Ity_I32);
12208 IRTemp cc_s390 = newTemp(Ity_I32);
12210 assign(op1, get_dpr_pair(r1));
12211 assign(op2, get_dpr_pair(r2));
12212 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
12214 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
12215 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12217 return "cextr";
12220 static const HChar *
12221 s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
12222 UChar r1, UChar r2)
12224 if (! s390_host_has_dfp) {
12225 emulation_failure(EmFail_S390X_DFP_insn);
12226 } else {
12227 if (! s390_host_has_fpext) {
12228 emulation_failure(EmFail_S390X_fpext);
12229 } else {
12230 IRTemp op = newTemp(Ity_D64);
12231 IRTemp result = newTemp(Ity_I32);
12232 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
12234 assign(op, get_dpr_dw0(r2));
12235 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
12236 mkexpr(op)));
12237 put_gpr_w1(r1, mkexpr(result));
12238 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
12241 return "clfdtr";
12244 static const HChar *
12245 s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
12246 UChar r1, UChar r2)
12248 if (! s390_host_has_dfp) {
12249 emulation_failure(EmFail_S390X_DFP_insn);
12250 } else {
12251 if (! s390_host_has_fpext) {
12252 emulation_failure(EmFail_S390X_fpext);
12253 } else {
12254 IRTemp op = newTemp(Ity_D128);
12255 IRTemp result = newTemp(Ity_I32);
12256 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
12258 assign(op, get_dpr_pair(r2));
12259 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
12260 mkexpr(op)));
12261 put_gpr_w1(r1, mkexpr(result));
12262 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op,
12263 rounding_mode);
12266 return "clfxtr";
12269 static const HChar *
12270 s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
12271 UChar r1, UChar r2)
12273 if (! s390_host_has_dfp) {
12274 emulation_failure(EmFail_S390X_DFP_insn);
12275 } else {
12276 if (! s390_host_has_fpext) {
12277 emulation_failure(EmFail_S390X_fpext);
12278 } else {
12279 IRTemp op = newTemp(Ity_D64);
12280 IRTemp result = newTemp(Ity_I64);
12281 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
12283 assign(op, get_dpr_dw0(r2));
12284 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
12285 mkexpr(op)));
12286 put_gpr_dw0(r1, mkexpr(result));
12287 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
12290 return "clgdtr";
12293 static const HChar *
12294 s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
12295 UChar r1, UChar r2)
12297 if (! s390_host_has_dfp) {
12298 emulation_failure(EmFail_S390X_DFP_insn);
12299 } else {
12300 if (! s390_host_has_fpext) {
12301 emulation_failure(EmFail_S390X_fpext);
12302 } else {
12303 IRTemp op = newTemp(Ity_D128);
12304 IRTemp result = newTemp(Ity_I64);
12305 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
12307 assign(op, get_dpr_pair(r2));
12308 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
12309 mkexpr(op)));
12310 put_gpr_dw0(r1, mkexpr(result));
12311 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
12312 rounding_mode);
12315 return "clgxtr";
12318 static const HChar *
12319 s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12321 if (! s390_host_has_dfp) {
12322 emulation_failure(EmFail_S390X_DFP_insn);
12323 } else {
12324 IRTemp op1 = newTemp(Ity_D64);
12325 IRTemp op2 = newTemp(Ity_D64);
12326 IRTemp result = newTemp(Ity_D64);
12327 IRTemp rounding_mode;
12329 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12330 emulation_warning(EmWarn_S390X_fpext_rounding);
12331 m4 = S390_DFP_ROUND_PER_FPC_0;
12334 rounding_mode = encode_dfp_rounding_mode(m4);
12335 assign(op1, get_dpr_dw0(r2));
12336 assign(op2, get_dpr_dw0(r3));
12337 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
12338 mkexpr(op2)));
12339 put_dpr_dw0(r1, mkexpr(result));
12341 return (m4 == 0) ? "ddtr" : "ddtra";
12344 static const HChar *
12345 s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12347 if (! s390_host_has_dfp) {
12348 emulation_failure(EmFail_S390X_DFP_insn);
12349 } else {
12350 IRTemp op1 = newTemp(Ity_D128);
12351 IRTemp op2 = newTemp(Ity_D128);
12352 IRTemp result = newTemp(Ity_D128);
12353 IRTemp rounding_mode;
12355 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12356 emulation_warning(EmWarn_S390X_fpext_rounding);
12357 m4 = S390_DFP_ROUND_PER_FPC_0;
12360 rounding_mode = encode_dfp_rounding_mode(m4);
12361 assign(op1, get_dpr_pair(r2));
12362 assign(op2, get_dpr_pair(r3));
12363 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
12364 mkexpr(op2)));
12365 put_dpr_pair(r1, mkexpr(result));
12367 return (m4 == 0) ? "dxtr" : "dxtra";
12370 static const HChar *
12371 s390_irgen_EEDTR(UChar r1, UChar r2)
12373 if (! s390_host_has_dfp) {
12374 emulation_failure(EmFail_S390X_DFP_insn);
12375 } else {
12376 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
12378 return "eedtr";
12381 static const HChar *
12382 s390_irgen_EEXTR(UChar r1, UChar r2)
12384 if (! s390_host_has_dfp) {
12385 emulation_failure(EmFail_S390X_DFP_insn);
12386 } else {
12387 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
12389 return "eextr";
12392 static const HChar *
12393 s390_irgen_ESDTR(UChar r1, UChar r2)
12395 if (! s390_host_has_dfp) {
12396 emulation_failure(EmFail_S390X_DFP_insn);
12397 } else {
12398 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
12400 return "esdtr";
12403 static const HChar *
12404 s390_irgen_ESXTR(UChar r1, UChar r2)
12406 if (! s390_host_has_dfp) {
12407 emulation_failure(EmFail_S390X_DFP_insn);
12408 } else {
12409 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
12411 return "esxtr";
12414 static const HChar *
12415 s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
12417 if (! s390_host_has_dfp) {
12418 emulation_failure(EmFail_S390X_DFP_insn);
12419 } else {
12420 IRTemp op1 = newTemp(Ity_I64);
12421 IRTemp op2 = newTemp(Ity_D64);
12422 IRTemp result = newTemp(Ity_D64);
12424 assign(op1, get_gpr_dw0(r2));
12425 assign(op2, get_dpr_dw0(r3));
12426 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
12427 put_dpr_dw0(r1, mkexpr(result));
12429 return "iedtr";
12432 static const HChar *
12433 s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
12435 if (! s390_host_has_dfp) {
12436 emulation_failure(EmFail_S390X_DFP_insn);
12437 } else {
12438 IRTemp op1 = newTemp(Ity_I64);
12439 IRTemp op2 = newTemp(Ity_D128);
12440 IRTemp result = newTemp(Ity_D128);
12442 assign(op1, get_gpr_dw0(r2));
12443 assign(op2, get_dpr_pair(r3));
12444 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
12445 put_dpr_pair(r1, mkexpr(result));
12447 return "iextr";
12450 static const HChar *
12451 s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12453 if (! s390_host_has_dfp) {
12454 emulation_failure(EmFail_S390X_DFP_insn);
12455 } else {
12456 IRTemp op = newTemp(Ity_D32);
12458 assign(op, get_dpr_w0(r2));
12459 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
12461 return "ldetr";
12464 static const HChar *
12465 s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
12467 IRTemp op = newTemp(Ity_D64);
12469 assign(op, get_dpr_dw0(r2));
12470 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
12472 return "lxdtr";
12475 static const HChar *
12476 s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
12477 UChar r1, UChar r2)
12479 if (! s390_host_has_dfp) {
12480 emulation_failure(EmFail_S390X_DFP_insn);
12481 } else {
12482 /* If fpext is not installed and m3 is in 1:7,
12483 rounding mode performed is unpredictable */
12484 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
12485 emulation_warning(EmWarn_S390X_fpext_rounding);
12486 m3 = S390_DFP_ROUND_PER_FPC_0;
12488 IRTemp result = newTemp(Ity_D64);
12490 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
12491 get_dpr_pair(r2)));
12492 put_dpr_dw0(r1, mkexpr(result));
12494 return "ldxtr";
12497 static const HChar *
12498 s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
12499 UChar r1, UChar r2)
12501 if (! s390_host_has_dfp) {
12502 emulation_failure(EmFail_S390X_DFP_insn);
12503 } else {
12504 /* If fpext is not installed and m3 is in 1:7,
12505 rounding mode performed is unpredictable */
12506 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
12507 emulation_warning(EmWarn_S390X_fpext_rounding);
12508 m3 = S390_DFP_ROUND_PER_FPC_0;
12510 IRTemp op = newTemp(Ity_D64);
12512 assign(op, get_dpr_dw0(r2));
12513 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
12514 mkexpr(op)));
12516 return "ledtr";
12519 static const HChar *
12520 s390_irgen_LTDTR(UChar r1, UChar r2)
12522 IRTemp result = newTemp(Ity_D64);
12524 assign(result, get_dpr_dw0(r2));
12525 put_dpr_dw0(r1, mkexpr(result));
12526 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
12528 return "ltdtr";
12531 static const HChar *
12532 s390_irgen_LTXTR(UChar r1, UChar r2)
12534 IRTemp result = newTemp(Ity_D128);
12536 assign(result, get_dpr_pair(r2));
12537 put_dpr_pair(r1, mkexpr(result));
12538 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
12540 return "ltxtr";
12543 static const HChar *
12544 s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12546 if (! s390_host_has_dfp) {
12547 emulation_failure(EmFail_S390X_DFP_insn);
12548 } else {
12549 IRTemp op1 = newTemp(Ity_D64);
12550 IRTemp op2 = newTemp(Ity_D64);
12551 IRTemp result = newTemp(Ity_D64);
12552 IRTemp rounding_mode;
12554 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12555 emulation_warning(EmWarn_S390X_fpext_rounding);
12556 m4 = S390_DFP_ROUND_PER_FPC_0;
12559 rounding_mode = encode_dfp_rounding_mode(m4);
12560 assign(op1, get_dpr_dw0(r2));
12561 assign(op2, get_dpr_dw0(r3));
12562 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
12563 mkexpr(op2)));
12564 put_dpr_dw0(r1, mkexpr(result));
12566 return (m4 == 0) ? "mdtr" : "mdtra";
12569 static const HChar *
12570 s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12572 if (! s390_host_has_dfp) {
12573 emulation_failure(EmFail_S390X_DFP_insn);
12574 } else {
12575 IRTemp op1 = newTemp(Ity_D128);
12576 IRTemp op2 = newTemp(Ity_D128);
12577 IRTemp result = newTemp(Ity_D128);
12578 IRTemp rounding_mode;
12580 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12581 emulation_warning(EmWarn_S390X_fpext_rounding);
12582 m4 = S390_DFP_ROUND_PER_FPC_0;
12585 rounding_mode = encode_dfp_rounding_mode(m4);
12586 assign(op1, get_dpr_pair(r2));
12587 assign(op2, get_dpr_pair(r3));
12588 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
12589 mkexpr(op2)));
12590 put_dpr_pair(r1, mkexpr(result));
12592 return (m4 == 0) ? "mxtr" : "mxtra";
12595 static const HChar *
12596 s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
12598 if (! s390_host_has_dfp) {
12599 emulation_failure(EmFail_S390X_DFP_insn);
12600 } else {
12601 IRTemp op1 = newTemp(Ity_D64);
12602 IRTemp op2 = newTemp(Ity_D64);
12603 IRTemp result = newTemp(Ity_D64);
12604 IRTemp rounding_mode;
12606 /* If fpext is not installed and m4 is in 1:7,
12607 rounding mode performed is unpredictable */
12608 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
12609 emulation_warning(EmWarn_S390X_fpext_rounding);
12610 m4 = S390_DFP_ROUND_PER_FPC_0;
12613 rounding_mode = encode_dfp_rounding_mode(m4);
12614 assign(op1, get_dpr_dw0(r2));
12615 assign(op2, get_dpr_dw0(r3));
12616 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
12617 mkexpr(op2)));
12618 put_dpr_dw0(r1, mkexpr(result));
12620 return "qadtr";
12623 static const HChar *
12624 s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
12626 if (! s390_host_has_dfp) {
12627 emulation_failure(EmFail_S390X_DFP_insn);
12628 } else {
12629 IRTemp op1 = newTemp(Ity_D128);
12630 IRTemp op2 = newTemp(Ity_D128);
12631 IRTemp result = newTemp(Ity_D128);
12632 IRTemp rounding_mode;
12634 /* If fpext is not installed and m4 is in 1:7,
12635 rounding mode performed is unpredictable */
12636 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
12637 emulation_warning(EmWarn_S390X_fpext_rounding);
12638 m4 = S390_DFP_ROUND_PER_FPC_0;
12641 rounding_mode = encode_dfp_rounding_mode(m4);
12642 assign(op1, get_dpr_pair(r2));
12643 assign(op2, get_dpr_pair(r3));
12644 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
12645 mkexpr(op2)));
12646 put_dpr_pair(r1, mkexpr(result));
12648 return "qaxtr";
12651 static const HChar *
12652 s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
12654 if (! s390_host_has_dfp) {
12655 emulation_failure(EmFail_S390X_DFP_insn);
12656 } else {
12657 IRTemp op1 = newTemp(Ity_I8);
12658 IRTemp op2 = newTemp(Ity_D64);
12659 IRTemp result = newTemp(Ity_D64);
12660 IRTemp rounding_mode;
12662 /* If fpext is not installed and m4 is in 1:7,
12663 rounding mode performed is unpredictable */
12664 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
12665 emulation_warning(EmWarn_S390X_fpext_rounding);
12666 m4 = S390_DFP_ROUND_PER_FPC_0;
12669 rounding_mode = encode_dfp_rounding_mode(m4);
12670 assign(op1, get_gpr_b7(r2));
12671 assign(op2, get_dpr_dw0(r3));
12672 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
12673 mkexpr(op1), mkexpr(op2)));
12674 put_dpr_dw0(r1, mkexpr(result));
12676 return "rrdtr";
12679 static const HChar *
12680 s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
12682 if (! s390_host_has_dfp) {
12683 emulation_failure(EmFail_S390X_DFP_insn);
12684 } else {
12685 IRTemp op1 = newTemp(Ity_I8);
12686 IRTemp op2 = newTemp(Ity_D128);
12687 IRTemp result = newTemp(Ity_D128);
12688 IRTemp rounding_mode;
12690 /* If fpext is not installed and m4 is in 1:7,
12691 rounding mode performed is unpredictable */
12692 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
12693 emulation_warning(EmWarn_S390X_fpext_rounding);
12694 m4 = S390_DFP_ROUND_PER_FPC_0;
12697 rounding_mode = encode_dfp_rounding_mode(m4);
12698 assign(op1, get_gpr_b7(r2));
12699 assign(op2, get_dpr_pair(r3));
12700 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
12701 mkexpr(op1), mkexpr(op2)));
12702 put_dpr_pair(r1, mkexpr(result));
12704 return "rrxtr";
12707 static const HChar *
12708 s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12710 if (! s390_host_has_dfp) {
12711 emulation_failure(EmFail_S390X_DFP_insn);
12712 } else {
12713 IRTemp op1 = newTemp(Ity_D64);
12714 IRTemp op2 = newTemp(Ity_D64);
12715 IRTemp result = newTemp(Ity_D64);
12716 IRTemp rounding_mode;
12718 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12719 emulation_warning(EmWarn_S390X_fpext_rounding);
12720 m4 = S390_DFP_ROUND_PER_FPC_0;
12723 rounding_mode = encode_dfp_rounding_mode(m4);
12724 assign(op1, get_dpr_dw0(r2));
12725 assign(op2, get_dpr_dw0(r3));
12726 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
12727 mkexpr(op2)));
12728 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
12729 put_dpr_dw0(r1, mkexpr(result));
12731 return (m4 == 0) ? "sdtr" : "sdtra";
12734 static const HChar *
12735 s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
12737 if (! s390_host_has_dfp) {
12738 emulation_failure(EmFail_S390X_DFP_insn);
12739 } else {
12740 IRTemp op1 = newTemp(Ity_D128);
12741 IRTemp op2 = newTemp(Ity_D128);
12742 IRTemp result = newTemp(Ity_D128);
12743 IRTemp rounding_mode;
12745 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
12746 emulation_warning(EmWarn_S390X_fpext_rounding);
12747 m4 = S390_DFP_ROUND_PER_FPC_0;
12750 rounding_mode = encode_dfp_rounding_mode(m4);
12751 assign(op1, get_dpr_pair(r2));
12752 assign(op2, get_dpr_pair(r3));
12753 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
12754 mkexpr(op2)));
12755 put_dpr_pair(r1, mkexpr(result));
12757 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
12759 return (m4 == 0) ? "sxtr" : "sxtra";
12762 static const HChar *
12763 s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
12765 if (! s390_host_has_dfp) {
12766 emulation_failure(EmFail_S390X_DFP_insn);
12767 } else {
12768 IRTemp op = newTemp(Ity_D64);
12770 assign(op, get_dpr_dw0(r3));
12771 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op),
12772 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
12773 mkU64(63)))));
12775 return "sldt";
12778 static const HChar *
12779 s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
12781 if (! s390_host_has_dfp) {
12782 emulation_failure(EmFail_S390X_DFP_insn);
12783 } else {
12784 IRTemp op = newTemp(Ity_D128);
12786 assign(op, get_dpr_pair(r3));
12787 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op),
12788 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
12789 mkU64(63)))));
12791 return "slxt";
12794 static const HChar *
12795 s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
12797 if (! s390_host_has_dfp) {
12798 emulation_failure(EmFail_S390X_DFP_insn);
12799 } else {
12800 IRTemp op = newTemp(Ity_D64);
12802 assign(op, get_dpr_dw0(r3));
12803 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op),
12804 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
12805 mkU64(63)))));
12807 return "srdt";
12810 static const HChar *
12811 s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
12813 if (! s390_host_has_dfp) {
12814 emulation_failure(EmFail_S390X_DFP_insn);
12815 } else {
12816 IRTemp op = newTemp(Ity_D128);
12818 assign(op, get_dpr_pair(r3));
12819 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op),
12820 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
12821 mkU64(63)))));
12823 return "srxt";
12826 static const HChar *
12827 s390_irgen_TDCET(UChar r1, IRTemp op2addr)
12829 if (! s390_host_has_dfp) {
12830 emulation_failure(EmFail_S390X_DFP_insn);
12831 } else {
12832 IRTemp value = newTemp(Ity_D32);
12834 assign(value, get_dpr_w0(r1));
12836 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
12838 return "tdcet";
12841 static const HChar *
12842 s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
12844 if (! s390_host_has_dfp) {
12845 emulation_failure(EmFail_S390X_DFP_insn);
12846 } else {
12847 IRTemp value = newTemp(Ity_D64);
12849 assign(value, get_dpr_dw0(r1));
12851 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
12853 return "tdcdt";
12856 static const HChar *
12857 s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
12859 if (! s390_host_has_dfp) {
12860 emulation_failure(EmFail_S390X_DFP_insn);
12861 } else {
12862 IRTemp value = newTemp(Ity_D128);
12864 assign(value, get_dpr_pair(r1));
12866 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
12868 return "tdcxt";
12871 static const HChar *
12872 s390_irgen_TDGET(UChar r1, IRTemp op2addr)
12874 if (! s390_host_has_dfp) {
12875 emulation_failure(EmFail_S390X_DFP_insn);
12876 } else {
12877 IRTemp value = newTemp(Ity_D32);
12879 assign(value, get_dpr_w0(r1));
12881 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
12883 return "tdget";
12886 static const HChar *
12887 s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
12889 if (! s390_host_has_dfp) {
12890 emulation_failure(EmFail_S390X_DFP_insn);
12891 } else {
12892 IRTemp value = newTemp(Ity_D64);
12894 assign(value, get_dpr_dw0(r1));
12896 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
12898 return "tdgdt";
12901 static const HChar *
12902 s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
12904 if (! s390_host_has_dfp) {
12905 emulation_failure(EmFail_S390X_DFP_insn);
12906 } else {
12907 IRTemp value = newTemp(Ity_D128);
12909 assign(value, get_dpr_pair(r1));
12911 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
12913 return "tdgxt";
12916 static const HChar *
12917 s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
12919 IRType ty;
12921 switch (length) {
12922 case 0: ty = Ity_I8; break;
12923 case 1: ty = Ity_I16; break;
12924 case 3: ty = Ity_I32; break;
12925 case 7: ty = Ity_I64; break;
12926 default: ty = Ity_INVALID;
12928 if (ty != Ity_INVALID) {
12929 IRTemp a = newTemp(ty);
12930 IRTemp b = newTemp(ty);
12932 assign(a, load(ty, mkexpr(start1)));
12933 assign(b, load(ty, mkexpr(start2)));
12934 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, a, b);
12935 } else {
12936 IRTemp len = newTemp(Ity_I64);
12938 assign(len, mkU64(length));
12939 s390_irgen_CLC_EX(len, start1, start2);
12941 return "clc";
12944 static const HChar *
12945 s390_irgen_CLCL(UChar r1, UChar r2)
12947 IRTemp addr1 = newTemp(Ity_I64);
12948 IRTemp addr2 = newTemp(Ity_I64);
12949 IRTemp addr1_load = newTemp(Ity_I64);
12950 IRTemp addr2_load = newTemp(Ity_I64);
12951 IRTemp len1 = newTemp(Ity_I32);
12952 IRTemp len2 = newTemp(Ity_I32);
12953 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
12954 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
12955 IRTemp single1 = newTemp(Ity_I8);
12956 IRTemp single2 = newTemp(Ity_I8);
12957 IRTemp pad = newTemp(Ity_I8);
12959 assign(addr1, get_gpr_dw0(r1));
12960 assign(r1p1, get_gpr_w1(r1 + 1));
12961 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
12962 assign(addr2, get_gpr_dw0(r2));
12963 assign(r2p1, get_gpr_w1(r2 + 1));
12964 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
12965 assign(pad, get_gpr_b4(r2 + 1));
12967 /* len1 == 0 and len2 == 0? Exit */
12968 s390_cc_set_val(0);
12969 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
12970 mkexpr(len2)), mkU32(0)));
12972 /* Because mkite evaluates both the then-clause and the else-clause
12973 we cannot load directly from addr1 here. If len1 is 0, then adddr1
12974 may be NULL and loading from there would segfault. So we provide a
12975 valid dummy address in that case. Loading from there does no harm and
12976 the value will be discarded at runtime. */
12977 assign(addr1_load,
12978 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
12979 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
12980 assign(single1,
12981 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
12982 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
12984 assign(addr2_load,
12985 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
12986 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
12987 assign(single2,
12988 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
12989 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
12991 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
12992 /* Fields differ ? */
12993 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
12995 /* Update len1 and addr1, unless len1 == 0. */
12996 put_gpr_dw0(r1,
12997 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
12998 mkexpr(addr1),
12999 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
13001 /* When updating len1 we must not modify bits (r1+1)[0:39] */
13002 put_gpr_w1(r1 + 1,
13003 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
13004 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
13005 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
13007 /* Update len2 and addr2, unless len2 == 0. */
13008 put_gpr_dw0(r2,
13009 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13010 mkexpr(addr2),
13011 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
13013 /* When updating len2 we must not modify bits (r2+1)[0:39] */
13014 put_gpr_w1(r2 + 1,
13015 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13016 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
13017 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
13019 iterate();
13021 return "clcl";
13024 static const HChar *
13025 s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
13027 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
13029 addr1 = newTemp(Ity_I64);
13030 addr3 = newTemp(Ity_I64);
13031 addr1_load = newTemp(Ity_I64);
13032 addr3_load = newTemp(Ity_I64);
13033 len1 = newTemp(Ity_I64);
13034 len3 = newTemp(Ity_I64);
13035 single1 = newTemp(Ity_I8);
13036 single3 = newTemp(Ity_I8);
13038 assign(addr1, get_gpr_dw0(r1));
13039 assign(len1, get_gpr_dw0(r1 + 1));
13040 assign(addr3, get_gpr_dw0(r3));
13041 assign(len3, get_gpr_dw0(r3 + 1));
13043 /* len1 == 0 and len3 == 0? Exit */
13044 s390_cc_set_val(0);
13045 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
13046 mkexpr(len3)), mkU64(0)));
13048 /* A mux requires both ways to be possible. This is a way to prevent clcle
13049 from reading from addr1 if it should read from the pad. Since the pad
13050 has no address, just read from the instruction, we discard that anyway */
13051 assign(addr1_load,
13052 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
13053 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
13055 /* same for addr3 */
13056 assign(addr3_load,
13057 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13058 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
13060 assign(single1,
13061 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
13062 unop(Iop_64to8, mkexpr(pad2)),
13063 load(Ity_I8, mkexpr(addr1_load))));
13065 assign(single3,
13066 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13067 unop(Iop_64to8, mkexpr(pad2)),
13068 load(Ity_I8, mkexpr(addr3_load))));
13070 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
13071 /* Both fields differ ? */
13072 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
13074 /* If a length in 0 we must not change this length and the address */
13075 put_gpr_dw0(r1,
13076 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
13077 mkexpr(addr1),
13078 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
13080 put_gpr_dw0(r1 + 1,
13081 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
13082 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
13084 put_gpr_dw0(r3,
13085 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13086 mkexpr(addr3),
13087 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
13089 put_gpr_dw0(r3 + 1,
13090 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13091 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
13093 iterate();
13095 return "clcle";
13099 static void
13100 s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
13102 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
13106 static void
13107 s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
13109 s390_irgen_xonc(Iop_And8, length, start1, start2);
13113 static void
13114 s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
13116 s390_irgen_xonc(Iop_Or8, length, start1, start2);
13120 static void
13121 s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
13123 IRTemp current1 = newTemp(Ity_I8);
13124 IRTemp current2 = newTemp(Ity_I8);
13125 IRTemp counter = newTemp(Ity_I64);
13127 assign(counter, get_counter_dw0());
13128 put_counter_dw0(mkU64(0));
13130 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
13131 mkexpr(counter))));
13132 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
13133 mkexpr(counter))));
13134 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
13135 False);
13137 /* Both fields differ ? */
13138 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
13140 /* Check for end of field */
13141 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
13142 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
13143 put_counter_dw0(mkU64(0));
13145 /* Equal. Clear CC, to avoid duplicate dependency on the comparison. */
13146 s390_cc_set_val(0);
13149 static void
13150 s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
13152 IRTemp counter = newTemp(Ity_I64);
13154 assign(counter, get_counter_dw0());
13156 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
13157 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
13159 /* Check for end of field */
13160 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
13161 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
13162 put_counter_dw0(mkU64(0));
13165 static void
13166 s390_irgen_MVCIN_EX(IRTemp length, IRTemp start1, IRTemp start2)
13168 IRTemp counter = newTemp(Ity_I64);
13170 assign(counter, get_counter_dw0());
13172 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
13173 load(Ity_I8, binop(Iop_Sub64, mkexpr(start2), mkexpr(counter))));
13175 /* Check for end of field */
13176 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
13177 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
13178 put_counter_dw0(mkU64(0));
13181 static void
13182 s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
13184 IRTemp op = newTemp(Ity_I8);
13185 IRTemp op1 = newTemp(Ity_I8);
13186 IRTemp result = newTemp(Ity_I64);
13187 IRTemp counter = newTemp(Ity_I64);
13189 assign(counter, get_counter_dw0());
13191 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
13193 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
13195 assign(op1, load(Ity_I8, mkexpr(result)));
13196 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
13198 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
13199 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
13200 put_counter_dw0(mkU64(0));
13204 static void
13205 s390_irgen_EX_SS(UChar r, IRTemp addr2, IRTemp torun,
13206 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
13207 UInt lensize)
13209 IRTemp cond;
13210 IRDirty *d;
13211 ULong ovl;
13213 IRTemp start1 = newTemp(Ity_I64);
13214 IRTemp start2 = newTemp(Ity_I64);
13215 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
13216 cond = newTemp(Ity_I1);
13218 /* Start with a check that the saved code is still correct */
13219 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
13220 /* If not, save the new value */
13221 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
13222 mkIRExprVec_2(mkexpr(torun), mkexpr(addr2)));
13223 d->guard = mkexpr(cond);
13224 stmt(IRStmt_Dirty(d));
13226 /* and restart */
13227 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
13228 mkU64(guest_IA_curr_instr)));
13229 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
13230 restart_if(mkexpr(cond));
13232 ovl = last_execute_target;
13233 assign(start1, binop(Iop_Add64, mkU64(SS_d1(ovl)),
13234 SS_b1(ovl) != 0 ? get_gpr_dw0(SS_b1(ovl)) : mkU64(0)));
13235 assign(start2, binop(Iop_Add64, mkU64(SS_d2(ovl)),
13236 SS_b2(ovl) != 0 ? get_gpr_dw0(SS_b2(ovl)) : mkU64(0)));
13237 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
13238 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(SS_l(ovl)))));
13239 irgen(len, start1, start2);
13241 last_execute_target = Invalid_execute_target;
13244 static const HChar *
13245 s390_irgen_EX(UChar r1, IRTemp addr2)
13247 IRTemp insn0, unmodified_insn;
13248 IRExpr* incr_addr;
13249 insn0 = newTemp(Ity_I64);
13250 unmodified_insn = newTemp(Ity_I64);
13251 assign(insn0, unop(Iop_16Uto64, load(Ity_I16, mkexpr(addr2))));
13252 incr_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13253 assign(
13254 unmodified_insn,
13255 binop(
13256 Iop_Or64, binop(Iop_Shl64, mkexpr(insn0), mkU8(48)),
13257 mkite(
13258 binop(Iop_CmpLT64U, mkexpr(insn0), mkU64(0x4000)), mkU64(0),
13259 mkite(binop(Iop_CmpLT64U, mkexpr(insn0), mkU64(0xc000)),
13260 binop(Iop_Shl64, unop(Iop_16Uto64, load(Ity_I16, incr_addr)),
13261 mkU8(32)),
13262 binop(Iop_Shl64, unop(Iop_32Uto64, load(Ity_I32, incr_addr)),
13263 mkU8(16))))));
13265 if (last_execute_target == Invalid_execute_target) {
13266 /* no code information yet */
13267 IRDirty *d;
13269 /* so safe the code... */
13270 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
13271 mkIRExprVec_2(mkexpr(unmodified_insn), mkexpr(addr2)));
13272 stmt(IRStmt_Dirty(d));
13273 /* and restart */
13274 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
13275 mkU64(guest_IA_curr_instr)));
13276 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
13277 restart_if(IRExpr_Const(IRConst_U1(True)));
13279 /* we know that this will be invalidated */
13280 put_IA(mkaddr_expr(guest_IA_next_instr));
13281 dis_res->whatNext = Dis_StopHere;
13282 dis_res->jk_StopHere = Ijk_InvalICache;
13283 return "ex";
13286 switch (last_execute_target & 0xff00000000000000ULL) {
13287 case 0xd200000000000000ULL:
13288 /* special case MVC */
13289 s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_MVC_EX, 64);
13290 return "ex@mvc";
13292 case 0xd500000000000000ULL:
13293 /* special case CLC */
13294 s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_CLC_EX, 64);
13295 return "ex@clc";
13297 case 0xd700000000000000ULL:
13298 /* special case XC */
13299 s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_XC_EX, 32);
13300 return "ex@xc";
13302 case 0xd600000000000000ULL:
13303 /* special case OC */
13304 s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_OC_EX, 32);
13305 return "ex@oc";
13307 case 0xd400000000000000ULL:
13308 /* special case NC */
13309 s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_NC_EX, 32);
13310 return "ex@nc";
13312 case 0xdc00000000000000ULL:
13313 /* special case TR */
13314 s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_TR_EX, 64);
13315 return "ex@tr";
13317 case 0xe800000000000000ULL:
13318 /* special case MVCIN */
13319 s390_irgen_EX_SS(r1, addr2, unmodified_insn, s390_irgen_MVCIN_EX, 64);
13320 return "ex@mvcin";
13322 default:
13324 /* everything else will get a self checking prefix that also checks the
13325 register content */
13326 IRDirty *d;
13327 UChar *bytes;
13328 IRTemp cond;
13329 IRTemp orperand;
13330 IRTemp torun;
13332 cond = newTemp(Ity_I1);
13333 orperand = newTemp(Ity_I64);
13334 torun = newTemp(Ity_I64);
13336 if (r1 == 0)
13337 assign(orperand, mkU64(0));
13338 else
13339 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
13340 /* This code is going to be translated */
13341 assign(torun, binop(Iop_Or64, mkexpr(unmodified_insn),
13342 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
13344 /* Start with a check that saved code is still correct. Compare the target
13345 * address as well, since it may be relevant to relative addressing. */
13346 assign(
13347 cond,
13348 binop(Iop_Or1,
13349 binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)),
13350 binop(Iop_CmpNE64, mkexpr(addr2), mkU64(guest_IA_rel_base))));
13351 /* If not, save the new values */
13352 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
13353 mkIRExprVec_2(mkexpr(torun), mkexpr(addr2)));
13354 d->guard = mkexpr(cond);
13355 stmt(IRStmt_Dirty(d));
13357 /* and restart */
13358 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART), mkU64(guest_IA_curr_instr)));
13359 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
13360 restart_if(mkexpr(cond));
13362 /* Now comes the actual translation */
13363 bytes = (UChar *) &last_execute_target;
13364 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
13365 dis_res);
13366 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
13367 vex_printf(" which was executed by\n");
13368 /* dont make useless translations in the next execute */
13369 last_execute_target = Invalid_execute_target;
13372 return "ex";
13375 static const HChar *
13376 s390_irgen_EXRL(UChar r1, UInt offset)
13378 IRTemp addr = newTemp(Ity_I64);
13379 Addr64 bytes_addr;
13380 UChar *bytes;
13381 /* we might save one round trip because we know the target */
13382 if (last_execute_target == Invalid_execute_target) {
13383 bytes_addr = addr_rel_long(offset);
13384 bytes = (UChar *)(HWord)bytes_addr;
13385 last_execute_target = ((ULong)bytes[0] << 56) | ((ULong)bytes[1] << 48);
13386 if (bytes[0] >= 0x40)
13387 last_execute_target |= ((ULong)bytes[2] << 40) | ((ULong)bytes[3] << 32);
13388 if (bytes[0] >= 0xc0)
13389 last_execute_target |= ((ULong)bytes[4] << 24) | ((ULong)bytes[5] << 16);
13390 guest_IA_rel_base = bytes_addr;
13391 } else
13392 bytes_addr = guest_IA_rel_base;
13393 assign(addr, mkU64(bytes_addr));
13394 s390_irgen_EX(r1, addr);
13395 return "exrl";
13398 static const HChar *
13399 s390_irgen_IPM(UChar r1)
13401 // As long as we dont support SPM, lets just assume 0 as program mask
13402 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
13403 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
13405 return "ipm";
13409 static const HChar *
13410 s390_irgen_SRST(UChar r1, UChar r2)
13412 IRTemp address = newTemp(Ity_I64);
13413 IRTemp next = newTemp(Ity_I64);
13414 IRTemp delim = newTemp(Ity_I8);
13415 IRTemp counter = newTemp(Ity_I64);
13416 IRTemp byte = newTemp(Ity_I8);
13418 assign(address, get_gpr_dw0(r2));
13419 assign(next, get_gpr_dw0(r1));
13421 assign(counter, get_counter_dw0());
13422 put_counter_dw0(mkU64(0));
13424 // start = next? CC=2 and out r1 and r2 unchanged
13425 s390_cc_set_val(2);
13426 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
13427 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
13429 assign(byte, load(Ity_I8, mkexpr(address)));
13430 assign(delim, get_gpr_b7(0));
13432 // byte = delim? CC=1, R1=address
13433 s390_cc_set_val(1);
13434 put_gpr_dw0(r1, mkexpr(address));
13435 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
13437 // else: all equal, no end yet, loop
13438 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
13439 put_gpr_dw0(r1, mkexpr(next));
13440 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
13442 iterate();
13444 return "srst";
13447 static const HChar *
13448 s390_irgen_CLST(UChar r1, UChar r2)
13450 IRTemp address1 = newTemp(Ity_I64);
13451 IRTemp address2 = newTemp(Ity_I64);
13452 IRTemp end = newTemp(Ity_I8);
13453 IRTemp counter = newTemp(Ity_I64);
13454 IRTemp byte1 = newTemp(Ity_I8);
13455 IRTemp byte2 = newTemp(Ity_I8);
13457 assign(address1, get_gpr_dw0(r1));
13458 assign(address2, get_gpr_dw0(r2));
13459 assign(end, get_gpr_b7(0));
13460 assign(counter, get_counter_dw0());
13461 put_counter_dw0(mkU64(0));
13462 assign(byte1, load(Ity_I8, mkexpr(address1)));
13463 assign(byte2, load(Ity_I8, mkexpr(address2)));
13465 // end in both? all equal, reset r1 and r2 to start values
13466 s390_cc_set_val(0);
13467 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
13468 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
13469 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
13470 binop(Iop_Or8,
13471 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
13472 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
13474 put_gpr_dw0(r1, mkexpr(address1));
13475 put_gpr_dw0(r2, mkexpr(address2));
13477 // End found in string1
13478 s390_cc_set_val(1);
13479 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
13481 // End found in string2
13482 s390_cc_set_val(2);
13483 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
13485 // string1 < string2
13486 s390_cc_set_val(1);
13487 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
13488 unop(Iop_8Uto32, mkexpr(byte2))));
13490 // string2 < string1
13491 s390_cc_set_val(2);
13492 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
13493 unop(Iop_8Uto32, mkexpr(byte1))));
13495 // else: all equal, no end yet, loop
13496 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
13497 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
13498 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
13500 iterate();
13502 return "clst";
13505 static void
13506 s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
13508 UChar reg;
13509 IRTemp addr = newTemp(Ity_I64);
13511 assign(addr, mkexpr(op2addr));
13512 reg = r1;
13513 do {
13514 IRTemp old = addr;
13516 reg %= 16;
13517 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
13518 addr = newTemp(Ity_I64);
13519 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
13520 reg++;
13521 } while (reg != (r3 + 1));
13524 static const HChar *
13525 s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
13527 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
13529 return "lm";
13532 static const HChar *
13533 s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
13535 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
13537 return "lmy";
13540 static const HChar *
13541 s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
13543 UChar reg;
13544 IRTemp addr = newTemp(Ity_I64);
13546 assign(addr, mkexpr(op2addr));
13547 reg = r1;
13548 do {
13549 IRTemp old = addr;
13551 reg %= 16;
13552 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
13553 addr = newTemp(Ity_I64);
13554 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
13555 reg++;
13556 } while (reg != (r3 + 1));
13558 return "lmh";
13561 static const HChar *
13562 s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
13564 UChar reg;
13565 IRTemp addr = newTemp(Ity_I64);
13567 assign(addr, mkexpr(op2addr));
13568 reg = r1;
13569 do {
13570 IRTemp old = addr;
13572 reg %= 16;
13573 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
13574 addr = newTemp(Ity_I64);
13575 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
13576 reg++;
13577 } while (reg != (r3 + 1));
13579 return "lmg";
13582 static void
13583 s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
13585 UChar reg;
13586 IRTemp addr = newTemp(Ity_I64);
13588 assign(addr, mkexpr(op2addr));
13589 reg = r1;
13590 do {
13591 IRTemp old = addr;
13593 reg %= 16;
13594 store(mkexpr(addr), get_gpr_w1(reg));
13595 addr = newTemp(Ity_I64);
13596 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
13597 reg++;
13598 } while( reg != (r3 + 1));
13601 static const HChar *
13602 s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
13604 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
13606 return "stm";
13609 static const HChar *
13610 s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
13612 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
13614 return "stmy";
13617 static const HChar *
13618 s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
13620 UChar reg;
13621 IRTemp addr = newTemp(Ity_I64);
13623 assign(addr, mkexpr(op2addr));
13624 reg = r1;
13625 do {
13626 IRTemp old = addr;
13628 reg %= 16;
13629 store(mkexpr(addr), get_gpr_w0(reg));
13630 addr = newTemp(Ity_I64);
13631 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
13632 reg++;
13633 } while( reg != (r3 + 1));
13635 return "stmh";
13638 static const HChar *
13639 s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
13641 UChar reg;
13642 IRTemp addr = newTemp(Ity_I64);
13644 assign(addr, mkexpr(op2addr));
13645 reg = r1;
13646 do {
13647 IRTemp old = addr;
13649 reg %= 16;
13650 store(mkexpr(addr), get_gpr_dw0(reg));
13651 addr = newTemp(Ity_I64);
13652 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
13653 reg++;
13654 } while( reg != (r3 + 1));
13656 return "stmg";
13659 static void
13660 s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
13662 IRTemp old1 = newTemp(Ity_I8);
13663 IRTemp old2 = newTemp(Ity_I8);
13664 IRTemp new1 = newTemp(Ity_I8);
13665 IRTemp counter = newTemp(Ity_I32);
13666 IRTemp addr1 = newTemp(Ity_I64);
13668 assign(counter, get_counter_w0());
13670 assign(addr1, binop(Iop_Add64, mkexpr(start1),
13671 unop(Iop_32Uto64, mkexpr(counter))));
13673 assign(old1, load(Ity_I8, mkexpr(addr1)));
13674 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
13675 unop(Iop_32Uto64,mkexpr(counter)))));
13676 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
13678 /* Special case: xc is used to zero memory */
13679 if (op == Iop_Xor8) {
13680 store(mkexpr(addr1),
13681 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
13682 mkU8(0), mkexpr(new1)));
13683 } else
13684 store(mkexpr(addr1), mkexpr(new1));
13685 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
13686 get_counter_w1()));
13688 /* Check for end of field */
13689 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
13690 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
13691 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
13692 False);
13693 put_counter_dw0(mkU64(0));
13696 static const HChar *
13697 s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
13699 IRTemp len = newTemp(Ity_I32);
13701 assign(len, mkU32(length));
13702 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
13704 return "xc";
13707 static void
13708 s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
13710 IRTemp start = newTemp(Ity_I64);
13711 assign(start,
13712 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
13714 if (length < 7) {
13715 for (UInt i = 0; i <= length; ++i) {
13716 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
13718 } else {
13719 if (length < 32) {
13720 for (UInt i = 0; i <= length - 7; i += 8) {
13721 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU64(0));
13723 } else {
13724 IRTemp counter = newTemp(Ity_I64);
13725 assign(counter, get_counter_dw0());
13726 store(binop(Iop_Add64, mkexpr(start), mkexpr(counter)), mkU64(0));
13727 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(8)));
13728 iterate_if(binop(Iop_CmpLE64U, mkexpr(counter), mkU64(length - 15)));
13730 /* Reset counter */
13731 put_counter_dw0(mkU64(0));
13733 /* Clear the remaining bytes with backward overlap */
13734 if ((length + 1) % 8 != 0) {
13735 store(binop(Iop_Add64, mkexpr(start), mkU64(length - 7)), mkU64(0));
13739 s390_cc_set_val(0);
13741 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
13742 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
13745 static const HChar *
13746 s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
13748 IRTemp len = newTemp(Ity_I32);
13750 assign(len, mkU32(length));
13751 s390_irgen_xonc(Iop_And8, len, start1, start2);
13753 return "nc";
13756 static const HChar *
13757 s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
13759 IRTemp len = newTemp(Ity_I32);
13761 assign(len, mkU32(length));
13762 s390_irgen_xonc(Iop_Or8, len, start1, start2);
13764 return "oc";
13768 static const HChar *
13769 s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
13771 IRTemp len = newTemp(Ity_I64);
13773 assign(len, mkU64(length));
13774 s390_irgen_MVC_EX(len, start1, start2);
13776 return "mvc";
13779 static const HChar *
13780 s390_irgen_MVCIN(UChar length, IRTemp start1, IRTemp start2)
13782 IRTemp len = newTemp(Ity_I64);
13784 assign(len, mkU64(length));
13785 s390_irgen_MVCIN_EX(len, start1, start2);
13787 return "mvcin";
13790 static const HChar *
13791 s390_irgen_MVCRL(IRTemp op1addr, IRTemp op2addr)
13793 IRTemp counter = newTemp(Ity_I64);
13794 IRTemp offset = newTemp(Ity_I64);
13796 assign(counter, get_counter_dw0());
13797 /* offset = length - 1 - counter, where length-1 is specified in r0 */
13798 assign(offset,
13799 binop(Iop_Sub64,
13800 unop(Iop_16Uto64,
13801 binop(Iop_And16, get_gpr_hw3(0), mkU16(0xfff))),
13802 mkexpr(counter)));
13804 store(binop(Iop_Add64, mkexpr(op1addr), mkexpr(offset)),
13805 load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkexpr(offset))));
13807 /* Check for end of field */
13808 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
13809 iterate_if(binop(Iop_CmpNE64, mkexpr(offset), mkU64(0)));
13810 put_counter_dw0(mkU64(0));
13812 return "mvcrl";
13815 static const HChar *
13816 s390_irgen_MVCL(UChar r1, UChar r2)
13818 IRTemp addr1 = newTemp(Ity_I64);
13819 IRTemp addr2 = newTemp(Ity_I64);
13820 IRTemp addr2_load = newTemp(Ity_I64);
13821 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
13822 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
13823 IRTemp len1 = newTemp(Ity_I32);
13824 IRTemp len2 = newTemp(Ity_I32);
13825 IRTemp pad = newTemp(Ity_I8);
13826 IRTemp single = newTemp(Ity_I8);
13828 assign(addr1, get_gpr_dw0(r1));
13829 assign(r1p1, get_gpr_w1(r1 + 1));
13830 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
13831 assign(addr2, get_gpr_dw0(r2));
13832 assign(r2p1, get_gpr_w1(r2 + 1));
13833 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
13834 assign(pad, get_gpr_b4(r2 + 1));
13836 /* len1 == 0 ? */
13837 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
13838 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
13840 /* Check for destructive overlap:
13841 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
13842 s390_cc_set_val(3);
13843 IRTemp cond1 = newTemp(Ity_I32);
13844 assign(cond1, unop(Iop_1Uto32,
13845 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
13846 IRTemp cond2 = newTemp(Ity_I32);
13847 assign(cond2, unop(Iop_1Uto32,
13848 binop(Iop_CmpLT64U, mkexpr(addr1),
13849 binop(Iop_Add64, mkexpr(addr2),
13850 unop(Iop_32Uto64, mkexpr(len1))))));
13851 IRTemp cond3 = newTemp(Ity_I32);
13852 assign(cond3, unop(Iop_1Uto32,
13853 binop(Iop_CmpLT64U,
13854 mkexpr(addr1),
13855 binop(Iop_Add64, mkexpr(addr2),
13856 unop(Iop_32Uto64, mkexpr(len2))))));
13858 next_insn_if(binop(Iop_CmpEQ32,
13859 binop(Iop_And32,
13860 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
13861 mkexpr(cond3)),
13862 mkU32(1)));
13864 /* See s390_irgen_CLCL for explanation why we cannot load directly
13865 and need two steps. */
13866 assign(addr2_load,
13867 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13868 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
13869 assign(single,
13870 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13871 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
13873 store(mkexpr(addr1), mkexpr(single));
13875 /* Update addr1 and len1 */
13876 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
13877 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
13879 /* Update addr2 and len2 */
13880 put_gpr_dw0(r2,
13881 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13882 mkexpr(addr2),
13883 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
13885 /* When updating len2 we must not modify bits (r2+1)[0:39] */
13886 put_gpr_w1(r2 + 1,
13887 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
13888 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
13889 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
13891 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
13892 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
13894 return "mvcl";
13898 static const HChar *
13899 s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
13901 IRTemp addr1, addr3, addr3_load, len1, len3, single;
13903 addr1 = newTemp(Ity_I64);
13904 addr3 = newTemp(Ity_I64);
13905 addr3_load = newTemp(Ity_I64);
13906 len1 = newTemp(Ity_I64);
13907 len3 = newTemp(Ity_I64);
13908 single = newTemp(Ity_I8);
13910 assign(addr1, get_gpr_dw0(r1));
13911 assign(len1, get_gpr_dw0(r1 + 1));
13912 assign(addr3, get_gpr_dw0(r3));
13913 assign(len3, get_gpr_dw0(r3 + 1));
13915 // len1 == 0 ?
13916 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
13917 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
13919 /* This is a hack to prevent mvcle from reading from addr3 if it
13920 should read from the pad. Since the pad has no address, just
13921 read from the instruction, we discard that anyway */
13922 assign(addr3_load,
13923 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13924 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
13926 assign(single,
13927 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13928 unop(Iop_64to8, mkexpr(pad2)),
13929 load(Ity_I8, mkexpr(addr3_load))));
13930 store(mkexpr(addr1), mkexpr(single));
13932 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
13934 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
13936 put_gpr_dw0(r3,
13937 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13938 mkexpr(addr3),
13939 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
13941 put_gpr_dw0(r3 + 1,
13942 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
13943 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
13945 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
13946 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
13948 return "mvcle";
13951 static const HChar *
13952 s390_irgen_MVST(UChar r1, UChar r2)
13954 IRTemp addr1 = newTemp(Ity_I64);
13955 IRTemp addr2 = newTemp(Ity_I64);
13956 IRTemp end = newTemp(Ity_I8);
13957 IRTemp byte = newTemp(Ity_I8);
13958 IRTemp counter = newTemp(Ity_I64);
13960 assign(addr1, get_gpr_dw0(r1));
13961 assign(addr2, get_gpr_dw0(r2));
13962 assign(counter, get_counter_dw0());
13963 assign(end, get_gpr_b7(0));
13964 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
13965 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
13967 // We use unlimited as cpu-determined number
13968 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
13969 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
13971 // and always set cc=1 at the end + update r1
13972 s390_cc_set_val(1);
13973 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
13974 put_counter_dw0(mkU64(0));
13976 return "mvst";
13979 static void
13980 s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
13982 IRTemp op1 = newTemp(Ity_I64);
13983 IRTemp result = newTemp(Ity_I64);
13985 assign(op1, binop(Iop_32HLto64,
13986 get_gpr_w1(r1), // high 32 bits
13987 get_gpr_w1(r1 + 1))); // low 32 bits
13988 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
13989 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
13990 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
13993 static void
13994 s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
13996 IRTemp op1 = newTemp(Ity_I128);
13997 IRTemp result = newTemp(Ity_I128);
13999 assign(op1, binop(Iop_64HLto128,
14000 get_gpr_dw0(r1), // high 64 bits
14001 get_gpr_dw0(r1 + 1))); // low 64 bits
14002 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
14003 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
14004 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
14007 static void
14008 s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
14010 IRTemp op1 = newTemp(Ity_I64);
14011 IRTemp result = newTemp(Ity_I128);
14013 assign(op1, get_gpr_dw0(r1 + 1));
14014 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
14015 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
14016 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
14019 static const HChar *
14020 s390_irgen_DR(UChar r1, UChar r2)
14022 IRTemp op2 = newTemp(Ity_I32);
14024 assign(op2, get_gpr_w1(r2));
14026 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
14028 return "dr";
14031 static const HChar *
14032 s390_irgen_D(UChar r1, IRTemp op2addr)
14034 IRTemp op2 = newTemp(Ity_I32);
14036 assign(op2, load(Ity_I32, mkexpr(op2addr)));
14038 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
14040 return "d";
14043 static const HChar *
14044 s390_irgen_DLR(UChar r1, UChar r2)
14046 IRTemp op2 = newTemp(Ity_I32);
14048 assign(op2, get_gpr_w1(r2));
14050 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
14052 return "dlr";
14055 static const HChar *
14056 s390_irgen_DL(UChar r1, IRTemp op2addr)
14058 IRTemp op2 = newTemp(Ity_I32);
14060 assign(op2, load(Ity_I32, mkexpr(op2addr)));
14062 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
14064 return "dl";
14067 static const HChar *
14068 s390_irgen_DLG(UChar r1, IRTemp op2addr)
14070 IRTemp op2 = newTemp(Ity_I64);
14072 assign(op2, load(Ity_I64, mkexpr(op2addr)));
14074 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
14076 return "dlg";
14079 static const HChar *
14080 s390_irgen_DLGR(UChar r1, UChar r2)
14082 IRTemp op2 = newTemp(Ity_I64);
14084 assign(op2, get_gpr_dw0(r2));
14086 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
14088 return "dlgr";
14091 static const HChar *
14092 s390_irgen_DSGR(UChar r1, UChar r2)
14094 IRTemp op2 = newTemp(Ity_I64);
14096 assign(op2, get_gpr_dw0(r2));
14098 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
14100 return "dsgr";
14103 static const HChar *
14104 s390_irgen_DSG(UChar r1, IRTemp op2addr)
14106 IRTemp op2 = newTemp(Ity_I64);
14108 assign(op2, load(Ity_I64, mkexpr(op2addr)));
14110 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
14112 return "dsg";
14115 static const HChar *
14116 s390_irgen_DSGFR(UChar r1, UChar r2)
14118 IRTemp op2 = newTemp(Ity_I64);
14120 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
14122 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
14124 return "dsgfr";
14127 static const HChar *
14128 s390_irgen_DSGF(UChar r1, IRTemp op2addr)
14130 IRTemp op2 = newTemp(Ity_I64);
14132 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
14134 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
14136 return "dsgf";
14139 static void
14140 s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
14142 UChar reg;
14143 IRTemp addr = newTemp(Ity_I64);
14145 assign(addr, mkexpr(op2addr));
14146 reg = r1;
14147 do {
14148 IRTemp old = addr;
14150 reg %= 16;
14151 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
14152 addr = newTemp(Ity_I64);
14153 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
14154 reg++;
14155 } while (reg != (r3 + 1));
14158 static const HChar *
14159 s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
14161 s390_irgen_load_ar_multiple(r1, r3, op2addr);
14163 return "lam";
14166 static const HChar *
14167 s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
14169 s390_irgen_load_ar_multiple(r1, r3, op2addr);
14171 return "lamy";
14174 static void
14175 s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
14177 UChar reg;
14178 IRTemp addr = newTemp(Ity_I64);
14180 assign(addr, mkexpr(op2addr));
14181 reg = r1;
14182 do {
14183 IRTemp old = addr;
14185 reg %= 16;
14186 store(mkexpr(addr), get_ar_w0(reg));
14187 addr = newTemp(Ity_I64);
14188 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
14189 reg++;
14190 } while (reg != (r3 + 1));
14193 static const HChar *
14194 s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
14196 s390_irgen_store_ar_multiple(r1, r3, op2addr);
14198 return "stam";
14201 static const HChar *
14202 s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
14204 s390_irgen_store_ar_multiple(r1, r3, op2addr);
14206 return "stamy";
14210 /* Implementation for 32-bit compare-and-swap */
14211 static void
14212 s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
14214 IRCAS *cas;
14215 IRTemp op1 = newTemp(Ity_I32);
14216 IRTemp old_mem = newTemp(Ity_I32);
14217 IRTemp op3 = newTemp(Ity_I32);
14218 IRTemp nequal = newTemp(Ity_I1);
14220 assign(op1, get_gpr_w1(r1));
14221 assign(op3, get_gpr_w1(r3));
14223 /* The first and second operands are compared. If they are equal,
14224 the third operand is stored at the second- operand location. */
14225 cas = mkIRCAS(IRTemp_INVALID, old_mem,
14226 Iend_BE, mkexpr(op2addr),
14227 NULL, mkexpr(op1), /* expected value */
14228 NULL, mkexpr(op3) /* new value */);
14229 stmt(IRStmt_CAS(cas));
14231 /* Set CC. Operands compared equal -> 0, else 1. */
14232 assign(nequal, binop(Iop_CasCmpNE32, mkexpr(op1), mkexpr(old_mem)));
14233 s390_cc_thunk_put1(S390_CC_OP_BITWISE, nequal, True);
14235 /* If operands were equal (cc == 0) just store the old value op1 in r1.
14236 Otherwise, store the old_value from memory in r1 and yield. */
14237 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
14238 yield_if(mkexpr(nequal));
14241 static const HChar *
14242 s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
14244 s390_irgen_cas_32(r1, r3, op2addr);
14246 return "cs";
14249 static const HChar *
14250 s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
14252 s390_irgen_cas_32(r1, r3, op2addr);
14254 return "csy";
14257 static const HChar *
14258 s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
14260 IRCAS *cas;
14261 IRTemp op1 = newTemp(Ity_I64);
14262 IRTemp old_mem = newTemp(Ity_I64);
14263 IRTemp op3 = newTemp(Ity_I64);
14264 IRTemp nequal = newTemp(Ity_I1);
14266 assign(op1, get_gpr_dw0(r1));
14267 assign(op3, get_gpr_dw0(r3));
14269 /* The first and second operands are compared. If they are equal,
14270 the third operand is stored at the second- operand location. */
14271 cas = mkIRCAS(IRTemp_INVALID, old_mem,
14272 Iend_BE, mkexpr(op2addr),
14273 NULL, mkexpr(op1), /* expected value */
14274 NULL, mkexpr(op3) /* new value */);
14275 stmt(IRStmt_CAS(cas));
14277 /* Set CC. Operands compared equal -> 0, else 1. */
14278 assign(nequal, binop(Iop_CasCmpNE64, mkexpr(op1), mkexpr(old_mem)));
14279 s390_cc_thunk_put1(S390_CC_OP_BITWISE, nequal, True);
14281 /* If operands were equal (cc == 0) just store the old value op1 in r1.
14282 Otherwise, store the old_value from memory in r1 and yield. */
14283 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
14284 yield_if(mkexpr(nequal));
14286 return "csg";
14289 /* Implementation for 32-bit compare-double-and-swap */
14290 static void
14291 s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
14293 IRCAS *cas;
14294 IRTemp op1_high = newTemp(Ity_I32);
14295 IRTemp op1_low = newTemp(Ity_I32);
14296 IRTemp old_mem_high = newTemp(Ity_I32);
14297 IRTemp old_mem_low = newTemp(Ity_I32);
14298 IRTemp op3_high = newTemp(Ity_I32);
14299 IRTemp op3_low = newTemp(Ity_I32);
14300 IRTemp nequal = newTemp(Ity_I1);
14302 assign(op1_high, get_gpr_w1(r1));
14303 assign(op1_low, get_gpr_w1(r1+1));
14304 assign(op3_high, get_gpr_w1(r3));
14305 assign(op3_low, get_gpr_w1(r3+1));
14307 /* The first and second operands are compared. If they are equal,
14308 the third operand is stored at the second-operand location. */
14309 cas = mkIRCAS(old_mem_high, old_mem_low,
14310 Iend_BE, mkexpr(op2addr),
14311 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
14312 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
14313 stmt(IRStmt_CAS(cas));
14315 /* Set CC. Operands compared equal -> 0, else 1. */
14316 assign(nequal,
14317 binop(Iop_CasCmpNE32,
14318 binop(Iop_Or32,
14319 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
14320 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
14321 mkU32(0)));
14323 s390_cc_thunk_put1(S390_CC_OP_BITWISE, nequal, True);
14325 /* If operands were equal (cc == 0) just store the old value op1 in r1.
14326 Otherwise, store the old_value from memory in r1 and yield. */
14327 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
14328 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
14329 yield_if(mkexpr(nequal));
14332 static const HChar *
14333 s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
14335 s390_irgen_cdas_32(r1, r3, op2addr);
14337 return "cds";
14340 static const HChar *
14341 s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
14343 s390_irgen_cdas_32(r1, r3, op2addr);
14345 return "cdsy";
14348 static const HChar *
14349 s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
14351 IRCAS *cas;
14352 IRTemp op1_high = newTemp(Ity_I64);
14353 IRTemp op1_low = newTemp(Ity_I64);
14354 IRTemp old_mem_high = newTemp(Ity_I64);
14355 IRTemp old_mem_low = newTemp(Ity_I64);
14356 IRTemp op3_high = newTemp(Ity_I64);
14357 IRTemp op3_low = newTemp(Ity_I64);
14358 IRTemp result = newTemp(Ity_I64);
14359 IRTemp nequal = newTemp(Ity_I1);
14361 assign(op1_high, get_gpr_dw0(r1));
14362 assign(op1_low, get_gpr_dw0(r1+1));
14363 assign(op3_high, get_gpr_dw0(r3));
14364 assign(op3_low, get_gpr_dw0(r3+1));
14366 /* The first and second operands are compared. If they are equal,
14367 the third operand is stored at the second-operand location. */
14368 cas = mkIRCAS(old_mem_high, old_mem_low,
14369 Iend_BE, mkexpr(op2addr),
14370 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
14371 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
14372 stmt(IRStmt_CAS(cas));
14374 /* Set CC. Operands compared equal -> 0, else 1. */
14375 assign(result, unop(Iop_1Uto64,
14376 binop(Iop_CmpNE64,
14377 binop(Iop_Or64,
14378 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
14379 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
14380 mkU64(0))));
14382 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
14384 /* If operands were equal (cc == 0) just store the old value op1 in r1.
14385 Otherwise, store the old_value from memory in r1 and yield. */
14386 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
14387 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
14388 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
14389 yield_if(mkexpr(nequal));
14391 return "cdsg";
14395 /* Binary floating point */
14397 static const HChar *
14398 s390_irgen_AXBR(UChar r1, UChar r2)
14400 IRTemp op1 = newTemp(Ity_F128);
14401 IRTemp op2 = newTemp(Ity_F128);
14402 IRTemp result = newTemp(Ity_F128);
14403 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14405 assign(op1, get_fpr_pair(r1));
14406 assign(op2, get_fpr_pair(r2));
14407 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
14408 mkexpr(op2)));
14409 put_fpr_pair(r1, mkexpr(result));
14411 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14413 return "axbr";
14416 /* Helper for "compare" insns CEBR, CDBR, CXBR, and their signalling
14417 counterparts. */
14418 static const HChar *
14419 s390_irgen_CxBR(const HChar *mnem, UChar r1, UChar r2, IRType type, IROp cmp_op)
14421 IRTemp op1 = newTemp(type);
14422 IRTemp op2 = newTemp(type);
14423 IRTemp cc_vex = newTemp(Ity_I32);
14424 IRTemp cc_s390 = newTemp(Ity_I32);
14426 assign(op1, get_fpr_float(r1, type));
14427 assign(op2, get_fpr_float(r2, type));
14428 assign(cc_vex, binop(cmp_op, mkexpr(op1), mkexpr(op2)));
14430 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
14431 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
14432 return mnem;
14435 static const HChar *
14436 s390_irgen_CEBR(UChar r1, UChar r2)
14438 return s390_irgen_CxBR("cebr", r1, r2, Ity_F32, Iop_CmpF32);
14441 static const HChar *
14442 s390_irgen_KEBR(UChar r1, UChar r2)
14444 return s390_irgen_CxBR("kebr", r1, r2, Ity_F32, Iop_CmpF32);
14447 static const HChar *
14448 s390_irgen_CDBR(UChar r1, UChar r2)
14450 return s390_irgen_CxBR("cdbr", r1, r2, Ity_F64, Iop_CmpF64);
14453 static const HChar *
14454 s390_irgen_KDBR(UChar r1, UChar r2)
14456 return s390_irgen_CxBR("kdbr", r1, r2, Ity_F64, Iop_CmpF64);
14459 static const HChar *
14460 s390_irgen_CXBR(UChar r1, UChar r2)
14462 return s390_irgen_CxBR("cxbr", r1, r2, Ity_F128, Iop_CmpF128);
14465 static const HChar *
14466 s390_irgen_KXBR(UChar r1, UChar r2)
14468 return s390_irgen_CxBR("kxbr", r1, r2, Ity_F128, Iop_CmpF128);
14471 /* Helper for "compare" insns CEB, CDB, and their signalling counterparts. */
14472 static const HChar *
14473 s390_irgen_CxB(const HChar *mnem, UChar r1, IRTemp op2addr, IRType type,
14474 IROp cmp_op)
14476 IRTemp op1 = newTemp(type);
14477 IRTemp op2 = newTemp(type);
14478 IRTemp cc_vex = newTemp(Ity_I32);
14479 IRTemp cc_s390 = newTemp(Ity_I32);
14481 assign(op1, get_fpr_float(r1, type));
14482 assign(op2, load(type, mkexpr(op2addr)));
14483 assign(cc_vex, binop(cmp_op, mkexpr(op1), mkexpr(op2)));
14485 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
14486 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
14487 return mnem;
14490 static const HChar *
14491 s390_irgen_CEB(UChar r1, IRTemp op2addr)
14493 return s390_irgen_CxB("ceb", r1, op2addr, Ity_F32, Iop_CmpF32);
14496 static const HChar *
14497 s390_irgen_KEB(UChar r1, IRTemp op2addr)
14499 return s390_irgen_CxB("keb", r1, op2addr, Ity_F32, Iop_CmpF32);
14502 static const HChar *
14503 s390_irgen_CDB(UChar r1, IRTemp op2addr)
14505 return s390_irgen_CxB("cdb", r1, op2addr, Ity_F64, Iop_CmpF64);
14508 static const HChar *
14509 s390_irgen_KDB(UChar r1, IRTemp op2addr)
14511 return s390_irgen_CxB("kdb", r1, op2addr, Ity_F64, Iop_CmpF64);
14514 static const HChar *
14515 s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
14516 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
14518 IRTemp op2 = newTemp(Ity_I32);
14520 assign(op2, get_gpr_w1(r2));
14521 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
14523 return "cxfbr";
14526 static const HChar *
14527 s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
14528 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
14530 if (! s390_host_has_fpext) {
14531 emulation_failure(EmFail_S390X_fpext);
14532 } else {
14533 IRTemp op2 = newTemp(Ity_I32);
14535 assign(op2, get_gpr_w1(r2));
14536 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
14538 return "cxlfbr";
14542 static const HChar *
14543 s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
14544 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
14546 IRTemp op2 = newTemp(Ity_I64);
14548 assign(op2, get_gpr_dw0(r2));
14549 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
14551 return "cxgbr";
14554 static const HChar *
14555 s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
14556 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
14558 if (! s390_host_has_fpext) {
14559 emulation_failure(EmFail_S390X_fpext);
14560 } else {
14561 IRTemp op2 = newTemp(Ity_I64);
14563 assign(op2, get_gpr_dw0(r2));
14564 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
14566 return "cxlgbr";
14569 static const HChar *
14570 s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
14571 UChar r1, UChar r2)
14573 IRTemp op = newTemp(Ity_F128);
14574 IRTemp result = newTemp(Ity_I32);
14575 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
14577 assign(op, get_fpr_pair(r2));
14578 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
14579 mkexpr(op)));
14580 put_gpr_w1(r1, mkexpr(result));
14581 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
14583 return "cfxbr";
14586 static const HChar *
14587 s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
14588 UChar r1, UChar r2)
14590 if (! s390_host_has_fpext) {
14591 emulation_failure(EmFail_S390X_fpext);
14592 } else {
14593 IRTemp op = newTemp(Ity_F128);
14594 IRTemp result = newTemp(Ity_I32);
14595 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
14597 assign(op, get_fpr_pair(r2));
14598 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
14599 mkexpr(op)));
14600 put_gpr_w1(r1, mkexpr(result));
14601 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
14603 return "clfxbr";
14607 static const HChar *
14608 s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
14609 UChar r1, UChar r2)
14611 IRTemp op = newTemp(Ity_F128);
14612 IRTemp result = newTemp(Ity_I64);
14613 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
14615 assign(op, get_fpr_pair(r2));
14616 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
14617 mkexpr(op)));
14618 put_gpr_dw0(r1, mkexpr(result));
14619 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
14621 return "cgxbr";
14624 static const HChar *
14625 s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
14626 UChar r1, UChar r2)
14628 if (! s390_host_has_fpext) {
14629 emulation_failure(EmFail_S390X_fpext);
14630 } else {
14631 IRTemp op = newTemp(Ity_F128);
14632 IRTemp result = newTemp(Ity_I64);
14633 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
14635 assign(op, get_fpr_pair(r2));
14636 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
14637 mkexpr(op)));
14638 put_gpr_dw0(r1, mkexpr(result));
14639 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
14640 rounding_mode);
14642 return "clgxbr";
14645 static const HChar *
14646 s390_irgen_DXBR(UChar r1, UChar r2)
14648 IRTemp op1 = newTemp(Ity_F128);
14649 IRTemp op2 = newTemp(Ity_F128);
14650 IRTemp result = newTemp(Ity_F128);
14651 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14653 assign(op1, get_fpr_pair(r1));
14654 assign(op2, get_fpr_pair(r2));
14655 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
14656 mkexpr(op2)));
14657 put_fpr_pair(r1, mkexpr(result));
14659 return "dxbr";
14662 static const HChar *
14663 s390_irgen_LTXBR(UChar r1, UChar r2)
14665 IRTemp result = newTemp(Ity_F128);
14667 assign(result, get_fpr_pair(r2));
14668 put_fpr_pair(r1, mkexpr(result));
14669 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14671 return "ltxbr";
14674 static const HChar *
14675 s390_irgen_LCXBR(UChar r1, UChar r2)
14677 IRTemp result = newTemp(Ity_F128);
14679 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
14680 put_fpr_pair(r1, mkexpr(result));
14681 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14683 return "lcxbr";
14686 static const HChar *
14687 s390_irgen_LXDBR(UChar r1, UChar r2)
14689 IRTemp op = newTemp(Ity_F64);
14691 assign(op, get_fpr_dw0(r2));
14692 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
14694 return "lxdbr";
14697 static const HChar *
14698 s390_irgen_LXEBR(UChar r1, UChar r2)
14700 IRTemp op = newTemp(Ity_F32);
14702 assign(op, get_fpr_w0(r2));
14703 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
14705 return "lxebr";
14708 static const HChar *
14709 s390_irgen_LXDB(UChar r1, IRTemp op2addr)
14711 IRTemp op = newTemp(Ity_F64);
14713 assign(op, load(Ity_F64, mkexpr(op2addr)));
14714 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
14716 return "lxdb";
14719 static const HChar *
14720 s390_irgen_LXEB(UChar r1, IRTemp op2addr)
14722 IRTemp op = newTemp(Ity_F32);
14724 assign(op, load(Ity_F32, mkexpr(op2addr)));
14725 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
14727 return "lxeb";
14730 static const HChar *
14731 s390_irgen_FIEBRA(UChar m3, UChar m4 __attribute__((unused)),
14732 UChar r1, UChar r2)
14734 IRTemp result = newTemp(Ity_F32);
14736 assign(result, binop(Iop_RoundF32toInt, mkexpr(encode_bfp_rounding_mode(m3)),
14737 get_fpr_w0(r2)));
14738 put_fpr_w0(r1, mkexpr(result));
14740 return "fiebra";
14743 static const HChar *
14744 s390_irgen_FIDBRA(UChar m3, UChar m4 __attribute__((unused)),
14745 UChar r1, UChar r2)
14747 IRTemp result = newTemp(Ity_F64);
14749 assign(result, binop(Iop_RoundF64toInt, mkexpr(encode_bfp_rounding_mode(m3)),
14750 get_fpr_dw0(r2)));
14751 put_fpr_dw0(r1, mkexpr(result));
14753 return "fidbra";
14756 static const HChar *
14757 s390_irgen_FIXBRA(UChar m3, UChar m4 __attribute__((unused)),
14758 UChar r1, UChar r2)
14760 IRTemp result = newTemp(Ity_F128);
14762 assign(result, binop(Iop_RoundF128toInt, mkexpr(encode_bfp_rounding_mode(m3)),
14763 get_fpr_pair(r2)));
14764 put_fpr_pair(r1, mkexpr(result));
14766 return "fixbra";
14769 static const HChar *
14770 s390_irgen_LNEBR(UChar r1, UChar r2)
14772 IRTemp result = newTemp(Ity_F32);
14774 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
14775 put_fpr_w0(r1, mkexpr(result));
14776 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
14778 return "lnebr";
14781 static const HChar *
14782 s390_irgen_LNDBR(UChar r1, UChar r2)
14784 IRTemp result = newTemp(Ity_F64);
14786 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
14787 put_fpr_dw0(r1, mkexpr(result));
14788 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
14790 return "lndbr";
14793 static const HChar *
14794 s390_irgen_LNXBR(UChar r1, UChar r2)
14796 IRTemp result = newTemp(Ity_F128);
14798 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
14799 put_fpr_pair(r1, mkexpr(result));
14800 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14802 return "lnxbr";
14805 static const HChar *
14806 s390_irgen_LPEBR(UChar r1, UChar r2)
14808 IRTemp result = newTemp(Ity_F32);
14810 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
14811 put_fpr_w0(r1, mkexpr(result));
14812 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
14814 return "lpebr";
14817 static const HChar *
14818 s390_irgen_LPDBR(UChar r1, UChar r2)
14820 IRTemp result = newTemp(Ity_F64);
14822 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
14823 put_fpr_dw0(r1, mkexpr(result));
14824 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
14826 return "lpdbr";
14829 static const HChar *
14830 s390_irgen_LPXBR(UChar r1, UChar r2)
14832 IRTemp result = newTemp(Ity_F128);
14834 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
14835 put_fpr_pair(r1, mkexpr(result));
14836 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
14838 return "lpxbr";
14841 static const HChar *
14842 s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
14843 UChar r1, UChar r2)
14845 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
14846 emulation_warning(EmWarn_S390X_fpext_rounding);
14847 m3 = S390_BFP_ROUND_PER_FPC;
14849 IRTemp result = newTemp(Ity_F64);
14851 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
14852 get_fpr_pair(r2)));
14853 put_fpr_dw0(r1, mkexpr(result));
14855 return "ldxbr";
14858 static const HChar *
14859 s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
14860 UChar r1, UChar r2)
14862 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
14863 emulation_warning(EmWarn_S390X_fpext_rounding);
14864 m3 = S390_BFP_ROUND_PER_FPC;
14866 IRTemp result = newTemp(Ity_F32);
14868 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
14869 get_fpr_pair(r2)));
14870 put_fpr_w0(r1, mkexpr(result));
14872 return "lexbr";
14875 static const HChar *
14876 s390_irgen_MXBR(UChar r1, UChar r2)
14878 IRTemp op1 = newTemp(Ity_F128);
14879 IRTemp op2 = newTemp(Ity_F128);
14880 IRTemp result = newTemp(Ity_F128);
14881 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14883 assign(op1, get_fpr_pair(r1));
14884 assign(op2, get_fpr_pair(r2));
14885 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
14886 mkexpr(op2)));
14887 put_fpr_pair(r1, mkexpr(result));
14889 return "mxbr";
14892 static const HChar *
14893 s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
14895 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14897 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
14898 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
14900 return "maebr";
14903 static const HChar *
14904 s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
14906 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14908 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
14909 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
14911 return "madbr";
14914 static const HChar *
14915 s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
14917 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
14918 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14920 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
14921 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
14923 return "maeb";
14926 static const HChar *
14927 s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
14929 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
14930 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14932 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
14933 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
14935 return "madb";
14938 static const HChar *
14939 s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
14941 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14943 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
14944 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
14946 return "msebr";
14949 static const HChar *
14950 s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
14952 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14954 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
14955 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
14957 return "msdbr";
14960 static const HChar *
14961 s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
14963 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
14964 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14966 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
14967 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
14969 return "mseb";
14972 static const HChar *
14973 s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
14975 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
14976 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14978 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
14979 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
14981 return "msdb";
14984 static const HChar *
14985 s390_irgen_SQEBR(UChar r1, UChar r2)
14987 IRTemp result = newTemp(Ity_F32);
14988 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
14990 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
14991 put_fpr_w0(r1, mkexpr(result));
14993 return "sqebr";
14996 static const HChar *
14997 s390_irgen_SQDBR(UChar r1, UChar r2)
14999 IRTemp result = newTemp(Ity_F64);
15000 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
15002 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
15003 put_fpr_dw0(r1, mkexpr(result));
15005 return "sqdbr";
15008 static const HChar *
15009 s390_irgen_SQXBR(UChar r1, UChar r2)
15011 IRTemp result = newTemp(Ity_F128);
15012 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
15014 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
15015 get_fpr_pair(r2)));
15016 put_fpr_pair(r1, mkexpr(result));
15018 return "sqxbr";
15021 static const HChar *
15022 s390_irgen_SQEB(UChar r1, IRTemp op2addr)
15024 IRTemp op = newTemp(Ity_F32);
15025 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
15027 assign(op, load(Ity_F32, mkexpr(op2addr)));
15028 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
15030 return "sqeb";
15033 static const HChar *
15034 s390_irgen_SQDB(UChar r1, IRTemp op2addr)
15036 IRTemp op = newTemp(Ity_F64);
15037 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
15039 assign(op, load(Ity_F64, mkexpr(op2addr)));
15040 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
15042 return "sqdb";
15045 static const HChar *
15046 s390_irgen_SXBR(UChar r1, UChar r2)
15048 IRTemp op1 = newTemp(Ity_F128);
15049 IRTemp op2 = newTemp(Ity_F128);
15050 IRTemp result = newTemp(Ity_F128);
15051 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
15053 assign(op1, get_fpr_pair(r1));
15054 assign(op2, get_fpr_pair(r2));
15055 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
15056 mkexpr(op2)));
15057 put_fpr_pair(r1, mkexpr(result));
15058 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
15060 return "sxbr";
15063 static const HChar *
15064 s390_irgen_TCEB(UChar r1, IRTemp op2addr)
15066 IRTemp value = newTemp(Ity_F32);
15068 assign(value, get_fpr_w0(r1));
15070 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
15072 return "tceb";
15075 static const HChar *
15076 s390_irgen_TCDB(UChar r1, IRTemp op2addr)
15078 IRTemp value = newTemp(Ity_F64);
15080 assign(value, get_fpr_dw0(r1));
15082 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
15084 return "tcdb";
15087 static const HChar *
15088 s390_irgen_TCXB(UChar r1, IRTemp op2addr)
15090 IRTemp value = newTemp(Ity_F128);
15092 assign(value, get_fpr_pair(r1));
15094 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
15096 return "tcxb";
15099 static const HChar *
15100 s390_irgen_LCDFR(UChar r1, UChar r2)
15102 IRTemp result = newTemp(Ity_F64);
15104 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
15105 put_fpr_dw0(r1, mkexpr(result));
15107 return "lcdfr";
15110 static const HChar *
15111 s390_irgen_LNDFR(UChar r1, UChar r2)
15113 IRTemp result = newTemp(Ity_F64);
15115 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
15116 put_fpr_dw0(r1, mkexpr(result));
15118 return "lndfr";
15121 static const HChar *
15122 s390_irgen_LPDFR(UChar r1, UChar r2)
15124 IRTemp result = newTemp(Ity_F64);
15126 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
15127 put_fpr_dw0(r1, mkexpr(result));
15129 return "lpdfr";
15132 static const HChar *
15133 s390_irgen_LDGR(UChar r1, UChar r2)
15135 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
15137 return "ldgr";
15140 static const HChar *
15141 s390_irgen_LGDR(UChar r1, UChar r2)
15143 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
15145 return "lgdr";
15149 static const HChar *
15150 s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
15152 IRTemp sign = newTemp(Ity_I64);
15153 IRTemp value = newTemp(Ity_I64);
15155 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
15156 mkU64(1ULL << 63)));
15157 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
15158 mkU64((1ULL << 63) - 1)));
15159 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
15160 mkexpr(sign))));
15162 return "cpsdr";
15166 static IRExpr *
15167 s390_call_cvb(IRExpr *in)
15169 IRExpr **args, *call;
15171 args = mkIRExprVec_1(in);
15172 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
15173 "s390_do_cvb", &s390_do_cvb, args);
15175 /* Nothing is excluded from definedness checking. */
15176 call->Iex.CCall.cee->mcx_mask = 0;
15178 return call;
15181 static const HChar *
15182 s390_irgen_CVB(UChar r1, IRTemp op2addr)
15184 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
15186 return "cvb";
15189 static const HChar *
15190 s390_irgen_CVBY(UChar r1, IRTemp op2addr)
15192 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
15194 return "cvby";
15198 static IRExpr *
15199 s390_call_cvd(IRExpr *in)
15201 IRExpr **args, *call;
15203 args = mkIRExprVec_1(in);
15204 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15205 "s390_do_cvd", &s390_do_cvd, args);
15207 /* Nothing is excluded from definedness checking. */
15208 call->Iex.CCall.cee->mcx_mask = 0;
15210 return call;
15213 static const HChar *
15214 s390_irgen_CVD(UChar r1, IRTemp op2addr)
15216 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
15218 return "cvd";
15221 static const HChar *
15222 s390_irgen_CVDY(UChar r1, IRTemp op2addr)
15224 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
15226 return "cvdy";
15229 static const HChar *
15230 s390_irgen_FLOGR(UChar r1, UChar r2)
15232 IRTemp input = newTemp(Ity_I64);
15233 IRTemp num = newTemp(Ity_I64);
15234 IRTemp shift_amount = newTemp(Ity_I8);
15236 /* Use the "count leading zeroes" operator with "natural" semantics. The
15237 results of FLOGR and Iop_ClzNat64 are the same for all inputs, including
15238 input == 0, in which case both operators yield 64. */
15240 assign(input, get_gpr_dw0(r2));
15241 assign(num, unop(Iop_ClzNat64, mkexpr(input)));
15242 put_gpr_dw0(r1, mkexpr(num));
15244 /* Set the leftmost '1' bit of the input value to zero. The general scheme
15245 is to first shift the input value by NUM + 1 bits to the left which
15246 causes the leftmost '1' bit to disappear. Then we shift logically to
15247 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
15248 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
15249 the width of the value-to-be-shifted, we need to special case
15250 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
15251 For both such INPUT values the result will be 0. */
15253 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
15254 mkU64(1))));
15256 put_gpr_dw0(r1 + 1,
15257 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
15258 /* == 0 || == 1*/ mkU64(0),
15259 /* otherwise */
15260 binop(Iop_Shr64,
15261 binop(Iop_Shl64, mkexpr(input),
15262 mkexpr(shift_amount)),
15263 mkexpr(shift_amount))));
15265 /* Compare the original value as an unsigned integer with 0. */
15266 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
15267 mktemp(Ity_I64, mkU64(0)), False);
15269 return "flogr";
15272 static const HChar *
15273 s390_irgen_POPCNT(UChar m3, UChar r1, UChar r2)
15275 s390_insn_assert("popcnt", (m3 & 7) == 0);
15277 static const ULong masks[] = {
15278 0x5555555555555555, 0x3333333333333333, 0x0F0F0F0F0F0F0F0F,
15279 0x00FF00FF00FF00FF, 0x0000FFFF0000FFFF, 0x00000000FFFFFFFF,
15281 Int i, n;
15282 IRTemp val = newTemp(Ity_I64);
15284 assign(val, get_gpr_dw0(r2));
15285 n = (m3 & 8) ? 6 : 3;
15286 for (i = 0; i < n; i++) {
15287 IRTemp mask = newTemp(Ity_I64);
15288 IRTemp tmp = newTemp(Ity_I64);
15290 assign (mask, mkU64(masks[i]));
15291 assign(tmp,
15292 binop(Iop_Add64,
15293 binop(Iop_And64,
15294 mkexpr(val),
15295 mkexpr(mask)),
15296 binop(Iop_And64,
15297 binop(Iop_Shr64, mkexpr(val), mkU8(1 << i)),
15298 mkexpr(mask))));
15299 val = tmp;
15301 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, val);
15302 put_gpr_dw0(r1, mkexpr(val));
15303 return "popcnt";
15306 static const HChar *
15307 s390_irgen_STCK(IRTemp op2addr)
15309 IRDirty *d;
15310 IRTemp cc = newTemp(Ity_I64);
15312 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
15313 &s390x_dirtyhelper_STCK,
15314 mkIRExprVec_1(mkexpr(op2addr)));
15315 d->mFx = Ifx_Write;
15316 d->mAddr = mkexpr(op2addr);
15317 d->mSize = 8;
15318 stmt(IRStmt_Dirty(d));
15319 s390_cc_set(cc);
15320 return "stck";
15323 static const HChar *
15324 s390_irgen_STCKF(IRTemp op2addr)
15326 if (! s390_host_has_stckf) {
15327 emulation_failure(EmFail_S390X_stckf);
15328 } else {
15329 IRTemp cc = newTemp(Ity_I64);
15331 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
15332 &s390x_dirtyhelper_STCKF,
15333 mkIRExprVec_1(mkexpr(op2addr)));
15334 d->mFx = Ifx_Write;
15335 d->mAddr = mkexpr(op2addr);
15336 d->mSize = 8;
15337 stmt(IRStmt_Dirty(d));
15338 s390_cc_set(cc);
15340 return "stckf";
15343 static const HChar *
15344 s390_irgen_STCKE(IRTemp op2addr)
15346 IRDirty *d;
15347 IRTemp cc = newTemp(Ity_I64);
15349 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
15350 &s390x_dirtyhelper_STCKE,
15351 mkIRExprVec_1(mkexpr(op2addr)));
15352 d->mFx = Ifx_Write;
15353 d->mAddr = mkexpr(op2addr);
15354 d->mSize = 16;
15355 stmt(IRStmt_Dirty(d));
15356 s390_cc_set(cc);
15357 return "stcke";
15360 static const HChar *
15361 s390_irgen_STFLE(UChar b2, UShort d2)
15363 if (! s390_host_has_stfle) {
15364 emulation_failure(EmFail_S390X_stfle);
15365 return "stfle";
15367 extension(S390_EXT_STFLE, b2 | (d2 << 8));
15368 return "stfle";
15371 static const HChar *
15372 s390_irgen_CKSM(UChar r1,UChar r2)
15374 IRTemp addr = newTemp(Ity_I64);
15375 IRTemp op = newTemp(Ity_I32);
15376 IRTemp len = newTemp(Ity_I64);
15377 IRTemp oldval = newTemp(Ity_I32);
15378 IRTemp mask = newTemp(Ity_I32);
15379 IRTemp newop = newTemp(Ity_I32);
15380 IRTemp result = newTemp(Ity_I32);
15381 IRTemp result1 = newTemp(Ity_I32);
15382 IRTemp inc = newTemp(Ity_I64);
15384 assign(oldval, get_gpr_w1(r1));
15385 assign(addr, get_gpr_dw0(r2));
15386 assign(len, get_gpr_dw0(r2+1));
15388 /* Condition code is always zero. */
15389 s390_cc_set_val(0);
15391 /* If length is zero, there is no need to calculate the checksum */
15392 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
15394 /* Assiging the increment variable to adjust address and length
15395 later on. */
15396 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
15397 mkexpr(len), mkU64(4)));
15399 /* If length < 4 the final 4-byte 2nd operand value is computed by
15400 appending the remaining bytes to the right with 0. This is done
15401 by AND'ing the 4 bytes loaded from memory with an appropriate
15402 mask. If length >= 4, that mask is simply 0xffffffff. */
15404 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
15405 /* Mask computation when len < 4:
15406 0xffffffff << (32 - (len % 4)*8) */
15407 binop(Iop_Shl32, mkU32(0xffffffff),
15408 unop(Iop_32to8,
15409 binop(Iop_Sub32, mkU32(32),
15410 binop(Iop_Shl32,
15411 unop(Iop_64to32,
15412 binop(Iop_And64,
15413 mkexpr(len), mkU64(3))),
15414 mkU8(3))))),
15415 mkU32(0xffffffff)));
15417 assign(op, load(Ity_I32, mkexpr(addr)));
15418 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
15419 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
15421 /* Checking for carry */
15422 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
15423 binop(Iop_Add32, mkexpr(result), mkU32(1)),
15424 mkexpr(result)));
15426 put_gpr_w1(r1, mkexpr(result1));
15427 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
15428 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
15430 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
15432 return "cksm";
15435 static const HChar *
15436 s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
15438 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
15439 src_addr = newTemp(Ity_I64);
15440 des_addr = newTemp(Ity_I64);
15441 tab_addr = newTemp(Ity_I64);
15442 test_byte = newTemp(Ity_I8);
15443 src_len = newTemp(Ity_I64);
15445 assign(src_addr, get_gpr_dw0(r2));
15446 assign(des_addr, get_gpr_dw0(r1));
15447 assign(tab_addr, get_gpr_dw0(1));
15448 assign(src_len, get_gpr_dw0(r1+1));
15449 assign(test_byte, get_gpr_b7(0));
15451 IRTemp op = newTemp(Ity_I8);
15452 IRTemp op1 = newTemp(Ity_I8);
15453 IRTemp result = newTemp(Ity_I64);
15455 /* End of source string? We're done; proceed to next insn */
15456 s390_cc_set_val(0);
15457 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
15459 /* Load character from source string, index translation table and
15460 store translated character in op1. */
15461 assign(op, load(Ity_I8, mkexpr(src_addr)));
15463 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
15464 mkexpr(tab_addr)));
15465 assign(op1, load(Ity_I8, mkexpr(result)));
15467 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
15468 s390_cc_set_val(1);
15469 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
15471 store(get_gpr_dw0(r1), mkexpr(op1));
15473 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
15474 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
15475 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
15477 iterate();
15479 return "troo";
15482 static const HChar *
15483 s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
15485 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
15486 src_addr = newTemp(Ity_I64);
15487 des_addr = newTemp(Ity_I64);
15488 tab_addr = newTemp(Ity_I64);
15489 test_byte = newTemp(Ity_I8);
15490 src_len = newTemp(Ity_I64);
15492 assign(src_addr, get_gpr_dw0(r2));
15493 assign(des_addr, get_gpr_dw0(r1));
15494 assign(tab_addr, get_gpr_dw0(1));
15495 assign(src_len, get_gpr_dw0(r1+1));
15496 assign(test_byte, get_gpr_b7(0));
15498 IRTemp op = newTemp(Ity_I16);
15499 IRTemp op1 = newTemp(Ity_I8);
15500 IRTemp result = newTemp(Ity_I64);
15502 /* End of source string? We're done; proceed to next insn */
15503 s390_cc_set_val(0);
15504 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
15506 /* Load character from source string, index translation table and
15507 store translated character in op1. */
15508 assign(op, load(Ity_I16, mkexpr(src_addr)));
15510 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
15511 mkexpr(tab_addr)));
15513 assign(op1, load(Ity_I8, mkexpr(result)));
15515 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
15516 s390_cc_set_val(1);
15517 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
15519 store(get_gpr_dw0(r1), mkexpr(op1));
15521 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
15522 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
15523 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
15525 iterate();
15527 return "trto";
15530 static const HChar *
15531 s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
15533 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
15534 src_addr = newTemp(Ity_I64);
15535 des_addr = newTemp(Ity_I64);
15536 tab_addr = newTemp(Ity_I64);
15537 test_byte = newTemp(Ity_I16);
15538 src_len = newTemp(Ity_I64);
15540 assign(src_addr, get_gpr_dw0(r2));
15541 assign(des_addr, get_gpr_dw0(r1));
15542 assign(tab_addr, get_gpr_dw0(1));
15543 assign(src_len, get_gpr_dw0(r1+1));
15544 assign(test_byte, get_gpr_hw3(0));
15546 IRTemp op = newTemp(Ity_I8);
15547 IRTemp op1 = newTemp(Ity_I16);
15548 IRTemp result = newTemp(Ity_I64);
15550 /* End of source string? We're done; proceed to next insn */
15551 s390_cc_set_val(0);
15552 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
15554 /* Load character from source string, index translation table and
15555 store translated character in op1. */
15556 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
15558 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
15559 mkexpr(tab_addr)));
15560 assign(op1, load(Ity_I16, mkexpr(result)));
15562 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
15563 s390_cc_set_val(1);
15564 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
15566 store(get_gpr_dw0(r1), mkexpr(op1));
15568 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
15569 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
15570 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
15572 iterate();
15574 return "trot";
15577 static const HChar *
15578 s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
15580 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
15581 src_addr = newTemp(Ity_I64);
15582 des_addr = newTemp(Ity_I64);
15583 tab_addr = newTemp(Ity_I64);
15584 test_byte = newTemp(Ity_I16);
15585 src_len = newTemp(Ity_I64);
15587 assign(src_addr, get_gpr_dw0(r2));
15588 assign(des_addr, get_gpr_dw0(r1));
15589 assign(tab_addr, get_gpr_dw0(1));
15590 assign(src_len, get_gpr_dw0(r1+1));
15591 assign(test_byte, get_gpr_hw3(0));
15593 IRTemp op = newTemp(Ity_I16);
15594 IRTemp op1 = newTemp(Ity_I16);
15595 IRTemp result = newTemp(Ity_I64);
15597 /* End of source string? We're done; proceed to next insn */
15598 s390_cc_set_val(0);
15599 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
15601 /* Load character from source string, index translation table and
15602 store translated character in op1. */
15603 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
15605 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
15606 mkexpr(tab_addr)));
15607 assign(op1, load(Ity_I16, mkexpr(result)));
15609 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
15610 s390_cc_set_val(1);
15611 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
15614 store(get_gpr_dw0(r1), mkexpr(op1));
15616 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
15617 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
15618 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
15620 iterate();
15622 return "trtt";
15625 static const HChar *
15626 s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
15628 IRTemp len = newTemp(Ity_I64);
15630 assign(len, mkU64(length));
15631 s390_irgen_TR_EX(len, start1, start2);
15633 return "tr";
15636 static const HChar *
15637 s390_irgen_TRE(UChar r1,UChar r2)
15639 IRTemp src_addr, tab_addr, src_len, test_byte;
15640 src_addr = newTemp(Ity_I64);
15641 tab_addr = newTemp(Ity_I64);
15642 src_len = newTemp(Ity_I64);
15643 test_byte = newTemp(Ity_I8);
15645 assign(src_addr, get_gpr_dw0(r1));
15646 assign(src_len, get_gpr_dw0(r1+1));
15647 assign(tab_addr, get_gpr_dw0(r2));
15648 assign(test_byte, get_gpr_b7(0));
15650 IRTemp op = newTemp(Ity_I8);
15651 IRTemp op1 = newTemp(Ity_I8);
15652 IRTemp result = newTemp(Ity_I64);
15654 /* End of source string? We're done; proceed to next insn */
15655 s390_cc_set_val(0);
15656 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
15658 /* Load character from source string and compare with test byte */
15659 assign(op, load(Ity_I8, mkexpr(src_addr)));
15661 s390_cc_set_val(1);
15662 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
15664 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
15665 mkexpr(tab_addr)));
15667 assign(op1, load(Ity_I8, mkexpr(result)));
15669 store(get_gpr_dw0(r1), mkexpr(op1));
15670 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
15671 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
15673 iterate();
15675 return "tre";
15678 static IRExpr *
15679 s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
15681 IRExpr **args, *call;
15682 args = mkIRExprVec_2(srcval, low_surrogate);
15683 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15684 "s390_do_cu21", &s390_do_cu21, args);
15686 /* Nothing is excluded from definedness checking. */
15687 call->Iex.CCall.cee->mcx_mask = 0;
15689 return call;
15692 static const HChar *
15693 s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
15695 IRTemp addr1 = newTemp(Ity_I64);
15696 IRTemp addr2 = newTemp(Ity_I64);
15697 IRTemp len1 = newTemp(Ity_I64);
15698 IRTemp len2 = newTemp(Ity_I64);
15700 assign(addr1, get_gpr_dw0(r1));
15701 assign(addr2, get_gpr_dw0(r2));
15702 assign(len1, get_gpr_dw0(r1 + 1));
15703 assign(len2, get_gpr_dw0(r2 + 1));
15705 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
15706 there are less than 2 bytes left, then the 2nd operand is exhausted
15707 and we're done here. cc = 0 */
15708 s390_cc_set_val(0);
15709 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
15711 /* There are at least two bytes there. Read them. */
15712 IRTemp srcval = newTemp(Ity_I32);
15713 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
15715 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
15716 inside the interval [0xd800 - 0xdbff] */
15717 IRTemp is_high_surrogate = newTemp(Ity_I32);
15718 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
15719 mkU32(1), mkU32(0));
15720 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
15721 mkU32(1), mkU32(0));
15722 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
15724 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
15725 then the 2nd operand is exhausted and we're done here. cc = 0 */
15726 IRExpr *not_enough_bytes =
15727 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
15729 next_insn_if(binop(Iop_CmpEQ32,
15730 binop(Iop_And32, mkexpr(is_high_surrogate),
15731 not_enough_bytes), mkU32(1)));
15733 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
15734 surrogate, read the next two bytes (low surrogate). */
15735 IRTemp low_surrogate = newTemp(Ity_I32);
15736 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
15738 assign(low_surrogate,
15739 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
15740 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
15741 mkU32(0))); // any value is fine; it will not be used
15743 /* Call the helper */
15744 IRTemp retval = newTemp(Ity_I64);
15745 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
15746 unop(Iop_32Uto64, mkexpr(low_surrogate))));
15748 /* Before we can test whether the 1st operand is exhausted we need to
15749 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
15750 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
15751 IRExpr *invalid_low_surrogate =
15752 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
15754 s390_cc_set_val(2);
15755 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
15758 /* Now test whether the 1st operand is exhausted */
15759 IRTemp num_bytes = newTemp(Ity_I64);
15760 assign(num_bytes, binop(Iop_And64,
15761 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
15762 mkU64(0xff)));
15763 s390_cc_set_val(1);
15764 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
15766 /* Extract the bytes to be stored at addr1 */
15767 IRTemp data = newTemp(Ity_I64);
15768 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
15770 /* To store the bytes construct 4 dirty helper calls. The helper calls
15771 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
15772 one of them will be called at runtime. */
15773 UInt i;
15774 for (i = 1; i <= 4; ++i) {
15775 IRDirty *d;
15777 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
15778 &s390x_dirtyhelper_CUxy,
15779 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
15780 mkexpr(num_bytes)));
15781 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
15782 d->mFx = Ifx_Write;
15783 d->mAddr = mkexpr(addr1);
15784 d->mSize = i;
15785 stmt(IRStmt_Dirty(d));
15788 /* Update source address and length */
15789 IRTemp num_src_bytes = newTemp(Ity_I64);
15790 assign(num_src_bytes,
15791 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
15792 mkU64(4), mkU64(2)));
15793 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
15794 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
15796 /* Update destination address and length */
15797 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
15798 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
15800 iterate();
15802 return "cu21";
15805 static IRExpr *
15806 s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
15808 IRExpr **args, *call;
15809 args = mkIRExprVec_2(srcval, low_surrogate);
15810 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15811 "s390_do_cu24", &s390_do_cu24, args);
15813 /* Nothing is excluded from definedness checking. */
15814 call->Iex.CCall.cee->mcx_mask = 0;
15816 return call;
15819 static const HChar *
15820 s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
15822 IRTemp addr1 = newTemp(Ity_I64);
15823 IRTemp addr2 = newTemp(Ity_I64);
15824 IRTemp len1 = newTemp(Ity_I64);
15825 IRTemp len2 = newTemp(Ity_I64);
15827 assign(addr1, get_gpr_dw0(r1));
15828 assign(addr2, get_gpr_dw0(r2));
15829 assign(len1, get_gpr_dw0(r1 + 1));
15830 assign(len2, get_gpr_dw0(r2 + 1));
15832 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
15833 there are less than 2 bytes left, then the 2nd operand is exhausted
15834 and we're done here. cc = 0 */
15835 s390_cc_set_val(0);
15836 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
15838 /* There are at least two bytes there. Read them. */
15839 IRTemp srcval = newTemp(Ity_I32);
15840 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
15842 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
15843 inside the interval [0xd800 - 0xdbff] */
15844 IRTemp is_high_surrogate = newTemp(Ity_I32);
15845 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
15846 mkU32(1), mkU32(0));
15847 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
15848 mkU32(1), mkU32(0));
15849 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
15851 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
15852 then the 2nd operand is exhausted and we're done here. cc = 0 */
15853 IRExpr *not_enough_bytes =
15854 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
15856 next_insn_if(binop(Iop_CmpEQ32,
15857 binop(Iop_And32, mkexpr(is_high_surrogate),
15858 not_enough_bytes),
15859 mkU32(1)));
15861 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
15862 surrogate, read the next two bytes (low surrogate). */
15863 IRTemp low_surrogate = newTemp(Ity_I32);
15864 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
15866 assign(low_surrogate,
15867 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
15868 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
15869 mkU32(0))); // any value is fine; it will not be used
15871 /* Call the helper */
15872 IRTemp retval = newTemp(Ity_I64);
15873 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
15874 unop(Iop_32Uto64, mkexpr(low_surrogate))));
15876 /* Before we can test whether the 1st operand is exhausted we need to
15877 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
15878 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
15879 IRExpr *invalid_low_surrogate =
15880 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
15882 s390_cc_set_val(2);
15883 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
15886 /* Now test whether the 1st operand is exhausted */
15887 s390_cc_set_val(1);
15888 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
15890 /* Extract the bytes to be stored at addr1 */
15891 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
15893 store(mkexpr(addr1), data);
15895 /* Update source address and length */
15896 IRTemp num_src_bytes = newTemp(Ity_I64);
15897 assign(num_src_bytes,
15898 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
15899 mkU64(4), mkU64(2)));
15900 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
15901 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
15903 /* Update destination address and length */
15904 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
15905 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
15907 iterate();
15909 return "cu24";
15912 static IRExpr *
15913 s390_call_cu42(IRExpr *srcval)
15915 IRExpr **args, *call;
15916 args = mkIRExprVec_1(srcval);
15917 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
15918 "s390_do_cu42", &s390_do_cu42, args);
15920 /* Nothing is excluded from definedness checking. */
15921 call->Iex.CCall.cee->mcx_mask = 0;
15923 return call;
15926 static const HChar *
15927 s390_irgen_CU42(UChar r1, UChar r2)
15929 IRTemp addr1 = newTemp(Ity_I64);
15930 IRTemp addr2 = newTemp(Ity_I64);
15931 IRTemp len1 = newTemp(Ity_I64);
15932 IRTemp len2 = newTemp(Ity_I64);
15934 assign(addr1, get_gpr_dw0(r1));
15935 assign(addr2, get_gpr_dw0(r2));
15936 assign(len1, get_gpr_dw0(r1 + 1));
15937 assign(len2, get_gpr_dw0(r2 + 1));
15939 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
15940 there are less than 4 bytes left, then the 2nd operand is exhausted
15941 and we're done here. cc = 0 */
15942 s390_cc_set_val(0);
15943 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
15945 /* Read the 2nd operand. */
15946 IRTemp srcval = newTemp(Ity_I32);
15947 assign(srcval, load(Ity_I32, mkexpr(addr2)));
15949 /* Call the helper */
15950 IRTemp retval = newTemp(Ity_I64);
15951 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
15953 /* If the UTF-32 character was invalid, set cc=2 and we're done.
15954 cc=2 outranks cc=1 (1st operand exhausted) */
15955 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
15957 s390_cc_set_val(2);
15958 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
15960 /* Now test whether the 1st operand is exhausted */
15961 IRTemp num_bytes = newTemp(Ity_I64);
15962 assign(num_bytes, binop(Iop_And64,
15963 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
15964 mkU64(0xff)));
15965 s390_cc_set_val(1);
15966 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
15968 /* Extract the bytes to be stored at addr1 */
15969 IRTemp data = newTemp(Ity_I64);
15970 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
15972 /* To store the bytes construct 2 dirty helper calls. The helper calls
15973 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
15974 that only one of them will be called at runtime. */
15976 Int i;
15977 for (i = 2; i <= 4; ++i) {
15978 IRDirty *d;
15980 if (i == 3) continue; // skip this one
15982 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
15983 &s390x_dirtyhelper_CUxy,
15984 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
15985 mkexpr(num_bytes)));
15986 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
15987 d->mFx = Ifx_Write;
15988 d->mAddr = mkexpr(addr1);
15989 d->mSize = i;
15990 stmt(IRStmt_Dirty(d));
15993 /* Update source address and length */
15994 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
15995 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
15997 /* Update destination address and length */
15998 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
15999 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
16001 iterate();
16003 return "cu42";
16006 static IRExpr *
16007 s390_call_cu41(IRExpr *srcval)
16009 IRExpr **args, *call;
16010 args = mkIRExprVec_1(srcval);
16011 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
16012 "s390_do_cu41", &s390_do_cu41, args);
16014 /* Nothing is excluded from definedness checking. */
16015 call->Iex.CCall.cee->mcx_mask = 0;
16017 return call;
16020 static const HChar *
16021 s390_irgen_CU41(UChar r1, UChar r2)
16023 IRTemp addr1 = newTemp(Ity_I64);
16024 IRTemp addr2 = newTemp(Ity_I64);
16025 IRTemp len1 = newTemp(Ity_I64);
16026 IRTemp len2 = newTemp(Ity_I64);
16028 assign(addr1, get_gpr_dw0(r1));
16029 assign(addr2, get_gpr_dw0(r2));
16030 assign(len1, get_gpr_dw0(r1 + 1));
16031 assign(len2, get_gpr_dw0(r2 + 1));
16033 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
16034 there are less than 4 bytes left, then the 2nd operand is exhausted
16035 and we're done here. cc = 0 */
16036 s390_cc_set_val(0);
16037 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
16039 /* Read the 2nd operand. */
16040 IRTemp srcval = newTemp(Ity_I32);
16041 assign(srcval, load(Ity_I32, mkexpr(addr2)));
16043 /* Call the helper */
16044 IRTemp retval = newTemp(Ity_I64);
16045 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
16047 /* If the UTF-32 character was invalid, set cc=2 and we're done.
16048 cc=2 outranks cc=1 (1st operand exhausted) */
16049 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
16051 s390_cc_set_val(2);
16052 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
16054 /* Now test whether the 1st operand is exhausted */
16055 IRTemp num_bytes = newTemp(Ity_I64);
16056 assign(num_bytes, binop(Iop_And64,
16057 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
16058 mkU64(0xff)));
16059 s390_cc_set_val(1);
16060 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
16062 /* Extract the bytes to be stored at addr1 */
16063 IRTemp data = newTemp(Ity_I64);
16064 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
16066 /* To store the bytes construct 4 dirty helper calls. The helper calls
16067 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
16068 one of them will be called at runtime. */
16069 UInt i;
16070 for (i = 1; i <= 4; ++i) {
16071 IRDirty *d;
16073 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
16074 &s390x_dirtyhelper_CUxy,
16075 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
16076 mkexpr(num_bytes)));
16077 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
16078 d->mFx = Ifx_Write;
16079 d->mAddr = mkexpr(addr1);
16080 d->mSize = i;
16081 stmt(IRStmt_Dirty(d));
16084 /* Update source address and length */
16085 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
16086 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
16088 /* Update destination address and length */
16089 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
16090 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
16092 iterate();
16094 return "cu41";
16097 static IRExpr *
16098 s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
16100 IRExpr **args, *call;
16101 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
16102 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
16103 &s390_do_cu12_cu14_helper1, args);
16105 /* Nothing is excluded from definedness checking. */
16106 call->Iex.CCall.cee->mcx_mask = 0;
16108 return call;
16111 static IRExpr *
16112 s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
16113 IRExpr *byte4, IRExpr *stuff)
16115 IRExpr **args, *call;
16116 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
16117 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
16118 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
16120 /* Nothing is excluded from definedness checking. */
16121 call->Iex.CCall.cee->mcx_mask = 0;
16123 return call;
16126 static IRExpr *
16127 s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
16128 IRExpr *byte4, IRExpr *stuff)
16130 IRExpr **args, *call;
16131 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
16132 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
16133 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
16135 /* Nothing is excluded from definedness checking. */
16136 call->Iex.CCall.cee->mcx_mask = 0;
16138 return call;
16141 static void
16142 s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
16144 IRTemp addr1 = newTemp(Ity_I64);
16145 IRTemp addr2 = newTemp(Ity_I64);
16146 IRTemp len1 = newTemp(Ity_I64);
16147 IRTemp len2 = newTemp(Ity_I64);
16149 assign(addr1, get_gpr_dw0(r1));
16150 assign(addr2, get_gpr_dw0(r2));
16151 assign(len1, get_gpr_dw0(r1 + 1));
16152 assign(len2, get_gpr_dw0(r2 + 1));
16154 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
16156 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
16157 there is less than 1 byte left, then the 2nd operand is exhausted
16158 and we're done here. cc = 0 */
16159 s390_cc_set_val(0);
16160 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
16162 /* There is at least one byte there. Read it. */
16163 IRTemp byte1 = newTemp(Ity_I64);
16164 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
16166 /* Call the helper to get number of bytes and invalid byte indicator */
16167 IRTemp retval1 = newTemp(Ity_I64);
16168 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
16169 mkU64(extended_checking)));
16171 /* Check for invalid 1st byte */
16172 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
16173 s390_cc_set_val(2);
16174 next_insn_if(is_invalid);
16176 /* How many bytes do we have to read? */
16177 IRTemp num_src_bytes = newTemp(Ity_I64);
16178 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
16180 /* Now test whether the 2nd operand is exhausted */
16181 s390_cc_set_val(0);
16182 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
16184 /* Read the remaining bytes */
16185 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
16187 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
16188 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
16189 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
16190 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
16191 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
16192 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
16193 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
16194 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
16195 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
16197 /* Call the helper to get the converted value and invalid byte indicator.
16198 We can pass at most 5 arguments; therefore some encoding is needed
16199 here */
16200 IRExpr *stuff = binop(Iop_Or64,
16201 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
16202 mkU64(extended_checking));
16203 IRTemp retval2 = newTemp(Ity_I64);
16205 if (is_cu12) {
16206 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
16207 byte4, stuff));
16208 } else {
16209 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
16210 byte4, stuff));
16213 /* Check for invalid character */
16214 s390_cc_set_val(2);
16215 is_invalid = unop(Iop_64to1, mkexpr(retval2));
16216 next_insn_if(is_invalid);
16218 /* Now test whether the 1st operand is exhausted */
16219 IRTemp num_bytes = newTemp(Ity_I64);
16220 assign(num_bytes, binop(Iop_And64,
16221 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
16222 mkU64(0xff)));
16223 s390_cc_set_val(1);
16224 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
16226 /* Extract the bytes to be stored at addr1 */
16227 IRTemp data = newTemp(Ity_I64);
16228 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
16230 if (is_cu12) {
16231 /* To store the bytes construct 2 dirty helper calls. The helper calls
16232 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
16233 that only one of them will be called at runtime. */
16235 Int i;
16236 for (i = 2; i <= 4; ++i) {
16237 IRDirty *d;
16239 if (i == 3) continue; // skip this one
16241 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
16242 &s390x_dirtyhelper_CUxy,
16243 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
16244 mkexpr(num_bytes)));
16245 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
16246 d->mFx = Ifx_Write;
16247 d->mAddr = mkexpr(addr1);
16248 d->mSize = i;
16249 stmt(IRStmt_Dirty(d));
16251 } else {
16252 // cu14
16253 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
16256 /* Update source address and length */
16257 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
16258 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
16260 /* Update destination address and length */
16261 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
16262 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
16264 iterate();
16267 static const HChar *
16268 s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
16270 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
16272 return "cu12";
16275 static const HChar *
16276 s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
16278 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
16280 return "cu14";
16283 static IRExpr *
16284 s390_call_ecag(IRExpr *op2addr)
16286 IRExpr **args, *call;
16288 args = mkIRExprVec_1(op2addr);
16289 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
16290 "s390_do_ecag", &s390_do_ecag, args);
16292 /* Nothing is excluded from definedness checking. */
16293 call->Iex.CCall.cee->mcx_mask = 0;
16295 return call;
16298 static const HChar *
16299 s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
16301 if (! s390_host_has_gie) {
16302 emulation_failure(EmFail_S390X_ecag);
16303 } else {
16304 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
16307 return "ecag";
16310 static const HChar *
16311 s390_irgen_VL(UChar v1, IRTemp op2addr)
16313 put_vr_qw(v1, load(Ity_V128, mkexpr(op2addr)));
16315 return "vl";
16318 static const HChar *
16319 s390_irgen_VLR(UChar v1, UChar v2)
16321 put_vr_qw(v1, get_vr_qw(v2));
16323 return "vlr";
16326 static const HChar *
16327 s390_irgen_VST(UChar v1, IRTemp op2addr)
16329 store(mkexpr(op2addr), get_vr_qw(v1));
16331 return "vst";
16334 static const HChar *
16335 s390_irgen_VLREP(UChar v1, IRTemp op2addr, UChar m3)
16337 IRType o2type = s390_vr_get_type(m3);
16338 IRExpr* o2 = load(o2type, mkexpr(op2addr));
16339 s390_vr_fill(v1, o2);
16340 return "vlrep";
16343 static const HChar *
16344 s390_irgen_VLEB(UChar v1, IRTemp op2addr, UChar m3)
16346 IRExpr* o2 = load(Ity_I8, mkexpr(op2addr));
16347 put_vr(v1, Ity_I8, m3, o2);
16349 return "vleb";
16352 static const HChar *
16353 s390_irgen_VLEH(UChar v1, IRTemp op2addr, UChar m3)
16355 IRExpr* o2 = load(Ity_I16, mkexpr(op2addr));
16356 put_vr(v1, Ity_I16, m3, o2);
16358 return "vleh";
16361 static const HChar *
16362 s390_irgen_VLEF(UChar v1, IRTemp op2addr, UChar m3)
16364 IRExpr* o2 = load(Ity_I32, mkexpr(op2addr));
16365 put_vr(v1, Ity_I32, m3, o2);
16367 return "vlef";
16370 static const HChar *
16371 s390_irgen_VLEG(UChar v1, IRTemp op2addr, UChar m3)
16373 IRExpr* o2 = load(Ity_I64, mkexpr(op2addr));
16374 put_vr(v1, Ity_I64, m3, o2);
16376 return "vleg";
16379 static const HChar *
16380 s390_irgen_VLEIB(UChar v1, UShort i2, UChar m3)
16382 IRExpr* o2 = unop(Iop_16to8, mkU16(i2));
16383 put_vr(v1, Ity_I8, m3, o2);
16385 return "vleib";
16388 static const HChar *
16389 s390_irgen_VLEIH(UChar v1, UShort i2, UChar m3)
16391 IRExpr* o2 = mkU16(i2);
16392 put_vr(v1, Ity_I16, m3, o2);
16394 return "vleih";
16397 static const HChar *
16398 s390_irgen_VLEIF(UChar v1, UShort i2, UChar m3)
16400 IRExpr* o2 = unop(Iop_16Sto32, mkU16(i2));
16401 put_vr(v1, Ity_I32, m3, o2);
16403 return "vleif";
16406 static const HChar *
16407 s390_irgen_VLEIG(UChar v1, UShort i2, UChar m3)
16409 IRExpr* o2 = unop(Iop_16Sto64, mkU16(i2));
16410 put_vr(v1, Ity_I64, m3, o2);
16412 return "vleig";
16415 static const HChar *
16416 s390_irgen_VLGV(UChar r1, IRTemp op2addr, UChar v3, UChar m4)
16418 IRType o2type = s390_vr_get_type(m4);
16419 IRExpr* index = unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr), mkU64(0xf)));
16420 IRExpr* o2;
16421 IRExpr* result;
16422 switch (o2type) {
16423 case Ity_I8:
16424 o2 = binop(Iop_GetElem8x16, get_vr_qw(v3), index);
16425 result = unop(Iop_8Uto64, o2);
16426 break;
16427 case Ity_I16:
16428 o2 = binop(Iop_GetElem16x8, get_vr_qw(v3), index);
16429 result = unop(Iop_16Uto64, o2);
16430 break;
16431 case Ity_I32:
16432 o2 = binop(Iop_GetElem32x4, get_vr_qw(v3), index);
16433 result = unop(Iop_32Uto64, o2);
16434 break;
16435 case Ity_I64:
16436 result = binop(Iop_GetElem64x2, get_vr_qw(v3), index);
16437 break;
16438 default:
16439 ppIRType(o2type);
16440 vpanic("s390_irgen_VLGV: unknown o2type");
16443 put_gpr_dw0(r1, result);
16444 return "vlgv";
16447 static const HChar *
16448 s390_irgen_VGBM(UChar v1, UShort i2, UChar m3 __attribute__((unused)))
16450 put_vr_qw(v1, mkV128(i2));
16452 return "vgbm";
16455 static const HChar *
16456 s390_irgen_VGM(UChar v1, UShort i2, UChar m3)
16458 s390_insn_assert("vgm", m3 <= 3);
16460 UChar max_idx = (8 << m3) - 1;
16461 UChar from = max_idx & (i2 >> 8);
16462 UChar to = max_idx & i2;
16463 ULong all_one = (1ULL << max_idx << 1) - 1;
16464 ULong value = (all_one >> from) ^ (all_one >> to >> 1);
16466 /* In case of wrap-around we now have a value that needs inverting:
16467 to from
16469 00000111111111110000000000000000 */
16470 if (to < from)
16471 value ^= all_one;
16473 IRExpr* fillValue;
16474 switch (m3) {
16475 case 0:
16476 fillValue = mkU8(value);
16477 break;
16478 case 1:
16479 fillValue = mkU16(value);
16480 break;
16481 case 2:
16482 fillValue = mkU32(value);
16483 break;
16484 case 3:
16485 fillValue = mkU64(value);
16486 break;
16487 default:
16488 vpanic("s390_irgen_VGM: unknown element size");
16491 s390_vr_fill(v1, fillValue);
16492 return "vgm";
16495 static const HChar *
16496 s390_irgen_VLLEZ(UChar v1, IRTemp op2addr, UChar m3)
16498 s390_insn_assert("vllez", m3 <= 3 || m3 == 6);
16500 IRType type = s390_vr_get_type(m3 & 3);
16501 IRExpr* op2 = load(type, mkexpr(op2addr));
16502 IRExpr* op2as64bit;
16503 switch (type) {
16504 case Ity_I8:
16505 op2as64bit = unop(Iop_8Uto64, op2);
16506 break;
16507 case Ity_I16:
16508 op2as64bit = unop(Iop_16Uto64, op2);
16509 break;
16510 case Ity_I32:
16511 op2as64bit = unop(Iop_32Uto64, op2);
16512 break;
16513 case Ity_I64:
16514 op2as64bit = op2;
16515 break;
16516 default:
16517 vpanic("s390_irgen_VLLEZ: unknown type");
16520 if (m3 == 6) {
16521 /* left-aligned */
16522 put_vr_dw0(v1, binop(Iop_Shl64, op2as64bit, mkU8(32)));
16523 } else {
16524 /* right-aligned */
16525 put_vr_dw0(v1, op2as64bit);
16527 put_vr_dw1(v1, mkU64(0));
16528 return "vllez";
16531 static const HChar *
16532 s390_irgen_VGEF(UChar v1, IRTemp op2addr, UChar m3)
16534 put_vr(v1, Ity_I32, m3, load(Ity_I32, mkexpr(op2addr)));
16535 return "vgef";
16538 static const HChar *
16539 s390_irgen_VGEG(UChar v1, IRTemp op2addr, UChar m3)
16541 put_vr(v1, Ity_I64, m3, load(Ity_I64, mkexpr(op2addr)));
16542 return "vgeg";
16545 static const HChar *
16546 s390_irgen_VLM(UChar v1, IRTemp op2addr, UChar v3)
16548 IRExpr* current = mkexpr(op2addr);
16549 vassert(v3 >= v1);
16550 vassert(v3 - v1 <= 16);
16552 for(UChar vr = v1; vr <= v3; vr++) {
16553 IRExpr* next = binop(Iop_Add64, current, mkU64(16));
16554 put_vr_qw(vr, load(Ity_V128, current));
16555 current = next;
16558 return "vlm";
16561 static const HChar *
16562 s390_irgen_VLVGP(UChar v1, UChar r2, UChar r3)
16564 put_vr_qw(v1, binop(Iop_64HLtoV128, get_gpr_dw0(r2), get_gpr_dw0(r3)));
16566 return "vlvgp";
16569 static const HChar *
16570 s390_irgen_VLVG(UChar v1, IRTemp op2addr, UChar r3, UChar m4)
16572 IRType type = s390_vr_get_type(m4);
16573 IRExpr* index = unop(Iop_64to8, mkexpr(op2addr));
16574 IRExpr* vr = get_vr_qw(v1);
16575 IRExpr* operand;
16576 switch (type) {
16577 case Ity_I8:
16578 operand = unop(Iop_64to8, get_gpr_dw0(r3));
16579 put_vr_qw(v1, triop(Iop_SetElem8x16, vr, index, operand));
16580 break;
16581 case Ity_I16:
16582 operand = unop(Iop_64to16, get_gpr_dw0(r3));
16583 put_vr_qw(v1, triop(Iop_SetElem16x8, vr, index, operand));
16584 break;
16585 case Ity_I32:
16586 operand = unop(Iop_64to32, get_gpr_dw0(r3));
16587 put_vr_qw(v1, triop(Iop_SetElem32x4, vr, index, operand));
16588 break;
16589 case Ity_I64:
16590 operand = get_gpr_dw0(r3);
16591 put_vr_qw(v1, triop(Iop_SetElem64x2, vr, index, operand));
16592 break;
16593 default:
16594 vpanic("s390_irgen_VLVG: unknown type");
16597 return "vlvg";
16600 static const HChar *
16601 s390_irgen_VMRH(UChar v1, UChar v2, UChar v3, UChar m4)
16603 const IROp ops[] = { Iop_InterleaveHI8x16, Iop_InterleaveHI16x8,
16604 Iop_InterleaveHI32x4, Iop_InterleaveHI64x2 };
16605 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
16606 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
16608 return "vmrh";
16611 static const HChar *
16612 s390_irgen_VMRL(UChar v1, UChar v2, UChar v3, UChar m4)
16614 const IROp ops[] = { Iop_InterleaveLO8x16, Iop_InterleaveLO16x8,
16615 Iop_InterleaveLO32x4, Iop_InterleaveLO64x2 };
16616 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
16617 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
16619 return "vmrl";
16622 static const HChar *
16623 s390_irgen_VPK(UChar v1, UChar v2, UChar v3, UChar m4)
16625 const IROp ops[] = { Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8,
16626 Iop_NarrowBin64to32x4 };
16627 Char index = m4 - 1;
16628 vassert((index >= 0) && (index < sizeof(ops) / sizeof(ops[0])));
16629 put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3)));
16630 return "vpk";
16633 static const HChar *
16634 s390_irgen_VPERM(UChar v1, UChar v2, UChar v3, UChar v4)
16636 put_vr_qw(v1, triop(Iop_Perm8x16x2,
16637 get_vr_qw(v2), get_vr_qw(v3), get_vr_qw(v4)));
16639 return "vperm";
16642 static const HChar *
16643 s390_irgen_VSCEF(UChar v1, IRTemp op2addr, UChar m3)
16645 store(mkexpr(op2addr), get_vr(v1, Ity_I32, m3));
16646 return "vscef";
16649 static const HChar *
16650 s390_irgen_VSCEG(UChar v1, IRTemp op2addr, UChar m3)
16652 store(mkexpr(op2addr), get_vr(v1, Ity_I64, m3));
16653 return "vsceg";
16656 static const HChar *
16657 s390_irgen_VPDI(UChar v1, UChar v2, UChar v3, UChar m4)
16659 /* These bits are reserved by specification */
16660 s390_insn_assert("vpdi", (m4 & 2) == 0 && (m4 & 8) == 0);
16662 put_vr_qw(v1, binop(Iop_64HLtoV128, m4 & 4 ? get_vr_dw1(v2) : get_vr_dw0(v2),
16663 m4 & 1 ? get_vr_dw1(v3) : get_vr_dw0(v3)));
16664 return "vpdi";
16667 static const HChar *
16668 s390_irgen_VSEG(UChar v1, UChar v2, UChar m3)
16670 IRType type = s390_vr_get_type(m3);
16671 switch(type) {
16672 case Ity_I8:
16673 put_vr_dw0(v1, unop(Iop_8Sto64, get_vr_b7(v2)));
16674 put_vr_dw1(v1, unop(Iop_8Sto64, get_vr_b15(v2)));
16675 break;
16676 case Ity_I16:
16677 put_vr_dw0(v1, unop(Iop_16Sto64, get_vr_hw3(v2)));
16678 put_vr_dw1(v1, unop(Iop_16Sto64, get_vr_hw7(v2)));
16679 break;
16680 case Ity_I32:
16681 put_vr_dw0(v1, unop(Iop_32Sto64, get_vr_w1(v2)));
16682 put_vr_dw1(v1, unop(Iop_32Sto64, get_vr_w3(v2)));
16683 break;
16684 default:
16685 ppIRType(type);
16686 vpanic("s390_irgen_VSEG: unknown type");
16689 return "vseg";
16692 static const HChar *
16693 s390_irgen_VSTEB(UChar v1, IRTemp op2addr, UChar m3)
16695 store(mkexpr(op2addr), get_vr(v1, Ity_I8, m3));
16697 return "vsteb";
16700 static const HChar *
16701 s390_irgen_VSTEH(UChar v1, IRTemp op2addr, UChar m3)
16703 store(mkexpr(op2addr), get_vr(v1, Ity_I16, m3));
16705 return "vsteh";
16708 static const HChar *
16709 s390_irgen_VSTEF(UChar v1, IRTemp op2addr, UChar m3)
16711 store(mkexpr(op2addr), get_vr(v1, Ity_I32, m3));
16713 return "vstef";
16716 static const HChar *
16717 s390_irgen_VSTEG(UChar v1, IRTemp op2addr, UChar m3)
16719 store(mkexpr(op2addr), get_vr(v1, Ity_I64, m3));
16721 return "vsteg";
16724 static const HChar *
16725 s390_irgen_VSTM(UChar v1, IRTemp op2addr, UChar v3)
16727 IRExpr* current = mkexpr(op2addr);
16728 vassert(v3 >= v1);
16729 vassert(v3 - v1 <= 16);
16731 for(UChar vr = v1; vr <= v3; vr++) {
16732 IRExpr* next = binop(Iop_Add64, current, mkU64(16));
16733 store(current, get_vr_qw(vr));
16734 current = next;
16737 return "vstm";
16740 static const HChar *
16741 s390_irgen_VUPH(UChar v1, UChar v2, UChar m3)
16743 const IROp ops[] = { Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2 };
16744 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
16745 put_vr_qw(v1, unop(ops[m3], get_vr_dw0(v2)));
16747 return "vuph";
16750 static const HChar *
16751 s390_irgen_VUPLH(UChar v1, UChar v2, UChar m3)
16753 const IROp ops[] = { Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2 };
16754 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
16755 put_vr_qw(v1, unop(ops[m3], get_vr_dw0(v2)));
16756 return "vuplh";
16759 static const HChar *
16760 s390_irgen_VUPL(UChar v1, UChar v2, UChar m3)
16762 const IROp ops[] = { Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2 };
16763 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
16764 put_vr_qw(v1, unop(ops[m3], get_vr_dw1(v2)));
16766 return "vupl";
16769 static const HChar *
16770 s390_irgen_VUPLL(UChar v1, UChar v2, UChar m3)
16772 const IROp ops[] = { Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2 };
16773 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
16774 put_vr_qw(v1, unop(ops[m3], get_vr_dw1(v2)));
16776 return "vupll";
16779 static const HChar *
16780 s390_irgen_VREP(UChar v1, UChar v3, UShort i2, UChar m4)
16782 IRType type = s390_vr_get_type(m4);
16783 IRExpr* arg = get_vr(v3, type, i2);
16784 s390_vr_fill(v1, arg);
16786 return "vrep";
16789 static const HChar *
16790 s390_irgen_VREPI(UChar v1, UShort i2, UChar m3)
16792 IRType type = s390_vr_get_type(m3);
16793 IRExpr *value;
16794 switch (type) {
16795 case Ity_I8:
16796 value = mkU8((UChar)i2);
16797 break;
16798 case Ity_I16:
16799 value = mkU16(i2);
16800 break;
16801 case Ity_I32:
16802 value = unop(Iop_16Sto32, mkU16(i2));
16803 break;
16804 case Ity_I64:
16805 value = unop(Iop_16Sto64, mkU16(i2));
16806 break;
16807 default:
16808 ppIRType(type);
16809 vpanic("s390_irgen_VREPI: unknown type");
16811 s390_vr_fill(v1, value);
16813 return "vrepi";
16816 static const HChar *
16817 s390_irgen_VPKS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
16819 if (!s390_vr_is_cs_set(m5)) {
16820 const IROp ops[] = { Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8,
16821 Iop_QNarrowBin64Sto32Sx4 };
16822 Char index = m4 - 1;
16823 vassert((index >= 0) && (index < sizeof(ops) / sizeof(ops[0])));
16824 put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3)));
16826 } else {
16827 IRDirty* d;
16828 IRTemp cc = newTemp(Ity_I64);
16830 s390x_vec_op_details_t details = { .serialized = 0ULL };
16831 details.op = S390_VEC_OP_VPKS;
16832 details.v1 = v1;
16833 details.v2 = v2;
16834 details.v3 = v3;
16835 details.m4 = m4;
16836 details.m5 = m5;
16838 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
16839 &s390x_dirtyhelper_vec_op,
16840 mkIRExprVec_2(IRExpr_GSPTR(),
16841 mkU64(details.serialized)));
16843 d->nFxState = 3;
16844 vex_bzero(&d->fxState, sizeof(d->fxState));
16845 d->fxState[0].fx = Ifx_Read;
16846 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
16847 d->fxState[0].size = sizeof(V128);
16848 d->fxState[1].fx = Ifx_Read;
16849 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
16850 d->fxState[1].size = sizeof(V128);
16851 d->fxState[2].fx = Ifx_Write;
16852 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
16853 d->fxState[2].size = sizeof(V128);
16855 stmt(IRStmt_Dirty(d));
16856 s390_cc_set(cc);
16859 return "vpks";
16862 static const HChar *
16863 s390_irgen_VPKLS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
16865 if (!s390_vr_is_cs_set(m5)) {
16866 const IROp ops[] = { Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8,
16867 Iop_QNarrowBin64Uto32Ux4 };
16868 Char index = m4 - 1;
16869 vassert((index >= 0) && (index < sizeof(ops) / sizeof(ops[0])));
16870 put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3)));
16872 } else {
16873 IRDirty* d;
16874 IRTemp cc = newTemp(Ity_I64);
16876 s390x_vec_op_details_t details = { .serialized = 0ULL };
16877 details.op = S390_VEC_OP_VPKLS;
16878 details.v1 = v1;
16879 details.v2 = v2;
16880 details.v3 = v3;
16881 details.m4 = m4;
16882 details.m5 = m5;
16884 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
16885 &s390x_dirtyhelper_vec_op,
16886 mkIRExprVec_2(IRExpr_GSPTR(),
16887 mkU64(details.serialized)));
16889 d->nFxState = 3;
16890 vex_bzero(&d->fxState, sizeof(d->fxState));
16891 d->fxState[0].fx = Ifx_Read;
16892 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
16893 d->fxState[0].size = sizeof(V128);
16894 d->fxState[1].fx = Ifx_Read;
16895 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
16896 d->fxState[1].size = sizeof(V128);
16897 d->fxState[2].fx = Ifx_Write;
16898 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
16899 d->fxState[2].size = sizeof(V128);
16901 stmt(IRStmt_Dirty(d));
16902 s390_cc_set(cc);
16905 return "vpkls";
16908 static const HChar *
16909 s390_irgen_VSEL(UChar v1, UChar v2, UChar v3, UChar v4)
16911 IRExpr* vIfTrue = get_vr_qw(v2);
16912 IRExpr* vIfFalse = get_vr_qw(v3);
16913 IRExpr* vCond = get_vr_qw(v4);
16915 put_vr_qw(v1, s390_V128_bitwiseITE(vCond, vIfTrue, vIfFalse));
16916 return "vsel";
16919 static const HChar *
16920 s390_irgen_VLBB(UChar v1, IRTemp addr, UChar m3)
16922 IRExpr* maxIndex = binop(Iop_Sub32,
16923 s390_getCountToBlockBoundary(addr, m3),
16924 mkU32(1));
16926 s390_vr_loadWithLength(v1, addr, maxIndex, False);
16928 return "vlbb";
16931 static const HChar *
16932 s390_irgen_VLL(UChar v1, IRTemp addr, UChar r3)
16934 s390_vr_loadWithLength(v1, addr, get_gpr_w1(r3), False);
16936 return "vll";
16939 static const HChar *
16940 s390_irgen_VLRL(UChar v1, IRTemp addr, UChar i3)
16942 s390_insn_assert("vlrl", (i3 & 0xf0) == 0);
16943 s390_vr_loadWithLength(v1, addr, mkU32((UInt) i3), True);
16945 return "vlrl";
16948 static const HChar *
16949 s390_irgen_VLRLR(UChar v1, UChar r3, IRTemp addr)
16951 s390_vr_loadWithLength(v1, addr, get_gpr_w1(r3), True);
16953 return "vlrlr";
16956 static const HChar *
16957 s390_irgen_VSTL(UChar v1, IRTemp addr, UChar r3)
16959 s390_vr_storeWithLength(v1, addr, get_gpr_w1(r3), False);
16960 return "vstl";
16963 static const HChar *
16964 s390_irgen_VSTRL(UChar v1, IRTemp addr, UChar i3)
16966 s390_insn_assert("vstrl", (i3 & 0xf0) == 0);
16967 s390_vr_storeWithLength(v1, addr, mkU32((UInt) i3), True);
16968 return "vstrl";
16971 static const HChar *
16972 s390_irgen_VSTRLR(UChar v1, UChar r3, IRTemp addr)
16974 s390_vr_storeWithLength(v1, addr, get_gpr_w1(r3), True);
16975 return "vstrlr";
16978 static const HChar *
16979 s390_irgen_VX(UChar v1, UChar v2, UChar v3)
16981 put_vr_qw(v1, binop(Iop_XorV128, get_vr_qw(v2), get_vr_qw(v3)));
16983 return "vx";
16986 static const HChar *
16987 s390_irgen_VN(UChar v1, UChar v2, UChar v3)
16989 put_vr_qw(v1, binop(Iop_AndV128, get_vr_qw(v2), get_vr_qw(v3)));
16991 return "vn";
16994 static const HChar *
16995 s390_irgen_VO(UChar v1, UChar v2, UChar v3)
16997 put_vr_qw(v1, binop(Iop_OrV128, get_vr_qw(v2), get_vr_qw(v3)));
16999 return "vo";
17002 static const HChar *
17003 s390_irgen_VOC(UChar v1, UChar v2, UChar v3)
17005 put_vr_qw(v1, binop(Iop_OrV128, get_vr_qw(v2),
17006 unop(Iop_NotV128, get_vr_qw(v3))));
17008 return "voc";
17011 static const HChar *
17012 s390_irgen_VNN(UChar v1, UChar v2, UChar v3)
17014 put_vr_qw(v1, unop(Iop_NotV128,
17015 binop(Iop_AndV128, get_vr_qw(v2), get_vr_qw(v3))));
17017 return "vnn";
17020 static const HChar *
17021 s390_irgen_VNO(UChar v1, UChar v2, UChar v3)
17023 put_vr_qw(v1, unop(Iop_NotV128,
17024 binop(Iop_OrV128, get_vr_qw(v2), get_vr_qw(v3))));
17026 return "vno";
17029 static const HChar *
17030 s390_irgen_VNX(UChar v1, UChar v2, UChar v3)
17032 put_vr_qw(v1, unop(Iop_NotV128,
17033 binop(Iop_XorV128, get_vr_qw(v2), get_vr_qw(v3))));
17035 return "vnx";
17038 static const HChar *
17039 s390_irgen_LZRF(UChar r1, IRTemp op2addr)
17041 IRTemp op2 = newTemp(Ity_I32);
17043 assign(op2, binop(Iop_And32, load(Ity_I32, mkexpr(op2addr)), mkU32(0xffffff00)));
17044 put_gpr_w1(r1, mkexpr(op2));
17046 return "lzrf";
17049 static const HChar *
17050 s390_irgen_LZRG(UChar r1, IRTemp op2addr)
17052 IRTemp op2 = newTemp(Ity_I64);
17054 assign(op2, binop(Iop_And64, load(Ity_I64, mkexpr(op2addr)), mkU64(0xffffffffffffff00UL)));
17055 put_gpr_dw0(r1, mkexpr(op2));
17057 return "lzrg";
17060 static const HChar *
17061 s390_irgen_LLZRGF(UChar r1, IRTemp op2addr)
17063 IRTemp op2 = newTemp(Ity_I32);
17065 assign(op2, binop(Iop_And32, load(Ity_I32, mkexpr(op2addr)), mkU32(0xffffff00)));
17066 put_gpr_w1(r1, mkexpr(op2));
17067 put_gpr_w0(r1, mkU32(0));
17069 return "llzrgf";
17072 static const HChar *
17073 s390_irgen_LOCFH(UChar r1, IRTemp op2addr)
17075 /* condition is checked in format handler */
17076 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
17078 return "locfh";
17081 static const HChar *
17082 s390_irgen_LOCFHR(UChar m3, UChar r1, UChar r2)
17084 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
17085 put_gpr_w0(r1, get_gpr_w0(r2));
17087 return "locfhr";
17090 static const HChar *
17091 s390_irgen_LOCHHI(UChar r1, UChar m3, UShort i2)
17093 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
17094 put_gpr_w0(r1, mkU32((UInt)(Int)(Short)i2));
17096 return "lochhi";
17099 static const HChar *
17100 s390_irgen_LOCHI(UChar r1, UChar m3, UShort i2)
17102 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
17103 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
17105 return "lochi";
17108 static const HChar *
17109 s390_irgen_LOCGHI(UChar r1, UChar m3, UShort i2)
17111 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
17112 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
17114 return "locghi";
17117 static const HChar *
17118 s390_irgen_STOCFH(UChar r1, IRTemp op2addr)
17120 /* condition is checked in format handler */
17121 store(mkexpr(op2addr), get_gpr_w1(r1));
17123 return "stocfh";
17126 static const HChar *
17127 s390_irgen_LCBB(UChar r1, IRTemp op2addr, UChar m3)
17129 IRTemp op2 = newTemp(Ity_I32);
17130 assign(op2, s390_getCountToBlockBoundary(op2addr, m3));
17131 put_gpr_w1(r1, mkexpr(op2));
17133 IRExpr* cc = mkite(binop(Iop_CmpEQ32, mkexpr(op2), mkU32(16)), mkU64(0), mkU64(3));
17134 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), cc, mkU64(0), mkU64(0));
17136 return "lcbb";
17139 /* Also known as "PRNO" */
17140 static const HChar *
17141 s390_irgen_PPNO(UChar r1, UChar r2)
17143 if (!s390_host_has_msa5) {
17144 emulation_failure(EmFail_S390X_ppno);
17145 return "ppno";
17148 /* Check for obvious specification exceptions */
17149 s390_insn_assert("ppno", r1 % 2 == 0 && r2 % 2 == 0 && r1 != 0 && r2 != 0);
17151 extension(S390_EXT_PRNO, r1 | (r2 << 4));
17152 return "ppno";
17155 static const HChar *
17156 s390_irgen_DFLTCC(UChar r3, UChar r1, UChar r2)
17158 s390_insn_assert("dfltcc", s390_host_has_dflt);
17160 /* Check for obvious specification exceptions */
17161 s390_insn_assert("dfltcc", r1 % 2 == 0 && r1 != 0 &&
17162 r2 % 2 == 0 && r2 != 0 && r3 >= 2);
17164 extension(S390_EXT_DFLT, r1 | (r2 << 4) | (r3 << 8));
17165 return "dfltcc";
17168 enum s390_VStrX {
17169 s390_VStrX_VSTRC,
17170 s390_VStrX_VFAE,
17171 s390_VStrX_VFEE
17174 #define S390_VEC_OP3(m, op0, op1, op2) \
17175 (m) == 0 ? op0 : (m) == 1 ? op1 : (m) == 2 ? op2 : Iop_INVALID;
17177 /* Helper function for transforming VSTRC, VFAE, or VFEE. These instructions
17178 share much of the same logic. */
17179 static void
17180 s390_irgen_VStrX(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5,
17181 UChar m6, enum s390_VStrX which_insn)
17183 IRTemp op2 = newTemp(Ity_V128);
17184 IRTemp op3 = newTemp(Ity_V128);
17185 IRExpr* tmp;
17186 IRExpr* match = NULL;
17187 UChar bitwidth = 8 << m5;
17188 UChar n_elem = 16 >> m5;
17189 IROp sub_op = S390_VEC_OP3(m5, Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4);
17190 IROp sar_op = S390_VEC_OP3(m5, Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4);
17191 IROp shl_op = S390_VEC_OP3(m5, Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4);
17192 IROp dup_op = S390_VEC_OP3(m5, Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4);
17193 IROp cmpeq_op = S390_VEC_OP3(m5, Iop_CmpEQ8x16,
17194 Iop_CmpEQ16x8, Iop_CmpEQ32x4);
17195 IROp cmpgt_op = S390_VEC_OP3(m5, Iop_CmpGT8Ux16,
17196 Iop_CmpGT16Ux8, Iop_CmpGT32Ux4);
17197 IROp getelem_op = S390_VEC_OP3(m5, Iop_GetElem8x16,
17198 Iop_GetElem16x8, Iop_GetElem32x4);
17200 assign(op2, get_vr_qw(v2));
17201 assign(op3, get_vr_qw(v3));
17203 switch (which_insn) {
17205 case s390_VStrX_VSTRC: {
17206 IRTemp op4 = newTemp(Ity_V128);
17207 assign(op4, get_vr_qw(v4));
17209 /* Mask off insignificant range boundaries from op3, i.e., all those for
17210 which the corresponding field in op4 has all or no bits set ("match
17211 always" / "match never"). */
17212 IRTemp bounds = newTemp(Ity_V128);
17213 tmp = unop(Iop_NotV128,
17214 binop(cmpeq_op, mkV128(0),
17215 binop(sar_op,
17216 binop(sub_op,
17217 binop(sar_op, mkexpr(op4),
17218 mkU8(bitwidth - 3)),
17219 mkV128(-1)),
17220 mkU8(1))));
17221 assign(bounds, binop(Iop_AndV128, mkexpr(op3), tmp));
17223 IRTemp flags_eq = newTemp(Ity_V128);
17224 IRTemp flags_lt = newTemp(Ity_V128);
17225 IRTemp flags_gt = newTemp(Ity_V128);
17226 assign(flags_eq, binop(sar_op, mkexpr(op4), mkU8(bitwidth - 1)));
17227 assign(flags_lt, binop(sar_op, binop(shl_op, mkexpr(op4), mkU8(1)),
17228 mkU8(bitwidth - 1)));
17229 assign(flags_gt, binop(sar_op, binop(shl_op, mkexpr(op4), mkU8(2)),
17230 mkU8(bitwidth - 1)));
17232 for (UChar idx = 0; idx < n_elem; idx += 2) {
17233 /* Match according to the even/odd pairs in op3 and op4 at idx */
17234 IRTemp part[2];
17236 for (UChar j = 0; j < 2; j++) {
17237 IRTemp a = newTemp(Ity_V128);
17238 assign(a, unop(dup_op,
17239 binop(getelem_op, mkexpr(bounds), mkU8(idx + j))));
17241 IRExpr* m[] = {
17242 binop(cmpeq_op, mkexpr(op2), mkexpr(a)),
17243 binop(cmpgt_op, mkexpr(a), mkexpr(op2)),
17244 binop(cmpgt_op, mkexpr(op2), mkexpr(a))
17246 IRExpr* f[] = {
17247 unop(dup_op, binop(getelem_op, mkexpr(flags_eq), mkU8(idx + j))),
17248 unop(dup_op, binop(getelem_op, mkexpr(flags_lt), mkU8(idx + j))),
17249 unop(dup_op, binop(getelem_op, mkexpr(flags_gt), mkU8(idx + j)))
17251 part[j] = newTemp(Ity_V128);
17252 assign(part[j], binop(Iop_OrV128,
17253 binop(Iop_OrV128,
17254 binop(Iop_AndV128, f[0], m[0]),
17255 binop(Iop_AndV128, f[1], m[1])),
17256 binop(Iop_AndV128, f[2], m[2])));
17258 tmp = binop(Iop_AndV128, mkexpr(part[0]), mkexpr(part[1]));
17259 match = idx == 0 ? tmp : binop(Iop_OrV128, match, tmp);
17261 break;
17264 case s390_VStrX_VFAE:
17265 for (UChar idx = 0; idx < n_elem; idx++) {
17266 IRTemp a = newTemp(Ity_V128);
17267 assign(a, binop(cmpeq_op, mkexpr(op2),
17268 unop(dup_op,
17269 binop(getelem_op, mkexpr(op3), mkU8(idx)))));
17270 match = idx == 0 ? mkexpr(a) : binop(Iop_OrV128, match, mkexpr(a));
17272 break;
17274 case s390_VStrX_VFEE:
17275 match = binop(cmpeq_op, mkexpr(op2), mkexpr(op3));
17276 break;
17278 default:
17279 vpanic("s390_irgen_VStrX: unknown insn");
17282 /* Invert first intermediate result if requested */
17283 if (m6 & 8)
17284 match = unop(Iop_NotV128, match);
17286 IRTemp inter1 = newTemp(Ity_V128);
17287 IRTemp inter2 = newTemp(Ity_V128);
17288 IRTemp accu = newTemp(Ity_V128);
17289 assign(inter1, match);
17291 /* Determine second intermediate and accumulated result */
17292 if (s390_vr_is_zs_set(m6)) {
17293 assign(inter2, binop(cmpeq_op, mkexpr(op2), mkV128(0)));
17294 assign(accu, binop(Iop_OrV128, mkexpr(inter1), mkexpr(inter2)));
17295 } else {
17296 assign(inter2, mkV128(0));
17297 assign(accu, mkexpr(inter1));
17300 IRTemp accu0 = newTemp(Ity_I64);
17301 IRTemp is_match0 = newTemp(Ity_I1);
17302 IRTemp mismatch_bits = newTemp(Ity_I64);
17304 assign(accu0, unop(Iop_V128HIto64, mkexpr(accu)));
17305 assign(is_match0, binop(Iop_ExpCmpNE64, mkexpr(accu0), mkU64(0)));
17306 assign(mismatch_bits, unop(Iop_ClzNat64,
17307 mkite(mkexpr(is_match0), mkexpr(accu0),
17308 unop(Iop_V128to64, mkexpr(accu)))));
17310 if (m6 & 4) {
17311 put_vr_qw(v1, mkexpr(inter1));
17312 } else {
17313 /* Determine byte position of first match */
17314 tmp = binop(Iop_Add64,
17315 binop(Iop_Shr64, mkexpr(mismatch_bits), mkU8(3)),
17316 mkite(mkexpr(is_match0), mkU64(0), mkU64(8)));
17317 put_vr_qw(v1, binop(Iop_64HLtoV128, tmp, mkU64(0)));
17320 if (s390_vr_is_cs_set(m6)) {
17321 /* Set condition code depending on...
17322 zero found
17324 +------
17325 match n | 3 0
17326 found y | 1 2 */
17328 IRTemp cc = newTemp(Ity_I64);
17330 tmp = binop(Iop_Shr64,
17331 mkite(mkexpr(is_match0),
17332 unop(Iop_V128HIto64, mkexpr(inter1)),
17333 unop(Iop_V128to64, mkexpr(inter1))),
17334 unop(Iop_64to8,
17335 binop(Iop_Sub64, mkU64(63), mkexpr(mismatch_bits))));
17336 tmp = binop(Iop_Shl64, tmp, mkU8(1));
17337 if (s390_vr_is_zs_set(m6)) {
17338 tmp = binop(Iop_Xor64, tmp,
17339 mkite(binop(Iop_ExpCmpNE64, mkU64(0),
17340 binop(Iop_Or64,
17341 unop(Iop_V128HIto64, mkexpr(inter2)),
17342 unop(Iop_V128to64, mkexpr(inter2)))),
17343 mkU64(0),
17344 mkU64(3)));
17345 } else {
17346 tmp = binop(Iop_Xor64, tmp, mkU64(3));
17348 assign(cc, tmp);
17349 s390_cc_set(cc);
17351 dis_res->hint = Dis_HintVerbose;
17354 static const HChar *
17355 s390_irgen_VFAE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17357 s390_insn_assert("vfae", m4 <= 2);
17358 s390_irgen_VStrX(v1, v2, v3, 255, m4, m5, s390_VStrX_VFAE);
17359 return "vfae";
17362 static const HChar *
17363 s390_irgen_VFEE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17365 s390_insn_assert("vfee", m4 < 3 && m5 == (m5 & 3));
17366 s390_irgen_VStrX(v1, v2, v3, 255, m4, m5, s390_VStrX_VFEE);
17367 return "vfee";
17370 static const HChar *
17371 s390_irgen_VFENE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17373 s390_insn_assert("vfene", m4 < 3 && m5 == (m5 & 3));
17375 static const IROp compare_op[3] = {
17376 Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4
17378 static const IROp abs_op[3] = {
17379 Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4
17381 IRTemp op2 = newTemp(Ity_V128);
17382 IRTemp op3 = newTemp(Ity_V128);
17383 IRTemp op2zero = newTemp(Ity_V128);
17384 IRTemp diff = newTemp(Ity_V128);
17385 IRTemp diff0 = newTemp(Ity_I64);
17386 IRTemp neq0 = newTemp(Ity_I1);
17387 IRTemp samebits = newTemp(Ity_I64);
17388 IRExpr* tmp;
17390 assign(op2, get_vr_qw(v2));
17391 assign(op3, get_vr_qw(v3));
17393 tmp = mkV128(0);
17394 if (s390_vr_is_zs_set(m5)) {
17395 tmp = binop(compare_op[m4], mkexpr(op2), tmp);
17396 if (s390_vr_is_cs_set(m5) && v3 != v2) {
17397 /* Count leading equal bits in the terminating element too */
17398 tmp = unop(abs_op[m4], tmp);
17400 assign(op2zero, tmp);
17401 tmp = mkexpr(op2zero);
17403 if (v3 != v2) {
17404 tmp = binop(Iop_XorV128, mkexpr(op2), mkexpr(op3));
17405 if (s390_vr_is_zs_set(m5))
17406 tmp = binop(Iop_OrV128, tmp, mkexpr(op2zero));
17409 assign(diff, tmp);
17410 assign(diff0, unop(Iop_V128HIto64, mkexpr(diff)));
17411 assign(neq0, binop(Iop_ExpCmpNE64, mkexpr(diff0), mkU64(0)));
17412 assign(samebits, unop(Iop_ClzNat64,
17413 mkite(mkexpr(neq0), mkexpr(diff0),
17414 unop(Iop_V128to64, mkexpr(diff)))));
17416 /* Determine the byte size of the initial equal-elements sequence */
17417 tmp = binop(Iop_Shr64, mkexpr(samebits), mkU8(m4 + 3));
17418 if (m4 != 0)
17419 tmp = binop(Iop_Shl64, tmp, mkU8(m4));
17420 tmp = binop(Iop_Add64, tmp, mkite(mkexpr(neq0), mkU64(0), mkU64(8)));
17421 put_vr_qw(v1, binop(Iop_64HLtoV128, tmp, mkU64(0)));
17423 if (s390_vr_is_cs_set(m5)) {
17424 /* Set condition code like follows --
17425 0: operands equal up to and including zero element
17426 1: op2 < op3 2: op2 > op3 3: op2 = op3 */
17427 IRTemp cc = newTemp(Ity_I64);
17428 if (v3 == v2) {
17429 tmp = mkU64(0);
17430 } else {
17431 IRTemp shift = newTemp(Ity_I8);
17432 IRExpr* op2half = mkite(mkexpr(neq0),
17433 unop(Iop_V128HIto64, mkexpr(op2)),
17434 unop(Iop_V128to64, mkexpr(op2)));
17435 IRExpr* op3half = mkite(mkexpr(neq0),
17436 unop(Iop_V128HIto64, mkexpr(op3)),
17437 unop(Iop_V128to64, mkexpr(op3)));
17438 assign(shift, unop(Iop_64to8,
17439 binop(Iop_Sub64, mkU64(63), mkexpr(samebits))));
17440 tmp = binop(Iop_Or64,
17441 binop(Iop_Shl64,
17442 binop(Iop_And64, mkU64(1),
17443 binop(Iop_Shr64, op2half, mkexpr(shift))),
17444 mkU8(1)),
17445 binop(Iop_And64, mkU64(1),
17446 binop(Iop_Shr64, op3half, mkexpr(shift))));
17448 assign(cc, mkite(binop(Iop_CmpEQ64, mkexpr(samebits), mkU64(64)),
17449 mkU64(3), tmp));
17450 s390_cc_set(cc);
17452 dis_res->hint = Dis_HintVerbose;
17453 return "vfene";
17456 static const HChar *
17457 s390_irgen_VISTR(UChar v1, UChar v2, UChar m3, UChar m5)
17459 s390_insn_assert("vistr", m3 < 3 && m5 == (m5 & 1));
17461 static const IROp compare_op[3] = {
17462 Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4
17464 IRExpr* t;
17465 IRTemp op2 = newTemp(Ity_V128);
17466 IRTemp op2term = newTemp(Ity_V128);
17467 IRTemp mask = newTemp(Ity_V128);
17469 assign(op2, get_vr_qw(v2));
17470 assign(op2term, binop(compare_op[m3], mkexpr(op2), mkV128(0)));
17471 t = mkexpr(op2term);
17473 for (UChar i = m3; i < 4; i++) {
17474 IRTemp s = newTemp(Ity_V128);
17475 assign(s, binop(Iop_OrV128, t, binop(Iop_ShrV128, t, mkU8(8 << i))));
17476 t = mkexpr(s);
17478 assign(mask, unop(Iop_NotV128, t));
17479 put_vr_qw(v1, binop(Iop_AndV128, mkexpr(op2), mkexpr(mask)));
17481 if (s390_vr_is_cs_set(m5)) {
17482 IRTemp cc = newTemp(Ity_I64);
17483 assign(cc, binop(Iop_And64, mkU64(3), unop(Iop_V128to64, mkexpr(mask))));
17484 s390_cc_set(cc);
17486 dis_res->hint = Dis_HintVerbose;
17487 return "vistr";
17490 static const HChar *
17491 s390_irgen_VSTRC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
17493 s390_insn_assert("vstrc", m5 <= 2);
17494 s390_irgen_VStrX(v1, v2, v3, v4, m5, m6, s390_VStrX_VSTRC);
17495 return "vstrc";
17498 static const HChar *
17499 s390_irgen_VSTRS(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
17501 s390_insn_assert("vstrs", m5 <= 2 && m6 == (m6 & 2));
17503 IRTemp op2 = newTemp(Ity_V128);
17504 IRTemp op3 = newTemp(Ity_V128);
17505 IRTemp op4 = newTemp(Ity_I8);
17506 IRTemp op2clean = newTemp(Ity_V128);
17507 IRTemp op3mask = newTemp(Ity_V128);
17508 IRTemp result = newTemp(Ity_V128);
17509 IRTemp ccnomatch = newTemp(Ity_I64);
17510 IRExpr* tmp;
17511 IRExpr* match = NULL;
17512 UChar elem_bits = 8 << m5;
17513 IROp cmpeq_op = S390_VEC_OP3(m5, Iop_CmpEQ8x16,
17514 Iop_CmpEQ16x8, Iop_CmpEQ32x4);
17516 assign(op2, get_vr_qw(v2));
17517 assign(op3, get_vr_qw(v3));
17518 assign(op4, get_vr_b7(v4));
17520 tmp = unop(Iop_Dup32x4,
17521 unop(Iop_1Sto32, binop(Iop_CmpNE8, mkexpr(op4), mkU8(16))));
17522 tmp = binop(Iop_ShrV128, tmp, binop(Iop_Shl8, mkexpr(op4), mkU8(3)));
17524 if (s390_vr_is_zs_set(m6)) {
17525 IRTemp op2eos = newTemp(Ity_V128);
17526 IRExpr* t;
17527 t = binop(cmpeq_op, mkexpr(op2), mkV128(0));
17528 for (UChar i = m5; i < 4; i++) {
17529 IRTemp s = newTemp(Ity_V128);
17530 assign(s, t);
17531 t = binop(Iop_OrV128, mkexpr(s), binop(Iop_ShrV128, mkexpr(s),
17532 mkU8(8 << i)));
17534 assign(op2eos, t);
17535 assign(op2clean, binop(Iop_AndV128, mkexpr(op2),
17536 unop(Iop_NotV128, mkexpr(op2eos))));
17537 assign(ccnomatch, binop(Iop_And64, mkU64(1),
17538 unop(Iop_V128to64, mkexpr(op2eos))));
17540 t = binop(cmpeq_op, mkexpr(op3), mkV128(0));
17541 for (UChar i = m5; i < 4; i++) {
17542 IRTemp s = newTemp(Ity_V128);
17543 assign(s, t);
17544 t = binop(Iop_OrV128, mkexpr(s), binop(Iop_ShrV128, mkexpr(s),
17545 mkU8(8 << i)));
17547 tmp = binop(Iop_OrV128, tmp, t);
17548 } else {
17549 assign(op2clean, mkexpr(op2));
17551 assign(op3mask, unop(Iop_NotV128, tmp));
17553 for (UChar shift = 0; shift < 128; shift += elem_bits) {
17554 IRTemp s = newTemp(Ity_V128);
17555 tmp = unop(Iop_NotV128,
17556 binop(cmpeq_op, mkexpr(op2clean),
17557 binop(Iop_ShrV128, mkexpr(op3), mkU8(shift))));
17558 assign(s, binop(Iop_CmpEQ64x2, mkV128(0),
17559 binop(Iop_AndV128, mkexpr(op3mask),
17560 binop(Iop_ShlV128, tmp, mkU8(shift)))));
17561 tmp = mkexpr(s);
17562 if (shift < 64) {
17563 tmp = binop(Iop_AndV128, tmp,
17564 unop(Iop_Dup16x8, binop(Iop_GetElem16x8, tmp, mkU8(4))));
17566 tmp = binop(Iop_AndV128, tmp,
17567 unop(Iop_Dup16x8, mkU16(1 << (15 - shift / 8))));
17568 if (shift)
17569 match = binop(Iop_OrV128, mkexpr(mktemp(Ity_V128, match)), tmp);
17570 else
17571 match = tmp;
17573 assign(result, unop(Iop_ClzNat64,
17574 binop(Iop_Or64,
17575 unop(Iop_V128HIto64, match),
17576 mkU64((1ULL << 48) - 1))));
17577 put_vr_qw(v1, binop(Iop_64HLtoV128, mkexpr(result), mkU64(0)));
17579 /* Set condition code.
17580 0: no match, no string terminator in op2
17581 1: no match, string terminator found
17582 2: full match
17583 3: partial match */
17584 IRTemp cc = newTemp(Ity_I64);
17585 tmp = binop(Iop_CmpLE64U,
17586 binop(Iop_Add64, mkexpr(result), unop(Iop_8Uto64, mkexpr(op4))),
17587 mkU64(16));
17588 assign(cc, mkite(binop(Iop_CmpEQ64, mkexpr(result), mkU64(16)),
17589 s390_vr_is_zs_set(m6) ? mkexpr(ccnomatch) : mkU64(0),
17590 mkite(tmp, mkU64(2), mkU64(3))));
17591 s390_cc_set(cc);
17593 dis_res->hint = Dis_HintVerbose;
17594 return "vstrs";
17597 static const HChar *
17598 s390_irgen_VNC(UChar v1, UChar v2, UChar v3)
17600 put_vr_qw(v1, binop(Iop_AndV128,
17601 get_vr_qw(v2), unop(Iop_NotV128, get_vr_qw(v3)))
17604 return "vnc";
17607 static const HChar *
17608 s390_irgen_VA(UChar v1, UChar v2, UChar v3, UChar m4)
17610 const IROp ops[] = { Iop_Add8x16, Iop_Add16x8, Iop_Add32x4,
17611 Iop_Add64x2, Iop_Add128x1 };
17612 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17613 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17615 return "va";
17618 static const HChar *
17619 s390_irgen_VS(UChar v1, UChar v2, UChar v3, UChar m4)
17621 const IROp ops[] = { Iop_Sub8x16, Iop_Sub16x8, Iop_Sub32x4,
17622 Iop_Sub64x2, Iop_Sub128x1 };
17623 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17624 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17626 return "vs";
17629 static const HChar *
17630 s390_irgen_VMX(UChar v1, UChar v2, UChar v3, UChar m4)
17632 const IROp ops[] = { Iop_Max8Sx16, Iop_Max16Sx8, Iop_Max32Sx4, Iop_Max64Sx2 };
17633 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17634 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17636 return "vmx";
17639 static const HChar *
17640 s390_irgen_VMXL(UChar v1, UChar v2, UChar v3, UChar m4)
17642 const IROp ops[] = { Iop_Max8Ux16, Iop_Max16Ux8, Iop_Max32Ux4, Iop_Max64Ux2 };
17643 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17644 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17646 return "vmxl";
17649 static const HChar *
17650 s390_irgen_VMN(UChar v1, UChar v2, UChar v3, UChar m4)
17652 const IROp ops[] = { Iop_Min8Sx16, Iop_Min16Sx8, Iop_Min32Sx4, Iop_Min64Sx2 };
17653 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17654 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17656 return "vmn";
17659 static const HChar *
17660 s390_irgen_VMNL(UChar v1, UChar v2, UChar v3, UChar m4)
17662 const IROp ops[] = { Iop_Min8Ux16, Iop_Min16Ux8, Iop_Min32Ux4, Iop_Min64Ux2 };
17663 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17664 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17666 return "vmnl";
17669 static const HChar *
17670 s390_irgen_VAVG(UChar v1, UChar v2, UChar v3, UChar m4)
17672 const IROp ops[] = { Iop_Avg8Sx16, Iop_Avg16Sx8, Iop_Avg32Sx4, Iop_Avg64Sx2 };
17673 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17674 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17676 return "vavg";
17679 static const HChar *
17680 s390_irgen_VAVGL(UChar v1, UChar v2, UChar v3, UChar m4)
17682 const IROp ops[] = { Iop_Avg8Ux16, Iop_Avg16Ux8, Iop_Avg32Ux4, Iop_Avg64Ux2 };
17683 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17684 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17686 return "vavgl";
17689 static const HChar *
17690 s390_irgen_VLC(UChar v1, UChar v2, UChar m3)
17692 vassert(m3 < 4);
17693 IRType type = s390_vr_get_type(m3);
17694 put_vr_qw(v1, s390_V128_get_complement(get_vr_qw(v2), type));
17695 return "vlc";
17698 static const HChar *
17699 s390_irgen_VLP(UChar v1, UChar v2, UChar m3)
17701 const IROp ops[] = { Iop_Abs8x16, Iop_Abs16x8, Iop_Abs32x4, Iop_Abs64x2 };
17702 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
17703 put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2)));
17705 return "vlp";
17708 static const HChar *
17709 s390_irgen_VCH(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17711 if (!s390_vr_is_cs_set(m5)) {
17712 const IROp ops[] = { Iop_CmpGT8Sx16, Iop_CmpGT16Sx8, Iop_CmpGT32Sx4,
17713 Iop_CmpGT64Sx2 };
17714 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17715 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17717 } else {
17718 IRDirty* d;
17719 IRTemp cc = newTemp(Ity_I64);
17721 s390x_vec_op_details_t details = { .serialized = 0ULL };
17722 details.op = S390_VEC_OP_VCH;
17723 details.v1 = v1;
17724 details.v2 = v2;
17725 details.v3 = v3;
17726 details.m4 = m4;
17727 details.m5 = m5;
17729 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17730 &s390x_dirtyhelper_vec_op,
17731 mkIRExprVec_2(IRExpr_GSPTR(),
17732 mkU64(details.serialized)));
17734 d->nFxState = 3;
17735 vex_bzero(&d->fxState, sizeof(d->fxState));
17736 d->fxState[0].fx = Ifx_Read;
17737 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17738 d->fxState[0].size = sizeof(V128);
17739 d->fxState[1].fx = Ifx_Read;
17740 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17741 d->fxState[1].size = sizeof(V128);
17742 d->fxState[2].fx = Ifx_Write;
17743 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17744 d->fxState[2].size = sizeof(V128);
17746 stmt(IRStmt_Dirty(d));
17747 s390_cc_set(cc);
17750 return "vch";
17753 static const HChar *
17754 s390_irgen_VCHL(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
17756 if (!s390_vr_is_cs_set(m5)) {
17757 const IROp ops[] = { Iop_CmpGT8Ux16, Iop_CmpGT16Ux8, Iop_CmpGT32Ux4,
17758 Iop_CmpGT64Ux2 };
17759 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17760 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17762 } else {
17763 IRDirty* d;
17764 IRTemp cc = newTemp(Ity_I64);
17766 s390x_vec_op_details_t details = { .serialized = 0ULL };
17767 details.op = S390_VEC_OP_VCHL;
17768 details.v1 = v1;
17769 details.v2 = v2;
17770 details.v3 = v3;
17771 details.m4 = m4;
17772 details.m5 = m5;
17774 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
17775 &s390x_dirtyhelper_vec_op,
17776 mkIRExprVec_2(IRExpr_GSPTR(),
17777 mkU64(details.serialized)));
17779 d->nFxState = 3;
17780 vex_bzero(&d->fxState, sizeof(d->fxState));
17781 d->fxState[0].fx = Ifx_Read;
17782 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
17783 d->fxState[0].size = sizeof(V128);
17784 d->fxState[1].fx = Ifx_Read;
17785 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
17786 d->fxState[1].size = sizeof(V128);
17787 d->fxState[2].fx = Ifx_Write;
17788 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
17789 d->fxState[2].size = sizeof(V128);
17791 stmt(IRStmt_Dirty(d));
17792 s390_cc_set(cc);
17795 return "vchl";
17798 static const HChar *
17799 s390_irgen_VCLZ(UChar v1, UChar v2, UChar m3)
17801 const IROp ops[] = { Iop_Clz8x16, Iop_Clz16x8, Iop_Clz32x4, Iop_Clz64x2 };
17802 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
17803 put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2)));
17805 return "vclz";
17808 static const HChar *
17809 s390_irgen_VCTZ(UChar v1, UChar v2, UChar m3)
17811 const IROp ops[] = { Iop_Ctz8x16, Iop_Ctz16x8, Iop_Ctz32x4, Iop_Ctz64x2 };
17812 vassert(m3 < sizeof(ops) / sizeof(ops[0]));
17813 put_vr_qw(v1, unop(ops[m3], get_vr_qw(v2)));
17815 return "vctz";
17818 static const HChar *
17819 s390_irgen_VPOPCT(UChar v1, UChar v2, UChar m3)
17821 s390_insn_assert("vpopct", m3 <= 3);
17823 IRExpr* cnt = unop(Iop_Cnt8x16, get_vr_qw(v2));
17825 if (m3 >= 1) {
17826 cnt = unop(Iop_PwAddL8Ux16, cnt);
17827 if (m3 >= 2) {
17828 cnt = unop(Iop_PwAddL16Ux8, cnt);
17829 if (m3 == 3)
17830 cnt = unop(Iop_PwAddL32Ux4, cnt);
17833 put_vr_qw(v1, cnt);
17835 return "vpopct";
17838 static const HChar *
17839 s390_irgen_VML(UChar v1, UChar v2, UChar v3, UChar m4)
17841 const IROp ops[] = { Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4 };
17842 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17843 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17845 return "vml";
17848 static const HChar *
17849 s390_irgen_VMLH(UChar v1, UChar v2, UChar v3, UChar m4)
17851 const IROp ops[] = { Iop_MulHi8Ux16, Iop_MulHi16Ux8, Iop_MulHi32Ux4 };
17852 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17853 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17855 return "vmlh";
17858 static const HChar *
17859 s390_irgen_VMH(UChar v1, UChar v2, UChar v3, UChar m4)
17861 const IROp ops[] = { Iop_MulHi8Sx16, Iop_MulHi16Sx8, Iop_MulHi32Sx4 };
17862 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17863 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17865 return "vmh";
17868 static const HChar *
17869 s390_irgen_VME(UChar v1, UChar v2, UChar v3, UChar m4)
17871 const IROp ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8, Iop_MullEven32Sx4 };
17872 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17873 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17875 return "vme";
17878 static const HChar *
17879 s390_irgen_VMLE(UChar v1, UChar v2, UChar v3, UChar m4)
17881 const IROp ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8, Iop_MullEven32Ux4 };
17882 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17883 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17885 return "vmle";
17888 static const HChar *
17889 s390_irgen_VESLV(UChar v1, UChar v2, UChar v3, UChar m4)
17891 const IROp ops[] = { Iop_Shl8x16, Iop_Shl16x8, Iop_Shl32x4, Iop_Shl64x2};
17892 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17893 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17895 return "veslv";
17898 static const HChar *
17899 s390_irgen_VESL(UChar v1, IRTemp op2addr, UChar v3, UChar m4)
17901 IRExpr* shift_amount = unop(Iop_64to8, mkexpr(op2addr));
17902 const IROp ops[] = { Iop_ShlN8x16, Iop_ShlN16x8, Iop_ShlN32x4, Iop_ShlN64x2 };
17903 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17904 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_amount));
17906 return "vesl";
17909 static const HChar *
17910 s390_irgen_VESRAV(UChar v1, UChar v2, UChar v3, UChar m4)
17912 const IROp ops[] = { Iop_Sar8x16, Iop_Sar16x8, Iop_Sar32x4, Iop_Sar64x2 };
17913 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17914 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17916 return "vesrav";
17919 static const HChar *
17920 s390_irgen_VESRA(UChar v1, IRTemp op2addr, UChar v3, UChar m4)
17922 IRExpr* shift_amount = unop(Iop_64to8, mkexpr(op2addr));
17923 const IROp ops[] = { Iop_SarN8x16, Iop_SarN16x8, Iop_SarN32x4, Iop_SarN64x2 };
17924 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17925 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_amount));
17927 return "vesra";
17930 static const HChar *
17931 s390_irgen_VESRLV(UChar v1, UChar v2, UChar v3, UChar m4)
17933 const IROp ops[] = { Iop_Shr8x16, Iop_Shr16x8, Iop_Shr32x4, Iop_Shr64x2 };
17934 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17935 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17937 return "vesrlv";
17940 static const HChar *
17941 s390_irgen_VESRL(UChar v1, IRTemp op2addr, UChar v3, UChar m4)
17943 IRExpr* shift_amount = unop(Iop_64to8, mkexpr(op2addr));
17944 const IROp ops[] = { Iop_ShrN8x16, Iop_ShrN16x8, Iop_ShrN32x4, Iop_ShrN64x2 };
17945 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17946 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_amount));
17948 return "vesrl";
17951 static const HChar *
17952 s390_irgen_VERLLV(UChar v1, UChar v2, UChar v3, UChar m4)
17954 const IROp ops[] = { Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2 };
17955 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17956 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
17958 return "verllv";
17961 static const HChar *
17962 s390_irgen_VERLL(UChar v1, IRTemp op2addr, UChar v3, UChar m4)
17965 There is no Iop_RolN?x?? operations
17966 so we have to use VECTOR x VECTOR variant.
17968 IRExpr* shift_vector = unop(Iop_Dup8x16, unop(Iop_64to8, mkexpr(op2addr)));
17969 const IROp ops[] = { Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2 };
17970 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
17971 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v3), shift_vector));
17973 return "verll";
17976 static const HChar *
17977 s390_irgen_VSL(UChar v1, UChar v2, UChar v3)
17979 IRTemp a = newTemp(Ity_V128);
17980 IRTemp b = newTemp(Ity_V128);
17982 assign(a, get_vr_qw(v2));
17983 assign(b, get_vr_qw(v3));
17985 put_vr_qw(v1,
17986 binop(Iop_OrV128,
17987 binop(Iop_Shl8x16, mkexpr(a), mkexpr(b)),
17988 binop(Iop_Shr8x16,
17989 binop(Iop_Shr8x16,
17990 binop(Iop_ShlV128, mkexpr(a), mkU8(8)),
17991 unop(Iop_NotV128, mkexpr(b))),
17992 unop(Iop_Dup8x16, mkU8(1)))));
17993 return "vsl";
17996 static const HChar *
17997 s390_irgen_VSRL(UChar v1, UChar v2, UChar v3)
17999 IRTemp a = newTemp(Ity_V128);
18000 IRTemp b = newTemp(Ity_V128);
18002 assign(a, get_vr_qw(v2));
18003 assign(b, get_vr_qw(v3));
18005 put_vr_qw(v1,
18006 binop(Iop_OrV128,
18007 binop(Iop_Shr8x16, mkexpr(a), mkexpr(b)),
18008 binop(Iop_Shl8x16,
18009 binop(Iop_Shl8x16,
18010 binop(Iop_ShrV128, mkexpr(a), mkU8(8)),
18011 unop(Iop_NotV128, mkexpr(b))),
18012 unop(Iop_Dup8x16, mkU8(1)))));
18013 return "vsrl";
18016 static const HChar *
18017 s390_irgen_VSRA(UChar v1, UChar v2, UChar v3)
18019 IRTemp a = newTemp(Ity_V128);
18020 IRTemp b = newTemp(Ity_V128);
18022 assign(a, get_vr_qw(v2));
18023 assign(b, get_vr_qw(v3));
18025 /* Shift-right: first byte arithmetically, all others logically */
18026 IRExpr* elems_shifted =
18027 binop(Iop_Sar8x16,
18028 binop(Iop_Shr8x16, mkexpr(a),
18029 binop(Iop_AndV128, mkexpr(b), mkV128(0x7fff))),
18030 binop(Iop_AndV128, mkexpr(b), mkV128(0x8000)));
18031 /* Then OR the appropriate bits from the byte to the left */
18032 put_vr_qw(v1,
18033 binop(Iop_OrV128, elems_shifted,
18034 binop(Iop_Shl8x16,
18035 binop(Iop_Shl8x16,
18036 binop(Iop_ShrV128, mkexpr(a), mkU8(8)),
18037 unop(Iop_NotV128, mkexpr(b))),
18038 unop(Iop_Dup8x16, mkU8(1)))));
18039 return "vsra";
18042 static const HChar *
18043 s390_irgen_VERIM(UChar v1, UChar v2, UChar v3, UChar i4, UChar m5)
18046 There is no Iop_RolN?x?? operations
18047 so we have to use VECTOR x VECTOR variant.
18049 const IROp ops[] = { Iop_Rol8x16, Iop_Rol16x8, Iop_Rol32x4, Iop_Rol64x2 };
18050 vassert(m5 < sizeof(ops) / sizeof(ops[0]));
18051 IRExpr* shift_vector = unop(Iop_Dup8x16, mkU8(i4));
18052 IRExpr* rotated_vector = binop(ops[m5], get_vr_qw(v2), shift_vector);
18054 /* result = (result & ~mask) | (rotated_vector & mask) */
18055 IRExpr* mask = get_vr_qw(v3);
18056 IRExpr* result = get_vr_qw(v1);
18057 put_vr_qw(v1, s390_V128_bitwiseITE(mask, rotated_vector, result));
18059 return "verim";
18062 static const HChar *
18063 s390_irgen_VEC(UChar v1, UChar v2, UChar m3)
18065 IRType type = s390_vr_get_type(m3);
18066 IRTemp op1 = newTemp(type);
18067 IRTemp op2 = newTemp(type);
18069 switch(type) {
18070 case Ity_I8:
18071 assign(op1, get_vr_b7(v1));
18072 assign(op2, get_vr_b7(v2));
18073 break;
18074 case Ity_I16:
18075 assign(op1, get_vr_hw3(v1));
18076 assign(op2, get_vr_hw3(v2));
18077 break;
18078 case Ity_I32:
18079 assign(op1, get_vr_w1(v1));
18080 assign(op2, get_vr_w1(v2));
18081 break;
18082 case Ity_I64:
18083 assign(op1, get_vr_dw0(v1));
18084 assign(op2, get_vr_dw0(v2));
18085 break;
18086 default:
18087 vpanic("s390_irgen_VEC: unknown type");
18090 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
18092 return "vec";
18095 static const HChar *
18096 s390_irgen_VECL(UChar v1, UChar v2, UChar m3)
18098 IRType type = s390_vr_get_type(m3);
18099 IRTemp op1 = newTemp(type);
18100 IRTemp op2 = newTemp(type);
18102 switch(type) {
18103 case Ity_I8:
18104 assign(op1, get_vr_b7(v1));
18105 assign(op2, get_vr_b7(v2));
18106 break;
18107 case Ity_I16:
18108 assign(op1, get_vr_hw3(v1));
18109 assign(op2, get_vr_hw3(v2));
18110 break;
18111 case Ity_I32:
18112 assign(op1, get_vr_w1(v1));
18113 assign(op2, get_vr_w1(v2));
18114 break;
18115 case Ity_I64:
18116 assign(op1, get_vr_dw0(v1));
18117 assign(op2, get_vr_dw0(v2));
18118 break;
18119 default:
18120 vpanic("s390_irgen_VECL: unknown type");
18123 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
18125 return "vecl";
18128 static const HChar *
18129 s390_irgen_VCEQ(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
18131 if (!s390_vr_is_cs_set(m5)) {
18132 const IROp ops[] = { Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4,
18133 Iop_CmpEQ64x2 };
18134 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
18135 put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3)));
18137 } else {
18138 IRDirty* d;
18139 IRTemp cc = newTemp(Ity_I64);
18141 s390x_vec_op_details_t details = { .serialized = 0ULL };
18142 details.op = S390_VEC_OP_VCEQ;
18143 details.v1 = v1;
18144 details.v2 = v2;
18145 details.v3 = v3;
18146 details.m4 = m4;
18147 details.m5 = m5;
18149 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18150 &s390x_dirtyhelper_vec_op,
18151 mkIRExprVec_2(IRExpr_GSPTR(),
18152 mkU64(details.serialized)));
18154 d->nFxState = 3;
18155 vex_bzero(&d->fxState, sizeof(d->fxState));
18156 d->fxState[0].fx = Ifx_Read;
18157 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18158 d->fxState[0].size = sizeof(V128);
18159 d->fxState[1].fx = Ifx_Read;
18160 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18161 d->fxState[1].size = sizeof(V128);
18162 d->fxState[2].fx = Ifx_Write;
18163 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18164 d->fxState[2].size = sizeof(V128);
18166 stmt(IRStmt_Dirty(d));
18167 s390_cc_set(cc);
18170 return "vceq";
18173 static const HChar *
18174 s390_irgen_VSLB(UChar v1, UChar v2, UChar v3)
18176 IRTemp shift_amount = newTemp(Ity_I8);
18177 assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b01111000)));
18179 put_vr_qw(v1, binop(Iop_ShlV128, get_vr_qw(v2), mkexpr(shift_amount)));
18180 return "vslb";
18183 static const HChar *
18184 s390_irgen_VSRLB(UChar v1, UChar v2, UChar v3)
18186 IRTemp shift_amount = newTemp(Ity_I8);
18187 assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b01111000)));
18189 put_vr_qw(v1, binop(Iop_ShrV128, get_vr_qw(v2), mkexpr(shift_amount)));
18190 return "vsrlb";
18193 static const HChar *
18194 s390_irgen_VSRAB(UChar v1, UChar v2, UChar v3)
18196 IRTemp shift_amount = newTemp(Ity_I8);
18197 assign(shift_amount, binop(Iop_And8, get_vr_b7(v3), mkU8(0b01111000)));
18199 put_vr_qw(v1, binop(Iop_SarV128, get_vr_qw(v2), mkexpr(shift_amount)));
18200 return "vsrab";
18203 static const HChar *
18204 s390_irgen_VSLDB(UChar v1, UChar v2, UChar v3, UChar i4)
18206 UChar imm = i4 & 0b00001111;
18208 if (imm == 0) {
18209 /* Just copy v2. */
18210 put_vr_qw(v1, get_vr_qw(v2));
18211 } else {
18212 /* Concatenate v2's tail with v3's head. */
18213 put_vr_qw(v1,
18214 binop(Iop_OrV128,
18215 binop(Iop_ShlV128, get_vr_qw(v2), mkU8(imm * 8)),
18216 binop(Iop_ShrV128, get_vr_qw(v3), mkU8((16 - imm) * 8))
18221 return "vsldb";
18224 static const HChar *
18225 s390_irgen_VSLD(UChar v1, UChar v2, UChar v3, UChar i4)
18227 s390_insn_assert("vsld", i4 <= 7);
18229 if (i4 == 0) {
18230 /* Just copy v2. */
18231 put_vr_qw(v1, get_vr_qw(v2));
18232 } else {
18233 /* Concatenate v2's tail with v3's head. */
18234 put_vr_qw(v1,
18235 binop(Iop_OrV128,
18236 binop(Iop_ShlV128, get_vr_qw(v2), mkU8(i4)),
18237 binop(Iop_ShrV128, get_vr_qw(v3), mkU8(128 - i4))
18242 return "vsld";
18245 static const HChar *
18246 s390_irgen_VSRD(UChar v1, UChar v2, UChar v3, UChar i4)
18248 s390_insn_assert("vsrd", i4 <= 7);
18250 if (i4 == 0) {
18251 /* Just copy v3. */
18252 put_vr_qw(v1, get_vr_qw(v3));
18253 } else {
18254 /* Concatenate v2's tail with v3's head. */
18255 put_vr_qw(v1,
18256 binop(Iop_OrV128,
18257 binop(Iop_ShlV128, get_vr_qw(v2), mkU8(128 - i4)),
18258 binop(Iop_ShrV128, get_vr_qw(v3), mkU8(i4))
18263 return "vsrd";
18266 static const HChar *
18267 s390_irgen_VMO(UChar v1, UChar v2, UChar v3, UChar m4)
18269 const IROp ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8,
18270 Iop_MullEven32Sx4 };
18271 UChar shifts[] = { 8, 16, 32 };
18272 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
18273 IRExpr* result = binop(ops[m4],
18274 binop(Iop_ShlV128, get_vr_qw(v2), mkU8(shifts[m4])),
18275 binop(Iop_ShlV128, get_vr_qw(v3), mkU8(shifts[m4]))
18277 put_vr_qw(v1, result);
18279 return "vmo";
18282 static const HChar *
18283 s390_irgen_VMLO(UChar v1, UChar v2, UChar v3, UChar m4)
18285 const IROp ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8,
18286 Iop_MullEven32Ux4 };
18287 UChar shifts[] = { 8, 16, 32 };
18288 vassert(m4 < sizeof(ops) / sizeof(ops[0]));
18289 IRExpr* result = binop(ops[m4],
18290 binop(Iop_ShlV128, get_vr_qw(v2), mkU8(shifts[m4])),
18291 binop(Iop_ShlV128, get_vr_qw(v3), mkU8(shifts[m4]))
18293 put_vr_qw(v1, result);
18295 return "vmlo";
18298 static const HChar *
18299 s390_irgen_VMAE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18301 const IROp mul_ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8,
18302 Iop_MullEven32Sx4 };
18303 const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2};
18304 vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
18306 IRExpr* mul_result = binop(mul_ops[m5], get_vr_qw(v2), get_vr_qw(v3));
18307 IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
18308 put_vr_qw(v1, result);
18310 return "vmae";
18313 static const HChar *
18314 s390_irgen_VMALE(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18316 const IROp mul_ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8,
18317 Iop_MullEven32Ux4 };
18318 const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2 };
18319 vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
18321 IRExpr* mul_result = binop(mul_ops[m5], get_vr_qw(v2), get_vr_qw(v3));
18322 IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
18323 put_vr_qw(v1, result);
18325 return "vmale";
18328 static const HChar *
18329 s390_irgen_VMAO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18331 const IROp mul_ops[] = { Iop_MullEven8Sx16, Iop_MullEven16Sx8,
18332 Iop_MullEven32Sx4 };
18333 const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2 };
18334 UChar shifts[] = { 8, 16, 32 };
18335 vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
18337 IRExpr* mul_result =
18338 binop(mul_ops[m5],
18339 binop(Iop_ShlV128, get_vr_qw(v2), mkU8(shifts[m5])),
18340 binop(Iop_ShlV128, get_vr_qw(v3), mkU8(shifts[m5])));
18341 IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
18342 put_vr_qw(v1, result);
18344 return "vmao";
18347 static const HChar *
18348 s390_irgen_VMALO(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18350 const IROp mul_ops[] = { Iop_MullEven8Ux16, Iop_MullEven16Ux8,
18351 Iop_MullEven32Ux4 };
18352 const IROp add_ops[] = { Iop_Add16x8, Iop_Add32x4, Iop_Add64x2 };
18353 UChar shifts[] = { 8, 16, 32 };
18354 vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
18356 IRExpr* mul_result = binop(mul_ops[m5],
18357 binop(Iop_ShlV128,
18358 get_vr_qw(v2), mkU8(shifts[m5])),
18359 binop(Iop_ShlV128,
18360 get_vr_qw(v3), mkU8(shifts[m5]))
18363 IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
18364 put_vr_qw(v1, result);
18366 return "vmalo";
18369 static const HChar *
18370 s390_irgen_VMAL(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18372 const IROp mul_ops[] = { Iop_Mul8x16, Iop_Mul16x8, Iop_Mul32x4 };
18373 const IROp add_ops[] = { Iop_Add8x16, Iop_Add16x8, Iop_Add32x4 };
18374 vassert(m5 < sizeof(mul_ops) / sizeof(mul_ops[0]));
18376 IRExpr* mul_result = binop(mul_ops[m5], get_vr_qw(v2), get_vr_qw(v3));
18377 IRExpr* result = binop(add_ops[m5], mul_result, get_vr_qw(v4));
18378 put_vr_qw(v1, result);
18380 return "vmal";
18383 static const HChar *
18384 s390_irgen_VSUM(UChar v1, UChar v2, UChar v3, UChar m4)
18386 IRType type = s390_vr_get_type(m4);
18387 IRExpr* mask;
18388 IRExpr* sum;
18389 switch(type) {
18390 case Ity_I8:
18391 sum = unop(Iop_PwAddL16Ux8, unop(Iop_PwAddL8Ux16, get_vr_qw(v2)));
18392 mask = mkV128(0b0001000100010001);
18393 break;
18394 case Ity_I16:
18395 sum = unop(Iop_PwAddL16Ux8, get_vr_qw(v2));
18396 mask = mkV128(0b0011001100110011);
18397 break;
18398 default:
18399 vpanic("s390_irgen_VSUM: invalid type ");
18402 IRExpr* addition = binop(Iop_AndV128, get_vr_qw(v3), mask);
18403 put_vr_qw(v1, binop(Iop_Add32x4, sum, addition));
18405 return "vsum";
18408 static const HChar *
18409 s390_irgen_VSUMG(UChar v1, UChar v2, UChar v3, UChar m4)
18411 IRType type = s390_vr_get_type(m4);
18412 IRExpr* mask;
18413 IRExpr* sum;
18414 switch(type) {
18415 case Ity_I16:
18416 sum = unop(Iop_PwAddL32Ux4, unop(Iop_PwAddL16Ux8, get_vr_qw(v2)));
18417 mask = mkV128(0b0000001100000011);
18418 break;
18419 case Ity_I32:
18420 sum = unop(Iop_PwAddL32Ux4, get_vr_qw(v2));
18421 mask = mkV128(0b0000111100001111);
18422 break;
18423 default:
18424 vpanic("s390_irgen_VSUMG: invalid type ");
18427 IRExpr* addition = binop(Iop_AndV128, get_vr_qw(v3), mask);
18428 put_vr_qw(v1, binop(Iop_Add64x2, sum, addition));
18430 return "vsumg";
18433 static const HChar *
18434 s390_irgen_VSUMQ(UChar v1, UChar v2, UChar v3, UChar m4)
18436 IRType type = s390_vr_get_type(m4);
18437 IRExpr* mask;
18438 IRExpr* sum;
18439 switch(type) {
18440 case Ity_I32:
18441 sum = unop(Iop_PwAddL64Ux2, unop(Iop_PwAddL32Ux4, get_vr_qw(v2)));
18442 mask = mkV128(0b0000000000001111);
18443 break;
18444 case Ity_I64:
18445 sum = unop(Iop_PwAddL64Ux2, get_vr_qw(v2));
18446 mask = mkV128(0b0000000011111111);
18447 break;
18448 default:
18449 vpanic("s390_irgen_VSUMQ: invalid type ");
18452 IRExpr* addition = binop(Iop_AndV128, get_vr_qw(v3), mask);
18453 put_vr_qw(v1, binop(Iop_Add128x1, sum, addition));
18455 return "vsumq";
18458 static const HChar *
18459 s390_irgen_VTM(UChar v1, UChar v2)
18461 IRDirty* d;
18462 IRTemp cc = newTemp(Ity_I64);
18464 s390x_vec_op_details_t details = { .serialized = 0ULL };
18465 details.op = S390_VEC_OP_VTM;
18466 details.v2 = v1;
18467 details.v3 = v2;
18468 details.read_only = 1;
18470 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18471 &s390x_dirtyhelper_vec_op,
18472 mkIRExprVec_2(IRExpr_GSPTR(),
18473 mkU64(details.serialized)));
18475 d->nFxState = 2;
18476 vex_bzero(&d->fxState, sizeof(d->fxState));
18477 d->fxState[0].fx = Ifx_Read;
18478 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18479 d->fxState[0].size = sizeof(V128);
18480 d->fxState[1].fx = Ifx_Read;
18481 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18482 d->fxState[1].size = sizeof(V128);
18484 stmt(IRStmt_Dirty(d));
18485 s390_cc_set(cc);
18487 return "vtm";
18490 static const HChar *
18491 s390_irgen_VAC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18493 vassert(m5 == 4); /* specification exception otherwise */
18495 IRTemp sum = newTemp(Ity_V128);
18496 assign(sum, binop(Iop_Add128x1, get_vr_qw(v2), get_vr_qw(v3)));
18498 IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0), mkU64(1));
18499 IRExpr* carry_in = binop(Iop_AndV128, get_vr_qw(v4), mask);
18500 put_vr_qw(v1, binop(Iop_Add128x1, mkexpr(sum), carry_in));
18502 return "vac";
18505 static const HChar *
18506 s390_irgen_VACC(UChar v1, UChar v2, UChar v3, UChar m4)
18508 IRType type = s390_vr_get_type(m4);
18509 IRExpr* arg1 = get_vr_qw(v2);
18510 IRExpr* arg2 = get_vr_qw(v3);
18512 put_vr_qw(v1, s390_V128_calculate_carry_out(arg1, arg2, type, False));
18513 return "vacc";
18516 static const HChar *
18517 s390_irgen_VACCC(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18519 vassert(m5 == 4); /* specification exception otherwise */
18520 IRExpr* result =
18521 s390_V128_calculate_carry_out_with_carry(get_vr_qw(v2),
18522 get_vr_qw(v3),
18523 get_vr_qw(v4)
18526 put_vr_qw(v1, result);
18527 return "vaccc";
18530 static const HChar*
18531 s390_irgen_VCKSM(UChar v1, UChar v2, UChar v3)
18534 IRTemp sum1 = s390_checksum_add(get_vr_w1(v3), get_vr_w0(v2));
18535 IRTemp sum2 = s390_checksum_add(mkexpr(sum1), get_vr_w1(v2));
18536 IRTemp sum3 = s390_checksum_add(mkexpr(sum2), get_vr_w2(v2));
18537 IRTemp result = s390_checksum_add(mkexpr(sum3), get_vr_w3(v2));
18539 put_vr_qw(v1, binop(Iop_64HLtoV128,
18540 unop(Iop_32Uto64, mkexpr(result)), mkU64(0ULL)));
18542 return "vcksm";
18545 static const HChar *
18546 s390_irgen_VGFM(UChar v1, UChar v2, UChar v3, UChar m4)
18548 IRDirty* d;
18549 IRTemp cc = newTemp(Ity_I64);
18551 s390x_vec_op_details_t details = { .serialized = 0ULL };
18552 details.op = S390_VEC_OP_VGFM;
18553 details.v1 = v1;
18554 details.v2 = v2;
18555 details.v3 = v3;
18556 details.m4 = m4;
18558 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18559 &s390x_dirtyhelper_vec_op,
18560 mkIRExprVec_2(IRExpr_GSPTR(),
18561 mkU64(details.serialized)));
18563 d->nFxState = 3;
18564 vex_bzero(&d->fxState, sizeof(d->fxState));
18565 d->fxState[0].fx = Ifx_Read;
18566 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18567 d->fxState[0].size = sizeof(V128);
18568 d->fxState[1].fx = Ifx_Read;
18569 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18570 d->fxState[1].size = sizeof(V128);
18571 d->fxState[2].fx = Ifx_Write;
18572 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18573 d->fxState[2].size = sizeof(V128);
18575 stmt(IRStmt_Dirty(d));
18576 return "vgfm";
18579 static const HChar *
18580 s390_irgen_VGFMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18582 IRDirty* d;
18583 IRTemp cc = newTemp(Ity_I64);
18585 s390x_vec_op_details_t details = { .serialized = 0ULL };
18586 details.op = S390_VEC_OP_VGFMA;
18587 details.v1 = v1;
18588 details.v2 = v2;
18589 details.v3 = v3;
18590 details.v4 = v4;
18591 details.m4 = m5;
18593 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18594 &s390x_dirtyhelper_vec_op,
18595 mkIRExprVec_2(IRExpr_GSPTR(),
18596 mkU64(details.serialized)));
18598 d->nFxState = 4;
18599 vex_bzero(&d->fxState, sizeof(d->fxState));
18600 d->fxState[0].fx = Ifx_Read;
18601 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18602 d->fxState[0].size = sizeof(V128);
18603 d->fxState[1].fx = Ifx_Read;
18604 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18605 d->fxState[1].size = sizeof(V128);
18606 d->fxState[2].fx = Ifx_Read;
18607 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128);
18608 d->fxState[2].size = sizeof(V128);
18609 d->fxState[3].fx = Ifx_Write;
18610 d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18611 d->fxState[3].size = sizeof(V128);
18613 stmt(IRStmt_Dirty(d));
18614 return "vgfma";
18617 static const HChar *
18618 s390_irgen_VSBI(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18620 vassert(m5 == 4); /* specification exception otherwise */
18622 IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0ULL), mkU64(1ULL));
18623 IRExpr* carry_in = binop(Iop_AndV128, get_vr_qw(v4), mask);
18625 IRTemp sum = newTemp(Ity_V128);
18626 assign(sum, binop(Iop_Add128x1,
18627 get_vr_qw(v2),
18628 unop(Iop_NotV128, get_vr_qw(v3))
18632 put_vr_qw(v1, binop(Iop_Add128x1, mkexpr(sum), carry_in));
18633 return "vsbi";
18636 static const HChar *
18637 s390_irgen_VSCBI(UChar v1, UChar v2, UChar v3, UChar m4)
18639 IRType type = s390_vr_get_type(m4);
18640 IRExpr* arg1 = get_vr_qw(v2);
18641 IRExpr* arg2 = s390_V128_get_complement(get_vr_qw(v3), type);
18642 IRExpr* result = s390_V128_calculate_carry_out(arg1, arg2, type, True);
18644 put_vr_qw(v1, result);
18645 return "vscbi";
18648 static const HChar *
18649 s390_irgen_VSBCBI(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18651 vassert(m5 == 4); /* specification exception otherwise */
18652 IRExpr* result =
18653 s390_V128_calculate_carry_out_with_carry(get_vr_qw(v2),
18654 unop(Iop_NotV128, get_vr_qw(v3)),
18655 get_vr_qw(v4));
18657 put_vr_qw(v1, result);
18658 return "vsbcbi";
18661 static const HChar *
18662 s390_irgen_VMAH(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18664 IRDirty* d;
18665 IRTemp cc = newTemp(Ity_I64);
18667 /* Check for specification exception */
18668 vassert(m5 < 3);
18670 s390x_vec_op_details_t details = { .serialized = 0ULL };
18671 details.op = S390_VEC_OP_VMAH;
18672 details.v1 = v1;
18673 details.v2 = v2;
18674 details.v3 = v3;
18675 details.v4 = v4;
18676 details.m4 = m5;
18678 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18679 &s390x_dirtyhelper_vec_op,
18680 mkIRExprVec_2(IRExpr_GSPTR(),
18681 mkU64(details.serialized)));
18683 d->nFxState = 4;
18684 vex_bzero(&d->fxState, sizeof(d->fxState));
18685 d->fxState[0].fx = Ifx_Read;
18686 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18687 d->fxState[0].size = sizeof(V128);
18688 d->fxState[1].fx = Ifx_Read;
18689 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18690 d->fxState[1].size = sizeof(V128);
18691 d->fxState[2].fx = Ifx_Read;
18692 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128);
18693 d->fxState[2].size = sizeof(V128);
18694 d->fxState[3].fx = Ifx_Write;
18695 d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18696 d->fxState[3].size = sizeof(V128);
18698 stmt(IRStmt_Dirty(d));
18700 return "vmah";
18703 static const HChar *
18704 s390_irgen_VMALH(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5)
18706 IRDirty* d;
18707 IRTemp cc = newTemp(Ity_I64);
18709 /* Check for specification exception */
18710 vassert(m5 < 3);
18712 s390x_vec_op_details_t details = { .serialized = 0ULL };
18713 details.op = S390_VEC_OP_VMALH;
18714 details.v1 = v1;
18715 details.v2 = v2;
18716 details.v3 = v3;
18717 details.v4 = v4;
18718 details.m4 = m5;
18720 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18721 &s390x_dirtyhelper_vec_op,
18722 mkIRExprVec_2(IRExpr_GSPTR(),
18723 mkU64(details.serialized)));
18725 d->nFxState = 4;
18726 vex_bzero(&d->fxState, sizeof(d->fxState));
18727 d->fxState[0].fx = Ifx_Read;
18728 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18729 d->fxState[0].size = sizeof(V128);
18730 d->fxState[1].fx = Ifx_Read;
18731 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18732 d->fxState[1].size = sizeof(V128);
18733 d->fxState[2].fx = Ifx_Read;
18734 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128);
18735 d->fxState[2].size = sizeof(V128);
18736 d->fxState[3].fx = Ifx_Write;
18737 d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18738 d->fxState[3].size = sizeof(V128);
18740 stmt(IRStmt_Dirty(d));
18742 return "vmalh";
18745 static const HChar *
18746 s390_irgen_VMSL(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
18748 s390_insn_assert("vmsl", m5 == 3 && (m6 & 3) == 0);
18750 IRDirty* d;
18751 IRTemp cc = newTemp(Ity_I64);
18753 s390x_vec_op_details_t details = { .serialized = 0ULL };
18754 details.op = S390_VEC_OP_VMSL;
18755 details.v1 = v1;
18756 details.v2 = v2;
18757 details.v3 = v3;
18758 details.v4 = v4;
18759 details.m4 = m5;
18760 details.m5 = m6;
18762 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
18763 &s390x_dirtyhelper_vec_op,
18764 mkIRExprVec_2(IRExpr_GSPTR(),
18765 mkU64(details.serialized)));
18767 d->nFxState = 4;
18768 vex_bzero(&d->fxState, sizeof(d->fxState));
18769 d->fxState[0].fx = Ifx_Read;
18770 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
18771 d->fxState[0].size = sizeof(V128);
18772 d->fxState[1].fx = Ifx_Read;
18773 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
18774 d->fxState[1].size = sizeof(V128);
18775 d->fxState[2].fx = Ifx_Read;
18776 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128);
18777 d->fxState[2].size = sizeof(V128);
18778 d->fxState[3].fx = Ifx_Write;
18779 d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
18780 d->fxState[3].size = sizeof(V128);
18782 stmt(IRStmt_Dirty(d));
18784 return "vmsl";
18787 static void
18788 s390_vector_fp_convert(IROp op, IRType fromType, IRType toType, Bool rounding,
18789 UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18791 Bool isSingleElementOp = s390_vr_is_single_element_control_set(m4);
18793 /* For Iop_F32toF64 we do this:
18794 f32[0] -> f64[0]
18795 f32[2] -> f64[1]
18797 For Iop_F64toF32 we do this:
18798 f64[0] -> f32[0]
18799 f64[1] -> f32[2]
18801 The magic below with scaling factors is used to achieve the logic
18802 described above.
18804 Int size_diff = sizeofIRType(toType) - sizeofIRType(fromType);
18805 const UChar sourceIndexScaleFactor = size_diff > 0 ? 2 : 1;
18806 const UChar destinationIndexScaleFactor = size_diff < 0 ? 2 : 1;
18807 UChar n_elem = (isSingleElementOp ? 1 :
18808 16 / (size_diff > 0 ?
18809 sizeofIRType(toType) : sizeofIRType(fromType)));
18811 for (UChar i = 0; i < n_elem; i++) {
18812 IRExpr* argument = get_vr(v2, fromType, i * sourceIndexScaleFactor);
18813 IRExpr* result;
18814 if (rounding) {
18815 if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) {
18816 emulation_warning(EmWarn_S390X_fpext_rounding);
18817 m5 = S390_BFP_ROUND_PER_FPC;
18819 result = binop(op,
18820 mkexpr(encode_bfp_rounding_mode(m5)),
18821 argument);
18822 } else {
18823 result = unop(op, argument);
18825 put_vr(v1, toType, i * destinationIndexScaleFactor, result);
18829 static const HChar *
18830 s390_irgen_VCDG(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18832 s390_insn_assert("vcdg", m3 == 2 || m3 == 3);
18834 s390_vector_fp_convert(m3 == 2 ? Iop_I32StoF32 : Iop_I64StoF64,
18835 m3 == 2 ? Ity_I32 : Ity_I64,
18836 m3 == 2 ? Ity_F32 : Ity_F64,
18837 True, v1, v2, m3, m4, m5);
18838 return "vcdg";
18841 static const HChar *
18842 s390_irgen_VCDLG(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18844 s390_insn_assert("vcdlg", m3 == 2 || m3 == 3);
18846 s390_vector_fp_convert(m3 == 2 ? Iop_I32UtoF32 : Iop_I64UtoF64,
18847 m3 == 2 ? Ity_I32 : Ity_I64,
18848 m3 == 2 ? Ity_F32 : Ity_F64,
18849 True, v1, v2, m3, m4, m5);
18850 return "vcdlg";
18853 static const HChar *
18854 s390_irgen_VCGD(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18856 s390_insn_assert("vcgd", m3 == 2 || m3 == 3);
18858 s390_vector_fp_convert(m3 == 2 ? Iop_F32toI32S : Iop_F64toI64S,
18859 m3 == 2 ? Ity_F32 : Ity_F64,
18860 m3 == 2 ? Ity_I32 : Ity_I64,
18861 True, v1, v2, m3, m4, m5);
18862 return "vcgd";
18865 static const HChar *
18866 s390_irgen_VCLGD(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18868 s390_insn_assert("vclgd", m3 == 2 || m3 == 3);
18870 s390_vector_fp_convert(m3 == 2 ? Iop_F32toI32U : Iop_F64toI64U,
18871 m3 == 2 ? Ity_F32 : Ity_F64,
18872 m3 == 2 ? Ity_I32 : Ity_I64,
18873 True, v1, v2, m3, m4, m5);
18874 return "vclgd";
18877 static const HChar *
18878 s390_irgen_VFI(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18880 s390_insn_assert("vfi",
18881 (m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4)));
18883 switch (m3) {
18884 case 2: s390_vector_fp_convert(Iop_RoundF32toInt, Ity_F32, Ity_F32, True,
18885 v1, v2, m3, m4, m5); break;
18886 case 3: s390_vector_fp_convert(Iop_RoundF64toInt, Ity_F64, Ity_F64, True,
18887 v1, v2, m3, m4, m5); break;
18888 case 4: s390_vector_fp_convert(Iop_RoundF128toInt, Ity_F128, Ity_F128, True,
18889 v1, v2, m3, m4, m5); break;
18892 return "vfi";
18895 static const HChar *
18896 s390_irgen_VFLL(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18898 s390_insn_assert("vfll", m3 == 2 || (s390_host_has_vxe && m3 == 3));
18900 if (m3 == 2)
18901 s390_vector_fp_convert(Iop_F32toF64, Ity_F32, Ity_F64, False,
18902 v1, v2, m3, m4, m5);
18903 else
18904 s390_vector_fp_convert(Iop_F64toF128, Ity_F64, Ity_F128, False,
18905 v1, v2, m3, m4, m5);
18907 return "vfll";
18910 static const HChar *
18911 s390_irgen_VFLR(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18913 s390_insn_assert("vflr", m3 == 3 || (s390_host_has_vxe && m3 == 4));
18915 if (m3 == 3)
18916 s390_vector_fp_convert(Iop_F64toF32, Ity_F64, Ity_F32, True,
18917 v1, v2, m3, m4, m5);
18918 else
18919 s390_vector_fp_convert(Iop_F128toF64, Ity_F128, Ity_F64, True,
18920 v1, v2, m3, m4, m5);
18922 return "vflr";
18925 static const HChar *
18926 s390_irgen_VFPSO(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5)
18928 s390_insn_assert("vfpso", m5 <= 2 &&
18929 (m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4)));
18931 Bool single = s390_vr_is_single_element_control_set(m4) || m3 == 4;
18932 IRType type = single ? s390_vr_get_ftype(m3) : Ity_V128;
18933 int idx = 2 * (m3 - 2) + (single ? 0 : 1);
18935 static const IROp negate_ops[] = {
18936 Iop_NegF32, Iop_Neg32Fx4,
18937 Iop_NegF64, Iop_Neg64Fx2,
18938 Iop_NegF128
18940 static const IROp abs_ops[] = {
18941 Iop_AbsF32, Iop_Abs32Fx4,
18942 Iop_AbsF64, Iop_Abs64Fx2,
18943 Iop_AbsF128
18946 if (m5 == 1) {
18947 /* Set sign to negative */
18948 put_vr(v1, type, 0,
18949 unop(negate_ops[idx],
18950 unop(abs_ops[idx], get_vr(v2, type, 0))));
18951 } else {
18952 /* m5 == 0: invert sign; m5 == 2: set sign to positive */
18953 const IROp *ops = m5 == 2 ? abs_ops : negate_ops;
18954 put_vr(v1, type, 0, unop(ops[idx], get_vr(v2, type, 0)));
18957 return "vfpso";
18960 static const HChar *
18961 s390x_vec_fp_binary_op(const HChar* mnm, const IROp ops[],
18962 UChar v1, UChar v2, UChar v3,
18963 UChar m4, UChar m5)
18965 s390_insn_assert(mnm, (m5 & 7) == 0 &&
18966 (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4)));
18968 int idx = 2 * (m4 - 2);
18970 if (m4 == 4 || s390_vr_is_single_element_control_set(m5)) {
18971 IRType type = s390_vr_get_ftype(m4);
18972 put_vr(v1, type, 0,
18973 triop(ops[idx], get_bfp_rounding_mode_from_fpc(),
18974 get_vr(v2, type, 0), get_vr(v3, type, 0)));
18975 } else {
18976 put_vr_qw(v1, triop(ops[idx + 1], get_bfp_rounding_mode_from_fpc(),
18977 get_vr_qw(v2), get_vr_qw(v3)));
18980 return mnm;
18983 static const HChar *
18984 s390x_vec_fp_unary_op(const HChar* mnm, const IROp ops[],
18985 UChar v1, UChar v2, UChar m3, UChar m4)
18987 s390_insn_assert(mnm, (m4 & 7) == 0 &&
18988 (m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4)));
18990 int idx = 2 * (m3 - 2);
18992 if (m3 == 4 || s390_vr_is_single_element_control_set(m4)) {
18993 IRType type = s390_vr_get_ftype(m3);
18994 put_vr(v1, type, 0,
18995 binop(ops[idx], get_bfp_rounding_mode_from_fpc(),
18996 get_vr(v2, type, 0)));
18998 else {
18999 put_vr_qw(v1, binop(ops[idx + 1], get_bfp_rounding_mode_from_fpc(),
19000 get_vr_qw(v2)));
19003 return mnm;
19007 static const HChar *
19008 s390_vector_fp_mulAddOrSub(UChar v1, UChar v2, UChar v3, UChar v4,
19009 UChar m5, UChar m6,
19010 const HChar* mnm, const IROp single_ops[],
19011 Bool negate)
19013 s390_insn_assert(mnm, m6 == 3 || (s390_host_has_vxe && m6 >= 2 && m6 <= 4));
19015 static const IROp negate_ops[] = { Iop_NegF32, Iop_NegF64, Iop_NegF128 };
19016 IRType type = s390_vr_get_ftype(m6);
19017 Bool single = s390_vr_is_single_element_control_set(m5) || m6 == 4;
19018 UChar n_elem = single ? 1 : s390_vr_get_n_elem(m6);
19019 IRTemp irrm_temp = newTemp(Ity_I32);
19020 assign(irrm_temp, get_bfp_rounding_mode_from_fpc());
19021 IRExpr* irrm = mkexpr(irrm_temp);
19023 for (UChar idx = 0; idx < n_elem; idx++) {
19024 IRExpr* result = qop(single_ops[m6 - 2],
19025 irrm,
19026 get_vr(v2, type, idx),
19027 get_vr(v3, type, idx),
19028 get_vr(v4, type, idx));
19029 put_vr(v1, type, idx, negate ? unop(negate_ops[m6 - 2], result) : result);
19031 return mnm;
19034 static const HChar *
19035 s390_irgen_VFA(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
19037 static const IROp vfa_ops[] = {
19038 Iop_AddF32, Iop_Add32Fx4,
19039 Iop_AddF64, Iop_Add64Fx2,
19040 Iop_AddF128,
19042 return s390x_vec_fp_binary_op("vfa", vfa_ops, v1, v2, v3, m4, m5);
19045 static const HChar *
19046 s390_irgen_VFS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
19048 static const IROp vfs_ops[] = {
19049 Iop_SubF32, Iop_Sub32Fx4,
19050 Iop_SubF64, Iop_Sub64Fx2,
19051 Iop_SubF128,
19053 return s390x_vec_fp_binary_op("vfs", vfs_ops, v1, v2, v3, m4, m5);
19056 static const HChar *
19057 s390_irgen_VFM(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
19059 static const IROp vfm_ops[] = {
19060 Iop_MulF32, Iop_Mul32Fx4,
19061 Iop_MulF64, Iop_Mul64Fx2,
19062 Iop_MulF128,
19064 return s390x_vec_fp_binary_op("vfm", vfm_ops, v1, v2, v3, m4, m5);
19067 static const HChar *
19068 s390_irgen_VFD(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
19070 static const IROp vfd_ops[] = {
19071 Iop_DivF32, Iop_Div32Fx4,
19072 Iop_DivF64, Iop_Div64Fx2,
19073 Iop_DivF128,
19075 return s390x_vec_fp_binary_op("vfd", vfd_ops, v1, v2, v3, m4, m5);
19078 static const HChar *
19079 s390_irgen_VFSQ(UChar v1, UChar v2, UChar m3, UChar m4)
19081 static const IROp vfsq_ops[] = {
19082 Iop_SqrtF32, Iop_Sqrt32Fx4,
19083 Iop_SqrtF64, Iop_Sqrt64Fx2,
19084 Iop_SqrtF128
19086 return s390x_vec_fp_unary_op("vfsq", vfsq_ops, v1, v2, m3, m4);
19089 static const IROp FMA_single_ops[] = {
19090 Iop_MAddF32, Iop_MAddF64, Iop_MAddF128
19093 static const HChar *
19094 s390_irgen_VFMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
19096 return s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6,
19097 "vfma", FMA_single_ops, False);
19100 static const HChar *
19101 s390_irgen_VFNMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
19103 return s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6,
19104 "vfnma", FMA_single_ops, True);
19107 static const IROp FMS_single_ops[] = {
19108 Iop_MSubF32, Iop_MSubF64, Iop_MSubF128
19111 static const HChar *
19112 s390_irgen_VFMS(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
19114 return s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6,
19115 "vfms", FMS_single_ops, False);
19118 static const HChar *
19119 s390_irgen_VFNMS(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6)
19121 return s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6,
19122 "vfnms", FMS_single_ops, True);
19125 static const HChar *
19126 s390_irgen_WFC(UChar v1, UChar v2, UChar m3, UChar m4)
19128 s390_insn_assert("wfc", m4 == 0 &&
19129 (m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4)));
19131 static const IROp ops[] = { Iop_CmpF32, Iop_CmpF64, Iop_CmpF128 };
19132 IRType type = s390_vr_get_ftype(m3);
19134 IRTemp cc_vex = newTemp(Ity_I32);
19135 assign(cc_vex, binop(ops[m3 - 2], get_vr(v1, type, 0), get_vr(v2, type, 0)));
19137 IRTemp cc_s390 = newTemp(Ity_I32);
19138 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
19139 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
19141 return "wfc";
19144 static const HChar *
19145 s390_irgen_WFK(UChar v1, UChar v2, UChar m3, UChar m4)
19147 s390_irgen_WFC(v1, v2, m3, m4);
19149 return "wfk";
19152 static const HChar *
19153 s390_irgen_VFCx(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6,
19154 const HChar *mnem, IRCmpFResult cmp, Bool equal_ok,
19155 IROp cmp32, IROp cmp64)
19157 s390_insn_assert(mnem, (m5 & 3) == 0 && (m6 & 14) == 0 &&
19158 (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4)));
19160 Bool single = s390_vr_is_single_element_control_set(m5) || m4 == 4;
19162 if (single) {
19163 static const IROp ops[] = { Iop_CmpF32, Iop_CmpF64, Iop_CmpF128 };
19164 IRType type = s390_vr_get_ftype(m4);
19165 IRTemp result = newTemp(Ity_I32);
19166 IRTemp cond = newTemp(Ity_I1);
19168 assign(result, binop(ops[m4 - 2],
19169 get_vr(v2, type, 0), get_vr(v3, type, 0)));
19170 if (equal_ok) {
19171 assign(cond,
19172 binop(Iop_Or1,
19173 binop(Iop_CmpEQ32, mkexpr(result), mkU32(cmp)),
19174 binop(Iop_CmpEQ32, mkexpr(result), mkU32(Ircr_EQ))));
19175 } else {
19176 assign(cond, binop(Iop_CmpEQ32, mkexpr(result), mkU32(cmp)));
19178 put_vr_qw(v1, mkite(mkexpr(cond),
19179 mkV128(0xffff),
19180 mkV128(0)));
19181 if (s390_vr_is_cs_set(m6)) {
19182 IRTemp cc = newTemp(Ity_I64);
19183 assign(cc, mkite(mkexpr(cond), mkU64(0), mkU64(3)));
19184 s390_cc_set(cc);
19186 } else {
19187 IRTemp result = newTemp(Ity_V128);
19189 assign(result, binop(m4 == 2 ? cmp32 : cmp64,
19190 get_vr_qw(v2), get_vr_qw(v3)));
19191 put_vr_qw(v1, mkexpr(result));
19192 if (s390_vr_is_cs_set(m6)) {
19193 IRTemp cc = newTemp(Ity_I64);
19194 assign(cc,
19195 mkite(binop(Iop_CmpEQ64,
19196 binop(Iop_And64,
19197 unop(Iop_V128to64, mkexpr(result)),
19198 unop(Iop_V128HIto64, mkexpr(result))),
19199 mkU64(-1ULL)),
19200 mkU64(0), /* all comparison results are true */
19201 mkite(binop(Iop_CmpEQ64,
19202 binop(Iop_Or64,
19203 unop(Iop_V128to64, mkexpr(result)),
19204 unop(Iop_V128HIto64, mkexpr(result))),
19205 mkU64(0)),
19206 mkU64(3), /* all false */
19207 mkU64(1)))); /* mixed true/false */
19208 s390_cc_set(cc);
19212 return mnem;
19215 static const HChar *
19216 s390_irgen_VFCE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6)
19218 return s390_irgen_VFCx(v1, v2, v3, m4, m5, m6, "vfce", Ircr_EQ,
19219 False, Iop_CmpEQ32Fx4, Iop_CmpEQ64Fx2);
19222 static const HChar *
19223 s390_irgen_VFCH(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6)
19225 /* Swap arguments and compare "low" instead. */
19226 return s390_irgen_VFCx(v1, v3, v2, m4, m5, m6, "vfch", Ircr_LT,
19227 False, Iop_CmpLT32Fx4, Iop_CmpLT64Fx2);
19230 static const HChar *
19231 s390_irgen_VFCHE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6)
19233 /* Swap arguments and compare "low or equal" instead. */
19234 return s390_irgen_VFCx(v1, v3, v2, m4, m5, m6, "vfche", Ircr_LT,
19235 True, Iop_CmpLE32Fx4, Iop_CmpLE64Fx2);
19238 static const HChar *
19239 s390_irgen_VFTCI(UChar v1, UChar v2, UShort i3, UChar m4, UChar m5)
19241 s390_insn_assert("vftci",
19242 (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4)));
19244 Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
19246 IRDirty* d;
19247 IRTemp cc = newTemp(Ity_I64);
19249 s390x_vec_op_details_t details = { .serialized = 0ULL };
19250 details.op = S390_VEC_OP_VFTCI;
19251 details.v1 = v1;
19252 details.v2 = v2;
19253 details.i3 = i3;
19254 details.m4 = m4;
19255 details.m5 = m5;
19257 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
19258 &s390x_dirtyhelper_vec_op,
19259 mkIRExprVec_2(IRExpr_GSPTR(),
19260 mkU64(details.serialized)));
19262 const UChar elementSize = isSingleElementOp ?
19263 sizeofIRType(s390_vr_get_ftype(m4)) : sizeof(V128);
19264 d->nFxState = 2;
19265 vex_bzero(&d->fxState, sizeof(d->fxState));
19266 d->fxState[0].fx = Ifx_Read;
19267 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
19268 d->fxState[0].size = elementSize;
19269 d->fxState[1].fx = Ifx_Write;
19270 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
19271 d->fxState[1].size = sizeof(V128);
19273 stmt(IRStmt_Dirty(d));
19274 s390_cc_set(cc);
19276 return "vftci";
19279 static const HChar *
19280 s390_irgen_VFMIN(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6)
19282 s390_insn_assert("vfmin",
19283 (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4)));
19285 Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
19286 IRDirty* d;
19288 s390x_vec_op_details_t details = { .serialized = 0ULL };
19289 details.op = S390_VEC_OP_VFMIN;
19290 details.v1 = v1;
19291 details.v2 = v2;
19292 details.v3 = v3;
19293 details.m4 = m4;
19294 details.m5 = m5;
19295 details.m6 = m6;
19297 d = unsafeIRDirty_0_N(0, "s390x_dirtyhelper_vec_op",
19298 &s390x_dirtyhelper_vec_op,
19299 mkIRExprVec_2(IRExpr_GSPTR(),
19300 mkU64(details.serialized)));
19302 const UChar elementSize = isSingleElementOp ?
19303 sizeofIRType(s390_vr_get_ftype(m4)) : sizeof(V128);
19304 d->nFxState = 3;
19305 vex_bzero(&d->fxState, sizeof(d->fxState));
19306 d->fxState[0].fx = Ifx_Read;
19307 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
19308 d->fxState[0].size = elementSize;
19309 d->fxState[1].fx = Ifx_Read;
19310 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
19311 d->fxState[1].size = elementSize;
19312 d->fxState[2].fx = Ifx_Write;
19313 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
19314 d->fxState[2].size = sizeof(V128);
19316 stmt(IRStmt_Dirty(d));
19317 return "vfmin";
19320 static const HChar *
19321 s390_irgen_VFMAX(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6)
19323 s390_insn_assert("vfmax",
19324 (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4)));
19326 Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5);
19327 IRDirty* d;
19329 s390x_vec_op_details_t details = { .serialized = 0ULL };
19330 details.op = S390_VEC_OP_VFMAX;
19331 details.v1 = v1;
19332 details.v2 = v2;
19333 details.v3 = v3;
19334 details.m4 = m4;
19335 details.m5 = m5;
19336 details.m6 = m6;
19338 d = unsafeIRDirty_0_N(0, "s390x_dirtyhelper_vec_op",
19339 &s390x_dirtyhelper_vec_op,
19340 mkIRExprVec_2(IRExpr_GSPTR(),
19341 mkU64(details.serialized)));
19343 const UChar elementSize = isSingleElementOp ?
19344 sizeofIRType(s390_vr_get_ftype(m4)) : sizeof(V128);
19345 d->nFxState = 3;
19346 vex_bzero(&d->fxState, sizeof(d->fxState));
19347 d->fxState[0].fx = Ifx_Read;
19348 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
19349 d->fxState[0].size = elementSize;
19350 d->fxState[1].fx = Ifx_Read;
19351 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
19352 d->fxState[1].size = elementSize;
19353 d->fxState[2].fx = Ifx_Write;
19354 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
19355 d->fxState[2].size = sizeof(V128);
19357 stmt(IRStmt_Dirty(d));
19358 return "vfmax";
19361 static const HChar *
19362 s390_irgen_VBPERM(UChar v1, UChar v2, UChar v3)
19364 IRDirty* d;
19365 IRTemp cc = newTemp(Ity_I64);
19367 s390x_vec_op_details_t details = { .serialized = 0ULL };
19368 details.op = S390_VEC_OP_VBPERM;
19369 details.v1 = v1;
19370 details.v2 = v2;
19371 details.v3 = v3;
19372 details.m4 = 0;
19373 details.m5 = 0;
19374 details.m6 = 0;
19376 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
19377 &s390x_dirtyhelper_vec_op,
19378 mkIRExprVec_2(IRExpr_GSPTR(),
19379 mkU64(details.serialized)));
19381 d->nFxState = 3;
19382 vex_bzero(&d->fxState, sizeof(d->fxState));
19383 d->fxState[0].fx = Ifx_Read;
19384 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
19385 d->fxState[0].size = sizeof(V128);
19386 d->fxState[1].fx = Ifx_Read;
19387 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
19388 d->fxState[1].size = sizeof(V128);
19389 d->fxState[2].fx = Ifx_Write;
19390 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
19391 d->fxState[2].size = sizeof(V128);
19393 stmt(IRStmt_Dirty(d));
19394 s390_cc_set(cc);
19395 return "vbperm";
19398 static const HChar *
19399 s390_irgen_SELR(UChar r3, UChar m4, UChar r1, UChar r2)
19401 IRExpr* cond = binop(Iop_CmpNE32, s390_call_calculate_cond(m4), mkU32(0));
19402 put_gpr_w1(r1, mkite(cond, get_gpr_w1(r2), get_gpr_w1(r3)));
19403 return "selr";
19406 static const HChar *
19407 s390_irgen_SELGR(UChar r3, UChar m4, UChar r1, UChar r2)
19409 IRExpr* cond = binop(Iop_CmpNE32, s390_call_calculate_cond(m4), mkU32(0));
19410 put_gpr_dw0(r1, mkite(cond, get_gpr_dw0(r2), get_gpr_dw0(r3)));
19411 return "selgr";
19414 static const HChar *
19415 s390_irgen_SELFHR(UChar r3, UChar m4, UChar r1, UChar r2)
19417 IRExpr* cond = binop(Iop_CmpNE32, s390_call_calculate_cond(m4), mkU32(0));
19418 put_gpr_w0(r1, mkite(cond, get_gpr_w0(r2), get_gpr_w0(r3)));
19419 return "selfhr";
19422 /* Helper function that byte-swaps each element of its V128 input operand */
19423 static IRExpr *
19424 s390_byteswap_elements(IRExpr* v, UChar m)
19426 static const ULong perm[4][2] = {
19427 { 0x0100030205040706, 0x09080b0a0d0c0f0e }, /* 2-byte elements */
19428 { 0x0302010007060504, 0x0b0a09080f0e0d0c }, /* 4-byte elements */
19429 { 0x0706050403020100, 0x0f0e0d0c0b0a0908 }, /* 8-byte elements */
19430 { 0x0f0e0d0c0b0a0908, 0x0706050403020100 }, /* whole vector */
19432 return binop(Iop_Perm8x16, v, binop(Iop_64HLtoV128,
19433 mkU64(perm[m - 1][0]),
19434 mkU64(perm[m - 1][1])));
19437 /* Helper function that reverses the elements of its V128 input operand */
19438 static IRExpr *
19439 s390_reverse_elements(IRExpr* v, UChar m)
19441 static const ULong perm[3][2] = {
19442 { 0x0e0f0c0d0a0b0809, 0x0607040502030001 }, /* 2-byte elements */
19443 { 0x0c0d0e0f08090a0b, 0x0405060700010203 }, /* 4-byte elements */
19444 { 0x08090a0b0c0d0e0f, 0x0001020304050607 }, /* 8-byte elements */
19446 return binop(Iop_Perm8x16, v, binop(Iop_64HLtoV128,
19447 mkU64(perm[m - 1][0]),
19448 mkU64(perm[m - 1][1])));
19451 static const HChar *
19452 s390_irgen_VLBR(UChar v1, IRTemp op2addr, UChar m3)
19454 s390_insn_assert("vlbr", m3 >= 1 && m3 <= 4);
19455 put_vr_qw(v1, s390_byteswap_elements(load(Ity_V128, mkexpr(op2addr)), m3));
19456 return "vlbr";
19459 static const HChar *
19460 s390_irgen_VSTBR(UChar v1, IRTemp op2addr, UChar m3)
19462 s390_insn_assert("vstbr", m3 >= 1 && m3 <= 4);
19463 store(mkexpr(op2addr), s390_byteswap_elements(get_vr_qw(v1), m3));
19464 return "vstbr";
19467 static const HChar *
19468 s390_irgen_VLER(UChar v1, IRTemp op2addr, UChar m3)
19470 s390_insn_assert("vler", m3 >= 1 && m3 <= 3);
19471 put_vr_qw(v1, s390_reverse_elements(load(Ity_V128, mkexpr(op2addr)), m3));
19472 return "vler";
19475 static const HChar *
19476 s390_irgen_VSTER(UChar v1, IRTemp op2addr, UChar m3)
19478 s390_insn_assert("vstbr", m3 >= 1 && m3 <= 4);
19479 store(mkexpr(op2addr), s390_reverse_elements(get_vr_qw(v1), m3));
19480 return "vstbr";
19483 /* Helper function that combines its two V128 operands by replacing element 'to'
19484 in 'a' by byte-swapped element 'from' in 'b' */
19485 static IRExpr *
19486 s390_insert_byteswapped(IRExpr* a, IRExpr* b, UChar m, UChar to, UChar from)
19488 UInt elem_size = 1U << m;
19489 UInt start = elem_size * to;
19490 UInt end = start + elem_size - 1;
19491 UInt offs = end + elem_size * from + 16;
19492 UInt i;
19494 ULong permH = 0;
19495 for (i = 0; i < 8; i++) {
19496 permH = (permH << 8) | (i >= start && i <= end ? offs - i : i);
19498 ULong permL = 0;
19499 for (i = 8; i < 16; i++) {
19500 permL = (permL << 8) | (i >= start && i <= end ? offs - i : i);
19502 return triop(Iop_Perm8x16x2, a, b, binop(Iop_64HLtoV128,
19503 mkU64(permH), mkU64(permL)));
19506 static const HChar *
19507 s390_irgen_VLEBRH(UChar v1, IRTemp op2addr, UChar m3)
19509 s390_insn_assert("vlebrh", m3 <= 7);
19510 IRTemp op2 = newTemp(Ity_I16);
19511 assign(op2, load(Ity_I16, mkexpr(op2addr)));
19512 put_vr(v1, Ity_I16, m3, binop(Iop_Or16,
19513 binop(Iop_Shl16, mkexpr(op2), mkU8(8)),
19514 binop(Iop_Shr16, mkexpr(op2), mkU8(8))));
19515 return "vlebrh";
19518 static const HChar *
19519 s390_irgen_VLEBRF(UChar v1, IRTemp op2addr, UChar m3)
19521 s390_insn_assert("vlebrf", m3 <= 3);
19522 IRTemp op1 = newTemp(Ity_V128);
19523 assign(op1, get_vr_qw(v1));
19524 IRTemp op2 = newTemp(Ity_I64);
19525 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
19526 IRExpr* b = binop(Iop_64HLtoV128, mkexpr(op2), mkexpr(op2));
19527 put_vr_qw(v1, s390_insert_byteswapped(mkexpr(op1), b, 2, m3, 3));
19528 return "vlebrf";
19531 static const HChar *
19532 s390_irgen_VLEBRG(UChar v1, IRTemp op2addr, UChar m3)
19534 s390_insn_assert("vlebrg", m3 <= 1);
19535 IRTemp op1 = newTemp(Ity_V128);
19536 assign(op1, get_vr_qw(v1));
19537 IRTemp op2 = newTemp(Ity_I64);
19538 assign(op2, load(Ity_I64, mkexpr(op2addr)));
19539 IRExpr* b = binop(Iop_64HLtoV128, mkexpr(op2), mkexpr(op2));
19540 put_vr_qw(v1, s390_insert_byteswapped(mkexpr(op1), b, 3, m3, 1));
19541 return "vlebrg";
19544 static const HChar *
19545 s390_irgen_VLBRREP(UChar v1, IRTemp op2addr, UChar m3)
19547 s390_insn_assert("vlbrrep", m3 >= 1 && m3 <= 3);
19548 static const ULong perm[3] = {
19549 0x0f0e0f0e0f0e0f0e, /* 2-byte element */
19550 0x0f0e0d0c0f0e0d0c, /* 4-byte element */
19551 0x0f0e0d0c0b0a0908 /* 8-byte element */
19553 IRExpr* permHL = mkU64(perm[m3 - 1]);
19554 IRTemp op2 = newTemp(Ity_I64);
19555 if (m3 == 3)
19556 assign(op2, load(Ity_I64, mkexpr(op2addr)));
19557 else
19558 assign(op2, unop(m3 == 2 ? Iop_32Uto64 : Iop_16Uto64,
19559 load(s390_vr_get_type(m3), mkexpr(op2addr))));
19560 put_vr_qw(v1, binop(Iop_Perm8x16,
19561 binop(Iop_64HLtoV128, mkexpr(op2), mkexpr(op2)),
19562 binop(Iop_64HLtoV128, permHL, permHL)));
19563 return "vlbrrep";
19566 static const HChar *
19567 s390_irgen_VLLEBRZ(UChar v1, IRTemp op2addr, UChar m3)
19569 s390_insn_assert("vllebrz", (m3 >= 1 && m3 <= 3) || m3 == 6);
19570 static const ULong perm[6] = {
19571 0x0000000000000f0e, /* 2-byte element */
19572 0x000000000f0e0d0c, /* 4-byte element */
19573 0x0f0e0d0c0b0a0908, /* 8-byte element */
19574 0, /* invalid (4) */
19575 0, /* invalid (5) */
19576 0x0f0e0d0c00000000, /* 4-byte element, left-aligned */
19578 IRExpr* permH = mkU64(perm[m3 - 1]);
19579 IRTemp op2 = newTemp(Ity_I64);
19580 if (m3 == 3)
19581 assign(op2, load(Ity_I64, mkexpr(op2addr)));
19582 else
19583 assign(op2, unop((m3 & 3) == 2 ? Iop_32Uto64 : Iop_16Uto64,
19584 load(s390_vr_get_type(m3 & 3), mkexpr(op2addr))));
19585 put_vr_qw(v1, binop(Iop_Perm8x16,
19586 binop(Iop_64HLtoV128, mkU64(0), mkexpr(op2)),
19587 binop(Iop_64HLtoV128, permH, mkU64(0))));
19588 return "vllebrz";
19591 static const HChar *
19592 s390_irgen_VSTEBRH(UChar v1, IRTemp op2addr, UChar m3)
19594 s390_insn_assert("vstebrh", m3 <= 7);
19595 IRTemp op1 = newTemp(Ity_I16);
19596 assign(op1, get_vr(v1, Ity_I16, m3));
19597 store(mkexpr(op2addr), binop(Iop_Or16,
19598 binop(Iop_Shl16, mkexpr(op1), mkU8(8)),
19599 binop(Iop_Shr16, mkexpr(op1), mkU8(8))));
19600 return "vstebrh";
19603 static const HChar *
19604 s390_irgen_VSTEBRF(UChar v1, IRTemp op2addr, UChar m3)
19606 s390_insn_assert("vstebrf", m3 <= 3);
19607 IRTemp op1 = newTemp(Ity_V128);
19608 assign(op1, get_vr_qw(v1));
19609 IRExpr* b = s390_insert_byteswapped(mkexpr(op1), mkexpr(op1), 2, 3, m3);
19610 store(mkexpr(op2addr), unop(Iop_V128to32, b));
19611 return "vstebrf";
19614 static const HChar *
19615 s390_irgen_VSTEBRG(UChar v1, IRTemp op2addr, UChar m3)
19617 s390_insn_assert("vstebrg", m3 <= 1);
19618 IRTemp op1 = newTemp(Ity_V128);
19619 assign(op1, get_vr_qw(v1));
19620 IRExpr* b = s390_insert_byteswapped(mkexpr(op1), mkexpr(op1), 3, 1, m3);
19621 store(mkexpr(op2addr), unop(Iop_V128to64, b));
19622 return "vstebrg";
19625 static const HChar *
19626 s390_irgen_VCxx(const HChar *mnem, s390x_vec_op_details_t details,
19627 UShort v2_offs, UShort v2_size)
19629 s390_insn_assert(mnem, s390_host_has_nnpa);
19631 IRDirty* d = unsafeIRDirty_0_N(0, "s390x_dirtyhelper_vec_op",
19632 &s390x_dirtyhelper_vec_op,
19633 mkIRExprVec_2(IRExpr_GSPTR(),
19634 mkU64(details.serialized)));
19635 d->nFxState = 2;
19636 vex_bzero(&d->fxState, sizeof(d->fxState));
19637 d->fxState[0].fx = Ifx_Read;
19638 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0)
19639 + details.v2 * sizeof(V128) + v2_offs;
19640 d->fxState[0].size = v2_size;
19641 d->fxState[1].fx = Ifx_Write;
19642 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0)
19643 + details.v1 * sizeof(V128);
19644 d->fxState[1].size = sizeof(V128);
19646 stmt(IRStmt_Dirty(d));
19647 return mnem;
19650 static const HChar *
19651 s390_irgen_VCNF(UChar v1, UChar v2, UChar m3, UChar m4)
19653 s390x_vec_op_details_t details = { .serialized = 0ULL };
19654 details.op = S390_VEC_OP_VCNF;
19655 details.v1 = v1;
19656 details.v2 = v2;
19657 details.m3 = m3;
19658 details.m4 = m4;
19659 return s390_irgen_VCxx("vcnf", details, 0, sizeof(V128));
19662 static const HChar *
19663 s390_irgen_VCLFNH(UChar v1, UChar v2, UChar m3, UChar m4)
19665 s390x_vec_op_details_t details = { .serialized = 0ULL };
19666 details.op = S390_VEC_OP_VCLFNH;
19667 details.v1 = v1;
19668 details.v2 = v2;
19669 details.m3 = m3;
19670 details.m4 = m4;
19671 return s390_irgen_VCxx("vclfnh", details, 0, sizeof(V128) / 2);
19674 static const HChar *
19675 s390_irgen_VCFN(UChar v1, UChar v2, UChar m3, UChar m4)
19677 s390x_vec_op_details_t details = { .serialized = 0ULL };
19678 details.op = S390_VEC_OP_VCFN;
19679 details.v1 = v1;
19680 details.v2 = v2;
19681 details.m3 = m3;
19682 details.m4 = m4;
19683 return s390_irgen_VCxx("vcfn", details, 0, sizeof(V128));
19686 static const HChar *
19687 s390_irgen_VCLFNL(UChar v1, UChar v2, UChar m3, UChar m4)
19689 s390x_vec_op_details_t details = { .serialized = 0ULL };
19690 details.op = S390_VEC_OP_VCLFNL;
19691 details.v1 = v1;
19692 details.v2 = v2;
19693 details.m3 = m3;
19694 details.m4 = m4;
19695 return s390_irgen_VCxx("vclfnl", details, sizeof(V128) / 2,
19696 sizeof(V128) / 2);
19699 static const HChar *
19700 s390_irgen_VCRNF(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
19702 s390_insn_assert("vcrnf", s390_host_has_nnpa);
19704 s390x_vec_op_details_t details = { .serialized = 0ULL };
19705 details.op = S390_VEC_OP_VCRNF;
19706 details.v1 = v1;
19707 details.v2 = v2;
19708 details.v3 = v3;
19709 details.m4 = m4;
19710 details.m5 = m5;
19711 details.m6 = 0;
19712 IRDirty* d = unsafeIRDirty_0_N(0, "s390x_dirtyhelper_vec_op",
19713 &s390x_dirtyhelper_vec_op,
19714 mkIRExprVec_2(IRExpr_GSPTR(),
19715 mkU64(details.serialized)));
19716 d->nFxState = 3;
19717 vex_bzero(&d->fxState, sizeof(d->fxState));
19718 d->fxState[0].fx = Ifx_Read;
19719 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128);
19720 d->fxState[0].size = sizeof(V128);
19721 d->fxState[1].fx = Ifx_Read;
19722 d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128);
19723 d->fxState[1].size = sizeof(V128);
19724 d->fxState[2].fx = Ifx_Write;
19725 d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
19726 d->fxState[2].size = sizeof(V128);
19728 stmt(IRStmt_Dirty(d));
19729 return "vcrnf";
19732 static const HChar *
19733 s390_irgen_NNPA(void)
19735 s390_insn_assert("nnpa", s390_host_has_nnpa);
19736 extension(S390_EXT_NNPA, 0);
19737 return "nnpa";
19740 static const HChar *
19741 s390_irgen_KM(UChar r1, UChar r2)
19743 s390_insn_assert("km", r1 != 0 && r1 % 2 == 0 && r2 != 0 && r2 % 2 == 0);
19744 extension(S390_EXT_KM, r1 | (r2 << 4));
19745 return "km";
19748 static const HChar *
19749 s390_irgen_KMC(UChar r1, UChar r2)
19751 s390_insn_assert("kmc", r1 != 0 && r1 % 2 == 0 && r2 != 0 && r2 % 2 == 0);
19752 extension(S390_EXT_KMC, r1 | (r2 << 4));
19753 return "kmc";
19756 static const HChar *
19757 s390_irgen_KIMD(UChar r1, UChar r2)
19759 /* r1 is reserved */
19760 s390_insn_assert("kimd", r2 != 0 && r2 % 2 == 0);
19761 extension(S390_EXT_KIMD, r1 | (r2 << 4));
19762 return "kimd";
19765 static const HChar *
19766 s390_irgen_KLMD(UChar r1, UChar r2)
19768 /* r1 is only used by some functions */
19769 s390_insn_assert("klmd", r2 != 0 && r2 % 2 == 0);
19770 extension(S390_EXT_KLMD, r1 | (r2 << 4));
19771 return "klmd";
19774 static const HChar *
19775 s390_irgen_KMAC(UChar r1, UChar r2)
19777 /* r1 is ignored */
19778 s390_insn_assert("kmac", r2 != 0 && r2 % 2 == 0);
19779 extension(S390_EXT_KMAC, r1 | (r2 << 4));
19780 return "kmac";
19783 static const HChar *
19784 s390_irgen_PCC(void)
19786 extension(S390_EXT_PCC, 0);
19787 return "pcc";
19790 static const HChar *
19791 s390_irgen_KMCTR(UChar r3, UChar r1, UChar r2)
19793 s390_insn_assert("kmctr", r1 % 2 == 0 && r1 != 0 && r2 % 2 == 0 && r2 != 0 &&
19794 r3 % 2 == 0 && r3 != 0);
19795 extension(S390_EXT_KMCTR, r1 | (r2 << 4) | (r3 << 8));
19796 return "kmctr";
19799 static const HChar *
19800 s390_irgen_KMO(UChar r1, UChar r2)
19802 s390_insn_assert("kmo", r1 != 0 && r1 % 2 == 0 && r2 != 0 && r2 % 2 == 0);
19803 extension(S390_EXT_KMO, r1 | (r2 << 4));
19804 return "kmo";
19807 static const HChar *
19808 s390_irgen_KMF(UChar r1, UChar r2)
19810 s390_insn_assert("kmf", r1 != 0 && r1 % 2 == 0 && r2 != 0 && r2 % 2 == 0);
19811 extension(S390_EXT_KMF, r1 | (r2 << 4));
19812 return "kmf";
19815 static const HChar *
19816 s390_irgen_KMA(UChar r3, UChar r1, UChar r2)
19818 s390_insn_assert("kma", r1 % 2 == 0 && r1 != 0 && r2 % 2 == 0 && r2 != 0 &&
19819 r3 % 2 == 0 && r3 != 0);
19820 extension(S390_EXT_KMA, r1 | (r2 << 4) | (r3 << 8));
19821 return "kma";
19824 static const HChar *
19825 s390_irgen_KDSA(UChar r1, UChar r2)
19827 /* r1 is reserved */
19828 s390_insn_assert("kdsa", r2 != 0 && r2 % 2 == 0);
19829 extension(S390_EXT_KDSA, r1 | (r2 << 4));
19830 return "kdsa";
19833 /* New insns are added here.
19834 If an insn is contingent on a facility being installed also
19835 check whether the list of supported facilities in function
19836 s390x_dirtyhelper_STFLE needs updating */
19838 /*------------------------------------------------------------*/
19839 /*--- Build IR for special instructions ---*/
19840 /*------------------------------------------------------------*/
19842 static void
19843 s390_irgen_client_request(void)
19845 if (0)
19846 vex_printf("%%R3 = client_request ( %%R2 )\n");
19848 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
19849 + S390_SPECIAL_OP_SIZE;
19851 dis_res->jk_StopHere = Ijk_ClientReq;
19852 dis_res->whatNext = Dis_StopHere;
19854 put_IA(mkaddr_expr(next));
19857 static void
19858 s390_irgen_guest_NRADDR(void)
19860 if (0)
19861 vex_printf("%%R3 = guest_NRADDR\n");
19863 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
19866 static void
19867 s390_irgen_call_noredir(void)
19869 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
19870 + S390_SPECIAL_OP_SIZE;
19872 /* Continue after special op */
19873 put_gpr_dw0(14, mkaddr_expr(next));
19875 /* The address is in REG1, all parameters are in the right (guest) places */
19876 put_IA(get_gpr_dw0(1));
19878 dis_res->whatNext = Dis_StopHere;
19879 dis_res->jk_StopHere = Ijk_NoRedir;
19882 static s390_decode_t
19883 s390_decode_2byte_and_irgen(const UChar *bytes)
19885 UShort ovl = ((UShort)bytes[0] << 8) | (UShort)bytes[1];
19887 switch (ovl & 0xffff) {
19888 case 0x0101: /* PR */ goto unimplemented;
19889 case 0x0102: /* UPT */ goto unimplemented;
19890 case 0x0104: /* PTFF */ goto unimplemented;
19891 case 0x0107: /* SCKPF */ goto unimplemented;
19892 case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
19893 case 0x010b: /* TAM */ goto unimplemented;
19894 case 0x010c: /* SAM24 */ goto unimplemented;
19895 case 0x010d: /* SAM31 */ goto unimplemented;
19896 case 0x010e: /* SAM64 */ goto unimplemented;
19897 case 0x01ff: /* TRAP2 */ goto unimplemented;
19900 switch ((ovl & 0xff00) >> 8) {
19901 case 0x04: /* SPM */ goto unimplemented;
19902 case 0x05: /* BALR */ goto unimplemented;
19903 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, RR_r1(ovl), RR_r2(ovl));
19904 goto ok;
19905 case 0x07: s390_format_RR(s390_irgen_BCR, RR_r1(ovl), RR_r2(ovl));
19906 goto ok;
19907 case 0x0a: s390_format_I(s390_irgen_SVC, I_i(ovl)); goto ok;
19908 case 0x0b: /* BSM */ goto unimplemented;
19909 case 0x0c: /* BASSM */ goto unimplemented;
19910 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, RR_r1(ovl), RR_r2(ovl));
19911 goto ok;
19912 case 0x0e: s390_format_RR_RR(s390_irgen_MVCL, RR_r1(ovl), RR_r2(ovl));
19913 goto ok;
19914 case 0x0f: s390_format_RR_RR(s390_irgen_CLCL, RR_r1(ovl), RR_r2(ovl));
19915 goto ok;
19916 case 0x10: s390_format_RR_RR(s390_irgen_LPR, RR_r1(ovl), RR_r2(ovl));
19917 goto ok;
19918 case 0x11: s390_format_RR_RR(s390_irgen_LNR, RR_r1(ovl), RR_r2(ovl));
19919 goto ok;
19920 case 0x12: s390_format_RR_RR(s390_irgen_LTR, RR_r1(ovl), RR_r2(ovl));
19921 goto ok;
19922 case 0x13: s390_format_RR_RR(s390_irgen_LCR, RR_r1(ovl), RR_r2(ovl));
19923 goto ok;
19924 case 0x14: s390_format_RR_RR(s390_irgen_NR, RR_r1(ovl), RR_r2(ovl));
19925 goto ok;
19926 case 0x15: s390_format_RR_RR(s390_irgen_CLR, RR_r1(ovl), RR_r2(ovl));
19927 goto ok;
19928 case 0x16: s390_format_RR_RR(s390_irgen_OR, RR_r1(ovl), RR_r2(ovl));
19929 goto ok;
19930 case 0x17: s390_format_RR_RR(s390_irgen_XR, RR_r1(ovl), RR_r2(ovl));
19931 goto ok;
19932 case 0x18: s390_format_RR_RR(s390_irgen_LR, RR_r1(ovl), RR_r2(ovl));
19933 goto ok;
19934 case 0x19: s390_format_RR_RR(s390_irgen_CR, RR_r1(ovl), RR_r2(ovl));
19935 goto ok;
19936 case 0x1a: s390_format_RR_RR(s390_irgen_AR, RR_r1(ovl), RR_r2(ovl));
19937 goto ok;
19938 case 0x1b: s390_format_RR_RR(s390_irgen_SR, RR_r1(ovl), RR_r2(ovl));
19939 goto ok;
19940 case 0x1c: s390_format_RR_RR(s390_irgen_MR, RR_r1(ovl), RR_r2(ovl));
19941 goto ok;
19942 case 0x1d: s390_format_RR_RR(s390_irgen_DR, RR_r1(ovl), RR_r2(ovl));
19943 goto ok;
19944 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, RR_r1(ovl), RR_r2(ovl));
19945 goto ok;
19946 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, RR_r1(ovl), RR_r2(ovl));
19947 goto ok;
19948 case 0x20: /* LPDR */ goto unimplemented;
19949 case 0x21: /* LNDR */ goto unimplemented;
19950 case 0x22: /* LTDR */ goto unimplemented;
19951 case 0x23: /* LCDR */ goto unimplemented;
19952 case 0x24: /* HDR */ goto unimplemented;
19953 case 0x25: /* LDXR */ goto unimplemented;
19954 case 0x26: /* MXR */ goto unimplemented;
19955 case 0x27: /* MXDR */ goto unimplemented;
19956 case 0x28: s390_format_RR_FF(s390_irgen_LDR, RR_r1(ovl), RR_r2(ovl));
19957 goto ok;
19958 case 0x29: /* CDR */ goto unimplemented;
19959 case 0x2a: /* ADR */ goto unimplemented;
19960 case 0x2b: /* SDR */ goto unimplemented;
19961 case 0x2c: /* MDR */ goto unimplemented;
19962 case 0x2d: /* DDR */ goto unimplemented;
19963 case 0x2e: /* AWR */ goto unimplemented;
19964 case 0x2f: /* SWR */ goto unimplemented;
19965 case 0x30: /* LPER */ goto unimplemented;
19966 case 0x31: /* LNER */ goto unimplemented;
19967 case 0x32: /* LTER */ goto unimplemented;
19968 case 0x33: /* LCER */ goto unimplemented;
19969 case 0x34: /* HER */ goto unimplemented;
19970 case 0x35: /* LEDR */ goto unimplemented;
19971 case 0x36: /* AXR */ goto unimplemented;
19972 case 0x37: /* SXR */ goto unimplemented;
19973 case 0x38: s390_format_RR_FF(s390_irgen_LER, RR_r1(ovl), RR_r2(ovl));
19974 goto ok;
19975 case 0x39: /* CER */ goto unimplemented;
19976 case 0x3a: /* AER */ goto unimplemented;
19977 case 0x3b: /* SER */ goto unimplemented;
19978 case 0x3c: /* MDER */ goto unimplemented;
19979 case 0x3d: /* DER */ goto unimplemented;
19980 case 0x3e: /* AUR */ goto unimplemented;
19981 case 0x3f: /* SUR */ goto unimplemented;
19984 return S390_DECODE_UNKNOWN_INSN;
19987 return S390_DECODE_OK;
19989 unimplemented:
19990 return S390_DECODE_UNIMPLEMENTED_INSN;
19993 static s390_decode_t
19994 s390_decode_4byte_and_irgen(const UChar *bytes)
19996 UInt ovl = ((UInt)bytes[0] << 24) | ((UInt)bytes[1] << 16) |
19997 ((UInt)bytes[2] << 8) | (UInt)bytes[3];
19999 switch ((ovl & 0xff0f0000) >> 16) {
20000 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, RI_r1(ovl),
20001 RI_i2(ovl)); goto ok;
20002 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, RI_r1(ovl),
20003 RI_i2(ovl)); goto ok;
20004 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, RI_r1(ovl),
20005 RI_i2(ovl)); goto ok;
20006 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, RI_r1(ovl),
20007 RI_i2(ovl)); goto ok;
20008 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, RI_r1(ovl),
20009 RI_i2(ovl)); goto ok;
20010 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, RI_r1(ovl),
20011 RI_i2(ovl)); goto ok;
20012 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, RI_r1(ovl),
20013 RI_i2(ovl)); goto ok;
20014 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, RI_r1(ovl),
20015 RI_i2(ovl)); goto ok;
20016 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, RI_r1(ovl),
20017 RI_i2(ovl)); goto ok;
20018 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, RI_r1(ovl),
20019 RI_i2(ovl)); goto ok;
20020 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, RI_r1(ovl),
20021 RI_i2(ovl)); goto ok;
20022 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, RI_r1(ovl),
20023 RI_i2(ovl)); goto ok;
20024 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, RI_r1(ovl),
20025 RI_i2(ovl)); goto ok;
20026 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, RI_r1(ovl),
20027 RI_i2(ovl)); goto ok;
20028 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, RI_r1(ovl),
20029 RI_i2(ovl)); goto ok;
20030 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, RI_r1(ovl),
20031 RI_i2(ovl)); goto ok;
20032 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, RI_r1(ovl),
20033 RI_i2(ovl)); goto ok;
20034 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, RI_r1(ovl),
20035 RI_i2(ovl)); goto ok;
20036 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, RI_r1(ovl),
20037 RI_i2(ovl)); goto ok;
20038 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, RI_r1(ovl),
20039 RI_i2(ovl)); goto ok;
20040 case 0xa704: s390_format_RI(s390_irgen_BRC, RI_r1(ovl), RI_i2(ovl));
20041 goto ok;
20042 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, RI_r1(ovl),
20043 RI_i2(ovl)); goto ok;
20044 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, RI_r1(ovl),
20045 RI_i2(ovl)); goto ok;
20046 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, RI_r1(ovl),
20047 RI_i2(ovl)); goto ok;
20048 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, RI_r1(ovl), RI_i2(ovl));
20049 goto ok;
20050 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, RI_r1(ovl),
20051 RI_i2(ovl)); goto ok;
20052 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, RI_r1(ovl), RI_i2(ovl));
20053 goto ok;
20054 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, RI_r1(ovl),
20055 RI_i2(ovl)); goto ok;
20056 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, RI_r1(ovl), RI_i2(ovl));
20057 goto ok;
20058 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, RI_r1(ovl),
20059 RI_i2(ovl)); goto ok;
20060 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, RI_r1(ovl), RI_i2(ovl));
20061 goto ok;
20062 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, RI_r1(ovl),
20063 RI_i2(ovl)); goto ok;
20066 switch ((ovl & 0xffff0000) >> 16) {
20067 case 0x8000: /* SSM */ goto unimplemented;
20068 case 0x8200: /* LPSW */ goto unimplemented;
20069 case 0x9300: /* TS */ goto unimplemented;
20070 case 0xb200: /* LBEAR */ goto unimplemented;
20071 case 0xb201: /* STBEAR */ goto unimplemented;
20072 case 0xb202: /* STIDP */ goto unimplemented;
20073 case 0xb204: /* SCK */ goto unimplemented;
20074 case 0xb205: s390_format_S_RD(s390_irgen_STCK, S_b2(ovl), S_d2(ovl));
20075 goto ok;
20076 case 0xb206: /* SCKC */ goto unimplemented;
20077 case 0xb207: /* STCKC */ goto unimplemented;
20078 case 0xb208: /* SPT */ goto unimplemented;
20079 case 0xb209: /* STPT */ goto unimplemented;
20080 case 0xb20a: /* SPKA */ goto unimplemented;
20081 case 0xb20b: /* IPK */ goto unimplemented;
20082 case 0xb20d: /* PTLB */ goto unimplemented;
20083 case 0xb210: /* SPX */ goto unimplemented;
20084 case 0xb211: /* STPX */ goto unimplemented;
20085 case 0xb212: /* STAP */ goto unimplemented;
20086 case 0xb214: /* SIE */ goto unimplemented;
20087 case 0xb218: /* PC */ goto unimplemented;
20088 case 0xb219: /* SAC */ goto unimplemented;
20089 case 0xb21a: /* CFC */ goto unimplemented;
20090 case 0xb221: /* IPTE */ goto unimplemented;
20091 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, RRE_r1(ovl)); goto ok;
20092 case 0xb223: /* IVSK */ goto unimplemented;
20093 case 0xb224: /* IAC */ goto unimplemented;
20094 case 0xb225: /* SSAR */ goto unimplemented;
20095 case 0xb226: /* EPAR */ goto unimplemented;
20096 case 0xb227: /* ESAR */ goto unimplemented;
20097 case 0xb228: /* PT */ goto unimplemented;
20098 case 0xb229: /* ISKE */ goto unimplemented;
20099 case 0xb22a: /* RRBE */ goto unimplemented;
20100 case 0xb22b: /* SSKE */ goto unimplemented;
20101 case 0xb22c: /* TB */ goto unimplemented;
20102 case 0xb22d: /* DXR */ goto unimplemented;
20103 case 0xb22e: /* PGIN */ goto unimplemented;
20104 case 0xb22f: /* PGOUT */ goto unimplemented;
20105 case 0xb230: /* CSCH */ goto unimplemented;
20106 case 0xb231: /* HSCH */ goto unimplemented;
20107 case 0xb232: /* MSCH */ goto unimplemented;
20108 case 0xb233: /* SSCH */ goto unimplemented;
20109 case 0xb234: /* STSCH */ goto unimplemented;
20110 case 0xb235: /* TSCH */ goto unimplemented;
20111 case 0xb236: /* TPI */ goto unimplemented;
20112 case 0xb237: /* SAL */ goto unimplemented;
20113 case 0xb238: /* RSCH */ goto unimplemented;
20114 case 0xb239: /* STCRW */ goto unimplemented;
20115 case 0xb23a: /* STCPS */ goto unimplemented;
20116 case 0xb23b: /* RCHP */ goto unimplemented;
20117 case 0xb23c: /* SCHM */ goto unimplemented;
20118 case 0xb240: /* BAKR */ goto unimplemented;
20119 case 0xb241: s390_format_RRE_RR(s390_irgen_CKSM, RRE_r1(ovl),
20120 RRE_r2(ovl)); goto ok;
20121 case 0xb244: /* SQDR */ goto unimplemented;
20122 case 0xb245: /* SQER */ goto unimplemented;
20123 case 0xb246: /* STURA */ goto unimplemented;
20124 case 0xb247: /* MSTA */ goto unimplemented;
20125 case 0xb248: /* PALB */ goto unimplemented;
20126 case 0xb249: /* EREG */ goto unimplemented;
20127 case 0xb24a: /* ESTA */ goto unimplemented;
20128 case 0xb24b: /* LURA */ goto unimplemented;
20129 case 0xb24c: /* TAR */ goto unimplemented;
20130 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, RRE_r1(ovl),
20131 RRE_r2(ovl)); goto ok;
20132 case 0xb24e: s390_format_RRE(s390_irgen_SAR, RRE_r1(ovl), RRE_r2(ovl));
20133 goto ok;
20134 case 0xb24f: s390_format_RRE(s390_irgen_EAR, RRE_r1(ovl), RRE_r2(ovl));
20135 goto ok;
20136 case 0xb250: /* CSP */ goto unimplemented;
20137 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, RRE_r1(ovl),
20138 RRE_r2(ovl)); goto ok;
20139 case 0xb254: /* MVPG */ goto unimplemented;
20140 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, RRE_r1(ovl),
20141 RRE_r2(ovl)); goto ok;
20142 case 0xb257: /* CUSE */ goto unimplemented;
20143 case 0xb258: /* BSG */ goto unimplemented;
20144 case 0xb25a: /* BSA */ goto unimplemented;
20145 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, RRE_r1(ovl),
20146 RRE_r2(ovl)); goto ok;
20147 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, RRE_r1(ovl),
20148 RRE_r2(ovl)); goto ok;
20149 case 0xb263: /* CMPSC */ goto unimplemented;
20150 case 0xb274: /* SIGA */ goto unimplemented;
20151 case 0xb276: /* XSCH */ goto unimplemented;
20152 case 0xb277: /* RP */ goto unimplemented;
20153 case 0xb278: s390_format_S_RD(s390_irgen_STCKE, S_b2(ovl), S_d2(ovl));goto ok;
20154 case 0xb279: /* SACF */ goto unimplemented;
20155 case 0xb27c: s390_format_S_RD(s390_irgen_STCKF, S_b2(ovl), S_d2(ovl));goto ok;
20156 case 0xb27d: /* STSI */ goto unimplemented;
20157 case 0xb280: /* LPP */ goto unimplemented;
20158 case 0xb284: /* LCCTL */ goto unimplemented;
20159 case 0xb285: /* LPCTL */ goto unimplemented;
20160 case 0xb286: /* QSI */ goto unimplemented;
20161 case 0xb287: /* LSCTL */ goto unimplemented;
20162 case 0xb28e: /* QCTRI */ goto unimplemented;
20163 case 0xb28f: /* QPACI */ goto unimplemented;
20164 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, S_b2(ovl), S_d2(ovl));
20165 goto ok;
20166 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, S_b2(ovl), S_d2(ovl));
20167 goto ok;
20168 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, S_b2(ovl), S_d2(ovl));
20169 goto ok;
20170 case 0xb2a5: s390_format_RRE_FF(s390_irgen_TRE, RRE_r1(ovl), RRE_r2(ovl)); goto ok;
20171 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, RRF3_r3(ovl),
20172 RRF3_r1(ovl), RRF3_r2(ovl));
20173 goto ok;
20174 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, RRF3_r3(ovl),
20175 RRF3_r1(ovl), RRF3_r2(ovl));
20176 goto ok;
20177 case 0xb2b0: s390_format_S_RD_raw(s390_irgen_STFLE, S_b2(ovl), S_d2(ovl));
20178 goto ok;
20179 case 0xb2b1: /* STFL */ goto unimplemented;
20180 case 0xb2b2: /* LPSWE */ goto unimplemented;
20181 case 0xb2b8: s390_irgen_srnmb_wrapper(S_b2(ovl), S_d2(ovl));
20182 goto ok;
20183 case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, S_b2(ovl), S_d2(ovl));
20184 goto ok;
20185 case 0xb2bd: /* LFAS */ goto unimplemented;
20186 case 0xb2e0: /* SCCTR */ goto unimplemented;
20187 case 0xb2e1: /* SPCTR */ goto unimplemented;
20188 case 0xb2e4: /* ECCTR */ goto unimplemented;
20189 case 0xb2e5: /* EPCTR */ goto unimplemented;
20190 case 0xb2e8: /* PPA */ goto unimplemented;
20191 case 0xb2ec: /* ETND */ goto unimplemented;
20192 case 0xb2ed: /* ECPGA */ goto unimplemented;
20193 case 0xb2f8: /* TEND */ goto unimplemented;
20194 case 0xb2fa: /* NIAI */ goto unimplemented;
20195 case 0xb2fc: /* TABORT */ goto unimplemented;
20196 case 0xb2ff: /* TRAP4 */ goto unimplemented;
20197 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, RRE_r1(ovl),
20198 RRE_r2(ovl)); goto ok;
20199 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, RRE_r1(ovl),
20200 RRE_r2(ovl)); goto ok;
20201 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, RRE_r1(ovl),
20202 RRE_r2(ovl)); goto ok;
20203 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, RRE_r1(ovl),
20204 RRE_r2(ovl)); goto ok;
20205 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, RRE_r1(ovl),
20206 RRE_r2(ovl)); goto ok;
20207 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, RRE_r1(ovl),
20208 RRE_r2(ovl)); goto ok;
20209 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, RRE_r1(ovl),
20210 RRE_r2(ovl)); goto ok;
20211 case 0xb307: /* MXDBR */ goto unimplemented;
20212 case 0xb308: s390_format_RRE_FF(s390_irgen_KEBR, RRE_r1(ovl),
20213 RRE_r2(ovl)); goto ok;
20214 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, RRE_r1(ovl),
20215 RRE_r2(ovl)); goto ok;
20216 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, RRE_r1(ovl),
20217 RRE_r2(ovl)); goto ok;
20218 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, RRE_r1(ovl),
20219 RRE_r2(ovl)); goto ok;
20220 case 0xb30c: /* MDEBR */ goto unimplemented;
20221 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, RRE_r1(ovl),
20222 RRE_r2(ovl)); goto ok;
20223 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, RRF_r1(ovl),
20224 RRF_r3(ovl), RRF_r2(ovl)); goto ok;
20225 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, RRF_r1(ovl),
20226 RRF_r3(ovl), RRF_r2(ovl)); goto ok;
20227 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, RRE_r1(ovl),
20228 RRE_r2(ovl)); goto ok;
20229 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, RRE_r1(ovl),
20230 RRE_r2(ovl)); goto ok;
20231 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, RRE_r1(ovl),
20232 RRE_r2(ovl)); goto ok;
20233 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, RRE_r1(ovl),
20234 RRE_r2(ovl)); goto ok;
20235 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, RRE_r1(ovl),
20236 RRE_r2(ovl)); goto ok;
20237 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, RRE_r1(ovl),
20238 RRE_r2(ovl)); goto ok;
20239 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, RRE_r1(ovl),
20240 RRE_r2(ovl)); goto ok;
20241 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, RRE_r1(ovl),
20242 RRE_r2(ovl)); goto ok;
20243 case 0xb318: s390_format_RRE_FF(s390_irgen_KDBR, RRE_r1(ovl),
20244 RRE_r2(ovl)); goto ok;
20245 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, RRE_r1(ovl),
20246 RRE_r2(ovl)); goto ok;
20247 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, RRE_r1(ovl),
20248 RRE_r2(ovl)); goto ok;
20249 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, RRE_r1(ovl),
20250 RRE_r2(ovl)); goto ok;
20251 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, RRE_r1(ovl),
20252 RRE_r2(ovl)); goto ok;
20253 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, RRE_r1(ovl),
20254 RRE_r2(ovl)); goto ok;
20255 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, RRF_r1(ovl),
20256 RRF_r3(ovl), RRF_r2(ovl)); goto ok;
20257 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, RRF_r1(ovl),
20258 RRF_r3(ovl), RRF_r2(ovl)); goto ok;
20259 case 0xb324: s390_format_RRE_FF(s390_irgen_LDER, RRE_r1(ovl),
20260 RRE_r2(ovl)); goto ok;
20261 case 0xb325: /* LXDR */ goto unimplemented;
20262 case 0xb326: /* LXER */ goto unimplemented;
20263 case 0xb32e: /* MAER */ goto unimplemented;
20264 case 0xb32f: /* MSER */ goto unimplemented;
20265 case 0xb336: /* SQXR */ goto unimplemented;
20266 case 0xb337: /* MEER */ goto unimplemented;
20267 case 0xb338: /* MAYLR */ goto unimplemented;
20268 case 0xb339: /* MYLR */ goto unimplemented;
20269 case 0xb33a: /* MAYR */ goto unimplemented;
20270 case 0xb33b: /* MYR */ goto unimplemented;
20271 case 0xb33c: /* MAYHR */ goto unimplemented;
20272 case 0xb33d: /* MYHR */ goto unimplemented;
20273 case 0xb33e: /* MADR */ goto unimplemented;
20274 case 0xb33f: /* MSDR */ goto unimplemented;
20275 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, RRE_r1(ovl),
20276 RRE_r2(ovl)); goto ok;
20277 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, RRE_r1(ovl),
20278 RRE_r2(ovl)); goto ok;
20279 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, RRE_r1(ovl),
20280 RRE_r2(ovl)); goto ok;
20281 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, RRE_r1(ovl),
20282 RRE_r2(ovl)); goto ok;
20283 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, RRF2_m3(ovl),
20284 RRF2_m4(ovl), RRF2_r1(ovl),
20285 RRF2_r2(ovl)); goto ok;
20286 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, RRF2_m3(ovl),
20287 RRF2_m4(ovl), RRF2_r1(ovl),
20288 RRF2_r2(ovl)); goto ok;
20289 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, RRF2_m3(ovl),
20290 RRF2_m4(ovl), RRF2_r1(ovl),
20291 RRF2_r2(ovl)); goto ok;
20292 case 0xb347: s390_format_RRF_UUFF(s390_irgen_FIXBRA, RRF2_m3(ovl),
20293 RRF2_m4(ovl), RRF2_r1(ovl),
20294 RRF2_r2(ovl)); goto ok;
20295 case 0xb348: s390_format_RRE_FF(s390_irgen_KXBR, RRE_r1(ovl),
20296 RRE_r2(ovl)); goto ok;
20297 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, RRE_r1(ovl),
20298 RRE_r2(ovl)); goto ok;
20299 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, RRE_r1(ovl),
20300 RRE_r2(ovl)); goto ok;
20301 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, RRE_r1(ovl),
20302 RRE_r2(ovl)); goto ok;
20303 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, RRE_r1(ovl),
20304 RRE_r2(ovl)); goto ok;
20305 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, RRE_r1(ovl),
20306 RRE_r2(ovl)); goto ok;
20307 case 0xb350: /* TBEDR */ goto unimplemented;
20308 case 0xb351: /* TBDR */ goto unimplemented;
20309 case 0xb353: /* DIEBR */ goto unimplemented;
20310 case 0xb357: s390_format_RRF_UUFF(s390_irgen_FIEBRA, RRF2_m3(ovl),
20311 RRF2_m4(ovl), RRF2_r1(ovl),
20312 RRF2_r2(ovl)); goto ok;
20313 case 0xb358: /* THDER */ goto unimplemented;
20314 case 0xb359: /* THDR */ goto unimplemented;
20315 case 0xb35b: /* DIDBR */ goto unimplemented;
20316 case 0xb35f: s390_format_RRF_UUFF(s390_irgen_FIDBRA, RRF2_m3(ovl),
20317 RRF2_m4(ovl), RRF2_r1(ovl),
20318 RRF2_r2(ovl)); goto ok;
20319 case 0xb360: /* LPXR */ goto unimplemented;
20320 case 0xb361: /* LNXR */ goto unimplemented;
20321 case 0xb362: /* LTXR */ goto unimplemented;
20322 case 0xb363: /* LCXR */ goto unimplemented;
20323 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, RRE_r1(ovl),
20324 RRE_r2(ovl)); goto ok;
20325 case 0xb366: /* LEXR */ goto unimplemented;
20326 case 0xb367: /* FIXR */ goto unimplemented;
20327 case 0xb369: /* CXR */ goto unimplemented;
20328 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, RRE_r1(ovl),
20329 RRE_r2(ovl)); goto ok;
20330 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, RRE_r1(ovl),
20331 RRE_r2(ovl)); goto ok;
20332 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, RRF3_r3(ovl),
20333 RRF3_r1(ovl), RRF3_r2(ovl));
20334 goto ok;
20335 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, RRE_r1(ovl),
20336 RRE_r2(ovl)); goto ok;
20337 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, RRE_r1(ovl)); goto ok;
20338 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, RRE_r1(ovl)); goto ok;
20339 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, RRE_r1(ovl)); goto ok;
20340 case 0xb377: /* FIER */ goto unimplemented;
20341 case 0xb37f: /* FIDR */ goto unimplemented;
20342 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, RRE_r1(ovl)); goto ok;
20343 case 0xb385: /* SFASR */ goto unimplemented;
20344 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, RRE_r1(ovl)); goto ok;
20345 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, RRF2_m3(ovl),
20346 RRF2_m4(ovl), RRF2_r1(ovl),
20347 RRF2_r2(ovl)); goto ok;
20348 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, RRF2_m3(ovl),
20349 RRF2_m4(ovl), RRF2_r1(ovl),
20350 RRF2_r2(ovl)); goto ok;
20351 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, RRF2_m3(ovl),
20352 RRF2_m4(ovl), RRF2_r1(ovl),
20353 RRF2_r2(ovl)); goto ok;
20354 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, RRF2_m3(ovl),
20355 RRF2_m4(ovl), RRF2_r1(ovl),
20356 RRF2_r2(ovl)); goto ok;
20357 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, RRF2_m3(ovl),
20358 RRF2_m4(ovl), RRF2_r1(ovl),
20359 RRF2_r2(ovl)); goto ok;
20360 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, RRF2_m3(ovl),
20361 RRF2_m4(ovl), RRF2_r1(ovl),
20362 RRF2_r2(ovl)); goto ok;
20363 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, RRF2_m3(ovl),
20364 RRF2_m4(ovl), RRF2_r1(ovl),
20365 RRF2_r2(ovl)); goto ok;
20366 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, RRF2_m3(ovl),
20367 RRF2_m4(ovl), RRF2_r1(ovl),
20368 RRF2_r2(ovl)); goto ok;
20369 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, RRF2_m3(ovl),
20370 RRF2_m4(ovl), RRF2_r1(ovl),
20371 RRF2_r2(ovl)); goto ok;
20372 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, RRF2_m3(ovl),
20373 RRF2_m4(ovl), RRF2_r1(ovl),
20374 RRF2_r2(ovl)); goto ok;
20375 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, RRF2_m3(ovl),
20376 RRF2_m4(ovl), RRF2_r1(ovl),
20377 RRF2_r2(ovl)); goto ok;
20378 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, RRF2_m3(ovl),
20379 RRF2_m4(ovl), RRF2_r1(ovl),
20380 RRF2_r2(ovl)); goto ok;
20381 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, RRF2_m3(ovl),
20382 RRF2_m4(ovl), RRF2_r1(ovl),
20383 RRF2_r2(ovl)); goto ok;
20384 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, RRF2_m3(ovl),
20385 RRF2_m4(ovl), RRF2_r1(ovl),
20386 RRF2_r2(ovl)); goto ok;
20387 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, RRF2_m3(ovl),
20388 RRF2_m4(ovl), RRF2_r1(ovl),
20389 RRF2_r2(ovl)); goto ok;
20390 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, RRF2_m3(ovl),
20391 RRF2_m4(ovl), RRF2_r1(ovl),
20392 RRF2_r2(ovl)); goto ok;
20393 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, RRF2_m3(ovl),
20394 RRF2_m4(ovl), RRF2_r1(ovl),
20395 RRF2_r2(ovl)); goto ok;
20396 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, RRF2_m3(ovl),
20397 RRF2_m4(ovl), RRF2_r1(ovl),
20398 RRF2_r2(ovl)); goto ok;
20399 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, RRF2_m3(ovl),
20400 RRF2_m4(ovl), RRF2_r1(ovl),
20401 RRF2_r2(ovl)); goto ok;
20402 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, RRF2_m3(ovl),
20403 RRF2_m4(ovl), RRF2_r1(ovl),
20404 RRF2_r2(ovl)); goto ok;
20405 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, RRF2_m3(ovl),
20406 RRF2_m4(ovl), RRF2_r1(ovl),
20407 RRF2_r2(ovl)); goto ok;
20408 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, RRF2_m3(ovl),
20409 RRF2_m4(ovl), RRF2_r1(ovl),
20410 RRF2_r2(ovl)); goto ok;
20411 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, RRF2_m3(ovl),
20412 RRF2_m4(ovl), RRF2_r1(ovl),
20413 RRF2_r2(ovl)); goto ok;
20414 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, RRF2_m3(ovl),
20415 RRF2_m4(ovl), RRF2_r1(ovl),
20416 RRF2_r2(ovl)); goto ok;
20417 case 0xb3b4: /* CEFR */ goto unimplemented;
20418 case 0xb3b5: /* CDFR */ goto unimplemented;
20419 case 0xb3b6: /* CXFR */ goto unimplemented;
20420 case 0xb3b8: /* CFER */ goto unimplemented;
20421 case 0xb3b9: /* CFDR */ goto unimplemented;
20422 case 0xb3ba: /* CFXR */ goto unimplemented;
20423 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, RRE_r1(ovl),
20424 RRE_r2(ovl)); goto ok;
20425 case 0xb3c4: /* CEGR */ goto unimplemented;
20426 case 0xb3c5: /* CDGR */ goto unimplemented;
20427 case 0xb3c6: /* CXGR */ goto unimplemented;
20428 case 0xb3c8: /* CGER */ goto unimplemented;
20429 case 0xb3c9: /* CGDR */ goto unimplemented;
20430 case 0xb3ca: /* CGXR */ goto unimplemented;
20431 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, RRE_r1(ovl),
20432 RRE_r2(ovl)); goto ok;
20433 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, RRF4_r3(ovl),
20434 RRF4_m4(ovl), RRF4_r1(ovl),
20435 RRF4_r2(ovl)); goto ok;
20436 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, RRF4_r3(ovl),
20437 RRF4_m4(ovl), RRF4_r1(ovl),
20438 RRF4_r2(ovl)); goto ok;
20439 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, RRF4_r3(ovl),
20440 RRF4_m4(ovl), RRF4_r1(ovl),
20441 RRF4_r2(ovl)); goto ok;
20442 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, RRF4_r3(ovl),
20443 RRF4_m4(ovl), RRF4_r1(ovl),
20444 RRF4_r2(ovl)); goto ok;
20445 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, RRF5_m4(ovl),
20446 RRF5_r1(ovl), RRF5_r2(ovl)); goto ok;
20447 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, RRF2_m3(ovl),
20448 RRF2_m4(ovl), RRF2_r1(ovl),
20449 RRF2_r2(ovl)); goto ok;
20450 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, RRE_r1(ovl),
20451 RRE_r2(ovl)); goto ok;
20452 case 0xb3d7: /* FIDTR */ goto unimplemented;
20453 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, RRF4_r3(ovl),
20454 RRF4_m4(ovl), RRF4_r1(ovl),
20455 RRF4_r2(ovl)); goto ok;
20456 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, RRF4_r3(ovl),
20457 RRF4_m4(ovl), RRF4_r1(ovl),
20458 RRF4_r2(ovl)); goto ok;
20459 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, RRF4_r3(ovl),
20460 RRF4_m4(ovl), RRF4_r1(ovl),
20461 RRF4_r2(ovl)); goto ok;
20462 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, RRF4_r3(ovl),
20463 RRF4_m4(ovl), RRF4_r1(ovl),
20464 RRF4_r2(ovl)); goto ok;
20465 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, RRF5_m4(ovl),
20466 RRF5_r1(ovl), RRF5_r2(ovl)); goto ok;
20467 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, RRF2_m3(ovl),
20468 RRF2_m4(ovl), RRF2_r1(ovl),
20469 RRF2_r2(ovl)); goto ok;
20470 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, RRE_r1(ovl),
20471 RRE_r2(ovl)); goto ok;
20472 case 0xb3df: /* FIXTR */ goto unimplemented;
20473 case 0xb3e0: /* KDTR */ goto unimplemented;
20474 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, RRF2_m3(ovl),
20475 RRF2_m4(ovl), RRF2_r1(ovl),
20476 RRF2_r2(ovl)); goto ok;
20477 case 0xb3e2: /* CUDTR */ goto unimplemented;
20478 case 0xb3e3: /* CSDTR */ goto unimplemented;
20479 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, RRE_r1(ovl),
20480 RRE_r2(ovl)); goto ok;
20481 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, RRE_r1(ovl),
20482 RRE_r2(ovl)); goto ok;
20483 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, RRE_r1(ovl),
20484 RRE_r2(ovl)); goto ok;
20485 case 0xb3e8: /* KXTR */ goto unimplemented;
20486 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, RRF2_m3(ovl),
20487 RRF2_m4(ovl), RRF2_r1(ovl),
20488 RRF2_r2(ovl)); goto ok;
20489 case 0xb3ea: /* CUXTR */ goto unimplemented;
20490 case 0xb3eb: /* CSXTR */ goto unimplemented;
20491 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, RRE_r1(ovl),
20492 RRE_r2(ovl)); goto ok;
20493 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, RRE_r1(ovl),
20494 RRE_r2(ovl)); goto ok;
20495 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, RRE_r1(ovl),
20496 RRE_r2(ovl)); goto ok;
20497 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, RRF2_m3(ovl),
20498 RRF2_m4(ovl), RRF2_r1(ovl),
20499 RRF2_r2(ovl)); goto ok;
20500 case 0xb3f2: /* CDUTR */ goto unimplemented;
20501 case 0xb3f3: /* CDSTR */ goto unimplemented;
20502 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, RRE_r1(ovl),
20503 RRE_r2(ovl)); goto ok;
20504 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, RRF4_r3(ovl),
20505 RRF4_m4(ovl), RRF4_r1(ovl),
20506 RRF4_r2(ovl)); goto ok;
20507 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, RRF3_r3(ovl),
20508 RRF3_r1(ovl), RRF3_r2(ovl)); goto ok;
20509 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, RRF4_r3(ovl),
20510 RRF4_m4(ovl), RRF4_r1(ovl),
20511 RRF4_r2(ovl)); goto ok;
20512 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, RRF2_m3(ovl),
20513 RRF2_m4(ovl), RRF2_r1(ovl),
20514 RRF2_r2(ovl)); goto ok;
20515 case 0xb3fa: /* CXUTR */ goto unimplemented;
20516 case 0xb3fb: /* CXSTR */ goto unimplemented;
20517 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, RRE_r1(ovl),
20518 RRE_r2(ovl)); goto ok;
20519 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, RRF4_r3(ovl),
20520 RRF4_m4(ovl), RRF4_r1(ovl),
20521 RRF4_r2(ovl)); goto ok;
20522 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, RRF3_r3(ovl),
20523 RRF3_r1(ovl), RRF3_r2(ovl)); goto ok;
20524 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, RRF4_r3(ovl),
20525 RRF4_m4(ovl), RRF4_r1(ovl),
20526 RRF4_r2(ovl)); goto ok;
20527 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, RRE_r1(ovl),
20528 RRE_r2(ovl)); goto ok;
20529 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, RRE_r1(ovl),
20530 RRE_r2(ovl)); goto ok;
20531 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, RRE_r1(ovl),
20532 RRE_r2(ovl)); goto ok;
20533 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, RRE_r1(ovl),
20534 RRE_r2(ovl)); goto ok;
20535 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, RRE_r1(ovl),
20536 RRE_r2(ovl)); goto ok;
20537 case 0xb905: /* LURAG */ goto unimplemented;
20538 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, RRE_r1(ovl),
20539 RRE_r2(ovl)); goto ok;
20540 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, RRE_r1(ovl),
20541 RRE_r2(ovl)); goto ok;
20542 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, RRE_r1(ovl),
20543 RRE_r2(ovl)); goto ok;
20544 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, RRE_r1(ovl),
20545 RRE_r2(ovl)); goto ok;
20546 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, RRE_r1(ovl),
20547 RRE_r2(ovl)); goto ok;
20548 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, RRE_r1(ovl),
20549 RRE_r2(ovl)); goto ok;
20550 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, RRE_r1(ovl),
20551 RRE_r2(ovl)); goto ok;
20552 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, RRE_r1(ovl),
20553 RRE_r2(ovl)); goto ok;
20554 case 0xb90e: /* EREGG */ goto unimplemented;
20555 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, RRE_r1(ovl),
20556 RRE_r2(ovl)); goto ok;
20557 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, RRE_r1(ovl),
20558 RRE_r2(ovl)); goto ok;
20559 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, RRE_r1(ovl),
20560 RRE_r2(ovl)); goto ok;
20561 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, RRE_r1(ovl),
20562 RRE_r2(ovl)); goto ok;
20563 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, RRE_r1(ovl),
20564 RRE_r2(ovl)); goto ok;
20565 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, RRE_r1(ovl),
20566 RRE_r2(ovl)); goto ok;
20567 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, RRE_r1(ovl),
20568 RRE_r2(ovl)); goto ok;
20569 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, RRE_r1(ovl),
20570 RRE_r2(ovl)); goto ok;
20571 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, RRE_r1(ovl),
20572 RRE_r2(ovl)); goto ok;
20573 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, RRE_r1(ovl),
20574 RRE_r2(ovl)); goto ok;
20575 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, RRE_r1(ovl),
20576 RRE_r2(ovl)); goto ok;
20577 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, RRE_r1(ovl),
20578 RRE_r2(ovl)); goto ok;
20579 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, RRE_r1(ovl),
20580 RRE_r2(ovl)); goto ok;
20581 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, RRE_r1(ovl),
20582 RRE_r2(ovl)); goto ok;
20583 case 0xb91e: s390_format_RRE_RR(s390_irgen_KMAC, RRE_r1(ovl),
20584 RRE_r2(ovl)); goto ok;
20585 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, RRE_r1(ovl),
20586 RRE_r2(ovl)); goto ok;
20587 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, RRE_r1(ovl),
20588 RRE_r2(ovl)); goto ok;
20589 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, RRE_r1(ovl),
20590 RRE_r2(ovl)); goto ok;
20591 case 0xb925: /* STURG */ goto unimplemented;
20592 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, RRE_r1(ovl),
20593 RRE_r2(ovl)); goto ok;
20594 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, RRE_r1(ovl),
20595 RRE_r2(ovl)); goto ok;
20596 case 0xb928: /* PCKMO */ goto unimplemented;
20597 case 0xb929: s390_format_RRF_R0RR2(s390_irgen_KMA, RRF4_r3(ovl),
20598 RRF4_r1(ovl), RRF4_r2(ovl)); goto ok;
20599 case 0xb92a: s390_format_RRE_RR(s390_irgen_KMF, RRE_r1(ovl),
20600 RRE_r2(ovl)); goto ok;
20601 case 0xb92b: s390_format_RRE_RR(s390_irgen_KMO, RRE_r1(ovl),
20602 RRE_r2(ovl)); goto ok;
20603 case 0xb92c: s390_format_E(s390_irgen_PCC); goto ok;
20604 case 0xb92d: s390_format_RRF_R0RR2(s390_irgen_KMCTR, RRF4_r3(ovl),
20605 RRF4_r1(ovl), RRF4_r2(ovl)); goto ok;
20606 case 0xb92e: s390_format_RRE_RR(s390_irgen_KM, RRE_r1(ovl),
20607 RRE_r2(ovl)); goto ok;
20608 case 0xb92f: s390_format_RRE_RR(s390_irgen_KMC, RRE_r1(ovl),
20609 RRE_r2(ovl)); goto ok;
20610 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, RRE_r1(ovl),
20611 RRE_r2(ovl)); goto ok;
20612 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, RRE_r1(ovl),
20613 RRE_r2(ovl)); goto ok;
20614 case 0xb938: /* SORTL */ goto unimplemented;
20615 case 0xb939: s390_format_RRF_R0RR2(s390_irgen_DFLTCC, RRF4_r3(ovl),
20616 RRF4_r1(ovl), RRF4_r2(ovl)); goto ok;
20617 case 0xb93a: s390_format_RRE_RR(s390_irgen_KDSA, RRE_r1(ovl),
20618 RRE_r2(ovl)); goto ok;
20619 case 0xb93b: s390_format_E(s390_irgen_NNPA); goto ok;
20620 case 0xb93c: s390_format_RRE_RR(s390_irgen_PPNO, RRE_r1(ovl),
20621 RRE_r2(ovl)); goto ok;
20622 case 0xb93e: s390_format_RRE_RR(s390_irgen_KIMD, RRE_r1(ovl),
20623 RRE_r2(ovl)); goto ok;
20624 case 0xb93f: s390_format_RRE_RR(s390_irgen_KLMD, RRE_r1(ovl),
20625 RRE_r2(ovl)); goto ok;
20626 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, RRF2_m3(ovl),
20627 RRF2_m4(ovl), RRF2_r1(ovl),
20628 RRF2_r2(ovl)); goto ok;
20629 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, RRF2_m3(ovl),
20630 RRF2_m4(ovl), RRF2_r1(ovl),
20631 RRF2_r2(ovl)); goto ok;
20632 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, RRF2_m3(ovl),
20633 RRF2_m4(ovl), RRF2_r1(ovl),
20634 RRF2_r2(ovl)); goto ok;
20635 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, RRE_r1(ovl),
20636 RRE_r2(ovl)); goto ok;
20637 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, RRF2_m3(ovl),
20638 RRF2_m4(ovl), RRF2_r1(ovl),
20639 RRF2_r2(ovl)); goto ok;
20640 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, RRF2_m3(ovl),
20641 RRF2_m4(ovl), RRF2_r1(ovl),
20642 RRF2_r2(ovl)); goto ok;
20643 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, RRF2_m3(ovl),
20644 RRF2_m4(ovl), RRF2_r1(ovl),
20645 RRF2_r2(ovl)); goto ok;
20646 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, RRF2_m3(ovl),
20647 RRF2_m4(ovl), RRF2_r1(ovl),
20648 RRF2_r2(ovl)); goto ok;
20649 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, RRF2_m3(ovl),
20650 RRF2_m4(ovl), RRF2_r1(ovl),
20651 RRF2_r2(ovl)); goto ok;
20652 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, RRF2_m3(ovl),
20653 RRF2_m4(ovl), RRF2_r1(ovl),
20654 RRF2_r2(ovl)); goto ok;
20655 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, RRF2_m3(ovl),
20656 RRF2_m4(ovl), RRF2_r1(ovl),
20657 RRF2_r2(ovl)); goto ok;
20658 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, RRF2_m3(ovl),
20659 RRF2_m4(ovl), RRF2_r1(ovl),
20660 RRF2_r2(ovl)); goto ok;
20661 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, RRF2_m3(ovl),
20662 RRF2_m4(ovl), RRF2_r1(ovl),
20663 RRF2_r2(ovl)); goto ok;
20664 case 0xb960: s390_format_RRF_U0RR(s390_irgen_CGRT, RRF2_m3(ovl),
20665 RRF2_r1(ovl), RRF2_r2(ovl),
20666 S390_XMNM_CAB); goto ok;
20667 case 0xb961: s390_format_RRF_U0RR(s390_irgen_CLGRT, RRF2_m3(ovl),
20668 RRF2_r1(ovl), RRF2_r2(ovl),
20669 S390_XMNM_CAB); goto ok;
20670 case 0xb964: s390_format_RRF_R0RR2(s390_irgen_NNGRK, RRF4_r3(ovl),
20671 RRF4_r1(ovl), RRF4_r2(ovl)); goto ok;
20672 case 0xb965: s390_format_RRF_R0RR2(s390_irgen_OCGRK, RRF4_r3(ovl),
20673 RRF4_r1(ovl), RRF4_r2(ovl)); goto ok;
20674 case 0xb966: s390_format_RRF_R0RR2(s390_irgen_NOGRK, RRF4_r3(ovl),
20675 RRF4_r1(ovl), RRF4_r2(ovl)); goto ok;
20676 case 0xb967: s390_format_RRF_R0RR2(s390_irgen_NXGRK, RRF4_r3(ovl),
20677 RRF4_r1(ovl), RRF4_r2(ovl)); goto ok;
20678 case 0xb968: /* CLZG */ goto unimplemented;
20679 case 0xb969: /* CTZG */ goto unimplemented;
20680 case 0xb96c: /* BEXTG */ goto unimplemented;
20681 case 0xb96d: /* BDEPG */ goto unimplemented;
20682 case 0xb972: s390_format_RRF_U0RR(s390_irgen_CRT, RRF2_m3(ovl),
20683 RRF2_r1(ovl), RRF2_r2(ovl),
20684 S390_XMNM_CAB); goto ok;
20685 case 0xb973: s390_format_RRF_U0RR(s390_irgen_CLRT, RRF2_m3(ovl),
20686 RRF2_r1(ovl), RRF2_r2(ovl),
20687 S390_XMNM_CAB); goto ok;
20688 case 0xb974: s390_format_RRF_R0RR2(s390_irgen_NNRK, RRF4_r3(ovl),
20689 RRF4_r1(ovl), RRF4_r2(ovl)); goto ok;
20690 case 0xb975: s390_format_RRF_R0RR2(s390_irgen_OCRK, RRF4_r3(ovl),
20691 RRF4_r1(ovl), RRF4_r2(ovl)); goto ok;
20692 case 0xb976: s390_format_RRF_R0RR2(s390_irgen_NORK, RRF4_r3(ovl),
20693 RRF4_r1(ovl), RRF4_r2(ovl)); goto ok;
20694 case 0xb977: s390_format_RRF_R0RR2(s390_irgen_NXRK, RRF4_r3(ovl),
20695 RRF4_r1(ovl), RRF4_r2(ovl)); goto ok;
20696 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, RRE_r1(ovl),
20697 RRE_r2(ovl)); goto ok;
20698 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, RRE_r1(ovl),
20699 RRE_r2(ovl)); goto ok;
20700 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, RRE_r1(ovl),
20701 RRE_r2(ovl)); goto ok;
20702 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, RRE_r1(ovl),
20703 RRE_r2(ovl)); goto ok;
20704 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, RRE_r1(ovl),
20705 RRE_r2(ovl)); goto ok;
20706 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, RRE_r1(ovl),
20707 RRE_r2(ovl)); goto ok;
20708 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, RRE_r1(ovl),
20709 RRE_r2(ovl)); goto ok;
20710 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, RRE_r1(ovl),
20711 RRE_r2(ovl)); goto ok;
20712 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, RRE_r1(ovl),
20713 RRE_r2(ovl)); goto ok;
20714 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, RRE_r1(ovl),
20715 RRE_r2(ovl)); goto ok;
20716 case 0xb98a: /* CSPG */ goto unimplemented;
20717 case 0xb98b: /* RDP */ goto unimplemented;
20718 case 0xb98d: /* EPSW */ goto unimplemented;
20719 case 0xb98e: /* IDTE */ goto unimplemented;
20720 case 0xb98f: /* CRDTE */ goto unimplemented;
20721 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, RRF3_r3(ovl),
20722 RRF3_r1(ovl), RRF3_r2(ovl)); goto ok;
20723 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, RRF3_r3(ovl),
20724 RRF3_r1(ovl), RRF3_r2(ovl)); goto ok;
20725 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, RRF3_r3(ovl),
20726 RRF3_r1(ovl), RRF3_r2(ovl)); goto ok;
20727 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, RRF3_r3(ovl),
20728 RRF3_r1(ovl), RRF3_r2(ovl)); goto ok;
20729 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, RRE_r1(ovl),
20730 RRE_r2(ovl)); goto ok;
20731 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, RRE_r1(ovl),
20732 RRE_r2(ovl)); goto ok;
20733 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, RRE_r1(ovl),
20734 RRE_r2(ovl)); goto ok;
20735 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, RRE_r1(ovl),
20736 RRE_r2(ovl)); goto ok;
20737 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, RRE_r1(ovl),
20738 RRE_r2(ovl)); goto ok;
20739 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, RRE_r1(ovl),
20740 RRE_r2(ovl)); goto ok;
20741 case 0xb99a: /* EPAIR */ goto unimplemented;
20742 case 0xb99b: /* ESAIR */ goto unimplemented;
20743 case 0xb99d: /* ESEA */ goto unimplemented;
20744 case 0xb99e: /* PTI */ goto unimplemented;
20745 case 0xb99f: /* SSAIR */ goto unimplemented;
20746 case 0xb9a1: /* TPEI */ goto unimplemented;
20747 case 0xb9a2: /* PTF */ goto unimplemented;
20748 case 0xb9aa: /* LPTEA */ goto unimplemented;
20749 case 0xb9ac: /* IRBM */ goto unimplemented;
20750 case 0xb9ae: /* RRBM */ goto unimplemented;
20751 case 0xb9af: /* PFMF */ goto unimplemented;
20752 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, RRF3_r3(ovl),
20753 RRF3_r1(ovl), RRF3_r2(ovl));
20754 goto ok;
20755 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, RRF3_r3(ovl),
20756 RRF3_r1(ovl), RRF3_r2(ovl));
20757 goto ok;
20758 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, RRE_r1(ovl),
20759 RRE_r2(ovl)); goto ok;
20760 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, RRE_r1(ovl),
20761 RRE_r2(ovl)); goto ok;
20762 case 0xb9bd: /* TRTRE */ goto unimplemented;
20763 case 0xb9be: /* SRSTU */ goto unimplemented;
20764 case 0xb9bf: /* TRTE */ goto unimplemented;
20765 case 0xb9c0: s390_format_RRF_RURR(s390_irgen_SELFHR, RRF4_r3(ovl),
20766 RRF4_m4(ovl), RRF4_r1(ovl),
20767 RRF4_r2(ovl)); goto ok;
20768 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, RRF4_r3(ovl),
20769 RRF4_r1(ovl), RRF4_r2(ovl));
20770 goto ok;
20771 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, RRF4_r3(ovl),
20772 RRF4_r1(ovl), RRF4_r2(ovl));
20773 goto ok;
20774 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, RRF4_r3(ovl),
20775 RRF4_r1(ovl), RRF4_r2(ovl));
20776 goto ok;
20777 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, RRF4_r3(ovl),
20778 RRF4_r1(ovl), RRF4_r2(ovl));
20779 goto ok;
20780 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, RRE_r1(ovl),
20781 RRE_r2(ovl)); goto ok;
20782 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, RRE_r1(ovl),
20783 RRE_r2(ovl)); goto ok;
20784 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, RRF4_r3(ovl),
20785 RRF4_r1(ovl), RRF4_r2(ovl));
20786 goto ok;
20787 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, RRF4_r3(ovl),
20788 RRF4_r1(ovl), RRF4_r2(ovl));
20789 goto ok;
20790 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, RRF4_r3(ovl),
20791 RRF4_r1(ovl), RRF4_r2(ovl));
20792 goto ok;
20793 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, RRF4_r3(ovl),
20794 RRF4_r1(ovl), RRF4_r2(ovl));
20795 goto ok;
20796 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, RRE_r1(ovl),
20797 RRE_r2(ovl)); goto ok;
20798 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, RRE_r1(ovl),
20799 RRE_r2(ovl)); goto ok;
20800 case 0xb9e0: s390_format_RRF_U0RR(s390_irgen_LOCFHR, RRF3_r3(ovl),
20801 RRF3_r1(ovl), RRF3_r2(ovl),
20802 S390_XMNM_CLS); goto ok;
20803 case 0xb9e1: s390_format_RRFa_U0RR(s390_irgen_POPCNT, RRF3_r3(ovl),
20804 RRF3_r1(ovl), RRF3_r2(ovl)); goto ok;
20805 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, RRF3_r3(ovl),
20806 RRF3_r1(ovl), RRF3_r2(ovl),
20807 S390_XMNM_CLS); goto ok;
20808 case 0xb9e3: s390_format_RRF_RURR(s390_irgen_SELGR, RRF4_r3(ovl),
20809 RRF4_m4(ovl), RRF4_r1(ovl),
20810 RRF4_r2(ovl)); goto ok;
20811 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, RRF4_r3(ovl),
20812 RRF4_r1(ovl), RRF4_r2(ovl));
20813 goto ok;
20814 case 0xb9e5: s390_format_RRF_R0RR2(s390_irgen_NCGRK, RRF4_r3(ovl),
20815 RRF4_r1(ovl), RRF4_r2(ovl));
20816 goto ok;
20817 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, RRF4_r3(ovl),
20818 RRF4_r1(ovl), RRF4_r2(ovl));
20819 goto ok;
20820 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, RRF4_r3(ovl),
20821 RRF4_r1(ovl), RRF4_r2(ovl));
20822 goto ok;
20823 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, RRF4_r3(ovl),
20824 RRF4_r1(ovl), RRF4_r2(ovl));
20825 goto ok;
20826 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, RRF4_r3(ovl),
20827 RRF4_r1(ovl), RRF4_r2(ovl));
20828 goto ok;
20829 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, RRF4_r3(ovl),
20830 RRF4_r1(ovl), RRF4_r2(ovl));
20831 goto ok;
20832 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, RRF4_r3(ovl),
20833 RRF4_r1(ovl), RRF4_r2(ovl));
20834 goto ok;
20835 case 0xb9ec: s390_format_RRF_R0RR2(s390_irgen_MGRK, RRF4_r3(ovl),
20836 RRF4_r1(ovl), RRF4_r2(ovl));
20837 goto ok;
20838 case 0xb9ed: s390_format_RRF_R0RR2(s390_irgen_MSGRKC, RRF4_r3(ovl),
20839 RRF4_r1(ovl), RRF4_r2(ovl));
20840 goto ok;
20841 case 0xb9f0: s390_format_RRF_RURR(s390_irgen_SELR, RRF4_r3(ovl),
20842 RRF4_m4(ovl), RRF4_r1(ovl),
20843 RRF4_r2(ovl)); goto ok;
20844 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, RRF3_r3(ovl),
20845 RRF3_r1(ovl), RRF3_r2(ovl),
20846 S390_XMNM_CLS); goto ok;
20847 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, RRF4_r3(ovl),
20848 RRF4_r1(ovl), RRF4_r2(ovl));
20849 goto ok;
20850 case 0xb9f5: s390_format_RRF_R0RR2(s390_irgen_NCRK, RRF4_r3(ovl),
20851 RRF4_r1(ovl), RRF4_r2(ovl));
20852 goto ok;
20853 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, RRF4_r3(ovl),
20854 RRF4_r1(ovl), RRF4_r2(ovl));
20855 goto ok;
20856 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, RRF4_r3(ovl),
20857 RRF4_r1(ovl), RRF4_r2(ovl));
20858 goto ok;
20859 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, RRF4_r3(ovl),
20860 RRF4_r1(ovl), RRF4_r2(ovl));
20861 goto ok;
20862 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, RRF4_r3(ovl),
20863 RRF4_r1(ovl), RRF4_r2(ovl));
20864 goto ok;
20865 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, RRF4_r3(ovl),
20866 RRF4_r1(ovl), RRF4_r2(ovl));
20867 goto ok;
20868 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, RRF4_r3(ovl),
20869 RRF4_r1(ovl), RRF4_r2(ovl));
20870 goto ok;
20871 case 0xb9fd: s390_format_RRF_R0RR2(s390_irgen_MSRKC, RRF4_r3(ovl),
20872 RRF4_r1(ovl), RRF4_r2(ovl));
20873 goto ok;
20876 switch ((ovl & 0xff000000) >> 24) {
20877 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, RX_r1(ovl), RX_x2(ovl),
20878 RX_b2(ovl), RX_d2(ovl)); goto ok;
20879 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, RX_r1(ovl), RX_x2(ovl),
20880 RX_b2(ovl), RX_d2(ovl)); goto ok;
20881 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, RX_r1(ovl), RX_x2(ovl),
20882 RX_b2(ovl), RX_d2(ovl)); goto ok;
20883 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, RX_r1(ovl), RX_x2(ovl),
20884 RX_b2(ovl), RX_d2(ovl)); goto ok;
20885 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, RX_r1(ovl), RX_x2(ovl),
20886 RX_b2(ovl), RX_d2(ovl)); goto ok;
20887 case 0x45: /* BAL */ goto unimplemented;
20888 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, RX_r1(ovl), RX_x2(ovl),
20889 RX_b2(ovl), RX_d2(ovl)); goto ok;
20890 case 0x47: s390_format_RX(s390_irgen_BC, RX_r1(ovl), RX_x2(ovl),
20891 RX_b2(ovl), RX_d2(ovl)); goto ok;
20892 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, RX_r1(ovl), RX_x2(ovl),
20893 RX_b2(ovl), RX_d2(ovl)); goto ok;
20894 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, RX_r1(ovl), RX_x2(ovl),
20895 RX_b2(ovl), RX_d2(ovl)); goto ok;
20896 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, RX_r1(ovl), RX_x2(ovl),
20897 RX_b2(ovl), RX_d2(ovl)); goto ok;
20898 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, RX_r1(ovl), RX_x2(ovl),
20899 RX_b2(ovl), RX_d2(ovl)); goto ok;
20900 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, RX_r1(ovl), RX_x2(ovl),
20901 RX_b2(ovl), RX_d2(ovl)); goto ok;
20902 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, RX_r1(ovl), RX_x2(ovl),
20903 RX_b2(ovl), RX_d2(ovl)); goto ok;
20904 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, RX_r1(ovl), RX_x2(ovl),
20905 RX_b2(ovl), RX_d2(ovl)); goto ok;
20906 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, RX_r1(ovl), RX_x2(ovl),
20907 RX_b2(ovl), RX_d2(ovl)); goto ok;
20908 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, RX_r1(ovl), RX_x2(ovl),
20909 RX_b2(ovl), RX_d2(ovl)); goto ok;
20910 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, RX_r1(ovl), RX_x2(ovl),
20911 RX_b2(ovl), RX_d2(ovl)); goto ok;
20912 case 0x54: s390_format_RX_RRRD(s390_irgen_N, RX_r1(ovl), RX_x2(ovl),
20913 RX_b2(ovl), RX_d2(ovl)); goto ok;
20914 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, RX_r1(ovl), RX_x2(ovl),
20915 RX_b2(ovl), RX_d2(ovl)); goto ok;
20916 case 0x56: s390_format_RX_RRRD(s390_irgen_O, RX_r1(ovl), RX_x2(ovl),
20917 RX_b2(ovl), RX_d2(ovl)); goto ok;
20918 case 0x57: s390_format_RX_RRRD(s390_irgen_X, RX_r1(ovl), RX_x2(ovl),
20919 RX_b2(ovl), RX_d2(ovl)); goto ok;
20920 case 0x58: s390_format_RX_RRRD(s390_irgen_L, RX_r1(ovl), RX_x2(ovl),
20921 RX_b2(ovl), RX_d2(ovl)); goto ok;
20922 case 0x59: s390_format_RX_RRRD(s390_irgen_C, RX_r1(ovl), RX_x2(ovl),
20923 RX_b2(ovl), RX_d2(ovl)); goto ok;
20924 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, RX_r1(ovl), RX_x2(ovl),
20925 RX_b2(ovl), RX_d2(ovl)); goto ok;
20926 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, RX_r1(ovl), RX_x2(ovl),
20927 RX_b2(ovl), RX_d2(ovl)); goto ok;
20928 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, RX_r1(ovl), RX_x2(ovl),
20929 RX_b2(ovl), RX_d2(ovl)); goto ok;
20930 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, RX_r1(ovl), RX_x2(ovl),
20931 RX_b2(ovl), RX_d2(ovl)); goto ok;
20932 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, RX_r1(ovl), RX_x2(ovl),
20933 RX_b2(ovl), RX_d2(ovl)); goto ok;
20934 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, RX_r1(ovl), RX_x2(ovl),
20935 RX_b2(ovl), RX_d2(ovl)); goto ok;
20936 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, RX_r1(ovl), RX_x2(ovl),
20937 RX_b2(ovl), RX_d2(ovl)); goto ok;
20938 case 0x67: /* MXD */ goto unimplemented;
20939 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, RX_r1(ovl), RX_x2(ovl),
20940 RX_b2(ovl), RX_d2(ovl)); goto ok;
20941 case 0x69: /* CD */ goto unimplemented;
20942 case 0x6a: /* AD */ goto unimplemented;
20943 case 0x6b: /* SD */ goto unimplemented;
20944 case 0x6c: /* MD */ goto unimplemented;
20945 case 0x6d: /* DD */ goto unimplemented;
20946 case 0x6e: /* AW */ goto unimplemented;
20947 case 0x6f: /* SW */ goto unimplemented;
20948 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, RX_r1(ovl), RX_x2(ovl),
20949 RX_b2(ovl), RX_d2(ovl)); goto ok;
20950 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, RX_r1(ovl), RX_x2(ovl),
20951 RX_b2(ovl), RX_d2(ovl)); goto ok;
20952 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, RX_r1(ovl), RX_x2(ovl),
20953 RX_b2(ovl), RX_d2(ovl)); goto ok;
20954 case 0x79: /* CE */ goto unimplemented;
20955 case 0x7a: /* AE */ goto unimplemented;
20956 case 0x7b: /* SE */ goto unimplemented;
20957 case 0x7c: /* MDE */ goto unimplemented;
20958 case 0x7d: /* DE */ goto unimplemented;
20959 case 0x7e: /* AU */ goto unimplemented;
20960 case 0x7f: /* SU */ goto unimplemented;
20961 case 0x83: /* DIAG */ goto unimplemented;
20962 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, RSI_r1(ovl),
20963 RSI_r3(ovl), RSI_i2(ovl)); goto ok;
20964 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, RSI_r1(ovl),
20965 RSI_r3(ovl), RSI_i2(ovl)); goto ok;
20966 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, RS_r1(ovl), RS_r3(ovl),
20967 RS_b2(ovl), RS_d2(ovl)); goto ok;
20968 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, RS_r1(ovl), RS_r3(ovl),
20969 RS_b2(ovl), RS_d2(ovl)); goto ok;
20970 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, RS_r1(ovl), RS_b2(ovl),
20971 RS_d2(ovl)); goto ok;
20972 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, RS_r1(ovl), RS_b2(ovl),
20973 RS_d2(ovl)); goto ok;
20974 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, RS_r1(ovl), RS_b2(ovl),
20975 RS_d2(ovl)); goto ok;
20976 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, RS_r1(ovl), RS_b2(ovl),
20977 RS_d2(ovl)); goto ok;
20978 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, RS_r1(ovl), RS_b2(ovl),
20979 RS_d2(ovl)); goto ok;
20980 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, RS_r1(ovl), RS_b2(ovl),
20981 RS_d2(ovl)); goto ok;
20982 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, RS_r1(ovl), RS_b2(ovl),
20983 RS_d2(ovl)); goto ok;
20984 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, RS_r1(ovl), RS_b2(ovl),
20985 RS_d2(ovl)); goto ok;
20986 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, RS_r1(ovl), RS_r3(ovl),
20987 RS_b2(ovl), RS_d2(ovl)); goto ok;
20988 case 0x91: s390_format_SI_URD(s390_irgen_TM, SI_i2(ovl), SI_b1(ovl),
20989 SI_d1(ovl)); goto ok;
20990 case 0x92: s390_format_SI_URD(s390_irgen_MVI, SI_i2(ovl), SI_b1(ovl),
20991 SI_d1(ovl)); goto ok;
20992 case 0x94: s390_format_SI_URD(s390_irgen_NI, SI_i2(ovl), SI_b1(ovl),
20993 SI_d1(ovl)); goto ok;
20994 case 0x95: s390_format_SI_URD(s390_irgen_CLI, SI_i2(ovl), SI_b1(ovl),
20995 SI_d1(ovl)); goto ok;
20996 case 0x96: s390_format_SI_URD(s390_irgen_OI, SI_i2(ovl), SI_b1(ovl),
20997 SI_d1(ovl)); goto ok;
20998 case 0x97: s390_format_SI_URD(s390_irgen_XI, SI_i2(ovl), SI_b1(ovl),
20999 SI_d1(ovl)); goto ok;
21000 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, RS_r1(ovl), RS_r3(ovl),
21001 RS_b2(ovl), RS_d2(ovl)); goto ok;
21002 case 0x99: /* TRACE */ goto unimplemented;
21003 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, RS_r1(ovl), RS_r3(ovl),
21004 RS_b2(ovl), RS_d2(ovl)); goto ok;
21005 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, RS_r1(ovl), RS_r3(ovl),
21006 RS_b2(ovl), RS_d2(ovl)); goto ok;
21007 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, RS_r1(ovl),
21008 RS_r3(ovl), RS_b2(ovl), RS_d2(ovl));
21009 goto ok;
21010 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, RS_r1(ovl),
21011 RS_r3(ovl), RS_b2(ovl), RS_d2(ovl));
21012 goto ok;
21013 case 0xac: /* STNSM */ goto unimplemented;
21014 case 0xad: /* STOSM */ goto unimplemented;
21015 case 0xae: /* SIGP */ goto unimplemented;
21016 case 0xaf: /* MC */ goto unimplemented;
21017 case 0xb1: /* LRA */ goto unimplemented;
21018 case 0xb6: /* STCTL */ goto unimplemented;
21019 case 0xb7: /* LCTL */ goto unimplemented;
21020 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, RS_r1(ovl), RS_r3(ovl),
21021 RS_b2(ovl), RS_d2(ovl)); goto ok;
21022 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, RS_r1(ovl), RS_r3(ovl),
21023 RS_b2(ovl), RS_d2(ovl)); goto ok;
21024 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, RS_r1(ovl), RS_r3(ovl),
21025 RS_b2(ovl), RS_d2(ovl)); goto ok;
21026 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, RS_r1(ovl), RS_r3(ovl),
21027 RS_b2(ovl), RS_d2(ovl)); goto ok;
21028 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, RS_r1(ovl), RS_r3(ovl),
21029 RS_b2(ovl), RS_d2(ovl)); goto ok;
21032 return S390_DECODE_UNKNOWN_INSN;
21035 return S390_DECODE_OK;
21037 unimplemented:
21038 return S390_DECODE_UNIMPLEMENTED_INSN;
21041 static s390_decode_t
21042 s390_decode_6byte_and_irgen(const UChar *bytes)
21044 ULong ovl = ((ULong)bytes[0] << 56) | ((ULong)bytes[1] << 48) |
21045 ((ULong)bytes[2] << 40) | ((ULong)bytes[3] << 32) |
21046 ((ULong)bytes[4] << 24) | ((ULong)bytes[5] << 16);
21048 switch ((ovl >> 16) & 0xff00000000ffULL) {
21049 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, RXY_r1(ovl),
21050 RXY_x2(ovl), RXY_b2(ovl),
21051 RXY_dl2(ovl),
21052 RXY_dh2(ovl)); goto ok;
21053 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
21054 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, RXY_r1(ovl),
21055 RXY_x2(ovl), RXY_b2(ovl),
21056 RXY_dl2(ovl),
21057 RXY_dh2(ovl)); goto ok;
21058 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, RXY_r1(ovl),
21059 RXY_x2(ovl), RXY_b2(ovl),
21060 RXY_dl2(ovl),
21061 RXY_dh2(ovl)); goto ok;
21062 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, RXY_r1(ovl),
21063 RXY_x2(ovl), RXY_b2(ovl),
21064 RXY_dl2(ovl),
21065 RXY_dh2(ovl)); goto ok;
21066 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, RXY_r1(ovl),
21067 RXY_x2(ovl), RXY_b2(ovl),
21068 RXY_dl2(ovl),
21069 RXY_dh2(ovl)); goto ok;
21070 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, RXY_r1(ovl),
21071 RXY_x2(ovl), RXY_b2(ovl),
21072 RXY_dl2(ovl),
21073 RXY_dh2(ovl)); goto ok;
21074 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, RXY_r1(ovl),
21075 RXY_x2(ovl), RXY_b2(ovl),
21076 RXY_dl2(ovl),
21077 RXY_dh2(ovl)); goto ok;
21078 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, RXY_r1(ovl),
21079 RXY_x2(ovl), RXY_b2(ovl),
21080 RXY_dl2(ovl),
21081 RXY_dh2(ovl)); goto ok;
21082 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, RXY_r1(ovl),
21083 RXY_x2(ovl), RXY_b2(ovl),
21084 RXY_dl2(ovl),
21085 RXY_dh2(ovl)); goto ok;
21086 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
21087 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, RXY_r1(ovl),
21088 RXY_x2(ovl), RXY_b2(ovl),
21089 RXY_dl2(ovl),
21090 RXY_dh2(ovl)); goto ok;
21091 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, RXY_r1(ovl),
21092 RXY_x2(ovl), RXY_b2(ovl),
21093 RXY_dl2(ovl),
21094 RXY_dh2(ovl)); goto ok;
21095 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
21096 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, RXY_r1(ovl),
21097 RXY_x2(ovl), RXY_b2(ovl),
21098 RXY_dl2(ovl),
21099 RXY_dh2(ovl)); goto ok;
21100 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, RXY_r1(ovl),
21101 RXY_x2(ovl), RXY_b2(ovl),
21102 RXY_dl2(ovl),
21103 RXY_dh2(ovl)); goto ok;
21104 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, RXY_r1(ovl),
21105 RXY_x2(ovl), RXY_b2(ovl),
21106 RXY_dl2(ovl),
21107 RXY_dh2(ovl)); goto ok;
21108 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, RXY_r1(ovl),
21109 RXY_x2(ovl), RXY_b2(ovl),
21110 RXY_dl2(ovl),
21111 RXY_dh2(ovl)); goto ok;
21112 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, RXY_r1(ovl),
21113 RXY_x2(ovl), RXY_b2(ovl),
21114 RXY_dl2(ovl),
21115 RXY_dh2(ovl)); goto ok;
21116 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, RXY_r1(ovl),
21117 RXY_x2(ovl), RXY_b2(ovl),
21118 RXY_dl2(ovl),
21119 RXY_dh2(ovl)); goto ok;
21120 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, RXY_r1(ovl),
21121 RXY_x2(ovl), RXY_b2(ovl),
21122 RXY_dl2(ovl),
21123 RXY_dh2(ovl)); goto ok;
21124 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, RXY_r1(ovl),
21125 RXY_x2(ovl), RXY_b2(ovl),
21126 RXY_dl2(ovl),
21127 RXY_dh2(ovl)); goto ok;
21128 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, RXY_r1(ovl),
21129 RXY_x2(ovl), RXY_b2(ovl),
21130 RXY_dl2(ovl),
21131 RXY_dh2(ovl)); goto ok;
21132 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, RXY_r1(ovl),
21133 RXY_x2(ovl), RXY_b2(ovl),
21134 RXY_dl2(ovl),
21135 RXY_dh2(ovl)); goto ok;
21136 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, RXY_r1(ovl),
21137 RXY_x2(ovl), RXY_b2(ovl),
21138 RXY_dl2(ovl),
21139 RXY_dh2(ovl)); goto ok;
21140 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, RXY_r1(ovl),
21141 RXY_x2(ovl), RXY_b2(ovl),
21142 RXY_dl2(ovl),
21143 RXY_dh2(ovl)); goto ok;
21144 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, RXY_r1(ovl),
21145 RXY_x2(ovl), RXY_b2(ovl),
21146 RXY_dl2(ovl),
21147 RXY_dh2(ovl)); goto ok;
21148 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, RXY_r1(ovl),
21149 RXY_x2(ovl), RXY_b2(ovl),
21150 RXY_dl2(ovl),
21151 RXY_dh2(ovl)); goto ok;
21152 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, RXY_r1(ovl),
21153 RXY_x2(ovl), RXY_b2(ovl),
21154 RXY_dl2(ovl),
21155 RXY_dh2(ovl)); goto ok;
21156 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
21157 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, RXY_r1(ovl),
21158 RXY_x2(ovl), RXY_b2(ovl),
21159 RXY_dl2(ovl),
21160 RXY_dh2(ovl)); goto ok;
21161 case 0xe3000000002aULL: s390_format_RXY_RRRD(s390_irgen_LZRG, RXY_r1(ovl),
21162 RXY_x2(ovl), RXY_b2(ovl),
21163 RXY_dl2(ovl),
21164 RXY_dh2(ovl)); goto ok;
21165 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
21166 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
21167 RXY_r1(ovl), RXY_x2(ovl),
21168 RXY_b2(ovl), RXY_dl2(ovl),
21169 RXY_dh2(ovl)); goto ok;
21170 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, RXY_r1(ovl),
21171 RXY_x2(ovl), RXY_b2(ovl),
21172 RXY_dl2(ovl),
21173 RXY_dh2(ovl)); goto ok;
21174 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, RXY_r1(ovl),
21175 RXY_x2(ovl), RXY_b2(ovl),
21176 RXY_dl2(ovl),
21177 RXY_dh2(ovl)); goto ok;
21178 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, RXY_r1(ovl),
21179 RXY_x2(ovl), RXY_b2(ovl),
21180 RXY_dl2(ovl),
21181 RXY_dh2(ovl)); goto ok;
21182 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, RXY_r1(ovl),
21183 RXY_x2(ovl), RXY_b2(ovl),
21184 RXY_dl2(ovl),
21185 RXY_dh2(ovl)); goto ok;
21186 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, RXY_r1(ovl),
21187 RXY_x2(ovl), RXY_b2(ovl),
21188 RXY_dl2(ovl),
21189 RXY_dh2(ovl)); goto ok;
21190 case 0xe30000000038ULL: s390_format_RXY_RRRD(s390_irgen_AGH, RXY_r1(ovl),
21191 RXY_x2(ovl), RXY_b2(ovl),
21192 RXY_dl2(ovl),
21193 RXY_dh2(ovl)); goto ok;
21194 case 0xe30000000039ULL: s390_format_RXY_RRRD(s390_irgen_SGH, RXY_r1(ovl),
21195 RXY_x2(ovl), RXY_b2(ovl),
21196 RXY_dl2(ovl),
21197 RXY_dh2(ovl)); goto ok;
21198 case 0xe3000000003aULL: s390_format_RXY_RRRD(s390_irgen_LLZRGF, RXY_r1(ovl),
21199 RXY_x2(ovl), RXY_b2(ovl),
21200 RXY_dl2(ovl),
21201 RXY_dh2(ovl)); goto ok;
21202 case 0xe3000000003bULL: s390_format_RXY_RRRD(s390_irgen_LZRF, RXY_r1(ovl),
21203 RXY_x2(ovl), RXY_b2(ovl),
21204 RXY_dl2(ovl),
21205 RXY_dh2(ovl)); goto ok;
21206 case 0xe3000000003cULL: s390_format_RXY_RRRD(s390_irgen_MGH, RXY_r1(ovl),
21207 RXY_x2(ovl), RXY_b2(ovl),
21208 RXY_dl2(ovl),
21209 RXY_dh2(ovl)); goto ok;
21210 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, RXY_r1(ovl),
21211 RXY_x2(ovl), RXY_b2(ovl),
21212 RXY_dl2(ovl),
21213 RXY_dh2(ovl)); goto ok;
21214 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
21215 RXY_r1(ovl), RXY_x2(ovl),
21216 RXY_b2(ovl), RXY_dl2(ovl),
21217 RXY_dh2(ovl)); goto ok;
21218 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, RXY_r1(ovl),
21219 RXY_x2(ovl), RXY_b2(ovl),
21220 RXY_dl2(ovl),
21221 RXY_dh2(ovl)); goto ok;
21222 case 0xe30000000047ULL: s390_format_RXY_RRRD(s390_irgen_BIC, RXY_r1(ovl),
21223 RXY_x2(ovl), RXY_b2(ovl),
21224 RXY_dl2(ovl),
21225 RXY_dh2(ovl)); goto ok;
21226 case 0xe30000000048ULL: /* LLGFSG */ goto unimplemented;
21227 case 0xe30000000049ULL: /* STGSC */ goto unimplemented;
21228 case 0xe3000000004cULL: /* LGG */ goto unimplemented;
21229 case 0xe3000000004dULL: /* LGSC */ goto unimplemented;
21230 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, RXY_r1(ovl),
21231 RXY_x2(ovl), RXY_b2(ovl),
21232 RXY_dl2(ovl),
21233 RXY_dh2(ovl)); goto ok;
21234 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, RXY_r1(ovl),
21235 RXY_x2(ovl), RXY_b2(ovl),
21236 RXY_dl2(ovl),
21237 RXY_dh2(ovl)); goto ok;
21238 case 0xe30000000053ULL: s390_format_RXY_RRRD(s390_irgen_MSC, RXY_r1(ovl),
21239 RXY_x2(ovl), RXY_b2(ovl),
21240 RXY_dl2(ovl),
21241 RXY_dh2(ovl)); goto ok;
21242 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, RXY_r1(ovl),
21243 RXY_x2(ovl), RXY_b2(ovl),
21244 RXY_dl2(ovl),
21245 RXY_dh2(ovl)); goto ok;
21246 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, RXY_r1(ovl),
21247 RXY_x2(ovl), RXY_b2(ovl),
21248 RXY_dl2(ovl),
21249 RXY_dh2(ovl)); goto ok;
21250 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, RXY_r1(ovl),
21251 RXY_x2(ovl), RXY_b2(ovl),
21252 RXY_dl2(ovl),
21253 RXY_dh2(ovl)); goto ok;
21254 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, RXY_r1(ovl),
21255 RXY_x2(ovl), RXY_b2(ovl),
21256 RXY_dl2(ovl),
21257 RXY_dh2(ovl)); goto ok;
21258 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, RXY_r1(ovl),
21259 RXY_x2(ovl), RXY_b2(ovl),
21260 RXY_dl2(ovl),
21261 RXY_dh2(ovl)); goto ok;
21262 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, RXY_r1(ovl),
21263 RXY_x2(ovl), RXY_b2(ovl),
21264 RXY_dl2(ovl),
21265 RXY_dh2(ovl)); goto ok;
21266 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, RXY_r1(ovl),
21267 RXY_x2(ovl), RXY_b2(ovl),
21268 RXY_dl2(ovl),
21269 RXY_dh2(ovl)); goto ok;
21270 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, RXY_r1(ovl),
21271 RXY_x2(ovl), RXY_b2(ovl),
21272 RXY_dl2(ovl),
21273 RXY_dh2(ovl)); goto ok;
21274 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, RXY_r1(ovl),
21275 RXY_x2(ovl), RXY_b2(ovl),
21276 RXY_dl2(ovl),
21277 RXY_dh2(ovl)); goto ok;
21278 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, RXY_r1(ovl),
21279 RXY_x2(ovl), RXY_b2(ovl),
21280 RXY_dl2(ovl),
21281 RXY_dh2(ovl)); goto ok;
21282 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, RXY_r1(ovl),
21283 RXY_x2(ovl), RXY_b2(ovl),
21284 RXY_dl2(ovl),
21285 RXY_dh2(ovl)); goto ok;
21286 case 0xe30000000060ULL: /* LXAB */ goto unimplemented;
21287 case 0xe30000000061ULL: /* LLXAB */ goto unimplemented;
21288 case 0xe30000000062ULL: /* LXAH */ goto unimplemented;
21289 case 0xe30000000063ULL: /* LLXAH */ goto unimplemented;
21290 case 0xe30000000064ULL: /* LXAF */ goto unimplemented;
21291 case 0xe30000000065ULL: /* LLXAF */ goto unimplemented;
21292 case 0xe30000000066ULL: /* LXAG */ goto unimplemented;
21293 case 0xe30000000067ULL: /* LLXAG */ goto unimplemented;
21294 case 0xe30000000068ULL: /* LXAQ */ goto unimplemented;
21295 case 0xe30000000069ULL: /* LLXAQ */ goto unimplemented;
21296 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, RXY_r1(ovl),
21297 RXY_x2(ovl), RXY_b2(ovl),
21298 RXY_dl2(ovl),
21299 RXY_dh2(ovl)); goto ok;
21300 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, RXY_r1(ovl),
21301 RXY_x2(ovl), RXY_b2(ovl),
21302 RXY_dl2(ovl),
21303 RXY_dh2(ovl)); goto ok;
21304 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, RXY_r1(ovl),
21305 RXY_x2(ovl), RXY_b2(ovl),
21306 RXY_dl2(ovl),
21307 RXY_dh2(ovl)); goto ok;
21308 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, RXY_r1(ovl),
21309 RXY_x2(ovl), RXY_b2(ovl),
21310 RXY_dl2(ovl),
21311 RXY_dh2(ovl)); goto ok;
21312 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, RXY_r1(ovl),
21313 RXY_x2(ovl), RXY_b2(ovl),
21314 RXY_dl2(ovl),
21315 RXY_dh2(ovl)); goto ok;
21316 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, RXY_r1(ovl),
21317 RXY_x2(ovl), RXY_b2(ovl),
21318 RXY_dl2(ovl),
21319 RXY_dh2(ovl)); goto ok;
21320 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, RXY_r1(ovl),
21321 RXY_x2(ovl), RXY_b2(ovl),
21322 RXY_dl2(ovl),
21323 RXY_dh2(ovl)); goto ok;
21324 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, RXY_r1(ovl),
21325 RXY_x2(ovl), RXY_b2(ovl),
21326 RXY_dl2(ovl),
21327 RXY_dh2(ovl)); goto ok;
21328 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, RXY_r1(ovl),
21329 RXY_x2(ovl), RXY_b2(ovl),
21330 RXY_dl2(ovl),
21331 RXY_dh2(ovl)); goto ok;
21332 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, RXY_r1(ovl),
21333 RXY_x2(ovl), RXY_b2(ovl),
21334 RXY_dl2(ovl),
21335 RXY_dh2(ovl)); goto ok;
21336 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, RXY_r1(ovl),
21337 RXY_x2(ovl), RXY_b2(ovl),
21338 RXY_dl2(ovl),
21339 RXY_dh2(ovl)); goto ok;
21340 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, RXY_r1(ovl),
21341 RXY_x2(ovl), RXY_b2(ovl),
21342 RXY_dl2(ovl),
21343 RXY_dh2(ovl)); goto ok;
21344 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, RXY_r1(ovl),
21345 RXY_x2(ovl), RXY_b2(ovl),
21346 RXY_dl2(ovl),
21347 RXY_dh2(ovl)); goto ok;
21348 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, RXY_r1(ovl),
21349 RXY_x2(ovl), RXY_b2(ovl),
21350 RXY_dl2(ovl),
21351 RXY_dh2(ovl)); goto ok;
21352 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, RXY_r1(ovl),
21353 RXY_x2(ovl), RXY_b2(ovl),
21354 RXY_dl2(ovl),
21355 RXY_dh2(ovl)); goto ok;
21356 case 0xe30000000083ULL: s390_format_RXY_RRRD(s390_irgen_MSGC, RXY_r1(ovl),
21357 RXY_x2(ovl), RXY_b2(ovl),
21358 RXY_dl2(ovl),
21359 RXY_dh2(ovl)); goto ok;
21360 case 0xe30000000084ULL: s390_format_RXY_RRRD(s390_irgen_MG, RXY_r1(ovl),
21361 RXY_x2(ovl), RXY_b2(ovl),
21362 RXY_dl2(ovl),
21363 RXY_dh2(ovl)); goto ok;
21364 case 0xe30000000085ULL: s390_format_RXY_RRRD(s390_irgen_LGAT, RXY_r1(ovl),
21365 RXY_x2(ovl), RXY_b2(ovl),
21366 RXY_dl2(ovl),
21367 RXY_dh2(ovl)); goto ok;
21369 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, RXY_r1(ovl),
21370 RXY_x2(ovl), RXY_b2(ovl),
21371 RXY_dl2(ovl),
21372 RXY_dh2(ovl)); goto ok;
21373 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, RXY_r1(ovl),
21374 RXY_x2(ovl), RXY_b2(ovl),
21375 RXY_dl2(ovl),
21376 RXY_dh2(ovl)); goto ok;
21377 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, RXY_r1(ovl),
21378 RXY_x2(ovl), RXY_b2(ovl),
21379 RXY_dl2(ovl),
21380 RXY_dh2(ovl)); goto ok;
21381 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, RXY_r1(ovl),
21382 RXY_x2(ovl), RXY_b2(ovl),
21383 RXY_dl2(ovl),
21384 RXY_dh2(ovl)); goto ok;
21385 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, RXY_r1(ovl),
21386 RXY_x2(ovl), RXY_b2(ovl),
21387 RXY_dl2(ovl),
21388 RXY_dh2(ovl)); goto ok;
21389 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, RXY_r1(ovl),
21390 RXY_x2(ovl), RXY_b2(ovl),
21391 RXY_dl2(ovl),
21392 RXY_dh2(ovl)); goto ok;
21393 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, RXY_r1(ovl),
21394 RXY_x2(ovl), RXY_b2(ovl),
21395 RXY_dl2(ovl),
21396 RXY_dh2(ovl)); goto ok;
21397 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, RXY_r1(ovl),
21398 RXY_x2(ovl), RXY_b2(ovl),
21399 RXY_dl2(ovl),
21400 RXY_dh2(ovl)); goto ok;
21401 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, RXY_r1(ovl),
21402 RXY_x2(ovl), RXY_b2(ovl),
21403 RXY_dl2(ovl),
21404 RXY_dh2(ovl)); goto ok;
21405 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, RXY_r1(ovl),
21406 RXY_x2(ovl), RXY_b2(ovl),
21407 RXY_dl2(ovl),
21408 RXY_dh2(ovl)); goto ok;
21409 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, RXY_r1(ovl),
21410 RXY_x2(ovl), RXY_b2(ovl),
21411 RXY_dl2(ovl),
21412 RXY_dh2(ovl)); goto ok;
21413 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, RXY_r1(ovl),
21414 RXY_x2(ovl), RXY_b2(ovl),
21415 RXY_dl2(ovl),
21416 RXY_dh2(ovl)); goto ok;
21417 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, RXY_r1(ovl),
21418 RXY_x2(ovl), RXY_b2(ovl),
21419 RXY_dl2(ovl),
21420 RXY_dh2(ovl)); goto ok;
21421 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, RXY_r1(ovl),
21422 RXY_x2(ovl), RXY_b2(ovl),
21423 RXY_dl2(ovl),
21424 RXY_dh2(ovl)); goto ok;
21425 case 0xe3000000009cULL: s390_format_RXY_RRRD(s390_irgen_LLGTAT, RXY_r1(ovl),
21426 RXY_x2(ovl), RXY_b2(ovl),
21427 RXY_dl2(ovl),
21428 RXY_dh2(ovl)); goto ok;
21429 case 0xe3000000009dULL: s390_format_RXY_RRRD(s390_irgen_LLGFAT, RXY_r1(ovl),
21430 RXY_x2(ovl), RXY_b2(ovl),
21431 RXY_dl2(ovl),
21432 RXY_dh2(ovl)); goto ok;
21433 case 0xe3000000009fULL: s390_format_RXY_RRRD(s390_irgen_LAT, RXY_r1(ovl),
21434 RXY_x2(ovl), RXY_b2(ovl),
21435 RXY_dl2(ovl),
21436 RXY_dh2(ovl)); goto ok;
21437 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, RXY_r1(ovl),
21438 RXY_x2(ovl), RXY_b2(ovl),
21439 RXY_dl2(ovl),
21440 RXY_dh2(ovl)); goto ok;
21441 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, RXY_r1(ovl),
21442 RXY_x2(ovl), RXY_b2(ovl),
21443 RXY_dl2(ovl),
21444 RXY_dh2(ovl)); goto ok;
21445 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, RXY_r1(ovl),
21446 RXY_x2(ovl), RXY_b2(ovl),
21447 RXY_dl2(ovl),
21448 RXY_dh2(ovl)); goto ok;
21449 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, RXY_r1(ovl),
21450 RXY_x2(ovl), RXY_b2(ovl),
21451 RXY_dl2(ovl),
21452 RXY_dh2(ovl)); goto ok;
21453 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, RXY_r1(ovl),
21454 RXY_x2(ovl), RXY_b2(ovl),
21455 RXY_dl2(ovl),
21456 RXY_dh2(ovl)); goto ok;
21457 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, RXY_r1(ovl),
21458 RXY_x2(ovl), RXY_b2(ovl),
21459 RXY_dl2(ovl),
21460 RXY_dh2(ovl)); goto ok;
21461 case 0xe300000000c8ULL: s390_format_RXY_RRRD(s390_irgen_LFHAT, RXY_r1(ovl),
21462 RXY_x2(ovl), RXY_b2(ovl),
21463 RXY_dl2(ovl),
21464 RXY_dh2(ovl)); goto ok;
21465 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, RXY_r1(ovl),
21466 RXY_x2(ovl), RXY_b2(ovl),
21467 RXY_dl2(ovl),
21468 RXY_dh2(ovl)); goto ok;
21469 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, RXY_r1(ovl),
21470 RXY_x2(ovl), RXY_b2(ovl),
21471 RXY_dl2(ovl),
21472 RXY_dh2(ovl)); goto ok;
21473 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, RXY_r1(ovl),
21474 RXY_x2(ovl), RXY_b2(ovl),
21475 RXY_dl2(ovl),
21476 RXY_dh2(ovl)); goto ok;
21477 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, RXY_r1(ovl),
21478 RXY_x2(ovl), RXY_b2(ovl),
21479 RXY_dl2(ovl),
21480 RXY_dh2(ovl)); goto ok;
21481 case 0xe60000000001ULL: s390_format_VRX_VRRDM(s390_irgen_VLEBRH, VRX_v1(ovl),
21482 VRX_x2(ovl), VRX_b2(ovl),
21483 VRX_d2(ovl), VRX_m3(ovl),
21484 VRX_rxb(ovl)); goto ok;
21485 case 0xe60000000002ULL: s390_format_VRX_VRRDM(s390_irgen_VLEBRG, VRX_v1(ovl),
21486 VRX_x2(ovl), VRX_b2(ovl),
21487 VRX_d2(ovl), VRX_m3(ovl),
21488 VRX_rxb(ovl)); goto ok;
21489 case 0xe60000000003ULL: s390_format_VRX_VRRDM(s390_irgen_VLEBRF, VRX_v1(ovl),
21490 VRX_x2(ovl), VRX_b2(ovl),
21491 VRX_d2(ovl), VRX_m3(ovl),
21492 VRX_rxb(ovl)); goto ok;
21493 case 0xe60000000004ULL: s390_format_VRX_VRRDM(s390_irgen_VLLEBRZ,
21494 VRX_v1(ovl),
21495 VRX_x2(ovl), VRX_b2(ovl),
21496 VRX_d2(ovl), VRX_m3(ovl),
21497 VRX_rxb(ovl)); goto ok;
21498 case 0xe60000000005ULL: s390_format_VRX_VRRDM(s390_irgen_VLBRREP,
21499 VRX_v1(ovl),
21500 VRX_x2(ovl), VRX_b2(ovl),
21501 VRX_d2(ovl), VRX_m3(ovl),
21502 VRX_rxb(ovl)); goto ok;
21503 case 0xe60000000006ULL: s390_format_VRX_VRRDM(s390_irgen_VLBR, VRX_v1(ovl),
21504 VRX_x2(ovl), VRX_b2(ovl),
21505 VRX_d2(ovl), VRX_m3(ovl),
21506 VRX_rxb(ovl)); goto ok;
21507 case 0xe60000000007ULL: s390_format_VRX_VRRDM(s390_irgen_VLER, VRX_v1(ovl),
21508 VRX_x2(ovl), VRX_b2(ovl),
21509 VRX_d2(ovl), VRX_m3(ovl),
21510 VRX_rxb(ovl)); goto ok;
21511 case 0xe60000000009ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEBRH,
21512 VRX_v1(ovl),
21513 VRX_x2(ovl), VRX_b2(ovl),
21514 VRX_d2(ovl), VRX_m3(ovl),
21515 VRX_rxb(ovl)); goto ok;
21516 case 0xe6000000000aULL: s390_format_VRX_VRRDM(s390_irgen_VSTEBRG,
21517 VRX_v1(ovl),
21518 VRX_x2(ovl), VRX_b2(ovl),
21519 VRX_d2(ovl), VRX_m3(ovl),
21520 VRX_rxb(ovl)); goto ok;
21521 case 0xe6000000000bULL: s390_format_VRX_VRRDM(s390_irgen_VSTEBRF,
21522 VRX_v1(ovl),
21523 VRX_x2(ovl), VRX_b2(ovl),
21524 VRX_d2(ovl), VRX_m3(ovl),
21525 VRX_rxb(ovl)); goto ok;
21526 case 0xe6000000000eULL: s390_format_VRX_VRRDM(s390_irgen_VSTBR, VRX_v1(ovl),
21527 VRX_x2(ovl), VRX_b2(ovl),
21528 VRX_d2(ovl), VRX_m3(ovl),
21529 VRX_rxb(ovl)); goto ok;
21530 case 0xe6000000000fULL: s390_format_VRX_VRRDM(s390_irgen_VSTER, VRX_v1(ovl),
21531 VRX_x2(ovl), VRX_b2(ovl),
21532 VRX_d2(ovl), VRX_m3(ovl),
21533 VRX_rxb(ovl)); goto ok;
21534 case 0xe60000000034ULL: /* VPKZ */ goto unimplemented;
21535 case 0xe60000000035ULL: s390_format_VSI_URDV(s390_irgen_VLRL, VSI_v1(ovl),
21536 VSI_b2(ovl), VSI_d2(ovl),
21537 VSI_i3(ovl),
21538 VSI_rxb(ovl)); goto ok;
21539 case 0xe60000000037ULL: s390_format_VRS_RRDV(s390_irgen_VLRLR, VRSd_v1(ovl),
21540 VRSd_r3(ovl), VRS_b2(ovl),
21541 VRS_d2(ovl),
21542 VRS_rxb(ovl)); goto ok;
21543 case 0xe6000000003cULL: /* VUPKZ */ goto unimplemented;
21544 case 0xe6000000003dULL: s390_format_VSI_URDV(s390_irgen_VSTRL, VSI_v1(ovl),
21545 VSI_b2(ovl), VSI_d2(ovl),
21546 VSI_i3(ovl),
21547 VSI_rxb(ovl)); goto ok;
21548 case 0xe6000000003fULL: s390_format_VRS_RRDV(s390_irgen_VSTRLR, VRSd_v1(ovl),
21549 VRSd_r3(ovl), VRS_b2(ovl),
21550 VRS_d2(ovl),
21551 VRS_rxb(ovl)); goto ok;
21552 case 0xe60000000049ULL: /* VLIP */ goto unimplemented;
21553 case 0xe6000000004aULL: /* VCVDQ */ goto unimplemented;
21554 case 0xe6000000004eULL: /* VCVBQ */ goto unimplemented;
21555 case 0xe60000000050ULL: /* VCVB */ goto unimplemented;
21556 case 0xe60000000051ULL: /* VCLZDP */ goto unimplemented;
21557 case 0xe60000000052ULL: /* VCVBG */ goto unimplemented;
21558 case 0xe60000000054ULL: /* VUPKZH */ goto unimplemented;
21559 case 0xe60000000055ULL: s390_format_VRRa_VVMM(s390_irgen_VCNF,
21560 VRRa_v1(ovl), VRRa_v2(ovl),
21561 VRRa_m3(ovl), VRRa_m4(ovl),
21562 VRRa_rxb(ovl)); goto ok;
21563 case 0xe60000000056ULL: s390_format_VRRa_VVMM(s390_irgen_VCLFNH,
21564 VRRa_v1(ovl), VRRa_v2(ovl),
21565 VRRa_m3(ovl), VRRa_m4(ovl),
21566 VRRa_rxb(ovl)); goto ok;
21567 case 0xe6000000005dULL: s390_format_VRRa_VVMM(s390_irgen_VCFN,
21568 VRRa_v1(ovl), VRRa_v2(ovl),
21569 VRRa_m3(ovl), VRRa_m4(ovl),
21570 VRRa_rxb(ovl)); goto ok;
21571 case 0xe6000000005eULL: s390_format_VRRa_VVMM(s390_irgen_VCLFNL,
21572 VRRa_v1(ovl), VRRa_v2(ovl),
21573 VRRa_m3(ovl), VRRa_m4(ovl),
21574 VRRa_rxb(ovl)); goto ok;
21575 case 0xe60000000058ULL: /* VCVD */ goto unimplemented;
21576 case 0xe60000000059ULL: /* VSRP */ goto unimplemented;
21577 case 0xe6000000005aULL: /* VCVDG */ goto unimplemented;
21578 case 0xe6000000005bULL: /* VPSOP */ goto unimplemented;
21579 case 0xe6000000005cULL: /* VUPKZL */ goto unimplemented;
21580 case 0xe6000000005fULL: /* VTP */ goto unimplemented;
21581 case 0xe60000000070ULL: /* VPKZR */ goto unimplemented;
21582 case 0xe60000000071ULL: /* VAP */ goto unimplemented;
21583 case 0xe60000000072ULL: /* VSRPR */ goto unimplemented;
21584 case 0xe60000000073ULL: /* VSP */ goto unimplemented;
21585 case 0xe60000000075ULL: s390_format_VRRa_VVVMM(s390_irgen_VCRNF,
21586 VRRa_v1(ovl), VRRa_v2(ovl),
21587 VRRa_v3(ovl),
21588 VRRa_m3(ovl), VRRa_m4(ovl),
21589 VRRa_rxb(ovl)); goto ok;
21590 case 0xe60000000077ULL: /* VCP */ goto unimplemented;
21591 case 0xe60000000078ULL: /* VMP */ goto unimplemented;
21592 case 0xe60000000079ULL: /* VMSP */ goto unimplemented;
21593 case 0xe60000000074ULL: /* VSCHP */ goto unimplemented;
21594 case 0xe6000000007aULL: /* VDP */ goto unimplemented;
21595 case 0xe6000000007bULL: /* VRP */ goto unimplemented;
21596 case 0xe6000000007cULL: /* VSCSHP */ goto unimplemented;
21597 case 0xe6000000007dULL: /* VCSPH */ goto unimplemented;
21598 case 0xe6000000007eULL: /* VSDP */ goto unimplemented;
21599 case 0xe6000000007fULL: /* VTZ */ goto unimplemented;
21600 case 0xe70000000000ULL: s390_format_VRX_VRRDM(s390_irgen_VLEB, VRX_v1(ovl),
21601 VRX_x2(ovl), VRX_b2(ovl),
21602 VRX_d2(ovl), VRX_m3(ovl),
21603 VRX_rxb(ovl)); goto ok;
21604 case 0xe70000000001ULL: s390_format_VRX_VRRDM(s390_irgen_VLEH, VRX_v1(ovl),
21605 VRX_x2(ovl), VRX_b2(ovl),
21606 VRX_d2(ovl), VRX_m3(ovl),
21607 VRX_rxb(ovl)); goto ok;
21608 case 0xe70000000002ULL: s390_format_VRX_VRRDM(s390_irgen_VLEG, VRX_v1(ovl),
21609 VRX_x2(ovl), VRX_b2(ovl),
21610 VRX_d2(ovl), VRX_m3(ovl),
21611 VRX_rxb(ovl)); goto ok;
21612 case 0xe70000000003ULL: s390_format_VRX_VRRDM(s390_irgen_VLEF, VRX_v1(ovl),
21613 VRX_x2(ovl), VRX_b2(ovl),
21614 VRX_d2(ovl), VRX_m3(ovl),
21615 VRX_rxb(ovl)); goto ok;
21616 case 0xe70000000004ULL: s390_format_VRX_VRRDM(s390_irgen_VLLEZ, VRX_v1(ovl),
21617 VRX_x2(ovl), VRX_b2(ovl),
21618 VRX_d2(ovl), VRX_m3(ovl),
21619 VRX_rxb(ovl)); goto ok;
21620 case 0xe70000000005ULL: s390_format_VRX_VRRDM(s390_irgen_VLREP, VRX_v1(ovl),
21621 VRX_x2(ovl), VRX_b2(ovl),
21622 VRX_d2(ovl), VRX_m3(ovl),
21623 VRX_rxb(ovl)); goto ok;
21624 case 0xe70000000006ULL: s390_format_VRX_VRRD(s390_irgen_VL, VRX_v1(ovl),
21625 VRX_x2(ovl), VRX_b2(ovl),
21626 VRX_d2(ovl), VRX_rxb(ovl)); goto ok;
21627 case 0xe70000000007ULL: s390_format_VRX_VRRDM(s390_irgen_VLBB, VRX_v1(ovl),
21628 VRX_x2(ovl), VRX_b2(ovl),
21629 VRX_d2(ovl), VRX_m3(ovl),
21630 VRX_rxb(ovl)); goto ok;
21631 case 0xe70000000008ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEB, VRX_v1(ovl),
21632 VRX_x2(ovl), VRX_b2(ovl),
21633 VRX_d2(ovl), VRX_m3(ovl),
21634 VRX_rxb(ovl)); goto ok;
21635 case 0xe70000000009ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEH, VRX_v1(ovl),
21636 VRX_x2(ovl), VRX_b2(ovl),
21637 VRX_d2(ovl), VRX_m3(ovl),
21638 VRX_rxb(ovl)); goto ok;
21639 case 0xe7000000000aULL: s390_format_VRX_VRRDM(s390_irgen_VSTEG, VRX_v1(ovl),
21640 VRX_x2(ovl), VRX_b2(ovl),
21641 VRX_d2(ovl), VRX_m3(ovl),
21642 VRX_rxb(ovl)); goto ok;
21643 case 0xe7000000000bULL: s390_format_VRX_VRRDM(s390_irgen_VSTEF, VRX_v1(ovl),
21644 VRX_x2(ovl), VRX_b2(ovl),
21645 VRX_d2(ovl), VRX_m3(ovl),
21646 VRX_rxb(ovl)); goto ok;
21647 case 0xe7000000000eULL: s390_format_VRX_VRRD(s390_irgen_VST, VRX_v1(ovl),
21648 VRX_x2(ovl), VRX_b2(ovl),
21649 VRX_d2(ovl), VRX_rxb(ovl)); goto ok;
21650 case 0xe70000000012ULL: s390_format_VRV_VVRDMT(s390_irgen_VGEG, VRX_v1(ovl),
21651 VRX_x2(ovl), VRX_b2(ovl),
21652 VRX_d2(ovl), VRX_m3(ovl),
21653 VRX_rxb(ovl), Ity_I64); goto ok;
21654 case 0xe70000000013ULL: s390_format_VRV_VVRDMT(s390_irgen_VGEF, VRX_v1(ovl),
21655 VRX_x2(ovl), VRX_b2(ovl),
21656 VRX_d2(ovl), VRX_m3(ovl),
21657 VRX_rxb(ovl), Ity_I32); goto ok;
21658 case 0xe7000000001aULL: s390_format_VRV_VVRDMT(s390_irgen_VSCEG, VRX_v1(ovl),
21659 VRX_x2(ovl), VRX_b2(ovl),
21660 VRX_d2(ovl), VRX_m3(ovl),
21661 VRX_rxb(ovl), Ity_I64); goto ok;
21662 case 0xe7000000001bULL: s390_format_VRV_VVRDMT(s390_irgen_VSCEF, VRX_v1(ovl),
21663 VRX_x2(ovl), VRX_b2(ovl),
21664 VRX_d2(ovl), VRX_m3(ovl),
21665 VRX_rxb(ovl), Ity_I32); goto ok;
21666 case 0xe70000000021ULL: s390_format_VRS_RRDVM(s390_irgen_VLGV, VRS_v1(ovl),
21667 VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl),
21668 VRS_m4(ovl), VRS_rxb(ovl)); goto ok;
21669 case 0xe70000000022ULL: s390_format_VRS_VRRDM(s390_irgen_VLVG, VRS_v1(ovl),
21670 VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl),
21671 VRS_m4(ovl), VRS_rxb(ovl)); goto ok;
21672 case 0xe70000000027ULL: s390_format_RXE_RRRDR(s390_irgen_LCBB, RXE_r1(ovl),
21673 RXE_x2(ovl), RXE_b2(ovl),
21674 RXE_d2(ovl), RXE_m3(ovl)); goto ok;
21675 case 0xe70000000030ULL: s390_format_VRS_VRDVM(s390_irgen_VESL, VRS_v1(ovl),
21676 VRS_b2(ovl), VRS_d2(ovl),
21677 VRS_v3(ovl), VRS_m4(ovl),
21678 VRS_rxb(ovl)); goto ok;
21679 case 0xe70000000033ULL: s390_format_VRS_VRDVM(s390_irgen_VERLL, VRS_v1(ovl),
21680 VRS_b2(ovl), VRS_d2(ovl),
21681 VRS_v3(ovl), VRS_m4(ovl),
21682 VRS_rxb(ovl)); goto ok;
21683 case 0xe70000000036ULL: s390_format_VRS_VRDV(s390_irgen_VLM, VRS_v1(ovl),
21684 VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl),
21685 VRS_rxb(ovl)); goto ok;
21686 case 0xe70000000037ULL: s390_format_VRS_VRRD(s390_irgen_VLL, VRS_v1(ovl),
21687 VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl),
21688 VRS_rxb(ovl)); goto ok;
21689 case 0xe70000000038ULL: s390_format_VRS_VRDVM(s390_irgen_VESRL, VRS_v1(ovl),
21690 VRS_b2(ovl), VRS_d2(ovl),
21691 VRS_v3(ovl), VRS_m4(ovl),
21692 VRS_rxb(ovl)); goto ok;
21693 case 0xe7000000003aULL: s390_format_VRS_VRDVM(s390_irgen_VESRA, VRS_v1(ovl),
21694 VRS_b2(ovl), VRS_d2(ovl),
21695 VRS_v3(ovl), VRS_m4(ovl),
21696 VRS_rxb(ovl)); goto ok;
21697 case 0xe7000000003eULL: s390_format_VRS_VRDV(s390_irgen_VSTM, VRS_v1(ovl),
21698 VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl),
21699 VRS_rxb(ovl)); goto ok;
21700 case 0xe7000000003fULL: s390_format_VRS_VRRD(s390_irgen_VSTL, VRS_v1(ovl),
21701 VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl),
21702 VRS_rxb(ovl)); goto ok;
21703 case 0xe70000000040ULL: s390_format_VRI_VIM(s390_irgen_VLEIB, VRI_v1(ovl),
21704 VRI_i2(ovl), VRI_m3(ovl),
21705 VRI_rxb(ovl)); goto ok;
21706 case 0xe70000000041ULL: s390_format_VRI_VIM(s390_irgen_VLEIH, VRI_v1(ovl),
21707 VRI_i2(ovl), VRI_m3(ovl),
21708 VRI_rxb(ovl)); goto ok;
21709 case 0xe70000000042ULL: s390_format_VRI_VIM(s390_irgen_VLEIG, VRI_v1(ovl),
21710 VRI_i2(ovl), VRI_m3(ovl),
21711 VRI_rxb(ovl)); goto ok;
21712 case 0xe70000000043ULL: s390_format_VRI_VIM(s390_irgen_VLEIF, VRI_v1(ovl),
21713 VRI_i2(ovl), VRI_m3(ovl),
21714 VRI_rxb(ovl)); goto ok;break;
21715 case 0xe70000000044ULL: s390_format_VRI_VIM(s390_irgen_VGBM, VRI_v1(ovl),
21716 VRI_i2(ovl), VRI_m3(ovl),
21717 VRI_rxb(ovl)); goto ok;
21718 case 0xe70000000045ULL: s390_format_VRI_VIM(s390_irgen_VREPI, VRI_v1(ovl),
21719 VRI_i2(ovl), VRI_m3(ovl),
21720 VRI_rxb(ovl)); goto ok;
21721 case 0xe70000000046ULL: s390_format_VRI_VIM(s390_irgen_VGM, VRI_v1(ovl),
21722 VRI_i2(ovl), VRI_m3(ovl),
21723 VRI_rxb(ovl)); goto ok;
21724 case 0xe7000000004aULL: s390_format_VRI_VVIMM(s390_irgen_VFTCI, VRIe_v1(ovl),
21725 VRIe_v2(ovl), VRIe_i3(ovl),
21726 VRIe_m4(ovl), VRIe_m5(ovl),
21727 VRIe_rxb(ovl)); goto ok;
21728 case 0xe7000000004dULL: s390_format_VRI_VVIM(s390_irgen_VREP, VRI_v1(ovl),
21729 VRI_v3(ovl), VRI_i2(ovl),
21730 VRI_m3(ovl), VRI_rxb(ovl)); goto ok;
21731 case 0xe70000000050ULL: s390_format_VRR_VVM(s390_irgen_VPOPCT, VRR_v1(ovl),
21732 VRR_v2(ovl), VRR_m4(ovl),
21733 VRR_rxb(ovl)); goto ok;
21734 case 0xe70000000052ULL: s390_format_VRR_VVM(s390_irgen_VCTZ, VRR_v1(ovl),
21735 VRR_v2(ovl), VRR_m4(ovl),
21736 VRR_rxb(ovl)); goto ok;
21737 case 0xe70000000053ULL: s390_format_VRR_VVM(s390_irgen_VCLZ, VRR_v1(ovl),
21738 VRR_v2(ovl), VRR_m4(ovl),
21739 VRR_rxb(ovl)); goto ok;
21740 case 0xe70000000054ULL: /* VGEM */ goto unimplemented;
21741 case 0xe70000000056ULL: s390_format_VRR_VV(s390_irgen_VLR, VRR_v1(ovl),
21742 VRR_v2(ovl), VRR_rxb(ovl)); goto ok;
21743 case 0xe7000000005cULL: s390_format_VRR_VVMM(s390_irgen_VISTR, VRR_v1(ovl),
21744 VRR_v2(ovl), VRR_m4(ovl),
21745 VRR_m5(ovl), VRR_rxb(ovl)); goto ok;
21746 case 0xe7000000005fULL: s390_format_VRR_VVM(s390_irgen_VSEG, VRR_v1(ovl),
21747 VRR_v2(ovl), VRR_m4(ovl),
21748 VRR_rxb(ovl)); goto ok;
21749 case 0xe70000000060ULL: s390_format_VRR_VVVM(s390_irgen_VMRL, VRR_v1(ovl),
21750 VRR_v2(ovl), VRR_r3(ovl),
21751 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21752 case 0xe70000000061ULL: s390_format_VRR_VVVM(s390_irgen_VMRH, VRR_v1(ovl),
21753 VRR_v2(ovl), VRR_r3(ovl),
21754 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21755 case 0xe70000000062ULL: s390_format_VRR_VRR(s390_irgen_VLVGP, VRR_v1(ovl),
21756 VRR_v2(ovl), VRR_r3(ovl),
21757 VRR_rxb(ovl)); goto ok;
21758 case 0xe70000000064ULL: s390_format_VRR_VVVM(s390_irgen_VSUM, VRR_v1(ovl),
21759 VRR_v2(ovl), VRR_r3(ovl),
21760 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21761 case 0xe70000000065ULL: s390_format_VRR_VVVM(s390_irgen_VSUMG, VRR_v1(ovl),
21762 VRR_v2(ovl), VRR_r3(ovl),
21763 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21764 case 0xe70000000066ULL: s390_format_VRR_VVV(s390_irgen_VCKSM, VRR_v1(ovl),
21765 VRR_v2(ovl), VRR_r3(ovl),
21766 VRR_rxb(ovl)); goto ok;
21767 case 0xe70000000067ULL: s390_format_VRR_VVVM(s390_irgen_VSUMQ, VRR_v1(ovl),
21768 VRR_v2(ovl), VRR_r3(ovl),
21769 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21770 case 0xe70000000068ULL: s390_format_VRR_VVV(s390_irgen_VN, VRR_v1(ovl),
21771 VRR_v2(ovl), VRR_r3(ovl),
21772 VRR_rxb(ovl)); goto ok;
21773 case 0xe70000000069ULL: s390_format_VRR_VVV(s390_irgen_VNC, VRR_v1(ovl),
21774 VRR_v2(ovl), VRR_r3(ovl),
21775 VRR_rxb(ovl)); goto ok;
21776 case 0xe7000000006aULL: s390_format_VRR_VVV(s390_irgen_VO, VRR_v1(ovl),
21777 VRR_v2(ovl), VRR_r3(ovl),
21778 VRR_rxb(ovl)); goto ok;
21779 case 0xe7000000006bULL: s390_format_VRR_VVV(s390_irgen_VNO, VRR_v1(ovl),
21780 VRR_v2(ovl), VRR_r3(ovl),
21781 VRR_rxb(ovl)); goto ok;
21782 case 0xe7000000006cULL: s390_format_VRR_VVV(s390_irgen_VNX, VRR_v1(ovl),
21783 VRR_v2(ovl), VRR_r3(ovl),
21784 VRR_rxb(ovl)); goto ok;
21785 case 0xe7000000006dULL: s390_format_VRR_VVV(s390_irgen_VX, VRR_v1(ovl),
21786 VRR_v2(ovl), VRR_r3(ovl),
21787 VRR_rxb(ovl)); goto ok;
21788 case 0xe7000000006eULL: s390_format_VRR_VVV(s390_irgen_VNN, VRR_v1(ovl),
21789 VRR_v2(ovl), VRR_r3(ovl),
21790 VRR_rxb(ovl)); goto ok;
21791 case 0xe7000000006fULL: s390_format_VRR_VVV(s390_irgen_VOC, VRR_v1(ovl),
21792 VRR_v2(ovl), VRR_r3(ovl),
21793 VRR_rxb(ovl)); goto ok;
21794 case 0xe70000000070ULL: s390_format_VRR_VVVM(s390_irgen_VESLV, VRR_v1(ovl),
21795 VRR_v2(ovl), VRR_r3(ovl),
21796 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21797 case 0xe70000000072ULL: s390_format_VRId_VVVIM(s390_irgen_VERIM, VRId_v1(ovl),
21798 VRId_v2(ovl), VRId_v3(ovl),
21799 VRId_i4(ovl), VRId_m5(ovl),
21800 VRId_rxb(ovl)); goto ok;
21801 case 0xe70000000073ULL: s390_format_VRR_VVVM(s390_irgen_VERLLV, VRR_v1(ovl),
21802 VRR_v2(ovl), VRR_r3(ovl),
21803 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21804 case 0xe70000000074ULL: s390_format_VRR_VVV(s390_irgen_VSL, VRR_v1(ovl),
21805 VRR_v2(ovl), VRR_r3(ovl),
21806 VRR_rxb(ovl)); goto ok;
21807 case 0xe70000000075ULL: s390_format_VRR_VVV(s390_irgen_VSLB, VRR_v1(ovl),
21808 VRR_v2(ovl), VRR_r3(ovl),
21809 VRR_rxb(ovl)); goto ok;
21810 case 0xe70000000077ULL: s390_format_VRId_VVVI(s390_irgen_VSLDB, VRId_v1(ovl),
21811 VRId_v2(ovl), VRId_v3(ovl),
21812 VRId_i4(ovl), VRId_rxb(ovl)); goto ok;
21813 case 0xe70000000078ULL: s390_format_VRR_VVVM(s390_irgen_VESRLV, VRR_v1(ovl),
21814 VRR_v2(ovl), VRR_r3(ovl),
21815 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21816 case 0xe7000000007aULL: s390_format_VRR_VVVM(s390_irgen_VESRAV, VRR_v1(ovl),
21817 VRR_v2(ovl), VRR_r3(ovl),
21818 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21819 case 0xe7000000007cULL: s390_format_VRR_VVV(s390_irgen_VSRL, VRR_v1(ovl),
21820 VRR_v2(ovl), VRR_r3(ovl),
21821 VRR_rxb(ovl)); goto ok;
21822 case 0xe7000000007dULL: s390_format_VRR_VVV(s390_irgen_VSRLB, VRR_v1(ovl),
21823 VRR_v2(ovl), VRR_r3(ovl),
21824 VRR_rxb(ovl)); goto ok;
21825 case 0xe7000000007eULL: s390_format_VRR_VVV(s390_irgen_VSRA, VRR_v1(ovl),
21826 VRR_v2(ovl), VRR_r3(ovl),
21827 VRR_rxb(ovl)); goto ok;
21828 case 0xe7000000007fULL: s390_format_VRR_VVV(s390_irgen_VSRAB, VRR_v1(ovl),
21829 VRR_v2(ovl), VRR_r3(ovl),
21830 VRR_rxb(ovl)); goto ok;
21831 case 0xe70000000080ULL: s390_format_VRR_VVVMM(s390_irgen_VFEE, VRR_v1(ovl),
21832 VRR_v2(ovl), VRR_r3(ovl),
21833 VRR_m4(ovl), VRR_m5(ovl),
21834 VRR_rxb(ovl)); goto ok;
21835 case 0xe70000000081ULL: s390_format_VRR_VVVMM(s390_irgen_VFENE, VRR_v1(ovl),
21836 VRR_v2(ovl), VRR_r3(ovl),
21837 VRR_m4(ovl), VRR_m5(ovl),
21838 VRR_rxb(ovl)); goto ok;
21839 case 0xe70000000082ULL: s390_format_VRR_VVVMM(s390_irgen_VFAE, VRR_v1(ovl),
21840 VRR_v2(ovl), VRR_r3(ovl),
21841 VRR_m4(ovl), VRR_m5(ovl),
21842 VRR_rxb(ovl)); goto ok;
21843 case 0xe70000000084ULL: s390_format_VRR_VVVM(s390_irgen_VPDI, VRR_v1(ovl),
21844 VRR_v2(ovl), VRR_r3(ovl),
21845 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21846 case 0xe70000000085ULL: s390_format_VRR_VVV(s390_irgen_VBPERM, VRR_v1(ovl),
21847 VRR_v2(ovl), VRR_r3(ovl),
21848 VRR_rxb(ovl)); goto ok;
21849 case 0xe70000000086ULL: s390_format_VRId_VVVI(s390_irgen_VSLD, VRId_v1(ovl),
21850 VRId_v2(ovl), VRId_v3(ovl),
21851 VRId_i4(ovl),
21852 VRId_rxb(ovl)); goto ok;
21853 case 0xe70000000087ULL: s390_format_VRId_VVVI(s390_irgen_VSRD, VRId_v1(ovl),
21854 VRId_v2(ovl), VRId_v3(ovl),
21855 VRId_i4(ovl),
21856 VRId_rxb(ovl)); goto ok;
21857 case 0xe70000000088ULL: /* VEVAL */ goto unimplemented;
21858 case 0xe70000000089ULL: /* VBLEND */ goto unimplemented;
21859 case 0xe7000000008aULL: s390_format_VRR_VVVVMM(s390_irgen_VSTRC, VRRd_v1(ovl),
21860 VRRd_v2(ovl), VRRd_v3(ovl),
21861 VRRd_v4(ovl), VRRd_m5(ovl),
21862 VRRd_m6(ovl),
21863 VRRd_rxb(ovl)); goto ok;
21864 case 0xe7000000008bULL: s390_format_VRR_VVVVMM(s390_irgen_VSTRS, VRRd_v1(ovl),
21865 VRRd_v2(ovl), VRRd_v3(ovl),
21866 VRRd_v4(ovl), VRRd_m5(ovl),
21867 VRRd_m6(ovl),
21868 VRRd_rxb(ovl)); goto ok;
21869 case 0xe7000000008cULL: s390_format_VRR_VVVV(s390_irgen_VPERM, VRR_v1(ovl),
21870 VRR_v2(ovl), VRR_r3(ovl),
21871 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21872 case 0xe7000000008dULL: s390_format_VRR_VVVV(s390_irgen_VSEL, VRR_v1(ovl),
21873 VRR_v2(ovl), VRR_r3(ovl),
21874 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21875 case 0xe7000000008eULL: s390_format_VRR_VVVVMM(s390_irgen_VFMS, VRRe_v1(ovl),
21876 VRRe_v2(ovl), VRRe_v3(ovl),
21877 VRRe_v4(ovl), VRRe_m5(ovl),
21878 VRRe_m6(ovl),
21879 VRRe_rxb(ovl)); goto ok;
21880 case 0xe7000000008fULL: s390_format_VRR_VVVVMM(s390_irgen_VFMA, VRRe_v1(ovl),
21881 VRRe_v2(ovl), VRRe_v3(ovl),
21882 VRRe_v4(ovl), VRRe_m5(ovl),
21883 VRRe_m6(ovl),
21884 VRRe_rxb(ovl)); goto ok;
21885 case 0xe70000000094ULL: s390_format_VRR_VVVM(s390_irgen_VPK, VRR_v1(ovl),
21886 VRR_v2(ovl), VRR_r3(ovl),
21887 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21888 case 0xe70000000095ULL: s390_format_VRR_VVVMM(s390_irgen_VPKLS, VRR_v1(ovl),
21889 VRR_v2(ovl), VRR_r3(ovl),
21890 VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl)); goto ok;
21891 case 0xe70000000097ULL: s390_format_VRR_VVVMM(s390_irgen_VPKS, VRR_v1(ovl),
21892 VRR_v2(ovl), VRR_r3(ovl),
21893 VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl)); goto ok;
21894 case 0xe7000000009eULL: s390_format_VRR_VVVVMM(s390_irgen_VFNMS, VRRe_v1(ovl),
21895 VRRe_v2(ovl), VRRe_v3(ovl),
21896 VRRe_v4(ovl), VRRe_m5(ovl),
21897 VRRe_m6(ovl),
21898 VRRe_rxb(ovl)); goto ok;
21899 case 0xe7000000009fULL: s390_format_VRR_VVVVMM(s390_irgen_VFNMA, VRRe_v1(ovl),
21900 VRRe_v2(ovl), VRRe_v3(ovl),
21901 VRRe_v4(ovl), VRRe_m5(ovl),
21902 VRRe_m6(ovl),
21903 VRRe_rxb(ovl)); goto ok;
21904 case 0xe700000000a1ULL: s390_format_VRR_VVVM(s390_irgen_VMLH, VRR_v1(ovl),
21905 VRR_v2(ovl), VRR_r3(ovl),
21906 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21907 case 0xe700000000a2ULL: s390_format_VRR_VVVM(s390_irgen_VML, VRR_v1(ovl),
21908 VRR_v2(ovl), VRR_r3(ovl),
21909 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21910 case 0xe700000000a3ULL: s390_format_VRR_VVVM(s390_irgen_VMH, VRR_v1(ovl),
21911 VRR_v2(ovl), VRR_r3(ovl),
21912 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21913 case 0xe700000000a4ULL: s390_format_VRR_VVVM(s390_irgen_VMLE, VRR_v1(ovl),
21914 VRR_v2(ovl), VRR_r3(ovl),
21915 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21916 case 0xe700000000a5ULL: s390_format_VRR_VVVM(s390_irgen_VMLO, VRR_v1(ovl),
21917 VRR_v2(ovl), VRR_r3(ovl),
21918 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21919 case 0xe700000000a6ULL: s390_format_VRR_VVVM(s390_irgen_VME, VRR_v1(ovl),
21920 VRR_v2(ovl), VRR_r3(ovl),
21921 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21922 case 0xe700000000a7ULL: s390_format_VRR_VVVM(s390_irgen_VMO, VRR_v1(ovl),
21923 VRR_v2(ovl), VRR_r3(ovl),
21924 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21925 case 0xe700000000a9ULL: s390_format_VRRd_VVVVM(s390_irgen_VMALH, VRRd_v1(ovl),
21926 VRRd_v2(ovl), VRRd_v3(ovl),
21927 VRRd_v4(ovl), VRRd_m5(ovl),
21928 VRRd_rxb(ovl)); goto ok;
21929 case 0xe700000000aaULL: s390_format_VRRd_VVVVM(s390_irgen_VMAL, VRRd_v1(ovl),
21930 VRRd_v2(ovl), VRRd_v3(ovl),
21931 VRRd_v4(ovl), VRRd_m5(ovl),
21932 VRRd_rxb(ovl)); goto ok;
21933 case 0xe700000000abULL: s390_format_VRRd_VVVVM(s390_irgen_VMAH, VRRd_v1(ovl),
21934 VRRd_v2(ovl), VRRd_v3(ovl),
21935 VRRd_v4(ovl), VRRd_m5(ovl),
21936 VRRd_rxb(ovl)); goto ok;
21937 case 0xe700000000acULL: s390_format_VRRd_VVVVM(s390_irgen_VMALE, VRRd_v1(ovl),
21938 VRRd_v2(ovl), VRRd_v3(ovl),
21939 VRRd_v4(ovl), VRRd_m5(ovl),
21940 VRRd_rxb(ovl)); goto ok;
21941 case 0xe700000000adULL: s390_format_VRRd_VVVVM(s390_irgen_VMALO, VRRd_v1(ovl),
21942 VRRd_v2(ovl), VRRd_v3(ovl),
21943 VRRd_v4(ovl), VRRd_m5(ovl),
21944 VRRd_rxb(ovl)); goto ok;
21945 case 0xe700000000aeULL: s390_format_VRRd_VVVVM(s390_irgen_VMAE, VRRd_v1(ovl),
21946 VRRd_v2(ovl), VRRd_v3(ovl),
21947 VRRd_v4(ovl), VRRd_m5(ovl),
21948 VRRd_rxb(ovl)); goto ok;
21949 case 0xe700000000afULL: s390_format_VRRd_VVVVM(s390_irgen_VMAO, VRRd_v1(ovl),
21950 VRRd_v2(ovl), VRRd_v3(ovl),
21951 VRRd_v4(ovl), VRRd_m5(ovl),
21952 VRRd_rxb(ovl)); goto ok;
21953 case 0xe700000000b0ULL: /* VDL */ goto unimplemented;
21954 case 0xe700000000b1ULL: /* VRL */ goto unimplemented;
21955 case 0xe700000000b2ULL: /* VD */ goto unimplemented;
21956 case 0xe700000000b3ULL: /* VR */ goto unimplemented;
21957 case 0xe700000000b4ULL: s390_format_VRR_VVVM(s390_irgen_VGFM, VRR_v1(ovl),
21958 VRR_v2(ovl), VRR_r3(ovl),
21959 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
21960 case 0xe700000000b8ULL: s390_format_VRR_VVVVMM(s390_irgen_VMSL, VRRd_v1(ovl),
21961 VRRd_v2(ovl), VRRd_v3(ovl),
21962 VRRd_v4(ovl), VRRd_m5(ovl),
21963 VRRd_m6(ovl),
21964 VRRd_rxb(ovl)); goto ok;
21965 case 0xe700000000b9ULL: s390_format_VRRd_VVVVM(s390_irgen_VACCC, VRRd_v1(ovl),
21966 VRRd_v2(ovl), VRRd_v3(ovl),
21967 VRRd_v4(ovl), VRRd_m5(ovl),
21968 VRRd_rxb(ovl)); goto ok;
21969 case 0xe700000000bbULL: s390_format_VRRd_VVVVM(s390_irgen_VAC, VRRd_v1(ovl),
21970 VRRd_v2(ovl), VRRd_v3(ovl),
21971 VRRd_v4(ovl), VRRd_m5(ovl),
21972 VRRd_rxb(ovl)); goto ok;
21973 case 0xe700000000bcULL: s390_format_VRRd_VVVVM(s390_irgen_VGFMA, VRRd_v1(ovl),
21974 VRRd_v2(ovl), VRRd_v3(ovl),
21975 VRRd_v4(ovl), VRRd_m5(ovl),
21976 VRRd_rxb(ovl)); goto ok;
21977 case 0xe700000000bdULL: s390_format_VRRd_VVVVM(s390_irgen_VSBCBI, VRRd_v1(ovl),
21978 VRRd_v2(ovl), VRRd_v3(ovl),
21979 VRRd_v4(ovl), VRRd_m5(ovl),
21980 VRRd_rxb(ovl)); goto ok;
21981 case 0xe700000000bfULL: s390_format_VRRd_VVVVM(s390_irgen_VSBI, VRRd_v1(ovl),
21982 VRRd_v2(ovl), VRRd_v3(ovl),
21983 VRRd_v4(ovl), VRRd_m5(ovl),
21984 VRRd_rxb(ovl)); goto ok;
21985 case 0xe700000000c0ULL: s390_format_VRRa_VVMMM(s390_irgen_VCLGD, VRRa_v1(ovl),
21986 VRRa_v2(ovl), VRRa_m3(ovl),
21987 VRRa_m4(ovl), VRRa_m5(ovl),
21988 VRRa_rxb(ovl)); goto ok;
21989 case 0xe700000000c1ULL: s390_format_VRRa_VVMMM(s390_irgen_VCDLG, VRRa_v1(ovl),
21990 VRRa_v2(ovl), VRRa_m3(ovl),
21991 VRRa_m4(ovl), VRRa_m5(ovl),
21992 VRRa_rxb(ovl)); goto ok;
21993 case 0xe700000000c2ULL: s390_format_VRRa_VVMMM(s390_irgen_VCGD, VRRa_v1(ovl),
21994 VRRa_v2(ovl), VRRa_m3(ovl),
21995 VRRa_m4(ovl), VRRa_m5(ovl),
21996 VRRa_rxb(ovl)); goto ok;
21997 case 0xe700000000c3ULL: s390_format_VRRa_VVMMM(s390_irgen_VCDG, VRRa_v1(ovl),
21998 VRRa_v2(ovl), VRRa_m3(ovl),
21999 VRRa_m4(ovl), VRRa_m5(ovl),
22000 VRRa_rxb(ovl)); goto ok;
22001 case 0xe700000000c4ULL: s390_format_VRRa_VVMMM(s390_irgen_VFLL, VRRa_v1(ovl),
22002 VRRa_v2(ovl), VRRa_m3(ovl),
22003 VRRa_m4(ovl), VRRa_m5(ovl),
22004 VRRa_rxb(ovl)); goto ok;
22005 case 0xe700000000c5ULL: s390_format_VRRa_VVMMM(s390_irgen_VFLR, VRRa_v1(ovl),
22006 VRRa_v2(ovl), VRRa_m3(ovl),
22007 VRRa_m4(ovl), VRRa_m5(ovl),
22008 VRRa_rxb(ovl)); goto ok;
22009 case 0xe700000000c7ULL: s390_format_VRRa_VVMMM(s390_irgen_VFI, VRRa_v1(ovl),
22010 VRRa_v2(ovl), VRRa_m3(ovl),
22011 VRRa_m4(ovl), VRRa_m5(ovl),
22012 VRRa_rxb(ovl)); goto ok;
22013 case 0xe700000000caULL: s390_format_VRRa_VVMM(s390_irgen_WFK, VRRa_v1(ovl),
22014 VRRa_v2(ovl), VRRa_m3(ovl),
22015 VRRa_m4(ovl),
22016 VRRa_rxb(ovl)); goto ok;
22017 case 0xe700000000cbULL: s390_format_VRRa_VVMM(s390_irgen_WFC, VRRa_v1(ovl),
22018 VRRa_v2(ovl), VRRa_m3(ovl),
22019 VRRa_m4(ovl),
22020 VRRa_rxb(ovl)); goto ok;
22021 case 0xe700000000ccULL: s390_format_VRRa_VVMMM(s390_irgen_VFPSO, VRRa_v1(ovl),
22022 VRRa_v2(ovl), VRRa_m3(ovl),
22023 VRRa_m4(ovl), VRRa_m5(ovl),
22024 VRRa_rxb(ovl)); goto ok;
22025 case 0xe700000000ceULL: s390_format_VRRa_VVMM(s390_irgen_VFSQ, VRRa_v1(ovl),
22026 VRRa_v2(ovl), VRRa_m3(ovl),
22027 VRRa_m4(ovl),
22028 VRRa_rxb(ovl)); goto ok;
22029 case 0xe700000000d4ULL: s390_format_VRR_VVM(s390_irgen_VUPLL, VRR_v1(ovl),
22030 VRR_v2(ovl), VRR_m4(ovl),
22031 VRR_rxb(ovl)); goto ok;
22032 case 0xe700000000d5ULL: s390_format_VRR_VVM(s390_irgen_VUPLH, VRR_v1(ovl),
22033 VRR_v2(ovl), VRR_m4(ovl),
22034 VRR_rxb(ovl)); goto ok;
22035 case 0xe700000000d6ULL: s390_format_VRR_VVM(s390_irgen_VUPL, VRR_v1(ovl),
22036 VRR_v2(ovl), VRR_m4(ovl),
22037 VRR_rxb(ovl)); goto ok;
22038 case 0xe700000000d7ULL: s390_format_VRR_VVM(s390_irgen_VUPH, VRR_v1(ovl),
22039 VRR_v2(ovl), VRR_m4(ovl),
22040 VRR_rxb(ovl)); goto ok;
22041 case 0xe700000000d8ULL: s390_format_VRR_VV(s390_irgen_VTM, VRR_v1(ovl),
22042 VRR_v2(ovl), VRR_rxb(ovl)); goto ok;
22043 case 0xe700000000d9ULL: s390_format_VRR_VVM(s390_irgen_VECL, VRR_v1(ovl),
22044 VRR_v2(ovl), VRR_m4(ovl),
22045 VRR_rxb(ovl)); goto ok;
22046 case 0xe700000000dbULL: s390_format_VRR_VVM(s390_irgen_VEC, VRR_v1(ovl),
22047 VRR_v2(ovl), VRR_m4(ovl),
22048 VRR_rxb(ovl)); goto ok;
22049 case 0xe700000000deULL: s390_format_VRR_VVM(s390_irgen_VLC, VRR_v1(ovl),
22050 VRR_v2(ovl), VRR_m4(ovl),
22051 VRR_rxb(ovl)); goto ok;
22052 case 0xe700000000dfULL: s390_format_VRR_VVM(s390_irgen_VLP, VRR_v1(ovl),
22053 VRR_v2(ovl), VRR_m4(ovl),
22054 VRR_rxb(ovl)); goto ok;
22055 case 0xe700000000e2ULL: s390_format_VRRa_VVVMM(s390_irgen_VFS, VRRa_v1(ovl),
22056 VRRa_v2(ovl), VRRa_v3(ovl),
22057 VRRa_m3(ovl), VRRa_m4(ovl),
22058 VRRa_rxb(ovl)); goto ok;
22059 case 0xe700000000e3ULL: s390_format_VRRa_VVVMM(s390_irgen_VFA, VRRa_v1(ovl),
22060 VRRa_v2(ovl), VRRa_v3(ovl),
22061 VRRa_m3(ovl), VRRa_m4(ovl),
22062 VRRa_rxb(ovl)); goto ok;
22063 case 0xe700000000e5ULL: s390_format_VRRa_VVVMM(s390_irgen_VFD, VRRa_v1(ovl),
22064 VRRa_v2(ovl), VRRa_v3(ovl),
22065 VRRa_m3(ovl), VRRa_m4(ovl),
22066 VRRa_rxb(ovl)); goto ok;
22067 case 0xe700000000e7ULL: s390_format_VRRa_VVVMM(s390_irgen_VFM, VRRa_v1(ovl),
22068 VRRa_v2(ovl), VRRa_v3(ovl),
22069 VRRa_m3(ovl), VRRa_m4(ovl),
22070 VRRa_rxb(ovl)); goto ok;
22071 case 0xe700000000e8ULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCE, VRRa_v1(ovl),
22072 VRRa_v2(ovl), VRRa_v3(ovl),
22073 VRRa_m3(ovl), VRRa_m4(ovl),
22074 VRRa_m5(ovl),
22075 VRRa_rxb(ovl)); goto ok;
22076 case 0xe700000000eaULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCHE, VRRa_v1(ovl),
22077 VRRa_v2(ovl), VRRa_v3(ovl),
22078 VRRa_m3(ovl), VRRa_m4(ovl),
22079 VRRa_m5(ovl),
22080 VRRa_rxb(ovl)); goto ok;
22081 case 0xe700000000ebULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCH, VRRa_v1(ovl),
22082 VRRa_v2(ovl), VRRa_v3(ovl),
22083 VRRa_m3(ovl), VRRa_m4(ovl),
22084 VRRa_m5(ovl),
22085 VRRa_rxb(ovl)); goto ok;
22086 case 0xe700000000eeULL: s390_format_VRRa_VVVMMM(s390_irgen_VFMIN, VRRa_v1(ovl),
22087 VRRa_v2(ovl), VRRa_v3(ovl),
22088 VRRa_m3(ovl), VRRa_m4(ovl),
22089 VRRa_m5(ovl),
22090 VRRa_rxb(ovl)); goto ok;
22091 case 0xe700000000efULL: s390_format_VRRa_VVVMMM(s390_irgen_VFMAX, VRRa_v1(ovl),
22092 VRRa_v2(ovl), VRRa_v3(ovl),
22093 VRRa_m3(ovl), VRRa_m4(ovl),
22094 VRRa_m5(ovl),
22095 VRRa_rxb(ovl)); goto ok;
22096 case 0xe700000000f0ULL: s390_format_VRR_VVVM(s390_irgen_VAVGL, VRR_v1(ovl),
22097 VRR_v2(ovl), VRR_r3(ovl),
22098 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
22099 case 0xe700000000f1ULL: s390_format_VRR_VVVM(s390_irgen_VACC, VRR_v1(ovl),
22100 VRR_v2(ovl), VRR_r3(ovl),
22101 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
22102 case 0xe700000000f2ULL: s390_format_VRR_VVVM(s390_irgen_VAVG, VRR_v1(ovl),
22103 VRR_v2(ovl), VRR_r3(ovl),
22104 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
22105 case 0xe700000000f3ULL: s390_format_VRR_VVVM(s390_irgen_VA, VRR_v1(ovl),
22106 VRR_v2(ovl), VRR_r3(ovl),
22107 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
22108 case 0xe700000000f5ULL: s390_format_VRR_VVVM(s390_irgen_VSCBI, VRR_v1(ovl),
22109 VRR_v2(ovl), VRR_r3(ovl),
22110 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
22111 case 0xe700000000f7ULL: s390_format_VRR_VVVM(s390_irgen_VS, VRR_v1(ovl),
22112 VRR_v2(ovl), VRR_r3(ovl),
22113 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
22114 case 0xe700000000f8ULL: s390_format_VRR_VVVMM(s390_irgen_VCEQ, VRR_v1(ovl),
22115 VRR_v2(ovl), VRR_r3(ovl),
22116 VRR_m4(ovl), VRR_m5(ovl),
22117 VRR_rxb(ovl)); goto ok;
22118 case 0xe700000000f9ULL: s390_format_VRR_VVVMM(s390_irgen_VCHL, VRR_v1(ovl),
22119 VRR_v2(ovl), VRR_r3(ovl),
22120 VRR_m4(ovl), VRR_m5(ovl),
22121 VRR_rxb(ovl)); goto ok;
22122 case 0xe700000000fbULL: s390_format_VRR_VVVMM(s390_irgen_VCH, VRR_v1(ovl),
22123 VRR_v2(ovl), VRR_r3(ovl),
22124 VRR_m4(ovl), VRR_m5(ovl),
22125 VRR_rxb(ovl)); goto ok;
22126 case 0xe700000000fcULL: s390_format_VRR_VVVM(s390_irgen_VMNL, VRR_v1(ovl),
22127 VRR_v2(ovl), VRR_r3(ovl),
22128 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
22129 case 0xe700000000fdULL: s390_format_VRR_VVVM(s390_irgen_VMXL, VRR_v1(ovl),
22130 VRR_v2(ovl), VRR_r3(ovl),
22131 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
22132 case 0xe700000000feULL: s390_format_VRR_VVVM(s390_irgen_VMN, VRR_v1(ovl),
22133 VRR_v2(ovl), VRR_r3(ovl),
22134 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
22135 case 0xe700000000ffULL: s390_format_VRR_VVVM(s390_irgen_VMX, VRR_v1(ovl),
22136 VRR_v2(ovl), VRR_r3(ovl),
22137 VRR_m4(ovl), VRR_rxb(ovl)); goto ok;
22138 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, RSY_r1(ovl),
22139 RSY_r3(ovl), RSY_b2(ovl),
22140 RSY_dl2(ovl),
22141 RSY_dh2(ovl)); goto ok;
22142 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, RSY_r1(ovl),
22143 RSY_r3(ovl), RSY_b2(ovl),
22144 RSY_dl2(ovl),
22145 RSY_dh2(ovl)); goto ok;
22146 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, RSY_r1(ovl),
22147 RSY_r3(ovl), RSY_b2(ovl),
22148 RSY_dl2(ovl),
22149 RSY_dh2(ovl)); goto ok;
22150 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, RSY_r1(ovl),
22151 RSY_r3(ovl), RSY_b2(ovl),
22152 RSY_dl2(ovl),
22153 RSY_dh2(ovl)); goto ok;
22154 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, RSY_r1(ovl),
22155 RSY_r3(ovl), RSY_b2(ovl),
22156 RSY_dl2(ovl),
22157 RSY_dh2(ovl)); goto ok;
22158 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
22159 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, RSY_r1(ovl),
22160 RSY_r3(ovl), RSY_b2(ovl),
22161 RSY_dl2(ovl),
22162 RSY_dh2(ovl)); goto ok;
22163 case 0xeb0000000016ULL: /* PFCR */ goto unimplemented;
22164 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, RSY_r1(ovl),
22165 RSY_r3(ovl), RSY_b2(ovl),
22166 RSY_dl2(ovl),
22167 RSY_dh2(ovl)); goto ok;
22168 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, RSY_r1(ovl),
22169 RSY_r3(ovl), RSY_b2(ovl),
22170 RSY_dl2(ovl),
22171 RSY_dh2(ovl)); goto ok;
22172 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, RSY_r1(ovl),
22173 RSY_r3(ovl), RSY_b2(ovl),
22174 RSY_dl2(ovl),
22175 RSY_dh2(ovl)); goto ok;
22176 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, RSY_r1(ovl),
22177 RSY_r3(ovl), RSY_b2(ovl),
22178 RSY_dl2(ovl),
22179 RSY_dh2(ovl)); goto ok;
22180 case 0xeb0000000023ULL: s390_format_RSY_R0RD(s390_irgen_CLT, RSY_r1(ovl),
22181 RSY_r3(ovl), RSY_b2(ovl),
22182 RSY_dl2(ovl),
22183 RSY_dh2(ovl)); goto ok;
22184 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, RSY_r1(ovl),
22185 RSY_r3(ovl), RSY_b2(ovl),
22186 RSY_dl2(ovl),
22187 RSY_dh2(ovl)); goto ok;
22188 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
22189 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, RSY_r1(ovl),
22190 RSY_r3(ovl), RSY_b2(ovl),
22191 RSY_dl2(ovl),
22192 RSY_dh2(ovl)); goto ok;
22193 case 0xeb000000002bULL: s390_format_RSY_R0RD(s390_irgen_CLGT, RSY_r1(ovl),
22194 RSY_r3(ovl), RSY_b2(ovl),
22195 RSY_dl2(ovl),
22196 RSY_dh2(ovl)); goto ok;
22197 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
22198 RSY_r1(ovl), RSY_r3(ovl),
22199 RSY_b2(ovl), RSY_dl2(ovl),
22200 RSY_dh2(ovl)); goto ok;
22201 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
22202 RSY_r1(ovl), RSY_r3(ovl),
22203 RSY_b2(ovl), RSY_dl2(ovl),
22204 RSY_dh2(ovl)); goto ok;
22205 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
22206 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, RSY_r1(ovl),
22207 RSY_r3(ovl), RSY_b2(ovl),
22208 RSY_dl2(ovl),
22209 RSY_dh2(ovl)); goto ok;
22210 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, RSY_r1(ovl),
22211 RSY_r3(ovl), RSY_b2(ovl),
22212 RSY_dl2(ovl),
22213 RSY_dh2(ovl)); goto ok;
22214 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, RSY_r1(ovl),
22215 RSY_r3(ovl), RSY_b2(ovl),
22216 RSY_dl2(ovl),
22217 RSY_dh2(ovl)); goto ok;
22218 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, RSY_r1(ovl),
22219 RSY_r3(ovl), RSY_b2(ovl),
22220 RSY_dl2(ovl),
22221 RSY_dh2(ovl)); goto ok;
22222 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
22223 RSY_r1(ovl), RSY_r3(ovl),
22224 RSY_b2(ovl), RSY_dl2(ovl),
22225 RSY_dh2(ovl)); goto ok;
22226 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, RSY_r1(ovl),
22227 RSY_r3(ovl), RSY_b2(ovl),
22228 RSY_dl2(ovl),
22229 RSY_dh2(ovl)); goto ok;
22230 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, SIY_i2(ovl),
22231 SIY_b1(ovl), SIY_dl1(ovl),
22232 SIY_dh1(ovl)); goto ok;
22233 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, SIY_i2(ovl),
22234 SIY_b1(ovl), SIY_dl1(ovl),
22235 SIY_dh1(ovl)); goto ok;
22236 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, SIY_i2(ovl),
22237 SIY_b1(ovl), SIY_dl1(ovl),
22238 SIY_dh1(ovl)); goto ok;
22239 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, SIY_i2(ovl),
22240 SIY_b1(ovl), SIY_dl1(ovl),
22241 SIY_dh1(ovl)); goto ok;
22242 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, SIY_i2(ovl),
22243 SIY_b1(ovl), SIY_dl1(ovl),
22244 SIY_dh1(ovl)); goto ok;
22245 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, SIY_i2(ovl),
22246 SIY_b1(ovl), SIY_dl1(ovl),
22247 SIY_dh1(ovl)); goto ok;
22248 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, SIY_i2(ovl),
22249 SIY_b1(ovl), SIY_dl1(ovl),
22250 SIY_dh1(ovl)); goto ok;
22251 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, SIY_i2(ovl),
22252 SIY_b1(ovl), SIY_dl1(ovl),
22253 SIY_dh1(ovl)); goto ok;
22254 case 0xeb0000000071ULL: /* LPSWEY */ goto unimplemented;
22255 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, SIY_i2(ovl),
22256 SIY_b1(ovl), SIY_dl1(ovl),
22257 SIY_dh1(ovl)); goto ok;
22258 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, SIY_i2(ovl),
22259 SIY_b1(ovl), SIY_dl1(ovl),
22260 SIY_dh1(ovl)); goto ok;
22261 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, RSY_r1(ovl),
22262 RSY_r3(ovl), RSY_b2(ovl),
22263 RSY_dl2(ovl),
22264 RSY_dh2(ovl)); goto ok;
22265 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, RSY_r1(ovl),
22266 RSY_r3(ovl), RSY_b2(ovl),
22267 RSY_dl2(ovl),
22268 RSY_dh2(ovl)); goto ok;
22269 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
22270 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
22271 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, RSY_r1(ovl),
22272 RSY_r3(ovl), RSY_b2(ovl),
22273 RSY_dl2(ovl),
22274 RSY_dh2(ovl)); goto ok;
22275 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, RSY_r1(ovl),
22276 RSY_r3(ovl), RSY_b2(ovl),
22277 RSY_dl2(ovl),
22278 RSY_dh2(ovl)); goto ok;
22279 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, RSY_r1(ovl),
22280 RSY_r3(ovl), RSY_b2(ovl),
22281 RSY_dl2(ovl),
22282 RSY_dh2(ovl)); goto ok;
22283 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, RSY_r1(ovl),
22284 RSY_r3(ovl), RSY_b2(ovl),
22285 RSY_dl2(ovl),
22286 RSY_dh2(ovl)); goto ok;
22287 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
22288 RSY_r1(ovl), RSY_r3(ovl),
22289 RSY_b2(ovl), RSY_dl2(ovl),
22290 RSY_dh2(ovl)); goto ok;
22291 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
22292 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, RSY_r1(ovl),
22293 RSY_r3(ovl), RSY_b2(ovl),
22294 RSY_dl2(ovl),
22295 RSY_dh2(ovl)); goto ok;
22296 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, RSY_r1(ovl),
22297 RSY_r3(ovl), RSY_b2(ovl),
22298 RSY_dl2(ovl),
22299 RSY_dh2(ovl)); goto ok;
22300 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, RSY_r1(ovl),
22301 RSY_r3(ovl), RSY_b2(ovl),
22302 RSY_dl2(ovl),
22303 RSY_dh2(ovl)); goto ok;
22304 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, RSY_r1(ovl),
22305 RSY_r3(ovl), RSY_b2(ovl),
22306 RSY_dl2(ovl),
22307 RSY_dh2(ovl)); goto ok;
22308 case 0xeb00000000e0ULL: s390_format_RSY_RDRM(s390_irgen_LOCFH, RSY_r1(ovl),
22309 RSY_r3(ovl), RSY_b2(ovl),
22310 RSY_dl2(ovl),
22311 RSY_dh2(ovl)); goto ok;
22312 case 0xeb00000000e1ULL: s390_format_RSY_RDRM(s390_irgen_STOCFH, RSY_r1(ovl),
22313 RSY_r3(ovl), RSY_b2(ovl),
22314 RSY_dl2(ovl),
22315 RSY_dh2(ovl)); goto ok;
22316 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, RSY_r1(ovl),
22317 RSY_r3(ovl), RSY_b2(ovl),
22318 RSY_dl2(ovl),
22319 RSY_dh2(ovl)); goto ok;
22320 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
22321 RSY_r1(ovl), RSY_r3(ovl),
22322 RSY_b2(ovl), RSY_dl2(ovl),
22323 RSY_dh2(ovl)); goto ok;
22324 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, RSY_r1(ovl),
22325 RSY_r3(ovl), RSY_b2(ovl),
22326 RSY_dl2(ovl),
22327 RSY_dh2(ovl)); goto ok;
22328 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, RSY_r1(ovl),
22329 RSY_r3(ovl), RSY_b2(ovl),
22330 RSY_dl2(ovl),
22331 RSY_dh2(ovl)); goto ok;
22332 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, RSY_r1(ovl),
22333 RSY_r3(ovl), RSY_b2(ovl),
22334 RSY_dl2(ovl),
22335 RSY_dh2(ovl)); goto ok;
22336 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, RSY_r1(ovl),
22337 RSY_r3(ovl), RSY_b2(ovl),
22338 RSY_dl2(ovl),
22339 RSY_dh2(ovl)); goto ok;
22340 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
22341 RSY_r1(ovl), RSY_r3(ovl),
22342 RSY_b2(ovl), RSY_dl2(ovl),
22343 RSY_dh2(ovl)); goto ok;
22344 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, RSY_r1(ovl),
22345 RSY_r3(ovl), RSY_b2(ovl),
22346 RSY_dl2(ovl),
22347 RSY_dh2(ovl)); goto ok;
22348 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, RSY_r1(ovl),
22349 RSY_r3(ovl), RSY_b2(ovl),
22350 RSY_dl2(ovl),
22351 RSY_dh2(ovl)); goto ok;
22352 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, RSY_r1(ovl),
22353 RSY_r3(ovl), RSY_b2(ovl),
22354 RSY_dl2(ovl),
22355 RSY_dh2(ovl)); goto ok;
22356 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, RSY_r1(ovl),
22357 RSY_r3(ovl), RSY_b2(ovl),
22358 RSY_dl2(ovl),
22359 RSY_dh2(ovl)); goto ok;
22360 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, RSY_r1(ovl),
22361 RSY_r3(ovl), RSY_b2(ovl),
22362 RSY_dl2(ovl),
22363 RSY_dh2(ovl)); goto ok;
22364 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, RSY_r1(ovl),
22365 RSY_r3(ovl), RSY_b2(ovl),
22366 RSY_dl2(ovl),
22367 RSY_dh2(ovl)); goto ok;
22368 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, RSY_r1(ovl),
22369 RSY_r3(ovl), RSY_b2(ovl),
22370 RSY_dl2(ovl),
22371 RSY_dh2(ovl)); goto ok;
22372 case 0xec0000000042ULL: s390_format_RIE_RUPIX(s390_irgen_LOCHI,
22373 RIEv3_r1(ovl),
22374 RIEv3_m3(ovl),
22375 RIEv3_i4(ovl)); goto ok;
22376 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, RIE_r1(ovl),
22377 RIE_r3(ovl), RIE_i2(ovl));
22378 goto ok;
22379 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, RIE_r1(ovl),
22380 RIE_r3(ovl), RIE_i2(ovl));
22381 goto ok;
22382 case 0xec0000000046ULL: s390_format_RIE_RUPIX(s390_irgen_LOCGHI,
22383 RIEv3_r1(ovl),
22384 RIEv3_m3(ovl),
22385 RIEv3_i4(ovl)); goto ok;
22386 case 0xec000000004eULL: s390_format_RIE_RUPIX(s390_irgen_LOCHHI,
22387 RIEv3_r1(ovl),
22388 RIEv3_m3(ovl),
22389 RIEv3_i4(ovl)); goto ok;
22390 case 0xec0000000051ULL: s390_format_RIE_RRUUU(s390_irgen_RISBLG,
22391 RIE_RRUUU_r1(ovl),
22392 RIE_RRUUU_r2(ovl),
22393 RIE_RRUUU_i3(ovl),
22394 RIE_RRUUU_i4(ovl),
22395 RIE_RRUUU_i5(ovl));
22396 goto ok;
22397 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
22398 RIE_RRUUU_r1(ovl),
22399 RIE_RRUUU_r2(ovl),
22400 RIE_RRUUU_i3(ovl),
22401 RIE_RRUUU_i4(ovl),
22402 RIE_RRUUU_i5(ovl));
22403 goto ok;
22404 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
22405 RIE_RRUUU_r1(ovl),
22406 RIE_RRUUU_r2(ovl),
22407 RIE_RRUUU_i3(ovl),
22408 RIE_RRUUU_i4(ovl),
22409 RIE_RRUUU_i5(ovl));
22410 goto ok;
22411 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
22412 RIE_RRUUU_r1(ovl),
22413 RIE_RRUUU_r2(ovl),
22414 RIE_RRUUU_i3(ovl),
22415 RIE_RRUUU_i4(ovl),
22416 RIE_RRUUU_i5(ovl));
22417 goto ok;
22418 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
22419 RIE_RRUUU_r1(ovl),
22420 RIE_RRUUU_r2(ovl),
22421 RIE_RRUUU_i3(ovl),
22422 RIE_RRUUU_i4(ovl),
22423 RIE_RRUUU_i5(ovl));
22424 goto ok;
22425 case 0xec0000000059ULL: s390_format_RIE_RRUUU(s390_irgen_RISBGN,
22426 RIE_RRUUU_r1(ovl),
22427 RIE_RRUUU_r2(ovl),
22428 RIE_RRUUU_i3(ovl),
22429 RIE_RRUUU_i4(ovl),
22430 RIE_RRUUU_i5(ovl));
22431 goto ok;
22432 case 0xec000000005dULL: s390_format_RIE_RRUUU(s390_irgen_RISBHG,
22433 RIE_RRUUU_r1(ovl),
22434 RIE_RRUUU_r2(ovl),
22435 RIE_RRUUU_i3(ovl),
22436 RIE_RRUUU_i4(ovl),
22437 RIE_RRUUU_i5(ovl));
22438 goto ok;
22439 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
22440 RIE_RRPU_r1(ovl),
22441 RIE_RRPU_r2(ovl),
22442 RIE_RRPU_i4(ovl),
22443 RIE_RRPU_m3(ovl)); goto ok;
22444 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
22445 RIE_RRPU_r1(ovl),
22446 RIE_RRPU_r2(ovl),
22447 RIE_RRPU_i4(ovl),
22448 RIE_RRPU_m3(ovl)); goto ok;
22449 case 0xec0000000070ULL: s390_format_R0IU(s390_irgen_CGIT,
22450 RIE_R0xU_r1(ovl),
22451 RIE_R0xU_i2(ovl),
22452 RIE_R0xU_m3(ovl)); goto ok;
22453 case 0xec0000000071ULL: s390_format_R0UU(s390_irgen_CLGIT,
22454 RIE_R0xU_r1(ovl),
22455 RIE_R0xU_i2(ovl),
22456 RIE_R0xU_m3(ovl)); goto ok;
22457 case 0xec0000000072ULL: s390_format_R0IU(s390_irgen_CIT,
22458 RIE_R0xU_r1(ovl),
22459 RIE_R0xU_i2(ovl),
22460 RIE_R0xU_m3(ovl)); goto ok;
22461 case 0xec0000000073ULL: s390_format_R0UU(s390_irgen_CLFIT,
22462 RIE_R0xU_r1(ovl),
22463 RIE_R0xU_i2(ovl),
22464 RIE_R0xU_m3(ovl)); goto ok;
22465 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
22466 RIE_RRPU_r1(ovl),
22467 RIE_RRPU_r2(ovl),
22468 RIE_RRPU_i4(ovl),
22469 RIE_RRPU_m3(ovl)); goto ok;
22470 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
22471 RIE_RRPU_r1(ovl),
22472 RIE_RRPU_r2(ovl),
22473 RIE_RRPU_i4(ovl),
22474 RIE_RRPU_m3(ovl)); goto ok;
22475 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
22476 RIEv3_r1(ovl),
22477 RIEv3_m3(ovl),
22478 RIEv3_i4(ovl),
22479 RIEv3_i2(ovl)); goto ok;
22480 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
22481 RIEv3_r1(ovl),
22482 RIEv3_m3(ovl),
22483 RIEv3_i4(ovl),
22484 RIEv3_i2(ovl)); goto ok;
22485 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
22486 RIEv3_r1(ovl),
22487 RIEv3_m3(ovl),
22488 RIEv3_i4(ovl),
22489 RIEv3_i2(ovl)); goto ok;
22490 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
22491 RIEv3_r1(ovl),
22492 RIEv3_m3(ovl),
22493 RIEv3_i4(ovl),
22494 RIEv3_i2(ovl)); goto ok;
22495 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, RIE_r1(ovl),
22496 RIE_r3(ovl), RIE_i2(ovl));
22497 goto ok;
22498 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
22499 RIE_r1(ovl), RIE_r3(ovl),
22500 RIE_i2(ovl)); goto ok;
22501 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
22502 RIE_r1(ovl), RIE_r3(ovl),
22503 RIE_i2(ovl)); goto ok;
22504 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
22505 RIE_r1(ovl), RIE_r3(ovl),
22506 RIE_i2(ovl)); goto ok;
22507 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, RRS_r1(ovl),
22508 RRS_r2(ovl), RRS_b4(ovl),
22509 RRS_d4(ovl), RRS_m3(ovl));
22510 goto ok;
22511 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, RRS_r1(ovl),
22512 RRS_r2(ovl), RRS_b4(ovl),
22513 RRS_d4(ovl), RRS_m3(ovl));
22514 goto ok;
22515 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, RRS_r1(ovl),
22516 RRS_r2(ovl), RRS_b4(ovl),
22517 RRS_d4(ovl), RRS_m3(ovl));
22518 goto ok;
22519 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, RRS_r1(ovl),
22520 RRS_r2(ovl), RRS_b4(ovl),
22521 RRS_d4(ovl), RRS_m3(ovl));
22522 goto ok;
22523 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
22524 RIS_r1(ovl), RIS_m3(ovl),
22525 RIS_b4(ovl), RIS_d4(ovl),
22526 RIS_i2(ovl)); goto ok;
22527 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
22528 RIS_r1(ovl), RIS_m3(ovl),
22529 RIS_b4(ovl), RIS_d4(ovl),
22530 RIS_i2(ovl)); goto ok;
22531 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, RIS_r1(ovl),
22532 RIS_m3(ovl), RIS_b4(ovl),
22533 RIS_d4(ovl),
22534 RIS_i2(ovl)); goto ok;
22535 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
22536 RIS_r1(ovl), RIS_m3(ovl),
22537 RIS_b4(ovl), RIS_d4(ovl),
22538 RIS_i2(ovl)); goto ok;
22539 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, RXE_r1(ovl),
22540 RXE_x2(ovl), RXE_b2(ovl),
22541 RXE_d2(ovl)); goto ok;
22542 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, RXE_r1(ovl),
22543 RXE_x2(ovl), RXE_b2(ovl),
22544 RXE_d2(ovl)); goto ok;
22545 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, RXE_r1(ovl),
22546 RXE_x2(ovl), RXE_b2(ovl),
22547 RXE_d2(ovl)); goto ok;
22548 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
22549 case 0xed0000000008ULL: s390_format_RXE_FRRD(s390_irgen_KEB, RXE_r1(ovl),
22550 RXE_x2(ovl), RXE_b2(ovl),
22551 RXE_d2(ovl)); goto ok;
22552 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, RXE_r1(ovl),
22553 RXE_x2(ovl), RXE_b2(ovl),
22554 RXE_d2(ovl)); goto ok;
22555 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, RXE_r1(ovl),
22556 RXE_x2(ovl), RXE_b2(ovl),
22557 RXE_d2(ovl)); goto ok;
22558 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, RXE_r1(ovl),
22559 RXE_x2(ovl), RXE_b2(ovl),
22560 RXE_d2(ovl)); goto ok;
22561 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
22562 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, RXE_r1(ovl),
22563 RXE_x2(ovl), RXE_b2(ovl),
22564 RXE_d2(ovl)); goto ok;
22565 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
22566 RXF_r3(ovl), RXF_x2(ovl),
22567 RXF_b2(ovl), RXF_d2(ovl),
22568 RXF_r1(ovl)); goto ok;
22569 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
22570 RXF_r3(ovl), RXF_x2(ovl),
22571 RXF_b2(ovl), RXF_d2(ovl),
22572 RXF_r1(ovl)); goto ok;
22573 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, RXE_r1(ovl),
22574 RXE_x2(ovl), RXE_b2(ovl),
22575 RXE_d2(ovl)); goto ok;
22576 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, RXE_r1(ovl),
22577 RXE_x2(ovl), RXE_b2(ovl),
22578 RXE_d2(ovl)); goto ok;
22579 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, RXE_r1(ovl),
22580 RXE_x2(ovl), RXE_b2(ovl),
22581 RXE_d2(ovl)); goto ok;
22582 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, RXE_r1(ovl),
22583 RXE_x2(ovl), RXE_b2(ovl),
22584 RXE_d2(ovl)); goto ok;
22585 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, RXE_r1(ovl),
22586 RXE_x2(ovl), RXE_b2(ovl),
22587 RXE_d2(ovl)); goto ok;
22588 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, RXE_r1(ovl),
22589 RXE_x2(ovl), RXE_b2(ovl),
22590 RXE_d2(ovl)); goto ok;
22591 case 0xed0000000018ULL: s390_format_RXE_FRRD(s390_irgen_KDB, RXE_r1(ovl),
22592 RXE_x2(ovl), RXE_b2(ovl),
22593 RXE_d2(ovl)); goto ok;
22594 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, RXE_r1(ovl),
22595 RXE_x2(ovl), RXE_b2(ovl),
22596 RXE_d2(ovl)); goto ok;
22597 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, RXE_r1(ovl),
22598 RXE_x2(ovl), RXE_b2(ovl),
22599 RXE_d2(ovl)); goto ok;
22600 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, RXE_r1(ovl),
22601 RXE_x2(ovl), RXE_b2(ovl),
22602 RXE_d2(ovl)); goto ok;
22603 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, RXE_r1(ovl),
22604 RXE_x2(ovl), RXE_b2(ovl),
22605 RXE_d2(ovl)); goto ok;
22606 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, RXE_r1(ovl),
22607 RXE_x2(ovl), RXE_b2(ovl),
22608 RXE_d2(ovl)); goto ok;
22609 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
22610 RXF_r3(ovl), RXF_x2(ovl),
22611 RXF_b2(ovl), RXF_d2(ovl),
22612 RXF_r1(ovl)); goto ok;
22613 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
22614 RXF_r3(ovl), RXF_x2(ovl),
22615 RXF_b2(ovl), RXF_d2(ovl),
22616 RXF_r1(ovl)); goto ok;
22617 case 0xed0000000024ULL: s390_format_RXE_FRRD(s390_irgen_LDE,
22618 RXE_r1(ovl), RXE_x2(ovl),
22619 RXE_b2(ovl),
22620 RXE_d2(ovl)); goto ok;
22621 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
22622 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
22623 case 0xed000000002eULL: /* MAE */ goto unimplemented;
22624 case 0xed000000002fULL: /* MSE */ goto unimplemented;
22625 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
22626 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
22627 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
22628 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
22629 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
22630 case 0xed000000003aULL: /* MAY */ goto unimplemented;
22631 case 0xed000000003bULL: /* MY */ goto unimplemented;
22632 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
22633 case 0xed000000003dULL: /* MYH */ goto unimplemented;
22634 case 0xed000000003eULL: /* MAD */ goto unimplemented;
22635 case 0xed000000003fULL: /* MSD */ goto unimplemented;
22636 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
22637 RXF_r3(ovl), RXF_x2(ovl),
22638 RXF_b2(ovl), RXF_d2(ovl),
22639 RXF_r1(ovl)); goto ok;
22640 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
22641 RXF_r3(ovl), RXF_x2(ovl),
22642 RXF_b2(ovl), RXF_d2(ovl),
22643 RXF_r1(ovl)); goto ok;
22644 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
22645 RXF_r3(ovl), RXF_x2(ovl),
22646 RXF_b2(ovl), RXF_d2(ovl),
22647 RXF_r1(ovl)); goto ok;
22648 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
22649 RXF_r3(ovl), RXF_x2(ovl),
22650 RXF_b2(ovl), RXF_d2(ovl),
22651 RXF_r1(ovl)); goto ok;
22652 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, RXE_r1(ovl),
22653 RXE_x2(ovl), RXE_b2(ovl),
22654 RXE_d2(ovl)); goto ok;
22655 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, RXE_r1(ovl),
22656 RXE_x2(ovl), RXE_b2(ovl),
22657 RXE_d2(ovl)); goto ok;
22658 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, RXE_r1(ovl),
22659 RXE_x2(ovl), RXE_b2(ovl),
22660 RXE_d2(ovl)); goto ok;
22661 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, RXE_r1(ovl),
22662 RXE_x2(ovl), RXE_b2(ovl),
22663 RXE_d2(ovl)); goto ok;
22664 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, RXE_r1(ovl),
22665 RXE_x2(ovl), RXE_b2(ovl),
22666 RXE_d2(ovl)); goto ok;
22667 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, RXE_r1(ovl),
22668 RXE_x2(ovl), RXE_b2(ovl),
22669 RXE_d2(ovl)); goto ok;
22670 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, RXY_r1(ovl),
22671 RXY_x2(ovl), RXY_b2(ovl),
22672 RXY_dl2(ovl),
22673 RXY_dh2(ovl)); goto ok;
22674 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, RXY_r1(ovl),
22675 RXY_x2(ovl), RXY_b2(ovl),
22676 RXY_dl2(ovl),
22677 RXY_dh2(ovl)); goto ok;
22678 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, RXY_r1(ovl),
22679 RXY_x2(ovl), RXY_b2(ovl),
22680 RXY_dl2(ovl),
22681 RXY_dh2(ovl)); goto ok;
22682 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, RXY_r1(ovl),
22683 RXY_x2(ovl), RXY_b2(ovl),
22684 RXY_dl2(ovl),
22685 RXY_dh2(ovl)); goto ok;
22686 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
22687 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
22688 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
22689 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
22690 case 0xed00000000acULL: /* CPDT */ goto unimplemented;
22691 case 0xed00000000adULL: /* CPXT */ goto unimplemented;
22692 case 0xed00000000aeULL: /* CDPT */ goto unimplemented;
22693 case 0xed00000000afULL: /* CXPT */ goto unimplemented;
22696 switch (((ovl >> 16) & 0xff0f00000000ULL) >> 32) {
22697 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, RIL_r1(ovl),
22698 RIL_i2(ovl)); goto ok;
22699 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, RIL_r1(ovl),
22700 RIL_i2(ovl)); goto ok;
22701 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, RIL_r1(ovl),
22702 RIL_i2(ovl)); goto ok;
22703 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, RIL_r1(ovl),
22704 RIL_i2(ovl)); goto ok;
22705 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, RIL_r1(ovl),
22706 RIL_i2(ovl)); goto ok;
22707 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, RIL_r1(ovl),
22708 RIL_i2(ovl)); goto ok;
22709 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, RIL_r1(ovl),
22710 RIL_i2(ovl)); goto ok;
22711 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, RIL_r1(ovl),
22712 RIL_i2(ovl)); goto ok;
22713 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, RIL_r1(ovl),
22714 RIL_i2(ovl)); goto ok;
22715 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, RIL_r1(ovl),
22716 RIL_i2(ovl)); goto ok;
22717 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, RIL_r1(ovl),
22718 RIL_i2(ovl)); goto ok;
22719 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, RIL_r1(ovl),
22720 RIL_i2(ovl)); goto ok;
22721 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, RIL_r1(ovl),
22722 RIL_i2(ovl)); goto ok;
22723 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, RIL_r1(ovl),
22724 RIL_i2(ovl)); goto ok;
22725 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, RIL_r1(ovl),
22726 RIL_i2(ovl)); goto ok;
22727 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, RIL_r1(ovl),
22728 RIL_i2(ovl)); goto ok;
22729 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, RIL_r1(ovl),
22730 RIL_i2(ovl)); goto ok;
22731 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, RIL_r1(ovl),
22732 RIL_i2(ovl)); goto ok;
22733 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, RIL_r1(ovl),
22734 RIL_i2(ovl)); goto ok;
22735 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, RIL_r1(ovl),
22736 RIL_i2(ovl)); goto ok;
22737 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, RIL_r1(ovl),
22738 RIL_i2(ovl)); goto ok;
22739 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, RIL_r1(ovl),
22740 RIL_i2(ovl)); goto ok;
22741 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, RIL_r1(ovl),
22742 RIL_i2(ovl)); goto ok;
22743 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, RIL_r1(ovl),
22744 RIL_i2(ovl)); goto ok;
22745 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, RIL_r1(ovl),
22746 RIL_i2(ovl)); goto ok;
22747 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, RIL_r1(ovl),
22748 RIL_i2(ovl)); goto ok;
22749 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, RIL_r1(ovl),
22750 RIL_i2(ovl)); goto ok;
22751 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, RIL_r1(ovl),
22752 RIL_i2(ovl)); goto ok;
22753 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, RIL_r1(ovl),
22754 RIL_i2(ovl)); goto ok;
22755 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, RIL_r1(ovl),
22756 RIL_i2(ovl)); goto ok;
22757 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, RIL_r1(ovl),
22758 RIL_i2(ovl)); goto ok;
22759 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, RIL_r1(ovl),
22760 RIL_i2(ovl)); goto ok;
22761 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, RIL_r1(ovl),
22762 RIL_i2(ovl)); goto ok;
22763 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, RIL_r1(ovl),
22764 RIL_i2(ovl)); goto ok;
22765 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, RIL_r1(ovl),
22766 RIL_i2(ovl)); goto ok;
22767 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, RIL_r1(ovl),
22768 RIL_i2(ovl)); goto ok;
22769 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, RIL_r1(ovl),
22770 RIL_i2(ovl)); goto ok;
22771 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, RIL_r1(ovl),
22772 RIL_i2(ovl)); goto ok;
22773 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, RIL_r1(ovl),
22774 RIL_i2(ovl)); goto ok;
22775 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, RIL_r1(ovl),
22776 RIL_i2(ovl)); goto ok;
22777 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, RIL_r1(ovl),
22778 RIL_i2(ovl)); goto ok;
22779 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, RIL_r1(ovl),
22780 RIL_i2(ovl)); goto ok;
22781 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, RIL_r1(ovl),
22782 RIL_i2(ovl)); goto ok;
22783 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, RIL_r1(ovl),
22784 RIL_i2(ovl)); goto ok;
22785 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, RIL_r1(ovl),
22786 RIL_i2(ovl)); goto ok;
22787 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, RIL_r1(ovl),
22788 RIL_i2(ovl)); goto ok;
22789 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, RIL_r1(ovl),
22790 RIL_i2(ovl)); goto ok;
22791 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, RIL_r1(ovl),
22792 RIL_i2(ovl)); goto ok;
22793 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, RIL_r1(ovl),
22794 RIL_i2(ovl)); goto ok;
22795 case 0xc800ULL: /* MVCOS */ goto unimplemented;
22796 case 0xc801ULL: /* ECTG */ goto unimplemented;
22797 case 0xc802ULL: /* CSST */ goto unimplemented;
22798 case 0xc804ULL: /* LPD */ goto unimplemented;
22799 case 0xc805ULL: /* LPDG */ goto unimplemented;
22800 case 0xc806ULL: /* CAL */ goto unimplemented;
22801 case 0xc807ULL: /* CALG */ goto unimplemented;
22802 case 0xc80fULL: /* CALGF */ goto unimplemented;
22803 case 0xcc06ULL: s390_format_RIL_RP(s390_irgen_BRCTH, RIL_r1(ovl),
22804 RIL_i2(ovl)); goto ok;
22805 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, RIL_r1(ovl),
22806 RIL_i2(ovl)); goto ok;
22807 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, RIL_r1(ovl),
22808 RIL_i2(ovl)); goto ok;
22809 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, RIL_r1(ovl),
22810 RIL_i2(ovl)); goto ok;
22811 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, RIL_r1(ovl),
22812 RIL_i2(ovl)); goto ok;
22813 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, RIL_r1(ovl),
22814 RIL_i2(ovl)); goto ok;
22817 switch (((ovl >> 16) & 0xff0000000000ULL) >> 40) {
22818 case 0xc5ULL: /* BPRP */ goto unimplemented;
22819 case 0xc7ULL: /* BPP */ goto unimplemented;
22820 case 0xd0ULL: /* TRTR */ goto unimplemented;
22821 case 0xd1ULL: /* MVN */ goto unimplemented;
22822 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, SS_l(ovl),
22823 SS_b1(ovl), SS_d1(ovl),
22824 SS_b2(ovl), SS_d2(ovl)); goto ok;
22825 case 0xd3ULL: /* MVZ */ goto unimplemented;
22826 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, SS_l(ovl),
22827 SS_b1(ovl), SS_d1(ovl),
22828 SS_b2(ovl), SS_d2(ovl)); goto ok;
22829 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, SS_l(ovl),
22830 SS_b1(ovl), SS_d1(ovl),
22831 SS_b2(ovl), SS_d2(ovl)); goto ok;
22832 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, SS_l(ovl),
22833 SS_b1(ovl), SS_d1(ovl),
22834 SS_b2(ovl), SS_d2(ovl)); goto ok;
22835 case 0xd7ULL:
22836 if (SS_b1(ovl) == SS_b2(ovl) && SS_d1(ovl) == SS_d2(ovl))
22837 s390_irgen_XC_sameloc(SS_l(ovl), SS_b1(ovl), SS_d1(ovl));
22838 else
22839 s390_format_SS_L0RDRD(s390_irgen_XC, SS_l(ovl),
22840 SS_b1(ovl), SS_d1(ovl),
22841 SS_b2(ovl), SS_d2(ovl));
22842 goto ok;
22843 case 0xd9ULL: /* MVCK */ goto unimplemented;
22844 case 0xdaULL: /* MVCP */ goto unimplemented;
22845 case 0xdbULL: /* MVCS */ goto unimplemented;
22846 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, SS_l(ovl),
22847 SS_b1(ovl), SS_d1(ovl),
22848 SS_b2(ovl), SS_d2(ovl)); goto ok;
22849 case 0xddULL: /* TRT */ goto unimplemented;
22850 case 0xdeULL: /* ED */ goto unimplemented;
22851 case 0xdfULL: /* EDMK */ goto unimplemented;
22852 case 0xe1ULL: /* PKU */ goto unimplemented;
22853 case 0xe2ULL: /* UNPKU */ goto unimplemented;
22854 case 0xe8ULL: s390_format_SS_L0RDRD(s390_irgen_MVCIN, SS_l(ovl),
22855 SS_b1(ovl), SS_d1(ovl),
22856 SS_b2(ovl), SS_d2(ovl)); goto ok;
22857 case 0xe9ULL: /* PKA */ goto unimplemented;
22858 case 0xeaULL: /* UNPKA */ goto unimplemented;
22859 case 0xeeULL: /* PLO */ goto unimplemented;
22860 case 0xefULL: /* LMD */ goto unimplemented;
22861 case 0xf0ULL: /* SRP */ goto unimplemented;
22862 case 0xf1ULL: /* MVO */ goto unimplemented;
22863 case 0xf2ULL: /* PACK */ goto unimplemented;
22864 case 0xf3ULL: /* UNPK */ goto unimplemented;
22865 case 0xf8ULL: /* ZAP */ goto unimplemented;
22866 case 0xf9ULL: /* CP */ goto unimplemented;
22867 case 0xfaULL: /* AP */ goto unimplemented;
22868 case 0xfbULL: /* SP */ goto unimplemented;
22869 case 0xfcULL: /* MP */ goto unimplemented;
22870 case 0xfdULL: /* DP */ goto unimplemented;
22873 switch (((ovl >> 16) & 0xffff00000000ULL) >> 32) {
22874 case 0xe500ULL: /* LASP */ goto unimplemented;
22875 case 0xe501ULL: /* TPROT */ goto unimplemented;
22876 case 0xe502ULL: /* STRAG */ goto unimplemented;
22877 case 0xe50aULL: s390_format_SSE_RDRD(s390_irgen_MVCRL,
22878 SS_b1(ovl), SS_d1(ovl),
22879 SS_b2(ovl), SS_d2(ovl)); goto ok;
22880 case 0xe50eULL: /* MVCSK */ goto unimplemented;
22881 case 0xe50fULL: /* MVCDK */ goto unimplemented;
22882 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, SIL_b1(ovl),
22883 SIL_d1(ovl), SIL_i2(ovl));
22884 goto ok;
22885 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, SIL_b1(ovl),
22886 SIL_d1(ovl), SIL_i2(ovl));
22887 goto ok;
22888 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, SIL_b1(ovl),
22889 SIL_d1(ovl), SIL_i2(ovl));
22890 goto ok;
22891 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, SIL_b1(ovl),
22892 SIL_d1(ovl), SIL_i2(ovl));
22893 goto ok;
22894 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, SIL_b1(ovl),
22895 SIL_d1(ovl), SIL_i2(ovl));
22896 goto ok;
22897 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, SIL_b1(ovl),
22898 SIL_d1(ovl), SIL_i2(ovl));
22899 goto ok;
22900 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, SIL_b1(ovl),
22901 SIL_d1(ovl), SIL_i2(ovl));
22902 goto ok;
22903 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, SIL_b1(ovl),
22904 SIL_d1(ovl), SIL_i2(ovl));
22905 goto ok;
22906 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, SIL_b1(ovl),
22907 SIL_d1(ovl), SIL_i2(ovl));
22908 goto ok;
22909 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
22910 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
22913 return S390_DECODE_UNKNOWN_INSN;
22916 return S390_DECODE_OK;
22918 unimplemented:
22919 return S390_DECODE_UNIMPLEMENTED_INSN;
22922 /* Handle "special" instructions. */
22923 static s390_decode_t
22924 s390_decode_special_and_irgen(const UChar *bytes)
22926 s390_decode_t status = S390_DECODE_OK;
22928 /* Got a "Special" instruction preamble. Which one is it? */
22929 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
22930 s390_irgen_client_request();
22931 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
22932 s390_irgen_guest_NRADDR();
22933 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
22934 s390_irgen_call_noredir();
22935 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
22936 vex_inject_ir(irsb, Iend_BE);
22938 /* Invalidate the current insn. The reason is that the IRop we're
22939 injecting here can change. In which case the translation has to
22940 be redone. For ease of handling, we simply invalidate all the
22941 time. */
22942 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
22943 mkU64(guest_IA_curr_instr)));
22944 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN),
22945 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
22946 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
22947 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
22949 put_IA(mkaddr_expr(guest_IA_next_instr));
22950 dis_res->whatNext = Dis_StopHere;
22951 dis_res->jk_StopHere = Ijk_InvalICache;
22952 } else {
22953 /* We don't know what it is. */
22954 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
22957 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
22959 return status;
22963 /* Function returns # bytes that were decoded or 0 in case of failure */
22964 static UInt
22965 s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres)
22967 s390_decode_t status;
22969 dis_res = dres;
22971 /* Spot the 8-byte preamble: 18ff lr r15,r15
22972 1811 lr r1,r1
22973 1822 lr r2,r2
22974 1833 lr r3,r3 */
22975 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
22976 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
22977 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
22979 /* Handle special instruction that follows that preamble. */
22980 if (0) vex_printf("special function handling...\n");
22982 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
22983 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
22985 status =
22986 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
22987 } else {
22988 /* Handle normal instructions. */
22989 switch (insn_length) {
22990 case 2:
22991 status = s390_decode_2byte_and_irgen(bytes);
22992 break;
22994 case 4:
22995 status = s390_decode_4byte_and_irgen(bytes);
22996 break;
22998 case 6:
22999 status = s390_decode_6byte_and_irgen(bytes);
23000 break;
23002 default:
23003 status = S390_DECODE_ERROR;
23004 break;
23007 /* If next instruction is execute, stop here */
23008 if (dis_res->whatNext == Dis_Continue &&
23009 (bytes[insn_length] == 0x44 ||
23010 (bytes[insn_length] == 0xc6 && (bytes[insn_length + 1] & 0xf) == 0))) {
23011 put_IA(mkaddr_expr(guest_IA_next_instr));
23012 dis_res->whatNext = Dis_StopHere;
23013 dis_res->jk_StopHere = Ijk_Boring;
23016 if (status == S390_DECODE_OK) {
23017 /* Adjust status if a specification exception was indicated. */
23018 if (is_specification_exception())
23019 status = S390_DECODE_SPECIFICATION_EXCEPTION;
23020 else
23021 return insn_length; /* OK */
23024 /* Decoding failed somehow */
23025 if (sigill_diag) {
23026 vex_printf("vex s390->IR: ");
23027 switch (status) {
23028 case S390_DECODE_UNKNOWN_INSN:
23029 vex_printf("unknown insn: ");
23030 break;
23032 case S390_DECODE_UNIMPLEMENTED_INSN:
23033 vex_printf("unimplemented insn: ");
23034 break;
23036 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
23037 vex_printf("unimplemented special insn: ");
23038 break;
23040 case S390_DECODE_SPECIFICATION_EXCEPTION:
23041 vex_printf("specification exception: ");
23042 break;
23044 case S390_DECODE_ERROR:
23045 vex_printf("decoding error: ");
23046 break;
23048 default:
23049 vpanic("s390_decode_and_irgen");
23052 vex_printf("%02x%02x", bytes[0], bytes[1]);
23053 if (insn_length > 2) {
23054 vex_printf(" %02x%02x", bytes[2], bytes[3]);
23056 if (insn_length > 4) {
23057 vex_printf(" %02x%02x", bytes[4], bytes[5]);
23059 vex_printf("\n");
23062 return 0; /* Failed */
23066 /* Disassemble a single instruction INSN into IR. */
23067 static DisResult
23068 disInstr_S390_WRK(const UChar *insn)
23070 UChar byte;
23071 UInt insn_length;
23072 DisResult dres;
23074 /* ---------------------------------------------------- */
23075 /* --- Compute instruction length -- */
23076 /* ---------------------------------------------------- */
23078 /* Get the first byte of the insn. */
23079 byte = insn[0];
23081 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
23082 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
23083 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
23085 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
23087 /* ---------------------------------------------------- */
23088 /* --- Initialise the DisResult data -- */
23089 /* ---------------------------------------------------- */
23090 dres.whatNext = Dis_Continue;
23091 dres.len = insn_length;
23092 dres.jk_StopHere = Ijk_INVALID;
23093 dres.hint = Dis_HintNone;
23095 /* fixs390: consider chasing of conditional jumps */
23097 /* Normal and special instruction handling starts here. */
23098 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
23099 /* All decode failures end up here. The decoder has already issued an
23100 error message.
23101 Tell the dispatcher that this insn cannot be decoded, and so has
23102 not been executed, and (is currently) the next to be executed.
23103 The insn address in the guest state needs to be set to
23104 guest_IA_curr_instr, otherwise the complaint will report an
23105 incorrect address. */
23106 put_IA(mkaddr_expr(guest_IA_curr_instr));
23108 dres.len = 0;
23109 dres.whatNext = Dis_StopHere;
23110 dres.jk_StopHere = Ijk_NoDecode;
23111 } else {
23112 /* Decode success */
23113 switch (dres.whatNext) {
23114 case Dis_Continue:
23115 put_IA(mkaddr_expr(guest_IA_next_instr));
23116 break;
23117 case Dis_StopHere:
23118 if (dres.jk_StopHere == Ijk_EmWarn ||
23119 dres.jk_StopHere == Ijk_EmFail) {
23120 /* We assume here, that emulation warnings are not given for
23121 insns that transfer control. There is no good way to
23122 do that. */
23123 put_IA(mkaddr_expr(guest_IA_next_instr));
23125 break;
23126 default:
23127 vpanic("disInstr_S390_WRK");
23131 return dres;
23135 /*------------------------------------------------------------*/
23136 /*--- Top-level fn ---*/
23137 /*------------------------------------------------------------*/
23139 /* Disassemble a single instruction into IR. The instruction
23140 is located in host memory at &guest_code[delta]. */
23142 DisResult
23143 disInstr_S390(IRSB *irsb_IN,
23144 const UChar *guest_code,
23145 Long delta,
23146 Addr guest_IP,
23147 VexArch guest_arch,
23148 const VexArchInfo *archinfo,
23149 const VexAbiInfo *abiinfo,
23150 VexEndness host_endness,
23151 Bool sigill_diag_IN)
23153 vassert(guest_arch == VexArchS390X);
23155 /* Set globals (see top of this file) */
23156 guest_IA_curr_instr = guest_IP;
23157 if (last_execute_target == Invalid_execute_target)
23158 guest_IA_rel_base = guest_IA_curr_instr;
23159 irsb = irsb_IN;
23160 sigill_diag = sigill_diag_IN;
23162 return disInstr_S390_WRK(guest_code + delta);
23165 /*---------------------------------------------------------------*/
23166 /*--- end guest_s390_toIR.c ---*/
23167 /*---------------------------------------------------------------*/