blob: f0add1ba1fe120a65c52e18658a3ee982d2f5216 [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
sewardj89ae8472013-10-18 14:12:58 +000011 Copyright IBM Corp. 2010-2013
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
florianb0b67102012-12-24 00:14:31 +000044#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h" /* s390_host_has_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000046
sewardj2019a972011-03-07 16:04:07 +000047
48/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000049/*--- Forward declarations ---*/
50/*------------------------------------------------------------*/
florian8462d112014-09-24 15:18:09 +000051static UInt s390_decode_and_irgen(const UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr64);
75static void *resteer_data;
76
sewardj442e51a2012-12-06 18:08:04 +000077/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
sewardj2019a972011-03-07 16:04:07 +000080/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_ERROR
90} s390_decode_t;
91
florian428dfdd2012-03-27 03:09:49 +000092
sewardj2019a972011-03-07 16:04:07 +000093/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR. ---*/
95/*------------------------------------------------------------*/
96
97/* Sign extend a value with the given number of bits. This is a
98 macro because it allows us to overload the type of the value.
99 Note that VALUE must have a signed type! */
100#undef sign_extend
101#define sign_extend(value,num_bits) \
102(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
103 (sizeof(__typeof__(value)) * 8 - (num_bits)))
104
105
106/* Add a statement to the current irsb. */
107static __inline__ void
108stmt(IRStmt *st)
109{
110 addStmtToIRSB(irsb, st);
111}
112
113/* Allocate a new temporary of the given type. */
114static __inline__ IRTemp
115newTemp(IRType type)
116{
117 vassert(isPlausibleIRType(type));
118
119 return newIRTemp(irsb->tyenv, type);
120}
121
122/* Create an expression node for a temporary */
123static __inline__ IRExpr *
124mkexpr(IRTemp tmp)
125{
126 return IRExpr_RdTmp(tmp);
127}
128
florian8844a632012-04-13 04:04:06 +0000129/* Generate an expression node for an address. */
130static __inline__ IRExpr *
131mkaddr_expr(Addr64 addr)
132{
133 return IRExpr_Const(IRConst_U64(addr));
134}
135
sewardj2019a972011-03-07 16:04:07 +0000136/* Add a statement that assigns to a temporary */
137static __inline__ void
138assign(IRTemp dst, IRExpr *expr)
139{
140 stmt(IRStmt_WrTmp(dst, expr));
141}
142
florian8844a632012-04-13 04:04:06 +0000143/* Write an address into the guest_IA */
144static __inline__ void
145put_IA(IRExpr *address)
146{
147 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
148}
149
sewardj2019a972011-03-07 16:04:07 +0000150/* Create a temporary of the given type and assign the expression to it */
151static __inline__ IRTemp
152mktemp(IRType type, IRExpr *expr)
153{
154 IRTemp temp = newTemp(type);
155
156 assign(temp, expr);
157
158 return temp;
159}
160
161/* Create a unary expression */
162static __inline__ IRExpr *
163unop(IROp kind, IRExpr *op)
164{
165 return IRExpr_Unop(kind, op);
166}
167
168/* Create a binary expression */
169static __inline__ IRExpr *
170binop(IROp kind, IRExpr *op1, IRExpr *op2)
171{
172 return IRExpr_Binop(kind, op1, op2);
173}
174
175/* Create a ternary expression */
176static __inline__ IRExpr *
177triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
178{
179 return IRExpr_Triop(kind, op1, op2, op3);
180}
181
182/* Create a quaternary expression */
183static __inline__ IRExpr *
184qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
185{
186 return IRExpr_Qop(kind, op1, op2, op3, op4);
187}
188
189/* Create an expression node for an 8-bit integer constant */
190static __inline__ IRExpr *
191mkU8(UInt value)
192{
193 vassert(value < 256);
194
195 return IRExpr_Const(IRConst_U8((UChar)value));
196}
197
198/* Create an expression node for a 16-bit integer constant */
199static __inline__ IRExpr *
200mkU16(UInt value)
201{
202 vassert(value < 65536);
203
204 return IRExpr_Const(IRConst_U16((UShort)value));
205}
206
207/* Create an expression node for a 32-bit integer constant */
208static __inline__ IRExpr *
209mkU32(UInt value)
210{
211 return IRExpr_Const(IRConst_U32(value));
212}
213
214/* Create an expression node for a 64-bit integer constant */
215static __inline__ IRExpr *
216mkU64(ULong value)
217{
218 return IRExpr_Const(IRConst_U64(value));
219}
220
221/* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223static __inline__ IRExpr *
224mkF32i(UInt value)
225{
226 return IRExpr_Const(IRConst_F32i(value));
227}
228
229/* Create an expression node for a 32-bit floating point constant
230 whose value is given by a bit pattern. */
231static __inline__ IRExpr *
232mkF64i(ULong value)
233{
234 return IRExpr_Const(IRConst_F64i(value));
235}
236
237/* Little helper function for my sanity. ITE = if-then-else */
238static IRExpr *
239mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
240{
241 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
242
florian99dd03e2013-01-29 03:56:06 +0000243 return IRExpr_ITE(condition, iftrue, iffalse);
sewardj2019a972011-03-07 16:04:07 +0000244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
sewardj05f5e012014-05-04 10:52:11 +0000420 stmt(IRStmt_Exit(condition, Ijk_InvalICache,
421 IRConst_U64(guest_IA_curr_instr),
florian6820ba52012-07-26 02:01:50 +0000422 S390X_GUEST_OFFSET(guest_IA)));
423}
424
425/* Convenience function to yield to thread scheduler */
426static void
427yield_if(IRExpr *condition)
428{
429 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
430 S390X_GUEST_OFFSET(guest_IA)));
431}
432
sewardj2019a972011-03-07 16:04:07 +0000433static __inline__ IRExpr *get_fpr_dw0(UInt);
434static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000435static __inline__ IRExpr *get_dpr_dw0(UInt);
436static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000437
438/* Read a floating point register pair and combine their contents into a
439 128-bit value */
440static IRExpr *
441get_fpr_pair(UInt archreg)
442{
443 IRExpr *high = get_fpr_dw0(archreg);
444 IRExpr *low = get_fpr_dw0(archreg + 2);
445
446 return binop(Iop_F64HLtoF128, high, low);
447}
448
449/* Write a 128-bit floating point value into a register pair. */
450static void
451put_fpr_pair(UInt archreg, IRExpr *expr)
452{
453 IRExpr *high = unop(Iop_F128HItoF64, expr);
454 IRExpr *low = unop(Iop_F128LOtoF64, expr);
455
456 put_fpr_dw0(archreg, high);
457 put_fpr_dw0(archreg + 2, low);
458}
459
floriane38f6412012-12-21 17:32:12 +0000460/* Read a floating point register pair cointaining DFP value
461 and combine their contents into a 128-bit value */
462
463static IRExpr *
464get_dpr_pair(UInt archreg)
465{
466 IRExpr *high = get_dpr_dw0(archreg);
467 IRExpr *low = get_dpr_dw0(archreg + 2);
468
469 return binop(Iop_D64HLtoD128, high, low);
470}
471
472/* Write a 128-bit decimal floating point value into a register pair. */
473static void
474put_dpr_pair(UInt archreg, IRExpr *expr)
475{
476 IRExpr *high = unop(Iop_D128HItoD64, expr);
477 IRExpr *low = unop(Iop_D128LOtoD64, expr);
478
479 put_dpr_dw0(archreg, high);
480 put_dpr_dw0(archreg + 2, low);
481}
482
floriane75dafa2012-09-01 17:54:09 +0000483/* Terminate the current IRSB with an emulation failure. */
484static void
florianafa3f042014-09-06 21:43:28 +0000485emulation_failure_with_expr(IRExpr *emfailure)
floriane75dafa2012-09-01 17:54:09 +0000486{
florianafa3f042014-09-06 21:43:28 +0000487 vassert(typeOfIRExpr(irsb->tyenv, emfailure) == Ity_I32);
488
489 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emfailure));
floriane75dafa2012-09-01 17:54:09 +0000490 dis_res->whatNext = Dis_StopHere;
491 dis_res->jk_StopHere = Ijk_EmFail;
492}
sewardj2019a972011-03-07 16:04:07 +0000493
florianafa3f042014-09-06 21:43:28 +0000494static void
495emulation_failure(VexEmNote fail_kind)
496{
497 emulation_failure_with_expr(mkU32(fail_kind));
498}
499
florian4b8efad2012-09-02 18:07:08 +0000500/* Terminate the current IRSB with an emulation warning. */
501static void
florianafa3f042014-09-06 21:43:28 +0000502emulation_warning_with_expr(IRExpr *emwarning)
503{
504 vassert(typeOfIRExpr(irsb->tyenv, emwarning) == Ity_I32);
505
506 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emwarning));
507 dis_res->whatNext = Dis_StopHere;
508 dis_res->jk_StopHere = Ijk_EmWarn;
509}
510
511static void
florian4b8efad2012-09-02 18:07:08 +0000512emulation_warning(VexEmNote warn_kind)
513{
florianafa3f042014-09-06 21:43:28 +0000514 emulation_warning_with_expr(mkU32(warn_kind));
florian4b8efad2012-09-02 18:07:08 +0000515}
516
sewardj2019a972011-03-07 16:04:07 +0000517/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000518/*--- IR Debugging aids. ---*/
519/*------------------------------------------------------------*/
520#if 0
521
522static ULong
523s390_do_print(HChar *text, ULong value)
524{
525 vex_printf("%s %llu\n", text, value);
526 return 0;
527}
528
529static void
530s390_print(HChar *text, IRExpr *value)
531{
532 IRDirty *d;
533
534 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
535 mkIRExprVec_2(mkU64((ULong)text), value));
536 stmt(IRStmt_Dirty(d));
537}
538#endif
539
540
541/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000542/*--- Build the flags thunk. ---*/
543/*------------------------------------------------------------*/
544
545/* Completely fill the flags thunk. We're always filling all fields.
546 Apparently, that is better for redundant PUT elimination. */
547static void
548s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
549{
550 UInt op_off, dep1_off, dep2_off, ndep_off;
551
florian428dfdd2012-03-27 03:09:49 +0000552 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
553 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
554 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
555 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000556
557 stmt(IRStmt_Put(op_off, op));
558 stmt(IRStmt_Put(dep1_off, dep1));
559 stmt(IRStmt_Put(dep2_off, dep2));
560 stmt(IRStmt_Put(ndep_off, ndep));
561}
562
563
564/* Create an expression for V and widen the result to 64 bit. */
565static IRExpr *
566s390_cc_widen(IRTemp v, Bool sign_extend)
567{
568 IRExpr *expr;
569
570 expr = mkexpr(v);
571
572 switch (typeOfIRTemp(irsb->tyenv, v)) {
573 case Ity_I64:
574 break;
575 case Ity_I32:
576 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
577 break;
578 case Ity_I16:
579 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
580 break;
581 case Ity_I8:
582 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
583 break;
584 default:
585 vpanic("s390_cc_widen");
586 }
587
588 return expr;
589}
590
591static void
592s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
593{
594 IRExpr *op, *dep1, *dep2, *ndep;
595
596 op = mkU64(opc);
597 dep1 = s390_cc_widen(d1, sign_extend);
598 dep2 = mkU64(0);
599 ndep = mkU64(0);
600
601 s390_cc_thunk_fill(op, dep1, dep2, ndep);
602}
603
604
605static void
606s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
607{
608 IRExpr *op, *dep1, *dep2, *ndep;
609
610 op = mkU64(opc);
611 dep1 = s390_cc_widen(d1, sign_extend);
612 dep2 = s390_cc_widen(d2, sign_extend);
613 ndep = mkU64(0);
614
615 s390_cc_thunk_fill(op, dep1, dep2, ndep);
616}
617
618
619/* memcheck believes that the NDEP field in the flags thunk is always
620 defined. But for some flag computations (e.g. add with carry) that is
621 just not true. We therefore need to convey to memcheck that the value
622 of the ndep field does matter and therefore we make the DEP2 field
623 depend on it:
624
625 DEP2 = original_DEP2 ^ NDEP
626
627 In s390_calculate_cc we exploit that (a^b)^b == a
628 I.e. we xor the DEP2 value with the NDEP value to recover the
629 original_DEP2 value. */
630static void
631s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
632{
633 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
634
635 op = mkU64(opc);
636 dep1 = s390_cc_widen(d1, sign_extend);
637 dep2 = s390_cc_widen(d2, sign_extend);
638 ndep = s390_cc_widen(nd, sign_extend);
639
640 dep2x = binop(Iop_Xor64, dep2, ndep);
641
642 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
643}
644
645
646/* Write one floating point value into the flags thunk */
647static void
648s390_cc_thunk_put1f(UInt opc, IRTemp d1)
649{
650 IRExpr *op, *dep1, *dep2, *ndep;
651
florianbafb8262013-05-31 15:41:55 +0000652 /* Make the CC_DEP1 slot appear completely defined.
653 Otherwise, assigning a 32-bit value will cause memcheck
654 to trigger an undefinedness error.
655 */
656 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
657 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
658 stmt(IRStmt_Put(dep1_off, mkU64(0)));
659 }
sewardj2019a972011-03-07 16:04:07 +0000660 op = mkU64(opc);
661 dep1 = mkexpr(d1);
662 dep2 = mkU64(0);
663 ndep = mkU64(0);
664
665 s390_cc_thunk_fill(op, dep1, dep2, ndep);
666}
667
668
669/* Write a floating point value and an integer into the flags thunk. The
670 integer value is zero-extended first. */
671static void
672s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
673{
674 IRExpr *op, *dep1, *dep2, *ndep;
675
florianbafb8262013-05-31 15:41:55 +0000676 /* Make the CC_DEP1 slot appear completely defined.
677 Otherwise, assigning a 32-bit value will cause memcheck
678 to trigger an undefinedness error.
679 */
680 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
681 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
682 stmt(IRStmt_Put(dep1_off, mkU64(0)));
683 }
sewardj2019a972011-03-07 16:04:07 +0000684 op = mkU64(opc);
685 dep1 = mkexpr(d1);
686 dep2 = s390_cc_widen(d2, False);
687 ndep = mkU64(0);
688
689 s390_cc_thunk_fill(op, dep1, dep2, ndep);
690}
691
692
693/* Write a 128-bit floating point value into the flags thunk. This is
694 done by splitting the value into two 64-bits values. */
695static void
696s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
697{
698 IRExpr *op, *hi, *lo, *ndep;
699
700 op = mkU64(opc);
701 hi = unop(Iop_F128HItoF64, mkexpr(d1));
702 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
703 ndep = mkU64(0);
704
705 s390_cc_thunk_fill(op, hi, lo, ndep);
706}
707
708
709/* Write a 128-bit floating point value and an integer into the flags thunk.
710 The integer value is zero-extended first. */
711static void
712s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
713{
714 IRExpr *op, *hi, *lo, *lox, *ndep;
715
716 op = mkU64(opc);
717 hi = unop(Iop_F128HItoF64, mkexpr(d1));
718 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
719 ndep = s390_cc_widen(nd, False);
720
721 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
722
723 s390_cc_thunk_fill(op, hi, lox, ndep);
724}
725
726
floriane38f6412012-12-21 17:32:12 +0000727/* Write a 128-bit decimal floating point value into the flags thunk.
728 This is done by splitting the value into two 64-bits values. */
729static void
730s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
731{
732 IRExpr *op, *hi, *lo, *ndep;
733
734 op = mkU64(opc);
735 hi = unop(Iop_D128HItoD64, mkexpr(d1));
736 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
737 ndep = mkU64(0);
738
739 s390_cc_thunk_fill(op, hi, lo, ndep);
740}
741
742
floriance9e3db2012-12-27 20:14:03 +0000743/* Write a 128-bit decimal floating point value and an integer into the flags
744 thunk. The integer value is zero-extended first. */
745static void
746s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
747{
748 IRExpr *op, *hi, *lo, *lox, *ndep;
749
750 op = mkU64(opc);
751 hi = unop(Iop_D128HItoD64, mkexpr(d1));
752 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
753 ndep = s390_cc_widen(nd, False);
754
755 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
756
757 s390_cc_thunk_fill(op, hi, lox, ndep);
758}
759
760
sewardj2019a972011-03-07 16:04:07 +0000761static void
762s390_cc_set(UInt val)
763{
764 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
765 mkU64(val), mkU64(0), mkU64(0));
766}
767
768/* Build IR to calculate the condition code from flags thunk.
769 Returns an expression of type Ity_I32 */
770static IRExpr *
771s390_call_calculate_cc(void)
772{
773 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
774
florian428dfdd2012-03-27 03:09:49 +0000775 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
776 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
777 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
778 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000779
780 args = mkIRExprVec_4(op, dep1, dep2, ndep);
781 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
782 "s390_calculate_cc", &s390_calculate_cc, args);
783
784 /* Exclude OP and NDEP from definedness checking. We're only
785 interested in DEP1 and DEP2. */
786 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
787
788 return call;
789}
790
791/* Build IR to calculate the internal condition code for a "compare and branch"
792 insn. Returns an expression of type Ity_I32 */
793static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000794s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000795{
florianff9613f2012-05-12 15:26:44 +0000796 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000797
florianff9613f2012-05-12 15:26:44 +0000798 switch (opc) {
799 case S390_CC_OP_SIGNED_COMPARE:
800 dep1 = s390_cc_widen(op1, True);
801 dep2 = s390_cc_widen(op2, True);
802 break;
803
804 case S390_CC_OP_UNSIGNED_COMPARE:
805 dep1 = s390_cc_widen(op1, False);
806 dep2 = s390_cc_widen(op2, False);
807 break;
808
809 default:
810 vpanic("s390_call_calculate_icc");
811 }
812
813 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000814 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000815
florianff9613f2012-05-12 15:26:44 +0000816 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000817 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000818 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000819
florianff9613f2012-05-12 15:26:44 +0000820 /* Exclude the requested condition, OP and NDEP from definedness
821 checking. We're only interested in DEP1 and DEP2. */
822 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000823
824 return call;
825}
826
827/* Build IR to calculate the condition code from flags thunk.
828 Returns an expression of type Ity_I32 */
829static IRExpr *
830s390_call_calculate_cond(UInt m)
831{
832 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
833
834 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000835 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
836 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
837 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
838 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000839
840 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
841 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
842 "s390_calculate_cond", &s390_calculate_cond, args);
843
844 /* Exclude the requested condition, OP and NDEP from definedness
845 checking. We're only interested in DEP1 and DEP2. */
846 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
847
848 return call;
849}
850
851#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
852#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
853#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
854#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
855#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
856#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
857#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
858 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
859#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
860 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000861
862
sewardj2019a972011-03-07 16:04:07 +0000863
864
865/*------------------------------------------------------------*/
866/*--- Guest register access ---*/
867/*------------------------------------------------------------*/
868
869
870/*------------------------------------------------------------*/
871/*--- ar registers ---*/
872/*------------------------------------------------------------*/
873
874/* Return the guest state offset of a ar register. */
875static UInt
876ar_offset(UInt archreg)
877{
878 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000879 S390X_GUEST_OFFSET(guest_a0),
880 S390X_GUEST_OFFSET(guest_a1),
881 S390X_GUEST_OFFSET(guest_a2),
882 S390X_GUEST_OFFSET(guest_a3),
883 S390X_GUEST_OFFSET(guest_a4),
884 S390X_GUEST_OFFSET(guest_a5),
885 S390X_GUEST_OFFSET(guest_a6),
886 S390X_GUEST_OFFSET(guest_a7),
887 S390X_GUEST_OFFSET(guest_a8),
888 S390X_GUEST_OFFSET(guest_a9),
889 S390X_GUEST_OFFSET(guest_a10),
890 S390X_GUEST_OFFSET(guest_a11),
891 S390X_GUEST_OFFSET(guest_a12),
892 S390X_GUEST_OFFSET(guest_a13),
893 S390X_GUEST_OFFSET(guest_a14),
894 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000895 };
896
897 vassert(archreg < 16);
898
899 return offset[archreg];
900}
901
902
903/* Return the guest state offset of word #0 of a ar register. */
904static __inline__ UInt
905ar_w0_offset(UInt archreg)
906{
907 return ar_offset(archreg) + 0;
908}
909
910/* Write word #0 of a ar to the guest state. */
911static __inline__ void
912put_ar_w0(UInt archreg, IRExpr *expr)
913{
914 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
915
916 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
917}
918
919/* Read word #0 of a ar register. */
920static __inline__ IRExpr *
921get_ar_w0(UInt archreg)
922{
923 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
924}
925
926
927/*------------------------------------------------------------*/
928/*--- fpr registers ---*/
929/*------------------------------------------------------------*/
930
931/* Return the guest state offset of a fpr register. */
932static UInt
933fpr_offset(UInt archreg)
934{
935 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000936 S390X_GUEST_OFFSET(guest_f0),
937 S390X_GUEST_OFFSET(guest_f1),
938 S390X_GUEST_OFFSET(guest_f2),
939 S390X_GUEST_OFFSET(guest_f3),
940 S390X_GUEST_OFFSET(guest_f4),
941 S390X_GUEST_OFFSET(guest_f5),
942 S390X_GUEST_OFFSET(guest_f6),
943 S390X_GUEST_OFFSET(guest_f7),
944 S390X_GUEST_OFFSET(guest_f8),
945 S390X_GUEST_OFFSET(guest_f9),
946 S390X_GUEST_OFFSET(guest_f10),
947 S390X_GUEST_OFFSET(guest_f11),
948 S390X_GUEST_OFFSET(guest_f12),
949 S390X_GUEST_OFFSET(guest_f13),
950 S390X_GUEST_OFFSET(guest_f14),
951 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000952 };
953
954 vassert(archreg < 16);
955
956 return offset[archreg];
957}
958
959
960/* Return the guest state offset of word #0 of a fpr register. */
961static __inline__ UInt
962fpr_w0_offset(UInt archreg)
963{
964 return fpr_offset(archreg) + 0;
965}
966
967/* Write word #0 of a fpr to the guest state. */
968static __inline__ void
969put_fpr_w0(UInt archreg, IRExpr *expr)
970{
971 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
972
973 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
974}
975
976/* Read word #0 of a fpr register. */
977static __inline__ IRExpr *
978get_fpr_w0(UInt archreg)
979{
980 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
981}
982
983/* Return the guest state offset of double word #0 of a fpr register. */
984static __inline__ UInt
985fpr_dw0_offset(UInt archreg)
986{
987 return fpr_offset(archreg) + 0;
988}
989
990/* Write double word #0 of a fpr to the guest state. */
991static __inline__ void
992put_fpr_dw0(UInt archreg, IRExpr *expr)
993{
994 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
995
996 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
997}
998
999/* Read double word #0 of a fpr register. */
1000static __inline__ IRExpr *
1001get_fpr_dw0(UInt archreg)
1002{
1003 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
1004}
1005
floriane38f6412012-12-21 17:32:12 +00001006/* Write word #0 of a dpr to the guest state. */
1007static __inline__ void
1008put_dpr_w0(UInt archreg, IRExpr *expr)
1009{
1010 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
1011
1012 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
1013}
1014
1015/* Read word #0 of a dpr register. */
1016static __inline__ IRExpr *
1017get_dpr_w0(UInt archreg)
1018{
1019 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
1020}
1021
florian12390202012-11-10 22:34:14 +00001022/* Write double word #0 of a fpr containg DFP value to the guest state. */
1023static __inline__ void
1024put_dpr_dw0(UInt archreg, IRExpr *expr)
1025{
1026 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
1027
1028 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1029}
1030
1031/* Read double word #0 of a fpr register containing DFP value. */
1032static __inline__ IRExpr *
1033get_dpr_dw0(UInt archreg)
1034{
1035 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1036}
sewardj2019a972011-03-07 16:04:07 +00001037
1038/*------------------------------------------------------------*/
1039/*--- gpr registers ---*/
1040/*------------------------------------------------------------*/
1041
1042/* Return the guest state offset of a gpr register. */
1043static UInt
1044gpr_offset(UInt archreg)
1045{
1046 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001047 S390X_GUEST_OFFSET(guest_r0),
1048 S390X_GUEST_OFFSET(guest_r1),
1049 S390X_GUEST_OFFSET(guest_r2),
1050 S390X_GUEST_OFFSET(guest_r3),
1051 S390X_GUEST_OFFSET(guest_r4),
1052 S390X_GUEST_OFFSET(guest_r5),
1053 S390X_GUEST_OFFSET(guest_r6),
1054 S390X_GUEST_OFFSET(guest_r7),
1055 S390X_GUEST_OFFSET(guest_r8),
1056 S390X_GUEST_OFFSET(guest_r9),
1057 S390X_GUEST_OFFSET(guest_r10),
1058 S390X_GUEST_OFFSET(guest_r11),
1059 S390X_GUEST_OFFSET(guest_r12),
1060 S390X_GUEST_OFFSET(guest_r13),
1061 S390X_GUEST_OFFSET(guest_r14),
1062 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001063 };
1064
1065 vassert(archreg < 16);
1066
1067 return offset[archreg];
1068}
1069
1070
1071/* Return the guest state offset of word #0 of a gpr register. */
1072static __inline__ UInt
1073gpr_w0_offset(UInt archreg)
1074{
1075 return gpr_offset(archreg) + 0;
1076}
1077
1078/* Write word #0 of a gpr to the guest state. */
1079static __inline__ void
1080put_gpr_w0(UInt archreg, IRExpr *expr)
1081{
1082 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1083
1084 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1085}
1086
1087/* Read word #0 of a gpr register. */
1088static __inline__ IRExpr *
1089get_gpr_w0(UInt archreg)
1090{
1091 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1092}
1093
1094/* Return the guest state offset of double word #0 of a gpr register. */
1095static __inline__ UInt
1096gpr_dw0_offset(UInt archreg)
1097{
1098 return gpr_offset(archreg) + 0;
1099}
1100
1101/* Write double word #0 of a gpr to the guest state. */
1102static __inline__ void
1103put_gpr_dw0(UInt archreg, IRExpr *expr)
1104{
1105 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1106
1107 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1108}
1109
1110/* Read double word #0 of a gpr register. */
1111static __inline__ IRExpr *
1112get_gpr_dw0(UInt archreg)
1113{
1114 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1115}
1116
1117/* Return the guest state offset of half word #1 of a gpr register. */
1118static __inline__ UInt
1119gpr_hw1_offset(UInt archreg)
1120{
1121 return gpr_offset(archreg) + 2;
1122}
1123
1124/* Write half word #1 of a gpr to the guest state. */
1125static __inline__ void
1126put_gpr_hw1(UInt archreg, IRExpr *expr)
1127{
1128 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1129
1130 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1131}
1132
1133/* Read half word #1 of a gpr register. */
1134static __inline__ IRExpr *
1135get_gpr_hw1(UInt archreg)
1136{
1137 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1138}
1139
1140/* Return the guest state offset of byte #6 of a gpr register. */
1141static __inline__ UInt
1142gpr_b6_offset(UInt archreg)
1143{
1144 return gpr_offset(archreg) + 6;
1145}
1146
1147/* Write byte #6 of a gpr to the guest state. */
1148static __inline__ void
1149put_gpr_b6(UInt archreg, IRExpr *expr)
1150{
1151 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1152
1153 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1154}
1155
1156/* Read byte #6 of a gpr register. */
1157static __inline__ IRExpr *
1158get_gpr_b6(UInt archreg)
1159{
1160 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1161}
1162
1163/* Return the guest state offset of byte #3 of a gpr register. */
1164static __inline__ UInt
1165gpr_b3_offset(UInt archreg)
1166{
1167 return gpr_offset(archreg) + 3;
1168}
1169
1170/* Write byte #3 of a gpr to the guest state. */
1171static __inline__ void
1172put_gpr_b3(UInt archreg, IRExpr *expr)
1173{
1174 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1175
1176 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1177}
1178
1179/* Read byte #3 of a gpr register. */
1180static __inline__ IRExpr *
1181get_gpr_b3(UInt archreg)
1182{
1183 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1184}
1185
1186/* Return the guest state offset of byte #0 of a gpr register. */
1187static __inline__ UInt
1188gpr_b0_offset(UInt archreg)
1189{
1190 return gpr_offset(archreg) + 0;
1191}
1192
1193/* Write byte #0 of a gpr to the guest state. */
1194static __inline__ void
1195put_gpr_b0(UInt archreg, IRExpr *expr)
1196{
1197 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1198
1199 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1200}
1201
1202/* Read byte #0 of a gpr register. */
1203static __inline__ IRExpr *
1204get_gpr_b0(UInt archreg)
1205{
1206 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1207}
1208
1209/* Return the guest state offset of word #1 of a gpr register. */
1210static __inline__ UInt
1211gpr_w1_offset(UInt archreg)
1212{
1213 return gpr_offset(archreg) + 4;
1214}
1215
1216/* Write word #1 of a gpr to the guest state. */
1217static __inline__ void
1218put_gpr_w1(UInt archreg, IRExpr *expr)
1219{
1220 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1221
1222 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1223}
1224
1225/* Read word #1 of a gpr register. */
1226static __inline__ IRExpr *
1227get_gpr_w1(UInt archreg)
1228{
1229 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1230}
1231
1232/* Return the guest state offset of half word #3 of a gpr register. */
1233static __inline__ UInt
1234gpr_hw3_offset(UInt archreg)
1235{
1236 return gpr_offset(archreg) + 6;
1237}
1238
1239/* Write half word #3 of a gpr to the guest state. */
1240static __inline__ void
1241put_gpr_hw3(UInt archreg, IRExpr *expr)
1242{
1243 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1244
1245 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1246}
1247
1248/* Read half word #3 of a gpr register. */
1249static __inline__ IRExpr *
1250get_gpr_hw3(UInt archreg)
1251{
1252 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1253}
1254
1255/* Return the guest state offset of byte #7 of a gpr register. */
1256static __inline__ UInt
1257gpr_b7_offset(UInt archreg)
1258{
1259 return gpr_offset(archreg) + 7;
1260}
1261
1262/* Write byte #7 of a gpr to the guest state. */
1263static __inline__ void
1264put_gpr_b7(UInt archreg, IRExpr *expr)
1265{
1266 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1267
1268 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1269}
1270
1271/* Read byte #7 of a gpr register. */
1272static __inline__ IRExpr *
1273get_gpr_b7(UInt archreg)
1274{
1275 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1276}
1277
1278/* Return the guest state offset of half word #0 of a gpr register. */
1279static __inline__ UInt
1280gpr_hw0_offset(UInt archreg)
1281{
1282 return gpr_offset(archreg) + 0;
1283}
1284
1285/* Write half word #0 of a gpr to the guest state. */
1286static __inline__ void
1287put_gpr_hw0(UInt archreg, IRExpr *expr)
1288{
1289 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1290
1291 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1292}
1293
1294/* Read half word #0 of a gpr register. */
1295static __inline__ IRExpr *
1296get_gpr_hw0(UInt archreg)
1297{
1298 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1299}
1300
1301/* Return the guest state offset of byte #4 of a gpr register. */
1302static __inline__ UInt
1303gpr_b4_offset(UInt archreg)
1304{
1305 return gpr_offset(archreg) + 4;
1306}
1307
1308/* Write byte #4 of a gpr to the guest state. */
1309static __inline__ void
1310put_gpr_b4(UInt archreg, IRExpr *expr)
1311{
1312 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1313
1314 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1315}
1316
1317/* Read byte #4 of a gpr register. */
1318static __inline__ IRExpr *
1319get_gpr_b4(UInt archreg)
1320{
1321 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1322}
1323
1324/* Return the guest state offset of byte #1 of a gpr register. */
1325static __inline__ UInt
1326gpr_b1_offset(UInt archreg)
1327{
1328 return gpr_offset(archreg) + 1;
1329}
1330
1331/* Write byte #1 of a gpr to the guest state. */
1332static __inline__ void
1333put_gpr_b1(UInt archreg, IRExpr *expr)
1334{
1335 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1336
1337 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1338}
1339
1340/* Read byte #1 of a gpr register. */
1341static __inline__ IRExpr *
1342get_gpr_b1(UInt archreg)
1343{
1344 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1345}
1346
1347/* Return the guest state offset of half word #2 of a gpr register. */
1348static __inline__ UInt
1349gpr_hw2_offset(UInt archreg)
1350{
1351 return gpr_offset(archreg) + 4;
1352}
1353
1354/* Write half word #2 of a gpr to the guest state. */
1355static __inline__ void
1356put_gpr_hw2(UInt archreg, IRExpr *expr)
1357{
1358 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1359
1360 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1361}
1362
1363/* Read half word #2 of a gpr register. */
1364static __inline__ IRExpr *
1365get_gpr_hw2(UInt archreg)
1366{
1367 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1368}
1369
1370/* Return the guest state offset of byte #5 of a gpr register. */
1371static __inline__ UInt
1372gpr_b5_offset(UInt archreg)
1373{
1374 return gpr_offset(archreg) + 5;
1375}
1376
1377/* Write byte #5 of a gpr to the guest state. */
1378static __inline__ void
1379put_gpr_b5(UInt archreg, IRExpr *expr)
1380{
1381 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1382
1383 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1384}
1385
1386/* Read byte #5 of a gpr register. */
1387static __inline__ IRExpr *
1388get_gpr_b5(UInt archreg)
1389{
1390 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1391}
1392
1393/* Return the guest state offset of byte #2 of a gpr register. */
1394static __inline__ UInt
1395gpr_b2_offset(UInt archreg)
1396{
1397 return gpr_offset(archreg) + 2;
1398}
1399
1400/* Write byte #2 of a gpr to the guest state. */
1401static __inline__ void
1402put_gpr_b2(UInt archreg, IRExpr *expr)
1403{
1404 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1405
1406 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1407}
1408
1409/* Read byte #2 of a gpr register. */
1410static __inline__ IRExpr *
1411get_gpr_b2(UInt archreg)
1412{
1413 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1414}
1415
1416/* Return the guest state offset of the counter register. */
1417static UInt
1418counter_offset(void)
1419{
floriane88b3c92011-07-05 02:48:39 +00001420 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001421}
1422
1423/* Return the guest state offset of double word #0 of the counter register. */
1424static __inline__ UInt
1425counter_dw0_offset(void)
1426{
1427 return counter_offset() + 0;
1428}
1429
1430/* Write double word #0 of the counter to the guest state. */
1431static __inline__ void
1432put_counter_dw0(IRExpr *expr)
1433{
1434 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1435
1436 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1437}
1438
1439/* Read double word #0 of the counter register. */
1440static __inline__ IRExpr *
1441get_counter_dw0(void)
1442{
1443 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1444}
1445
1446/* Return the guest state offset of word #0 of the counter register. */
1447static __inline__ UInt
1448counter_w0_offset(void)
1449{
1450 return counter_offset() + 0;
1451}
1452
1453/* Return the guest state offset of word #1 of the counter register. */
1454static __inline__ UInt
1455counter_w1_offset(void)
1456{
1457 return counter_offset() + 4;
1458}
1459
1460/* Write word #0 of the counter to the guest state. */
1461static __inline__ void
1462put_counter_w0(IRExpr *expr)
1463{
1464 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1465
1466 stmt(IRStmt_Put(counter_w0_offset(), expr));
1467}
1468
1469/* Read word #0 of the counter register. */
1470static __inline__ IRExpr *
1471get_counter_w0(void)
1472{
1473 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1474}
1475
1476/* Write word #1 of the counter to the guest state. */
1477static __inline__ void
1478put_counter_w1(IRExpr *expr)
1479{
1480 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1481
1482 stmt(IRStmt_Put(counter_w1_offset(), expr));
1483}
1484
1485/* Read word #1 of the counter register. */
1486static __inline__ IRExpr *
1487get_counter_w1(void)
1488{
1489 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1490}
1491
1492/* Return the guest state offset of the fpc register. */
1493static UInt
1494fpc_offset(void)
1495{
floriane88b3c92011-07-05 02:48:39 +00001496 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001497}
1498
1499/* Return the guest state offset of word #0 of the fpc register. */
1500static __inline__ UInt
1501fpc_w0_offset(void)
1502{
1503 return fpc_offset() + 0;
1504}
1505
1506/* Write word #0 of the fpc to the guest state. */
1507static __inline__ void
1508put_fpc_w0(IRExpr *expr)
1509{
1510 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1511
1512 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1513}
1514
1515/* Read word #0 of the fpc register. */
1516static __inline__ IRExpr *
1517get_fpc_w0(void)
1518{
1519 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1520}
1521
1522
1523/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001524/*--- Rounding modes ---*/
1525/*------------------------------------------------------------*/
1526
florian125e20d2012-10-07 15:42:37 +00001527/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001528 IRRoundingMode:
1529
1530 rounding mode | s390 | IR
1531 -------------------------
1532 to nearest | 00 | 00
1533 to zero | 01 | 11
1534 to +infinity | 10 | 10
1535 to -infinity | 11 | 01
1536
1537 So: IR = (4 - s390) & 3
1538*/
1539static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001540get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001541{
1542 IRTemp fpc_bits = newTemp(Ity_I32);
1543
1544 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1545 Prior to that bits [30:31] contained the bfp rounding mode with
1546 bit 29 being unused and having a value of 0. So we can always
1547 extract the least significant 3 bits. */
1548 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1549
1550 /* fixs390:
1551
1552
1553 if (! s390_host_has_fpext && rounding_mode > 3) {
1554 emulation warning @ runtime and
1555 set fpc to round nearest
1556 }
1557 */
1558
1559 /* For now silently adjust an unsupported rounding mode to "nearest" */
1560 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1561 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001562 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001563
1564 // rm_IR = (4 - rm_s390) & 3;
1565 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1566}
1567
1568/* Encode the s390 rounding mode as it appears in the m3 field of certain
1569 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1570 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1571 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1572 considers the default rounding mode (4.3.3). */
1573static IRTemp
1574encode_bfp_rounding_mode(UChar mode)
1575{
1576 IRExpr *rm;
1577
1578 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001579 case S390_BFP_ROUND_PER_FPC:
1580 rm = get_bfp_rounding_mode_from_fpc();
1581 break;
1582 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1583 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1584 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1585 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1586 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1587 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001588 default:
1589 vpanic("encode_bfp_rounding_mode");
1590 }
1591
1592 return mktemp(Ity_I32, rm);
1593}
1594
florianc8e4f562012-10-27 16:19:31 +00001595/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1596 IRRoundingMode:
1597
1598 rounding mode | s390 | IR
1599 ------------------------------------------------
1600 to nearest, ties to even | 000 | 000
1601 to zero | 001 | 011
1602 to +infinity | 010 | 010
1603 to -infinity | 011 | 001
1604 to nearest, ties away from 0 | 100 | 100
1605 to nearest, ties toward 0 | 101 | 111
1606 to away from 0 | 110 | 110
1607 to prepare for shorter precision | 111 | 101
1608
1609 So: IR = (s390 ^ ((s390 << 1) & 2))
1610*/
florianc8e4f562012-10-27 16:19:31 +00001611static IRExpr *
1612get_dfp_rounding_mode_from_fpc(void)
1613{
1614 IRTemp fpc_bits = newTemp(Ity_I32);
1615
1616 /* The dfp rounding mode is stored in bits [25:27].
1617 extract the bits at 25:27 and right shift 4 times. */
1618 assign(fpc_bits, binop(Iop_Shr32,
1619 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1620 mkU8(4)));
1621
1622 IRExpr *rm_s390 = mkexpr(fpc_bits);
1623 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1624
1625 return binop(Iop_Xor32, rm_s390,
1626 binop( Iop_And32,
1627 binop(Iop_Shl32, rm_s390, mkU8(1)),
1628 mkU32(2)));
1629}
1630
1631/* Encode the s390 rounding mode as it appears in the m3 field of certain
1632 instructions to VEX's IRRoundingMode. */
1633static IRTemp
1634encode_dfp_rounding_mode(UChar mode)
1635{
1636 IRExpr *rm;
1637
1638 switch (mode) {
1639 case S390_DFP_ROUND_PER_FPC_0:
1640 case S390_DFP_ROUND_PER_FPC_2:
1641 rm = get_dfp_rounding_mode_from_fpc(); break;
1642 case S390_DFP_ROUND_NEAREST_EVEN_4:
1643 case S390_DFP_ROUND_NEAREST_EVEN_8:
florian79e5a482013-06-06 19:12:46 +00001644 rm = mkU32(Irrm_NEAREST); break;
florianc8e4f562012-10-27 16:19:31 +00001645 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1646 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
florian79e5a482013-06-06 19:12:46 +00001647 rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
florianc8e4f562012-10-27 16:19:31 +00001648 case S390_DFP_ROUND_PREPARE_SHORT_3:
1649 case S390_DFP_ROUND_PREPARE_SHORT_15:
florian79e5a482013-06-06 19:12:46 +00001650 rm = mkU32(Irrm_PREPARE_SHORTER); break;
florianc8e4f562012-10-27 16:19:31 +00001651 case S390_DFP_ROUND_ZERO_5:
1652 case S390_DFP_ROUND_ZERO_9:
florian79e5a482013-06-06 19:12:46 +00001653 rm = mkU32(Irrm_ZERO ); break;
florianc8e4f562012-10-27 16:19:31 +00001654 case S390_DFP_ROUND_POSINF_6:
1655 case S390_DFP_ROUND_POSINF_10:
florian79e5a482013-06-06 19:12:46 +00001656 rm = mkU32(Irrm_PosINF); break;
florianc8e4f562012-10-27 16:19:31 +00001657 case S390_DFP_ROUND_NEGINF_7:
1658 case S390_DFP_ROUND_NEGINF_11:
florian79e5a482013-06-06 19:12:46 +00001659 rm = mkU32(Irrm_NegINF); break;
florianc8e4f562012-10-27 16:19:31 +00001660 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
florian79e5a482013-06-06 19:12:46 +00001661 rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
florianc8e4f562012-10-27 16:19:31 +00001662 case S390_DFP_ROUND_AWAY_0:
florian79e5a482013-06-06 19:12:46 +00001663 rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
florianc8e4f562012-10-27 16:19:31 +00001664 default:
1665 vpanic("encode_dfp_rounding_mode");
1666 }
1667
1668 return mktemp(Ity_I32, rm);
1669}
florian12390202012-11-10 22:34:14 +00001670
florianc8e4f562012-10-27 16:19:31 +00001671
florian2c74d242012-09-12 19:38:42 +00001672/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001673/*--- Condition code helpers ---*/
1674/*------------------------------------------------------------*/
1675
1676/* The result of a Iop_CmpFxx operation is a condition code. It is
1677 encoded using the values defined in type IRCmpFxxResult.
1678 Before we can store the condition code into the guest state (or do
1679 anything else with it for that matter) we need to convert it to
1680 the encoding that s390 uses. This is what this function does.
1681
1682 s390 VEX b6 b2 b0 cc.1 cc.0
1683 0 0x40 EQ 1 0 0 0 0
1684 1 0x01 LT 0 0 1 0 1
1685 2 0x00 GT 0 0 0 1 0
1686 3 0x45 Unordered 1 1 1 1 1
1687
1688 The following bits from the VEX encoding are interesting:
1689 b0, b2, b6 with b0 being the LSB. We observe:
1690
1691 cc.0 = b0;
1692 cc.1 = b2 | (~b0 & ~b6)
1693
1694 with cc being the s390 condition code.
1695*/
1696static IRExpr *
1697convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1698{
1699 IRTemp cc0 = newTemp(Ity_I32);
1700 IRTemp cc1 = newTemp(Ity_I32);
1701 IRTemp b0 = newTemp(Ity_I32);
1702 IRTemp b2 = newTemp(Ity_I32);
1703 IRTemp b6 = newTemp(Ity_I32);
1704
1705 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1706 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1707 mkU32(1)));
1708 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1709 mkU32(1)));
1710
1711 assign(cc0, mkexpr(b0));
1712 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1713 binop(Iop_And32,
1714 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1715 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1716 )));
1717
1718 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1719}
1720
1721
1722/* The result of a Iop_CmpDxx operation is a condition code. It is
1723 encoded using the values defined in type IRCmpDxxResult.
1724 Before we can store the condition code into the guest state (or do
1725 anything else with it for that matter) we need to convert it to
1726 the encoding that s390 uses. This is what this function does. */
1727static IRExpr *
1728convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1729{
1730 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1731 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001732 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001733}
1734
1735
1736/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001737/*--- Build IR for formats ---*/
1738/*------------------------------------------------------------*/
1739static void
florian55085f82012-11-21 00:36:55 +00001740s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001741 UChar i)
1742{
florian55085f82012-11-21 00:36:55 +00001743 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001744
sewardj7ee97522011-05-09 21:45:04 +00001745 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001746 s390_disasm(ENC2(MNM, UINT), mnm, i);
1747}
1748
1749static void
florian78d5ef72013-05-11 15:02:58 +00001750s390_format_E(const HChar *(*irgen)(void))
1751{
1752 const HChar *mnm = irgen();
1753
1754 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1755 s390_disasm(ENC1(MNM), mnm);
1756}
1757
1758static void
florian55085f82012-11-21 00:36:55 +00001759s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001760 UChar r1, UShort i2)
1761{
1762 irgen(r1, i2);
1763}
1764
1765static void
florian55085f82012-11-21 00:36:55 +00001766s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001767 UChar r1, UShort i2)
1768{
florian55085f82012-11-21 00:36:55 +00001769 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001770
sewardj7ee97522011-05-09 21:45:04 +00001771 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001772 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1773}
1774
1775static void
florian55085f82012-11-21 00:36:55 +00001776s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001777 UChar r1, UShort i2)
1778{
florian55085f82012-11-21 00:36:55 +00001779 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001780
sewardj7ee97522011-05-09 21:45:04 +00001781 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001782 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1783}
1784
1785static void
florian55085f82012-11-21 00:36:55 +00001786s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001787 UChar r1, UShort i2)
1788{
florian55085f82012-11-21 00:36:55 +00001789 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001790
sewardj7ee97522011-05-09 21:45:04 +00001791 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001792 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1793}
1794
1795static void
florian55085f82012-11-21 00:36:55 +00001796s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001797 UChar r1, UChar r3, UShort i2)
1798{
florian55085f82012-11-21 00:36:55 +00001799 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001800
sewardj7ee97522011-05-09 21:45:04 +00001801 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001802 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1803}
1804
1805static void
florian55085f82012-11-21 00:36:55 +00001806s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001807 UChar r1, UChar r3, UShort i2)
1808{
florian55085f82012-11-21 00:36:55 +00001809 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001810
sewardj7ee97522011-05-09 21:45:04 +00001811 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001812 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1813}
1814
1815static void
florian55085f82012-11-21 00:36:55 +00001816s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1817 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001818 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1819{
florian55085f82012-11-21 00:36:55 +00001820 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001821
sewardj7ee97522011-05-09 21:45:04 +00001822 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001823 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1824 i5);
1825}
1826
1827static void
florian55085f82012-11-21 00:36:55 +00001828s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1829 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001830 UChar r1, UChar r2, UShort i4, UChar m3)
1831{
florian55085f82012-11-21 00:36:55 +00001832 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001833
sewardj7ee97522011-05-09 21:45:04 +00001834 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001835 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1836 r2, m3, (Int)(Short)i4);
1837}
1838
1839static void
florian55085f82012-11-21 00:36:55 +00001840s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1841 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001842 UChar r1, UChar m3, UShort i4, UChar i2)
1843{
florian55085f82012-11-21 00:36:55 +00001844 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001845
sewardj7ee97522011-05-09 21:45:04 +00001846 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001847 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1848 r1, i2, m3, (Int)(Short)i4);
1849}
1850
1851static void
florian55085f82012-11-21 00:36:55 +00001852s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1853 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001854 UChar r1, UChar m3, UShort i4, UChar i2)
1855{
florian55085f82012-11-21 00:36:55 +00001856 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001857
sewardj7ee97522011-05-09 21:45:04 +00001858 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001859 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1860 (Int)(Char)i2, m3, (Int)(Short)i4);
1861}
1862
1863static void
florian55085f82012-11-21 00:36:55 +00001864s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001865 UChar r1, UInt i2)
1866{
1867 irgen(r1, i2);
1868}
1869
1870static void
florian55085f82012-11-21 00:36:55 +00001871s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001872 UChar r1, UInt i2)
1873{
florian55085f82012-11-21 00:36:55 +00001874 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001875
sewardj7ee97522011-05-09 21:45:04 +00001876 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001877 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1878}
1879
1880static void
florian55085f82012-11-21 00:36:55 +00001881s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001882 UChar r1, UInt i2)
1883{
florian55085f82012-11-21 00:36:55 +00001884 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001885
sewardj7ee97522011-05-09 21:45:04 +00001886 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001887 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1888}
1889
1890static void
florian55085f82012-11-21 00:36:55 +00001891s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001892 UChar r1, UInt i2)
1893{
florian55085f82012-11-21 00:36:55 +00001894 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001895
sewardj7ee97522011-05-09 21:45:04 +00001896 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001897 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1898}
1899
1900static void
florian55085f82012-11-21 00:36:55 +00001901s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001902 UChar r1, UInt i2)
1903{
florian55085f82012-11-21 00:36:55 +00001904 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001905
sewardj7ee97522011-05-09 21:45:04 +00001906 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001907 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1908}
1909
1910static void
florian55085f82012-11-21 00:36:55 +00001911s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001912 IRTemp op4addr),
1913 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1914{
florian55085f82012-11-21 00:36:55 +00001915 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001916 IRTemp op4addr = newTemp(Ity_I64);
1917
1918 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1919 mkU64(0)));
1920
1921 mnm = irgen(r1, m3, i2, op4addr);
1922
sewardj7ee97522011-05-09 21:45:04 +00001923 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001924 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1925 (Int)(Char)i2, m3, d4, 0, b4);
1926}
1927
1928static void
florian55085f82012-11-21 00:36:55 +00001929s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001930 IRTemp op4addr),
1931 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1932{
florian55085f82012-11-21 00:36:55 +00001933 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001934 IRTemp op4addr = newTemp(Ity_I64);
1935
1936 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1937 mkU64(0)));
1938
1939 mnm = irgen(r1, m3, i2, op4addr);
1940
sewardj7ee97522011-05-09 21:45:04 +00001941 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001942 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1943 i2, m3, d4, 0, b4);
1944}
1945
1946static void
florian55085f82012-11-21 00:36:55 +00001947s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001948 UChar r1, UChar r2)
1949{
1950 irgen(r1, r2);
1951}
1952
1953static void
florian55085f82012-11-21 00:36:55 +00001954s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001955 UChar r1, UChar r2)
1956{
florian55085f82012-11-21 00:36:55 +00001957 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001958
sewardj7ee97522011-05-09 21:45:04 +00001959 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001960 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1961}
1962
1963static void
florian55085f82012-11-21 00:36:55 +00001964s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001965 UChar r1, UChar r2)
1966{
florian55085f82012-11-21 00:36:55 +00001967 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001968
sewardj7ee97522011-05-09 21:45:04 +00001969 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001970 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1971}
1972
1973static void
florian55085f82012-11-21 00:36:55 +00001974s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001975 UChar r1, UChar r2)
1976{
1977 irgen(r1, r2);
1978}
1979
1980static void
florian55085f82012-11-21 00:36:55 +00001981s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001982 UChar r1, UChar r2)
1983{
florian55085f82012-11-21 00:36:55 +00001984 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001985
sewardj7ee97522011-05-09 21:45:04 +00001986 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001987 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1988}
1989
1990static void
florian55085f82012-11-21 00:36:55 +00001991s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001992 UChar r1, UChar r2)
1993{
florian55085f82012-11-21 00:36:55 +00001994 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001995
sewardj7ee97522011-05-09 21:45:04 +00001996 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001997 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1998}
1999
2000static void
florian55085f82012-11-21 00:36:55 +00002001s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002002 UChar r1, UChar r2)
2003{
florian55085f82012-11-21 00:36:55 +00002004 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002005
sewardj7ee97522011-05-09 21:45:04 +00002006 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002007 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
2008}
2009
2010static void
florian55085f82012-11-21 00:36:55 +00002011s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002012 UChar r1, UChar r2)
2013{
florian55085f82012-11-21 00:36:55 +00002014 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002015
sewardj7ee97522011-05-09 21:45:04 +00002016 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002017 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
2018}
2019
2020static void
florian55085f82012-11-21 00:36:55 +00002021s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002022 UChar r1)
2023{
florian55085f82012-11-21 00:36:55 +00002024 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002025
sewardj7ee97522011-05-09 21:45:04 +00002026 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002027 s390_disasm(ENC2(MNM, GPR), mnm, r1);
2028}
2029
2030static void
florian55085f82012-11-21 00:36:55 +00002031s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002032 UChar r1)
2033{
florian55085f82012-11-21 00:36:55 +00002034 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002035
sewardj7ee97522011-05-09 21:45:04 +00002036 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002037 s390_disasm(ENC2(MNM, FPR), mnm, r1);
2038}
2039
2040static void
florian55085f82012-11-21 00:36:55 +00002041s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002042 UChar m3, UChar r1, UChar r2)
2043{
florian55085f82012-11-21 00:36:55 +00002044 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002045
2046 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002047 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002048}
2049
2050static void
florian55085f82012-11-21 00:36:55 +00002051s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002052 UChar r1, UChar r3, UChar r2)
2053{
florian55085f82012-11-21 00:36:55 +00002054 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002055
sewardj7ee97522011-05-09 21:45:04 +00002056 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002057 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2058}
2059
2060static void
florian5c539732013-02-14 14:27:12 +00002061s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2062 UChar r3, UChar r1, UChar r2)
2063{
2064 const HChar *mnm = irgen(r3, r1, r2);
2065
2066 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2067 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2068}
2069
2070static void
florian55085f82012-11-21 00:36:55 +00002071s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2072 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002073 UChar m3, UChar m4, UChar r1, UChar r2)
2074{
florian55085f82012-11-21 00:36:55 +00002075 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002076
2077 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2078 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2079}
2080
2081static void
floriane38f6412012-12-21 17:32:12 +00002082s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2083 UChar m4, UChar r1, UChar r2)
2084{
2085 const HChar *mnm = irgen(m4, r1, r2);
2086
2087 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2088 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2089}
2090
2091static void
florian55085f82012-11-21 00:36:55 +00002092s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2093 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002094 UChar m3, UChar m4, UChar r1, UChar r2)
2095{
florian55085f82012-11-21 00:36:55 +00002096 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002097
2098 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2099 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2100}
2101
2102static void
florian55085f82012-11-21 00:36:55 +00002103s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2104 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002105 UChar m3, UChar m4, UChar r1, UChar r2)
2106{
florian55085f82012-11-21 00:36:55 +00002107 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002108
2109 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2110 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2111}
2112
2113
2114static void
florian55085f82012-11-21 00:36:55 +00002115s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002116 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2117{
2118 irgen(m3, r1, r2);
2119
sewardj7ee97522011-05-09 21:45:04 +00002120 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002121 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2122}
2123
2124static void
florian55085f82012-11-21 00:36:55 +00002125s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002126 UChar r3, UChar r1, UChar r2)
2127{
florian55085f82012-11-21 00:36:55 +00002128 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002129
sewardj7ee97522011-05-09 21:45:04 +00002130 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002131 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2132}
2133
2134static void
florian5c539732013-02-14 14:27:12 +00002135s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2136 UChar r3, UChar m4, UChar r1, UChar r2)
2137{
2138 const HChar *mnm = irgen(r3, m4, r1, r2);
2139
2140 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2141 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2142}
2143
2144static void
2145s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2146 UChar r3, UChar m4, UChar r1, UChar r2)
2147{
2148 const HChar *mnm = irgen(r3, m4, r1, r2);
2149
2150 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2151 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2152}
2153
2154static void
florian55085f82012-11-21 00:36:55 +00002155s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002156 UChar r3, UChar m4, UChar r1, UChar r2)
2157{
florian55085f82012-11-21 00:36:55 +00002158 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002159
2160 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2161 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2162}
2163
2164static void
florian55085f82012-11-21 00:36:55 +00002165s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002166 UChar r3, UChar r1, UChar r2)
2167{
florian55085f82012-11-21 00:36:55 +00002168 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002169
sewardj7ee97522011-05-09 21:45:04 +00002170 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002171 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2172}
2173
2174static void
florian55085f82012-11-21 00:36:55 +00002175s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2176 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002177 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2178{
florian55085f82012-11-21 00:36:55 +00002179 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002180 IRTemp op4addr = newTemp(Ity_I64);
2181
2182 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2183 mkU64(0)));
2184
2185 mnm = irgen(r1, r2, m3, op4addr);
2186
sewardj7ee97522011-05-09 21:45:04 +00002187 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002188 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2189 r2, m3, d4, 0, b4);
2190}
2191
2192static void
florian55085f82012-11-21 00:36:55 +00002193s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002194 UChar r1, UChar b2, UShort d2)
2195{
florian55085f82012-11-21 00:36:55 +00002196 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002197 IRTemp op2addr = newTemp(Ity_I64);
2198
2199 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2200 mkU64(0)));
2201
2202 mnm = irgen(r1, op2addr);
2203
sewardj7ee97522011-05-09 21:45:04 +00002204 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002205 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2206}
2207
2208static void
florian55085f82012-11-21 00:36:55 +00002209s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002210 UChar r1, UChar r3, UChar b2, UShort d2)
2211{
florian55085f82012-11-21 00:36:55 +00002212 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002213 IRTemp op2addr = newTemp(Ity_I64);
2214
2215 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2216 mkU64(0)));
2217
2218 mnm = irgen(r1, r3, op2addr);
2219
sewardj7ee97522011-05-09 21:45:04 +00002220 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002221 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2222}
2223
2224static void
florian55085f82012-11-21 00:36:55 +00002225s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002226 UChar r1, UChar r3, UChar b2, UShort d2)
2227{
florian55085f82012-11-21 00:36:55 +00002228 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002229 IRTemp op2addr = newTemp(Ity_I64);
2230
2231 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2232 mkU64(0)));
2233
2234 mnm = irgen(r1, r3, op2addr);
2235
sewardj7ee97522011-05-09 21:45:04 +00002236 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002237 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2238}
2239
2240static void
florian55085f82012-11-21 00:36:55 +00002241s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002242 UChar r1, UChar r3, UChar b2, UShort d2)
2243{
florian55085f82012-11-21 00:36:55 +00002244 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002245 IRTemp op2addr = newTemp(Ity_I64);
2246
2247 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2248 mkU64(0)));
2249
2250 mnm = irgen(r1, r3, op2addr);
2251
sewardj7ee97522011-05-09 21:45:04 +00002252 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002253 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2254}
2255
2256static void
florian55085f82012-11-21 00:36:55 +00002257s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002258 UChar r1, UChar r3, UShort i2)
2259{
florian55085f82012-11-21 00:36:55 +00002260 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002261
sewardj7ee97522011-05-09 21:45:04 +00002262 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002263 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2264}
2265
2266static void
florian55085f82012-11-21 00:36:55 +00002267s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002268 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2269{
florian55085f82012-11-21 00:36:55 +00002270 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002271 IRTemp op2addr = newTemp(Ity_I64);
2272 IRTemp d2 = newTemp(Ity_I64);
2273
2274 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2275 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2276 mkU64(0)));
2277
2278 mnm = irgen(r1, r3, op2addr);
2279
sewardj7ee97522011-05-09 21:45:04 +00002280 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002281 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2282}
2283
2284static void
florian55085f82012-11-21 00:36:55 +00002285s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002286 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2287{
florian55085f82012-11-21 00:36:55 +00002288 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002289 IRTemp op2addr = newTemp(Ity_I64);
2290 IRTemp d2 = newTemp(Ity_I64);
2291
2292 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2293 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2294 mkU64(0)));
2295
2296 mnm = irgen(r1, r3, op2addr);
2297
sewardj7ee97522011-05-09 21:45:04 +00002298 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002299 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2300}
2301
2302static void
florian55085f82012-11-21 00:36:55 +00002303s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002304 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2305{
florian55085f82012-11-21 00:36:55 +00002306 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002307 IRTemp op2addr = newTemp(Ity_I64);
2308 IRTemp d2 = newTemp(Ity_I64);
2309
2310 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2311 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2312 mkU64(0)));
2313
2314 mnm = irgen(r1, r3, op2addr);
2315
sewardj7ee97522011-05-09 21:45:04 +00002316 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002317 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2318}
2319
2320static void
florian55085f82012-11-21 00:36:55 +00002321s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002322 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2323 Int xmnm_kind)
2324{
2325 IRTemp op2addr = newTemp(Ity_I64);
2326 IRTemp d2 = newTemp(Ity_I64);
2327
florian6820ba52012-07-26 02:01:50 +00002328 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2329
sewardjd7bde722011-04-05 13:19:33 +00002330 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2331 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2332 mkU64(0)));
2333
2334 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002335
2336 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002337
sewardj7ee97522011-05-09 21:45:04 +00002338 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002339 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2340}
2341
2342static void
florian55085f82012-11-21 00:36:55 +00002343s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002344 IRTemp op2addr),
2345 UChar r1, UChar x2, UChar b2, UShort d2)
2346{
2347 IRTemp op2addr = newTemp(Ity_I64);
2348
2349 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2350 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2351 mkU64(0)));
2352
2353 irgen(r1, x2, b2, d2, op2addr);
2354}
2355
2356static void
florian55085f82012-11-21 00:36:55 +00002357s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002358 UChar r1, UChar x2, UChar b2, UShort d2)
2359{
florian55085f82012-11-21 00:36:55 +00002360 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002361 IRTemp op2addr = newTemp(Ity_I64);
2362
2363 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2364 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2365 mkU64(0)));
2366
2367 mnm = irgen(r1, op2addr);
2368
sewardj7ee97522011-05-09 21:45:04 +00002369 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002370 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2371}
2372
2373static void
florian55085f82012-11-21 00:36:55 +00002374s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002375 UChar r1, UChar x2, UChar b2, UShort d2)
2376{
florian55085f82012-11-21 00:36:55 +00002377 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002378 IRTemp op2addr = newTemp(Ity_I64);
2379
2380 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2381 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2382 mkU64(0)));
2383
2384 mnm = irgen(r1, op2addr);
2385
sewardj7ee97522011-05-09 21:45:04 +00002386 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002387 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2388}
2389
2390static void
florian55085f82012-11-21 00:36:55 +00002391s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002392 UChar r1, UChar x2, UChar b2, UShort d2)
2393{
florian55085f82012-11-21 00:36:55 +00002394 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002395 IRTemp op2addr = newTemp(Ity_I64);
2396
2397 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2398 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2399 mkU64(0)));
2400
2401 mnm = irgen(r1, op2addr);
2402
sewardj7ee97522011-05-09 21:45:04 +00002403 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002404 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2405}
2406
2407static void
florian55085f82012-11-21 00:36:55 +00002408s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002409 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2410{
florian55085f82012-11-21 00:36:55 +00002411 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002412 IRTemp op2addr = newTemp(Ity_I64);
2413
2414 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2415 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2416 mkU64(0)));
2417
2418 mnm = irgen(r3, op2addr, r1);
2419
sewardj7ee97522011-05-09 21:45:04 +00002420 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002421 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2422}
2423
2424static void
florian55085f82012-11-21 00:36:55 +00002425s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002426 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2427{
florian55085f82012-11-21 00:36:55 +00002428 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002429 IRTemp op2addr = newTemp(Ity_I64);
2430 IRTemp d2 = newTemp(Ity_I64);
2431
2432 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2433 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2434 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2435 mkU64(0)));
2436
2437 mnm = irgen(r1, op2addr);
2438
sewardj7ee97522011-05-09 21:45:04 +00002439 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002440 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2441}
2442
2443static void
florian55085f82012-11-21 00:36:55 +00002444s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002445 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2446{
florian55085f82012-11-21 00:36:55 +00002447 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002448 IRTemp op2addr = newTemp(Ity_I64);
2449 IRTemp d2 = newTemp(Ity_I64);
2450
2451 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2452 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2453 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2454 mkU64(0)));
2455
2456 mnm = irgen(r1, op2addr);
2457
sewardj7ee97522011-05-09 21:45:04 +00002458 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002459 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2460}
2461
2462static void
florian55085f82012-11-21 00:36:55 +00002463s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002464 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2465{
florian55085f82012-11-21 00:36:55 +00002466 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002467 IRTemp op2addr = newTemp(Ity_I64);
2468 IRTemp d2 = newTemp(Ity_I64);
2469
2470 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2471 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2472 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2473 mkU64(0)));
2474
2475 mnm = irgen();
2476
sewardj7ee97522011-05-09 21:45:04 +00002477 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002478 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2479}
2480
2481static void
florian55085f82012-11-21 00:36:55 +00002482s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002483 UChar b2, UShort d2)
2484{
florian55085f82012-11-21 00:36:55 +00002485 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002486 IRTemp op2addr = newTemp(Ity_I64);
2487
2488 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2489 mkU64(0)));
2490
2491 mnm = irgen(op2addr);
2492
sewardj7ee97522011-05-09 21:45:04 +00002493 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002494 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2495}
2496
2497static void
florian55085f82012-11-21 00:36:55 +00002498s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002499 UChar i2, UChar b1, UShort d1)
2500{
florian55085f82012-11-21 00:36:55 +00002501 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002502 IRTemp op1addr = newTemp(Ity_I64);
2503
2504 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2505 mkU64(0)));
2506
2507 mnm = irgen(i2, op1addr);
2508
sewardj7ee97522011-05-09 21:45:04 +00002509 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002510 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2511}
2512
2513static void
florian55085f82012-11-21 00:36:55 +00002514s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002515 UChar i2, UChar b1, UShort dl1, UChar dh1)
2516{
florian55085f82012-11-21 00:36:55 +00002517 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002518 IRTemp op1addr = newTemp(Ity_I64);
2519 IRTemp d1 = newTemp(Ity_I64);
2520
2521 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2522 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2523 mkU64(0)));
2524
2525 mnm = irgen(i2, op1addr);
2526
sewardj7ee97522011-05-09 21:45:04 +00002527 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002528 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2529}
2530
2531static void
florian55085f82012-11-21 00:36:55 +00002532s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002533 UChar i2, UChar b1, UShort dl1, UChar dh1)
2534{
florian55085f82012-11-21 00:36:55 +00002535 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002536 IRTemp op1addr = newTemp(Ity_I64);
2537 IRTemp d1 = newTemp(Ity_I64);
2538
2539 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2540 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2541 mkU64(0)));
2542
2543 mnm = irgen(i2, op1addr);
2544
sewardj7ee97522011-05-09 21:45:04 +00002545 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002546 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2547}
2548
2549static void
florian55085f82012-11-21 00:36:55 +00002550s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002551 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2552{
florian55085f82012-11-21 00:36:55 +00002553 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002554 IRTemp op1addr = newTemp(Ity_I64);
2555 IRTemp op2addr = newTemp(Ity_I64);
2556
2557 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2558 mkU64(0)));
2559 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2560 mkU64(0)));
2561
2562 mnm = irgen(l, op1addr, op2addr);
2563
sewardj7ee97522011-05-09 21:45:04 +00002564 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002565 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2566}
2567
2568static void
florian55085f82012-11-21 00:36:55 +00002569s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002570 UChar b1, UShort d1, UShort i2)
2571{
florian55085f82012-11-21 00:36:55 +00002572 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002573 IRTemp op1addr = newTemp(Ity_I64);
2574
2575 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2576 mkU64(0)));
2577
2578 mnm = irgen(i2, op1addr);
2579
sewardj7ee97522011-05-09 21:45:04 +00002580 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002581 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2582}
2583
2584static void
florian55085f82012-11-21 00:36:55 +00002585s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002586 UChar b1, UShort d1, UShort i2)
2587{
florian55085f82012-11-21 00:36:55 +00002588 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002589 IRTemp op1addr = newTemp(Ity_I64);
2590
2591 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2592 mkU64(0)));
2593
2594 mnm = irgen(i2, op1addr);
2595
sewardj7ee97522011-05-09 21:45:04 +00002596 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002597 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2598}
2599
2600
2601
2602/*------------------------------------------------------------*/
2603/*--- Build IR for opcodes ---*/
2604/*------------------------------------------------------------*/
2605
florian55085f82012-11-21 00:36:55 +00002606static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002607s390_irgen_AR(UChar r1, UChar r2)
2608{
2609 IRTemp op1 = newTemp(Ity_I32);
2610 IRTemp op2 = newTemp(Ity_I32);
2611 IRTemp result = newTemp(Ity_I32);
2612
2613 assign(op1, get_gpr_w1(r1));
2614 assign(op2, get_gpr_w1(r2));
2615 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2616 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2617 put_gpr_w1(r1, mkexpr(result));
2618
2619 return "ar";
2620}
2621
florian55085f82012-11-21 00:36:55 +00002622static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002623s390_irgen_AGR(UChar r1, UChar r2)
2624{
2625 IRTemp op1 = newTemp(Ity_I64);
2626 IRTemp op2 = newTemp(Ity_I64);
2627 IRTemp result = newTemp(Ity_I64);
2628
2629 assign(op1, get_gpr_dw0(r1));
2630 assign(op2, get_gpr_dw0(r2));
2631 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2632 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2633 put_gpr_dw0(r1, mkexpr(result));
2634
2635 return "agr";
2636}
2637
florian55085f82012-11-21 00:36:55 +00002638static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002639s390_irgen_AGFR(UChar r1, UChar r2)
2640{
2641 IRTemp op1 = newTemp(Ity_I64);
2642 IRTemp op2 = newTemp(Ity_I64);
2643 IRTemp result = newTemp(Ity_I64);
2644
2645 assign(op1, get_gpr_dw0(r1));
2646 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2647 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2648 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2649 put_gpr_dw0(r1, mkexpr(result));
2650
2651 return "agfr";
2652}
2653
florian55085f82012-11-21 00:36:55 +00002654static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002655s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2656{
2657 IRTemp op2 = newTemp(Ity_I32);
2658 IRTemp op3 = newTemp(Ity_I32);
2659 IRTemp result = newTemp(Ity_I32);
2660
2661 assign(op2, get_gpr_w1(r2));
2662 assign(op3, get_gpr_w1(r3));
2663 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2664 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2665 put_gpr_w1(r1, mkexpr(result));
2666
2667 return "ark";
2668}
2669
florian55085f82012-11-21 00:36:55 +00002670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002671s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2672{
2673 IRTemp op2 = newTemp(Ity_I64);
2674 IRTemp op3 = newTemp(Ity_I64);
2675 IRTemp result = newTemp(Ity_I64);
2676
2677 assign(op2, get_gpr_dw0(r2));
2678 assign(op3, get_gpr_dw0(r3));
2679 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2680 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2681 put_gpr_dw0(r1, mkexpr(result));
2682
2683 return "agrk";
2684}
2685
florian55085f82012-11-21 00:36:55 +00002686static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002687s390_irgen_A(UChar r1, IRTemp op2addr)
2688{
2689 IRTemp op1 = newTemp(Ity_I32);
2690 IRTemp op2 = newTemp(Ity_I32);
2691 IRTemp result = newTemp(Ity_I32);
2692
2693 assign(op1, get_gpr_w1(r1));
2694 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2695 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2696 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2697 put_gpr_w1(r1, mkexpr(result));
2698
2699 return "a";
2700}
2701
florian55085f82012-11-21 00:36:55 +00002702static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002703s390_irgen_AY(UChar r1, IRTemp op2addr)
2704{
2705 IRTemp op1 = newTemp(Ity_I32);
2706 IRTemp op2 = newTemp(Ity_I32);
2707 IRTemp result = newTemp(Ity_I32);
2708
2709 assign(op1, get_gpr_w1(r1));
2710 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2711 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2712 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2713 put_gpr_w1(r1, mkexpr(result));
2714
2715 return "ay";
2716}
2717
florian55085f82012-11-21 00:36:55 +00002718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002719s390_irgen_AG(UChar r1, IRTemp op2addr)
2720{
2721 IRTemp op1 = newTemp(Ity_I64);
2722 IRTemp op2 = newTemp(Ity_I64);
2723 IRTemp result = newTemp(Ity_I64);
2724
2725 assign(op1, get_gpr_dw0(r1));
2726 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2727 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2728 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2729 put_gpr_dw0(r1, mkexpr(result));
2730
2731 return "ag";
2732}
2733
florian55085f82012-11-21 00:36:55 +00002734static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002735s390_irgen_AGF(UChar r1, IRTemp op2addr)
2736{
2737 IRTemp op1 = newTemp(Ity_I64);
2738 IRTemp op2 = newTemp(Ity_I64);
2739 IRTemp result = newTemp(Ity_I64);
2740
2741 assign(op1, get_gpr_dw0(r1));
2742 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2743 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2744 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2745 put_gpr_dw0(r1, mkexpr(result));
2746
2747 return "agf";
2748}
2749
florian55085f82012-11-21 00:36:55 +00002750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002751s390_irgen_AFI(UChar r1, UInt i2)
2752{
2753 IRTemp op1 = newTemp(Ity_I32);
2754 Int op2;
2755 IRTemp result = newTemp(Ity_I32);
2756
2757 assign(op1, get_gpr_w1(r1));
2758 op2 = (Int)i2;
2759 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2760 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2761 mkU32((UInt)op2)));
2762 put_gpr_w1(r1, mkexpr(result));
2763
2764 return "afi";
2765}
2766
florian55085f82012-11-21 00:36:55 +00002767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002768s390_irgen_AGFI(UChar r1, UInt i2)
2769{
2770 IRTemp op1 = newTemp(Ity_I64);
2771 Long op2;
2772 IRTemp result = newTemp(Ity_I64);
2773
2774 assign(op1, get_gpr_dw0(r1));
2775 op2 = (Long)(Int)i2;
2776 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2777 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2778 mkU64((ULong)op2)));
2779 put_gpr_dw0(r1, mkexpr(result));
2780
2781 return "agfi";
2782}
2783
florian55085f82012-11-21 00:36:55 +00002784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002785s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2786{
2787 Int op2;
2788 IRTemp op3 = newTemp(Ity_I32);
2789 IRTemp result = newTemp(Ity_I32);
2790
2791 op2 = (Int)(Short)i2;
2792 assign(op3, get_gpr_w1(r3));
2793 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2794 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2795 op2)), op3);
2796 put_gpr_w1(r1, mkexpr(result));
2797
2798 return "ahik";
2799}
2800
florian55085f82012-11-21 00:36:55 +00002801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002802s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2803{
2804 Long op2;
2805 IRTemp op3 = newTemp(Ity_I64);
2806 IRTemp result = newTemp(Ity_I64);
2807
2808 op2 = (Long)(Short)i2;
2809 assign(op3, get_gpr_dw0(r3));
2810 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2811 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2812 op2)), op3);
2813 put_gpr_dw0(r1, mkexpr(result));
2814
2815 return "aghik";
2816}
2817
florian55085f82012-11-21 00:36:55 +00002818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002819s390_irgen_ASI(UChar i2, IRTemp op1addr)
2820{
2821 IRTemp op1 = newTemp(Ity_I32);
2822 Int op2;
2823 IRTemp result = newTemp(Ity_I32);
2824
2825 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2826 op2 = (Int)(Char)i2;
2827 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2828 store(mkexpr(op1addr), mkexpr(result));
2829 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2830 mkU32((UInt)op2)));
2831
2832 return "asi";
2833}
2834
florian55085f82012-11-21 00:36:55 +00002835static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002836s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2837{
2838 IRTemp op1 = newTemp(Ity_I64);
2839 Long op2;
2840 IRTemp result = newTemp(Ity_I64);
2841
2842 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2843 op2 = (Long)(Char)i2;
2844 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2845 store(mkexpr(op1addr), mkexpr(result));
2846 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2847 mkU64((ULong)op2)));
2848
2849 return "agsi";
2850}
2851
florian55085f82012-11-21 00:36:55 +00002852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002853s390_irgen_AH(UChar r1, IRTemp op2addr)
2854{
2855 IRTemp op1 = newTemp(Ity_I32);
2856 IRTemp op2 = newTemp(Ity_I32);
2857 IRTemp result = newTemp(Ity_I32);
2858
2859 assign(op1, get_gpr_w1(r1));
2860 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2861 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2862 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2863 put_gpr_w1(r1, mkexpr(result));
2864
2865 return "ah";
2866}
2867
florian55085f82012-11-21 00:36:55 +00002868static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002869s390_irgen_AHY(UChar r1, IRTemp op2addr)
2870{
2871 IRTemp op1 = newTemp(Ity_I32);
2872 IRTemp op2 = newTemp(Ity_I32);
2873 IRTemp result = newTemp(Ity_I32);
2874
2875 assign(op1, get_gpr_w1(r1));
2876 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2877 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2878 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2879 put_gpr_w1(r1, mkexpr(result));
2880
2881 return "ahy";
2882}
2883
florian55085f82012-11-21 00:36:55 +00002884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002885s390_irgen_AHI(UChar r1, UShort i2)
2886{
2887 IRTemp op1 = newTemp(Ity_I32);
2888 Int op2;
2889 IRTemp result = newTemp(Ity_I32);
2890
2891 assign(op1, get_gpr_w1(r1));
2892 op2 = (Int)(Short)i2;
2893 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2894 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2895 mkU32((UInt)op2)));
2896 put_gpr_w1(r1, mkexpr(result));
2897
2898 return "ahi";
2899}
2900
florian55085f82012-11-21 00:36:55 +00002901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002902s390_irgen_AGHI(UChar r1, UShort i2)
2903{
2904 IRTemp op1 = newTemp(Ity_I64);
2905 Long op2;
2906 IRTemp result = newTemp(Ity_I64);
2907
2908 assign(op1, get_gpr_dw0(r1));
2909 op2 = (Long)(Short)i2;
2910 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2911 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2912 mkU64((ULong)op2)));
2913 put_gpr_dw0(r1, mkexpr(result));
2914
2915 return "aghi";
2916}
2917
florian55085f82012-11-21 00:36:55 +00002918static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002919s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2920{
2921 IRTemp op2 = newTemp(Ity_I32);
2922 IRTemp op3 = newTemp(Ity_I32);
2923 IRTemp result = newTemp(Ity_I32);
2924
2925 assign(op2, get_gpr_w0(r2));
2926 assign(op3, get_gpr_w0(r3));
2927 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2928 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2929 put_gpr_w0(r1, mkexpr(result));
2930
2931 return "ahhhr";
2932}
2933
florian55085f82012-11-21 00:36:55 +00002934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002935s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2936{
2937 IRTemp op2 = newTemp(Ity_I32);
2938 IRTemp op3 = newTemp(Ity_I32);
2939 IRTemp result = newTemp(Ity_I32);
2940
2941 assign(op2, get_gpr_w0(r2));
2942 assign(op3, get_gpr_w1(r3));
2943 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2944 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2945 put_gpr_w0(r1, mkexpr(result));
2946
2947 return "ahhlr";
2948}
2949
florian55085f82012-11-21 00:36:55 +00002950static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002951s390_irgen_AIH(UChar r1, UInt i2)
2952{
2953 IRTemp op1 = newTemp(Ity_I32);
2954 Int op2;
2955 IRTemp result = newTemp(Ity_I32);
2956
2957 assign(op1, get_gpr_w0(r1));
2958 op2 = (Int)i2;
2959 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2960 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2961 mkU32((UInt)op2)));
2962 put_gpr_w0(r1, mkexpr(result));
2963
2964 return "aih";
2965}
2966
florian55085f82012-11-21 00:36:55 +00002967static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002968s390_irgen_ALR(UChar r1, UChar r2)
2969{
2970 IRTemp op1 = newTemp(Ity_I32);
2971 IRTemp op2 = newTemp(Ity_I32);
2972 IRTemp result = newTemp(Ity_I32);
2973
2974 assign(op1, get_gpr_w1(r1));
2975 assign(op2, get_gpr_w1(r2));
2976 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2977 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2978 put_gpr_w1(r1, mkexpr(result));
2979
2980 return "alr";
2981}
2982
florian55085f82012-11-21 00:36:55 +00002983static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002984s390_irgen_ALGR(UChar r1, UChar r2)
2985{
2986 IRTemp op1 = newTemp(Ity_I64);
2987 IRTemp op2 = newTemp(Ity_I64);
2988 IRTemp result = newTemp(Ity_I64);
2989
2990 assign(op1, get_gpr_dw0(r1));
2991 assign(op2, get_gpr_dw0(r2));
2992 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2993 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2994 put_gpr_dw0(r1, mkexpr(result));
2995
2996 return "algr";
2997}
2998
florian55085f82012-11-21 00:36:55 +00002999static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003000s390_irgen_ALGFR(UChar r1, UChar r2)
3001{
3002 IRTemp op1 = newTemp(Ity_I64);
3003 IRTemp op2 = newTemp(Ity_I64);
3004 IRTemp result = newTemp(Ity_I64);
3005
3006 assign(op1, get_gpr_dw0(r1));
3007 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
3008 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3009 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3010 put_gpr_dw0(r1, mkexpr(result));
3011
3012 return "algfr";
3013}
3014
florian55085f82012-11-21 00:36:55 +00003015static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003016s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
3017{
3018 IRTemp op2 = newTemp(Ity_I32);
3019 IRTemp op3 = newTemp(Ity_I32);
3020 IRTemp result = newTemp(Ity_I32);
3021
3022 assign(op2, get_gpr_w1(r2));
3023 assign(op3, get_gpr_w1(r3));
3024 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3025 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3026 put_gpr_w1(r1, mkexpr(result));
3027
3028 return "alrk";
3029}
3030
florian55085f82012-11-21 00:36:55 +00003031static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003032s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
3033{
3034 IRTemp op2 = newTemp(Ity_I64);
3035 IRTemp op3 = newTemp(Ity_I64);
3036 IRTemp result = newTemp(Ity_I64);
3037
3038 assign(op2, get_gpr_dw0(r2));
3039 assign(op3, get_gpr_dw0(r3));
3040 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
3041 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
3042 put_gpr_dw0(r1, mkexpr(result));
3043
3044 return "algrk";
3045}
3046
florian55085f82012-11-21 00:36:55 +00003047static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003048s390_irgen_AL(UChar r1, IRTemp op2addr)
3049{
3050 IRTemp op1 = newTemp(Ity_I32);
3051 IRTemp op2 = newTemp(Ity_I32);
3052 IRTemp result = newTemp(Ity_I32);
3053
3054 assign(op1, get_gpr_w1(r1));
3055 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3056 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3057 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3058 put_gpr_w1(r1, mkexpr(result));
3059
3060 return "al";
3061}
3062
florian55085f82012-11-21 00:36:55 +00003063static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003064s390_irgen_ALY(UChar r1, IRTemp op2addr)
3065{
3066 IRTemp op1 = newTemp(Ity_I32);
3067 IRTemp op2 = newTemp(Ity_I32);
3068 IRTemp result = newTemp(Ity_I32);
3069
3070 assign(op1, get_gpr_w1(r1));
3071 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3072 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3073 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3074 put_gpr_w1(r1, mkexpr(result));
3075
3076 return "aly";
3077}
3078
florian55085f82012-11-21 00:36:55 +00003079static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003080s390_irgen_ALG(UChar r1, IRTemp op2addr)
3081{
3082 IRTemp op1 = newTemp(Ity_I64);
3083 IRTemp op2 = newTemp(Ity_I64);
3084 IRTemp result = newTemp(Ity_I64);
3085
3086 assign(op1, get_gpr_dw0(r1));
3087 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3088 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3089 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3090 put_gpr_dw0(r1, mkexpr(result));
3091
3092 return "alg";
3093}
3094
florian55085f82012-11-21 00:36:55 +00003095static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003096s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3097{
3098 IRTemp op1 = newTemp(Ity_I64);
3099 IRTemp op2 = newTemp(Ity_I64);
3100 IRTemp result = newTemp(Ity_I64);
3101
3102 assign(op1, get_gpr_dw0(r1));
3103 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3104 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3105 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3106 put_gpr_dw0(r1, mkexpr(result));
3107
3108 return "algf";
3109}
3110
florian55085f82012-11-21 00:36:55 +00003111static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003112s390_irgen_ALFI(UChar r1, UInt i2)
3113{
3114 IRTemp op1 = newTemp(Ity_I32);
3115 UInt op2;
3116 IRTemp result = newTemp(Ity_I32);
3117
3118 assign(op1, get_gpr_w1(r1));
3119 op2 = i2;
3120 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3121 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3122 mkU32(op2)));
3123 put_gpr_w1(r1, mkexpr(result));
3124
3125 return "alfi";
3126}
3127
florian55085f82012-11-21 00:36:55 +00003128static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003129s390_irgen_ALGFI(UChar r1, UInt i2)
3130{
3131 IRTemp op1 = newTemp(Ity_I64);
3132 ULong op2;
3133 IRTemp result = newTemp(Ity_I64);
3134
3135 assign(op1, get_gpr_dw0(r1));
3136 op2 = (ULong)i2;
3137 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3138 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3139 mkU64(op2)));
3140 put_gpr_dw0(r1, mkexpr(result));
3141
3142 return "algfi";
3143}
3144
florian55085f82012-11-21 00:36:55 +00003145static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003146s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3147{
3148 IRTemp op2 = newTemp(Ity_I32);
3149 IRTemp op3 = newTemp(Ity_I32);
3150 IRTemp result = newTemp(Ity_I32);
3151
3152 assign(op2, get_gpr_w0(r2));
3153 assign(op3, get_gpr_w0(r3));
3154 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3155 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3156 put_gpr_w0(r1, mkexpr(result));
3157
3158 return "alhhhr";
3159}
3160
florian55085f82012-11-21 00:36:55 +00003161static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003162s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3163{
3164 IRTemp op2 = newTemp(Ity_I32);
3165 IRTemp op3 = newTemp(Ity_I32);
3166 IRTemp result = newTemp(Ity_I32);
3167
3168 assign(op2, get_gpr_w0(r2));
3169 assign(op3, get_gpr_w1(r3));
3170 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3171 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3172 put_gpr_w0(r1, mkexpr(result));
3173
3174 return "alhhlr";
3175}
3176
florian55085f82012-11-21 00:36:55 +00003177static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003178s390_irgen_ALCR(UChar r1, UChar r2)
3179{
3180 IRTemp op1 = newTemp(Ity_I32);
3181 IRTemp op2 = newTemp(Ity_I32);
3182 IRTemp result = newTemp(Ity_I32);
3183 IRTemp carry_in = newTemp(Ity_I32);
3184
3185 assign(op1, get_gpr_w1(r1));
3186 assign(op2, get_gpr_w1(r2));
3187 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3188 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3189 mkexpr(carry_in)));
3190 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3191 put_gpr_w1(r1, mkexpr(result));
3192
3193 return "alcr";
3194}
3195
florian55085f82012-11-21 00:36:55 +00003196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003197s390_irgen_ALCGR(UChar r1, UChar r2)
3198{
3199 IRTemp op1 = newTemp(Ity_I64);
3200 IRTemp op2 = newTemp(Ity_I64);
3201 IRTemp result = newTemp(Ity_I64);
3202 IRTemp carry_in = newTemp(Ity_I64);
3203
3204 assign(op1, get_gpr_dw0(r1));
3205 assign(op2, get_gpr_dw0(r2));
3206 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3207 mkU8(1))));
3208 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3209 mkexpr(carry_in)));
3210 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3211 put_gpr_dw0(r1, mkexpr(result));
3212
3213 return "alcgr";
3214}
3215
florian55085f82012-11-21 00:36:55 +00003216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003217s390_irgen_ALC(UChar r1, IRTemp op2addr)
3218{
3219 IRTemp op1 = newTemp(Ity_I32);
3220 IRTemp op2 = newTemp(Ity_I32);
3221 IRTemp result = newTemp(Ity_I32);
3222 IRTemp carry_in = newTemp(Ity_I32);
3223
3224 assign(op1, get_gpr_w1(r1));
3225 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3226 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3227 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3228 mkexpr(carry_in)));
3229 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3230 put_gpr_w1(r1, mkexpr(result));
3231
3232 return "alc";
3233}
3234
florian55085f82012-11-21 00:36:55 +00003235static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003236s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3237{
3238 IRTemp op1 = newTemp(Ity_I64);
3239 IRTemp op2 = newTemp(Ity_I64);
3240 IRTemp result = newTemp(Ity_I64);
3241 IRTemp carry_in = newTemp(Ity_I64);
3242
3243 assign(op1, get_gpr_dw0(r1));
3244 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3245 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3246 mkU8(1))));
3247 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3248 mkexpr(carry_in)));
3249 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3250 put_gpr_dw0(r1, mkexpr(result));
3251
3252 return "alcg";
3253}
3254
florian55085f82012-11-21 00:36:55 +00003255static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003256s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3257{
3258 IRTemp op1 = newTemp(Ity_I32);
3259 UInt op2;
3260 IRTemp result = newTemp(Ity_I32);
3261
3262 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3263 op2 = (UInt)(Int)(Char)i2;
3264 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3265 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3266 mkU32(op2)));
3267 store(mkexpr(op1addr), mkexpr(result));
3268
3269 return "alsi";
3270}
3271
florian55085f82012-11-21 00:36:55 +00003272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003273s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3274{
3275 IRTemp op1 = newTemp(Ity_I64);
3276 ULong op2;
3277 IRTemp result = newTemp(Ity_I64);
3278
3279 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3280 op2 = (ULong)(Long)(Char)i2;
3281 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3282 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3283 mkU64(op2)));
3284 store(mkexpr(op1addr), mkexpr(result));
3285
3286 return "algsi";
3287}
3288
florian55085f82012-11-21 00:36:55 +00003289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003290s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3291{
3292 UInt op2;
3293 IRTemp op3 = newTemp(Ity_I32);
3294 IRTemp result = newTemp(Ity_I32);
3295
3296 op2 = (UInt)(Int)(Short)i2;
3297 assign(op3, get_gpr_w1(r3));
3298 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3299 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3300 op3);
3301 put_gpr_w1(r1, mkexpr(result));
3302
3303 return "alhsik";
3304}
3305
florian55085f82012-11-21 00:36:55 +00003306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003307s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3308{
3309 ULong op2;
3310 IRTemp op3 = newTemp(Ity_I64);
3311 IRTemp result = newTemp(Ity_I64);
3312
3313 op2 = (ULong)(Long)(Short)i2;
3314 assign(op3, get_gpr_dw0(r3));
3315 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3316 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3317 op3);
3318 put_gpr_dw0(r1, mkexpr(result));
3319
3320 return "alghsik";
3321}
3322
florian55085f82012-11-21 00:36:55 +00003323static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003324s390_irgen_ALSIH(UChar r1, UInt i2)
3325{
3326 IRTemp op1 = newTemp(Ity_I32);
3327 UInt op2;
3328 IRTemp result = newTemp(Ity_I32);
3329
3330 assign(op1, get_gpr_w0(r1));
3331 op2 = i2;
3332 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3333 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3334 mkU32(op2)));
3335 put_gpr_w0(r1, mkexpr(result));
3336
3337 return "alsih";
3338}
3339
florian55085f82012-11-21 00:36:55 +00003340static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003341s390_irgen_ALSIHN(UChar r1, UInt i2)
3342{
3343 IRTemp op1 = newTemp(Ity_I32);
3344 UInt op2;
3345 IRTemp result = newTemp(Ity_I32);
3346
3347 assign(op1, get_gpr_w0(r1));
3348 op2 = i2;
3349 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3350 put_gpr_w0(r1, mkexpr(result));
3351
3352 return "alsihn";
3353}
3354
florian55085f82012-11-21 00:36:55 +00003355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003356s390_irgen_NR(UChar r1, UChar r2)
3357{
3358 IRTemp op1 = newTemp(Ity_I32);
3359 IRTemp op2 = newTemp(Ity_I32);
3360 IRTemp result = newTemp(Ity_I32);
3361
3362 assign(op1, get_gpr_w1(r1));
3363 assign(op2, get_gpr_w1(r2));
3364 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3365 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3366 put_gpr_w1(r1, mkexpr(result));
3367
3368 return "nr";
3369}
3370
florian55085f82012-11-21 00:36:55 +00003371static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003372s390_irgen_NGR(UChar r1, UChar r2)
3373{
3374 IRTemp op1 = newTemp(Ity_I64);
3375 IRTemp op2 = newTemp(Ity_I64);
3376 IRTemp result = newTemp(Ity_I64);
3377
3378 assign(op1, get_gpr_dw0(r1));
3379 assign(op2, get_gpr_dw0(r2));
3380 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3381 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3382 put_gpr_dw0(r1, mkexpr(result));
3383
3384 return "ngr";
3385}
3386
florian55085f82012-11-21 00:36:55 +00003387static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003388s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3389{
3390 IRTemp op2 = newTemp(Ity_I32);
3391 IRTemp op3 = newTemp(Ity_I32);
3392 IRTemp result = newTemp(Ity_I32);
3393
3394 assign(op2, get_gpr_w1(r2));
3395 assign(op3, get_gpr_w1(r3));
3396 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3397 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3398 put_gpr_w1(r1, mkexpr(result));
3399
3400 return "nrk";
3401}
3402
florian55085f82012-11-21 00:36:55 +00003403static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003404s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3405{
3406 IRTemp op2 = newTemp(Ity_I64);
3407 IRTemp op3 = newTemp(Ity_I64);
3408 IRTemp result = newTemp(Ity_I64);
3409
3410 assign(op2, get_gpr_dw0(r2));
3411 assign(op3, get_gpr_dw0(r3));
3412 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3413 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3414 put_gpr_dw0(r1, mkexpr(result));
3415
3416 return "ngrk";
3417}
3418
florian55085f82012-11-21 00:36:55 +00003419static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003420s390_irgen_N(UChar r1, IRTemp op2addr)
3421{
3422 IRTemp op1 = newTemp(Ity_I32);
3423 IRTemp op2 = newTemp(Ity_I32);
3424 IRTemp result = newTemp(Ity_I32);
3425
3426 assign(op1, get_gpr_w1(r1));
3427 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3428 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3429 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3430 put_gpr_w1(r1, mkexpr(result));
3431
3432 return "n";
3433}
3434
florian55085f82012-11-21 00:36:55 +00003435static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003436s390_irgen_NY(UChar r1, IRTemp op2addr)
3437{
3438 IRTemp op1 = newTemp(Ity_I32);
3439 IRTemp op2 = newTemp(Ity_I32);
3440 IRTemp result = newTemp(Ity_I32);
3441
3442 assign(op1, get_gpr_w1(r1));
3443 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3444 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3445 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3446 put_gpr_w1(r1, mkexpr(result));
3447
3448 return "ny";
3449}
3450
florian55085f82012-11-21 00:36:55 +00003451static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003452s390_irgen_NG(UChar r1, IRTemp op2addr)
3453{
3454 IRTemp op1 = newTemp(Ity_I64);
3455 IRTemp op2 = newTemp(Ity_I64);
3456 IRTemp result = newTemp(Ity_I64);
3457
3458 assign(op1, get_gpr_dw0(r1));
3459 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3460 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3461 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3462 put_gpr_dw0(r1, mkexpr(result));
3463
3464 return "ng";
3465}
3466
florian55085f82012-11-21 00:36:55 +00003467static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003468s390_irgen_NI(UChar i2, IRTemp op1addr)
3469{
3470 IRTemp op1 = newTemp(Ity_I8);
3471 UChar op2;
3472 IRTemp result = newTemp(Ity_I8);
3473
3474 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3475 op2 = i2;
3476 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3477 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3478 store(mkexpr(op1addr), mkexpr(result));
3479
3480 return "ni";
3481}
3482
florian55085f82012-11-21 00:36:55 +00003483static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003484s390_irgen_NIY(UChar i2, IRTemp op1addr)
3485{
3486 IRTemp op1 = newTemp(Ity_I8);
3487 UChar op2;
3488 IRTemp result = newTemp(Ity_I8);
3489
3490 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3491 op2 = i2;
3492 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3493 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3494 store(mkexpr(op1addr), mkexpr(result));
3495
3496 return "niy";
3497}
3498
florian55085f82012-11-21 00:36:55 +00003499static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003500s390_irgen_NIHF(UChar r1, UInt i2)
3501{
3502 IRTemp op1 = newTemp(Ity_I32);
3503 UInt op2;
3504 IRTemp result = newTemp(Ity_I32);
3505
3506 assign(op1, get_gpr_w0(r1));
3507 op2 = i2;
3508 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3509 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3510 put_gpr_w0(r1, mkexpr(result));
3511
3512 return "nihf";
3513}
3514
florian55085f82012-11-21 00:36:55 +00003515static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003516s390_irgen_NIHH(UChar r1, UShort i2)
3517{
3518 IRTemp op1 = newTemp(Ity_I16);
3519 UShort op2;
3520 IRTemp result = newTemp(Ity_I16);
3521
3522 assign(op1, get_gpr_hw0(r1));
3523 op2 = i2;
3524 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3525 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3526 put_gpr_hw0(r1, mkexpr(result));
3527
3528 return "nihh";
3529}
3530
florian55085f82012-11-21 00:36:55 +00003531static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003532s390_irgen_NIHL(UChar r1, UShort i2)
3533{
3534 IRTemp op1 = newTemp(Ity_I16);
3535 UShort op2;
3536 IRTemp result = newTemp(Ity_I16);
3537
3538 assign(op1, get_gpr_hw1(r1));
3539 op2 = i2;
3540 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3541 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3542 put_gpr_hw1(r1, mkexpr(result));
3543
3544 return "nihl";
3545}
3546
florian55085f82012-11-21 00:36:55 +00003547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003548s390_irgen_NILF(UChar r1, UInt i2)
3549{
3550 IRTemp op1 = newTemp(Ity_I32);
3551 UInt op2;
3552 IRTemp result = newTemp(Ity_I32);
3553
3554 assign(op1, get_gpr_w1(r1));
3555 op2 = i2;
3556 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3557 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3558 put_gpr_w1(r1, mkexpr(result));
3559
3560 return "nilf";
3561}
3562
florian55085f82012-11-21 00:36:55 +00003563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003564s390_irgen_NILH(UChar r1, UShort i2)
3565{
3566 IRTemp op1 = newTemp(Ity_I16);
3567 UShort op2;
3568 IRTemp result = newTemp(Ity_I16);
3569
3570 assign(op1, get_gpr_hw2(r1));
3571 op2 = i2;
3572 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3573 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3574 put_gpr_hw2(r1, mkexpr(result));
3575
3576 return "nilh";
3577}
3578
florian55085f82012-11-21 00:36:55 +00003579static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003580s390_irgen_NILL(UChar r1, UShort i2)
3581{
3582 IRTemp op1 = newTemp(Ity_I16);
3583 UShort op2;
3584 IRTemp result = newTemp(Ity_I16);
3585
3586 assign(op1, get_gpr_hw3(r1));
3587 op2 = i2;
3588 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3589 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3590 put_gpr_hw3(r1, mkexpr(result));
3591
3592 return "nill";
3593}
3594
florian55085f82012-11-21 00:36:55 +00003595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003596s390_irgen_BASR(UChar r1, UChar r2)
3597{
3598 IRTemp target = newTemp(Ity_I64);
3599
3600 if (r2 == 0) {
3601 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3602 } else {
3603 if (r1 != r2) {
3604 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3605 call_function(get_gpr_dw0(r2));
3606 } else {
3607 assign(target, get_gpr_dw0(r2));
3608 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3609 call_function(mkexpr(target));
3610 }
3611 }
3612
3613 return "basr";
3614}
3615
florian55085f82012-11-21 00:36:55 +00003616static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003617s390_irgen_BAS(UChar r1, IRTemp op2addr)
3618{
3619 IRTemp target = newTemp(Ity_I64);
3620
3621 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3622 assign(target, mkexpr(op2addr));
3623 call_function(mkexpr(target));
3624
3625 return "bas";
3626}
3627
florian55085f82012-11-21 00:36:55 +00003628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003629s390_irgen_BCR(UChar r1, UChar r2)
3630{
3631 IRTemp cond = newTemp(Ity_I32);
3632
sewardja52e37e2011-04-28 18:48:06 +00003633 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3634 stmt(IRStmt_MBE(Imbe_Fence));
3635 }
3636
sewardj2019a972011-03-07 16:04:07 +00003637 if ((r2 == 0) || (r1 == 0)) {
3638 } else {
3639 if (r1 == 15) {
3640 return_from_function(get_gpr_dw0(r2));
3641 } else {
3642 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003643 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3644 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003645 }
3646 }
sewardj7ee97522011-05-09 21:45:04 +00003647 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003648 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3649
3650 return "bcr";
3651}
3652
florian55085f82012-11-21 00:36:55 +00003653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003654s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3655{
3656 IRTemp cond = newTemp(Ity_I32);
3657
3658 if (r1 == 0) {
3659 } else {
3660 if (r1 == 15) {
3661 always_goto(mkexpr(op2addr));
3662 } else {
3663 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003664 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3665 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003666 }
3667 }
sewardj7ee97522011-05-09 21:45:04 +00003668 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003669 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3670
3671 return "bc";
3672}
3673
florian55085f82012-11-21 00:36:55 +00003674static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003675s390_irgen_BCTR(UChar r1, UChar r2)
3676{
3677 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3678 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003679 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3680 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003681 }
3682
3683 return "bctr";
3684}
3685
florian55085f82012-11-21 00:36:55 +00003686static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003687s390_irgen_BCTGR(UChar r1, UChar r2)
3688{
3689 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3690 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003691 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3692 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003693 }
3694
3695 return "bctgr";
3696}
3697
florian55085f82012-11-21 00:36:55 +00003698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003699s390_irgen_BCT(UChar r1, IRTemp op2addr)
3700{
3701 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003702 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3703 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003704
3705 return "bct";
3706}
3707
florian55085f82012-11-21 00:36:55 +00003708static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003709s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3710{
3711 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003712 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3713 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003714
3715 return "bctg";
3716}
3717
florian55085f82012-11-21 00:36:55 +00003718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003719s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3720{
3721 IRTemp value = newTemp(Ity_I32);
3722
3723 assign(value, get_gpr_w1(r3 | 1));
3724 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003725 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3726 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003727
3728 return "bxh";
3729}
3730
florian55085f82012-11-21 00:36:55 +00003731static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003732s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3733{
3734 IRTemp value = newTemp(Ity_I64);
3735
3736 assign(value, get_gpr_dw0(r3 | 1));
3737 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003738 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3739 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003740
3741 return "bxhg";
3742}
3743
florian55085f82012-11-21 00:36:55 +00003744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003745s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3746{
3747 IRTemp value = newTemp(Ity_I32);
3748
3749 assign(value, get_gpr_w1(r3 | 1));
3750 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003751 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3752 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003753
3754 return "bxle";
3755}
3756
florian55085f82012-11-21 00:36:55 +00003757static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003758s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3759{
3760 IRTemp value = newTemp(Ity_I64);
3761
3762 assign(value, get_gpr_dw0(r3 | 1));
3763 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003764 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3765 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003766
3767 return "bxleg";
3768}
3769
florian55085f82012-11-21 00:36:55 +00003770static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003771s390_irgen_BRAS(UChar r1, UShort i2)
3772{
3773 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003774 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003775
3776 return "bras";
3777}
3778
florian55085f82012-11-21 00:36:55 +00003779static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003780s390_irgen_BRASL(UChar r1, UInt i2)
3781{
3782 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003783 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003784
3785 return "brasl";
3786}
3787
florian55085f82012-11-21 00:36:55 +00003788static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003789s390_irgen_BRC(UChar r1, UShort i2)
3790{
3791 IRTemp cond = newTemp(Ity_I32);
3792
3793 if (r1 == 0) {
3794 } else {
3795 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003796 always_goto_and_chase(
3797 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003798 } else {
3799 assign(cond, s390_call_calculate_cond(r1));
3800 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3801 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3802
3803 }
3804 }
sewardj7ee97522011-05-09 21:45:04 +00003805 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003806 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3807
3808 return "brc";
3809}
3810
florian55085f82012-11-21 00:36:55 +00003811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003812s390_irgen_BRCL(UChar r1, UInt i2)
3813{
3814 IRTemp cond = newTemp(Ity_I32);
3815
3816 if (r1 == 0) {
3817 } else {
3818 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003819 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003820 } else {
3821 assign(cond, s390_call_calculate_cond(r1));
3822 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3823 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3824 }
3825 }
sewardj7ee97522011-05-09 21:45:04 +00003826 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003827 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3828
3829 return "brcl";
3830}
3831
florian55085f82012-11-21 00:36:55 +00003832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003833s390_irgen_BRCT(UChar r1, UShort i2)
3834{
3835 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3836 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3837 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3838
3839 return "brct";
3840}
3841
florian55085f82012-11-21 00:36:55 +00003842static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003843s390_irgen_BRCTG(UChar r1, UShort i2)
3844{
3845 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3846 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3847 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3848
3849 return "brctg";
3850}
3851
florian55085f82012-11-21 00:36:55 +00003852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003853s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3854{
3855 IRTemp value = newTemp(Ity_I32);
3856
3857 assign(value, get_gpr_w1(r3 | 1));
3858 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3859 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3860 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3861
3862 return "brxh";
3863}
3864
florian55085f82012-11-21 00:36:55 +00003865static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003866s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3867{
3868 IRTemp value = newTemp(Ity_I64);
3869
3870 assign(value, get_gpr_dw0(r3 | 1));
3871 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3872 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3873 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3874
3875 return "brxhg";
3876}
3877
florian55085f82012-11-21 00:36:55 +00003878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003879s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3880{
3881 IRTemp value = newTemp(Ity_I32);
3882
3883 assign(value, get_gpr_w1(r3 | 1));
3884 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3885 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3886 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3887
3888 return "brxle";
3889}
3890
florian55085f82012-11-21 00:36:55 +00003891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003892s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3893{
3894 IRTemp value = newTemp(Ity_I64);
3895
3896 assign(value, get_gpr_dw0(r3 | 1));
3897 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3898 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3899 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3900
3901 return "brxlg";
3902}
3903
florian55085f82012-11-21 00:36:55 +00003904static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003905s390_irgen_CR(UChar r1, UChar r2)
3906{
3907 IRTemp op1 = newTemp(Ity_I32);
3908 IRTemp op2 = newTemp(Ity_I32);
3909
3910 assign(op1, get_gpr_w1(r1));
3911 assign(op2, get_gpr_w1(r2));
3912 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3913
3914 return "cr";
3915}
3916
florian55085f82012-11-21 00:36:55 +00003917static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003918s390_irgen_CGR(UChar r1, UChar r2)
3919{
3920 IRTemp op1 = newTemp(Ity_I64);
3921 IRTemp op2 = newTemp(Ity_I64);
3922
3923 assign(op1, get_gpr_dw0(r1));
3924 assign(op2, get_gpr_dw0(r2));
3925 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3926
3927 return "cgr";
3928}
3929
florian55085f82012-11-21 00:36:55 +00003930static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003931s390_irgen_CGFR(UChar r1, UChar r2)
3932{
3933 IRTemp op1 = newTemp(Ity_I64);
3934 IRTemp op2 = newTemp(Ity_I64);
3935
3936 assign(op1, get_gpr_dw0(r1));
3937 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3938 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3939
3940 return "cgfr";
3941}
3942
florian55085f82012-11-21 00:36:55 +00003943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003944s390_irgen_C(UChar r1, IRTemp op2addr)
3945{
3946 IRTemp op1 = newTemp(Ity_I32);
3947 IRTemp op2 = newTemp(Ity_I32);
3948
3949 assign(op1, get_gpr_w1(r1));
3950 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3951 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3952
3953 return "c";
3954}
3955
florian55085f82012-11-21 00:36:55 +00003956static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003957s390_irgen_CY(UChar r1, IRTemp op2addr)
3958{
3959 IRTemp op1 = newTemp(Ity_I32);
3960 IRTemp op2 = newTemp(Ity_I32);
3961
3962 assign(op1, get_gpr_w1(r1));
3963 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3964 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3965
3966 return "cy";
3967}
3968
florian55085f82012-11-21 00:36:55 +00003969static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003970s390_irgen_CG(UChar r1, IRTemp op2addr)
3971{
3972 IRTemp op1 = newTemp(Ity_I64);
3973 IRTemp op2 = newTemp(Ity_I64);
3974
3975 assign(op1, get_gpr_dw0(r1));
3976 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3977 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3978
3979 return "cg";
3980}
3981
florian55085f82012-11-21 00:36:55 +00003982static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003983s390_irgen_CGF(UChar r1, IRTemp op2addr)
3984{
3985 IRTemp op1 = newTemp(Ity_I64);
3986 IRTemp op2 = newTemp(Ity_I64);
3987
3988 assign(op1, get_gpr_dw0(r1));
3989 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3990 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3991
3992 return "cgf";
3993}
3994
florian55085f82012-11-21 00:36:55 +00003995static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003996s390_irgen_CFI(UChar r1, UInt i2)
3997{
3998 IRTemp op1 = newTemp(Ity_I32);
3999 Int op2;
4000
4001 assign(op1, get_gpr_w1(r1));
4002 op2 = (Int)i2;
4003 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4004 mkU32((UInt)op2)));
4005
4006 return "cfi";
4007}
4008
florian55085f82012-11-21 00:36:55 +00004009static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004010s390_irgen_CGFI(UChar r1, UInt i2)
4011{
4012 IRTemp op1 = newTemp(Ity_I64);
4013 Long op2;
4014
4015 assign(op1, get_gpr_dw0(r1));
4016 op2 = (Long)(Int)i2;
4017 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4018 mkU64((ULong)op2)));
4019
4020 return "cgfi";
4021}
4022
florian55085f82012-11-21 00:36:55 +00004023static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004024s390_irgen_CRL(UChar r1, UInt i2)
4025{
4026 IRTemp op1 = newTemp(Ity_I32);
4027 IRTemp op2 = newTemp(Ity_I32);
4028
4029 assign(op1, get_gpr_w1(r1));
4030 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4031 i2 << 1))));
4032 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4033
4034 return "crl";
4035}
4036
florian55085f82012-11-21 00:36:55 +00004037static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004038s390_irgen_CGRL(UChar r1, UInt i2)
4039{
4040 IRTemp op1 = newTemp(Ity_I64);
4041 IRTemp op2 = newTemp(Ity_I64);
4042
4043 assign(op1, get_gpr_dw0(r1));
4044 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4045 i2 << 1))));
4046 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4047
4048 return "cgrl";
4049}
4050
florian55085f82012-11-21 00:36:55 +00004051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004052s390_irgen_CGFRL(UChar r1, UInt i2)
4053{
4054 IRTemp op1 = newTemp(Ity_I64);
4055 IRTemp op2 = newTemp(Ity_I64);
4056
4057 assign(op1, get_gpr_dw0(r1));
4058 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4059 ((ULong)(Long)(Int)i2 << 1)))));
4060 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4061
4062 return "cgfrl";
4063}
4064
florian55085f82012-11-21 00:36:55 +00004065static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004066s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4067{
4068 IRTemp op1 = newTemp(Ity_I32);
4069 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004070 IRTemp cond = newTemp(Ity_I32);
4071
4072 if (m3 == 0) {
4073 } else {
4074 if (m3 == 14) {
4075 always_goto(mkexpr(op4addr));
4076 } else {
4077 assign(op1, get_gpr_w1(r1));
4078 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004079 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4080 op1, op2));
florianf321da72012-07-21 20:32:57 +00004081 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4082 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004083 }
4084 }
4085
4086 return "crb";
4087}
4088
florian55085f82012-11-21 00:36:55 +00004089static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004090s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4091{
4092 IRTemp op1 = newTemp(Ity_I64);
4093 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004094 IRTemp cond = newTemp(Ity_I32);
4095
4096 if (m3 == 0) {
4097 } else {
4098 if (m3 == 14) {
4099 always_goto(mkexpr(op4addr));
4100 } else {
4101 assign(op1, get_gpr_dw0(r1));
4102 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004103 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4104 op1, op2));
florianf321da72012-07-21 20:32:57 +00004105 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4106 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004107 }
4108 }
4109
4110 return "cgrb";
4111}
4112
florian55085f82012-11-21 00:36:55 +00004113static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004114s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4115{
4116 IRTemp op1 = newTemp(Ity_I32);
4117 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004118 IRTemp cond = newTemp(Ity_I32);
4119
4120 if (m3 == 0) {
4121 } else {
4122 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004123 always_goto_and_chase(
4124 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004125 } else {
4126 assign(op1, get_gpr_w1(r1));
4127 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004128 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4129 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004130 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4131 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4132
4133 }
4134 }
4135
4136 return "crj";
4137}
4138
florian55085f82012-11-21 00:36:55 +00004139static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004140s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4141{
4142 IRTemp op1 = newTemp(Ity_I64);
4143 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004144 IRTemp cond = newTemp(Ity_I32);
4145
4146 if (m3 == 0) {
4147 } else {
4148 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004149 always_goto_and_chase(
4150 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004151 } else {
4152 assign(op1, get_gpr_dw0(r1));
4153 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004154 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4155 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004156 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4157 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4158
4159 }
4160 }
4161
4162 return "cgrj";
4163}
4164
florian55085f82012-11-21 00:36:55 +00004165static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004166s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4167{
4168 IRTemp op1 = newTemp(Ity_I32);
4169 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004170 IRTemp cond = newTemp(Ity_I32);
4171
4172 if (m3 == 0) {
4173 } else {
4174 if (m3 == 14) {
4175 always_goto(mkexpr(op4addr));
4176 } else {
4177 assign(op1, get_gpr_w1(r1));
4178 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004179 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4180 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004181 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4182 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004183 }
4184 }
4185
4186 return "cib";
4187}
4188
florian55085f82012-11-21 00:36:55 +00004189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004190s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4191{
4192 IRTemp op1 = newTemp(Ity_I64);
4193 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004194 IRTemp cond = newTemp(Ity_I32);
4195
4196 if (m3 == 0) {
4197 } else {
4198 if (m3 == 14) {
4199 always_goto(mkexpr(op4addr));
4200 } else {
4201 assign(op1, get_gpr_dw0(r1));
4202 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004203 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4204 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004205 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4206 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004207 }
4208 }
4209
4210 return "cgib";
4211}
4212
florian55085f82012-11-21 00:36:55 +00004213static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004214s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4215{
4216 IRTemp op1 = newTemp(Ity_I32);
4217 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004218 IRTemp cond = newTemp(Ity_I32);
4219
4220 if (m3 == 0) {
4221 } else {
4222 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004223 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004224 } else {
4225 assign(op1, get_gpr_w1(r1));
4226 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004227 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4228 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004229 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4230 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4231
4232 }
4233 }
4234
4235 return "cij";
4236}
4237
florian55085f82012-11-21 00:36:55 +00004238static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004239s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4240{
4241 IRTemp op1 = newTemp(Ity_I64);
4242 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004243 IRTemp cond = newTemp(Ity_I32);
4244
4245 if (m3 == 0) {
4246 } else {
4247 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004248 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004249 } else {
4250 assign(op1, get_gpr_dw0(r1));
4251 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004252 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4253 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004254 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4255 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4256
4257 }
4258 }
4259
4260 return "cgij";
4261}
4262
florian55085f82012-11-21 00:36:55 +00004263static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004264s390_irgen_CH(UChar r1, IRTemp op2addr)
4265{
4266 IRTemp op1 = newTemp(Ity_I32);
4267 IRTemp op2 = newTemp(Ity_I32);
4268
4269 assign(op1, get_gpr_w1(r1));
4270 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4271 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4272
4273 return "ch";
4274}
4275
florian55085f82012-11-21 00:36:55 +00004276static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004277s390_irgen_CHY(UChar r1, IRTemp op2addr)
4278{
4279 IRTemp op1 = newTemp(Ity_I32);
4280 IRTemp op2 = newTemp(Ity_I32);
4281
4282 assign(op1, get_gpr_w1(r1));
4283 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4284 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4285
4286 return "chy";
4287}
4288
florian55085f82012-11-21 00:36:55 +00004289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004290s390_irgen_CGH(UChar r1, IRTemp op2addr)
4291{
4292 IRTemp op1 = newTemp(Ity_I64);
4293 IRTemp op2 = newTemp(Ity_I64);
4294
4295 assign(op1, get_gpr_dw0(r1));
4296 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4297 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4298
4299 return "cgh";
4300}
4301
florian55085f82012-11-21 00:36:55 +00004302static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004303s390_irgen_CHI(UChar r1, UShort i2)
4304{
4305 IRTemp op1 = newTemp(Ity_I32);
4306 Int op2;
4307
4308 assign(op1, get_gpr_w1(r1));
4309 op2 = (Int)(Short)i2;
4310 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4311 mkU32((UInt)op2)));
4312
4313 return "chi";
4314}
4315
florian55085f82012-11-21 00:36:55 +00004316static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004317s390_irgen_CGHI(UChar r1, UShort i2)
4318{
4319 IRTemp op1 = newTemp(Ity_I64);
4320 Long op2;
4321
4322 assign(op1, get_gpr_dw0(r1));
4323 op2 = (Long)(Short)i2;
4324 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4325 mkU64((ULong)op2)));
4326
4327 return "cghi";
4328}
4329
florian55085f82012-11-21 00:36:55 +00004330static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004331s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4332{
4333 IRTemp op1 = newTemp(Ity_I16);
4334 Short op2;
4335
4336 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4337 op2 = (Short)i2;
4338 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4339 mkU16((UShort)op2)));
4340
4341 return "chhsi";
4342}
4343
florian55085f82012-11-21 00:36:55 +00004344static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004345s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4346{
4347 IRTemp op1 = newTemp(Ity_I32);
4348 Int op2;
4349
4350 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4351 op2 = (Int)(Short)i2;
4352 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4353 mkU32((UInt)op2)));
4354
4355 return "chsi";
4356}
4357
florian55085f82012-11-21 00:36:55 +00004358static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004359s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4360{
4361 IRTemp op1 = newTemp(Ity_I64);
4362 Long op2;
4363
4364 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4365 op2 = (Long)(Short)i2;
4366 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4367 mkU64((ULong)op2)));
4368
4369 return "cghsi";
4370}
4371
florian55085f82012-11-21 00:36:55 +00004372static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004373s390_irgen_CHRL(UChar r1, UInt i2)
4374{
4375 IRTemp op1 = newTemp(Ity_I32);
4376 IRTemp op2 = newTemp(Ity_I32);
4377
4378 assign(op1, get_gpr_w1(r1));
4379 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4380 ((ULong)(Long)(Int)i2 << 1)))));
4381 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4382
4383 return "chrl";
4384}
4385
florian55085f82012-11-21 00:36:55 +00004386static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004387s390_irgen_CGHRL(UChar r1, UInt i2)
4388{
4389 IRTemp op1 = newTemp(Ity_I64);
4390 IRTemp op2 = newTemp(Ity_I64);
4391
4392 assign(op1, get_gpr_dw0(r1));
4393 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4394 ((ULong)(Long)(Int)i2 << 1)))));
4395 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4396
4397 return "cghrl";
4398}
4399
florian55085f82012-11-21 00:36:55 +00004400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004401s390_irgen_CHHR(UChar r1, UChar r2)
4402{
4403 IRTemp op1 = newTemp(Ity_I32);
4404 IRTemp op2 = newTemp(Ity_I32);
4405
4406 assign(op1, get_gpr_w0(r1));
4407 assign(op2, get_gpr_w0(r2));
4408 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4409
4410 return "chhr";
4411}
4412
florian55085f82012-11-21 00:36:55 +00004413static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004414s390_irgen_CHLR(UChar r1, UChar r2)
4415{
4416 IRTemp op1 = newTemp(Ity_I32);
4417 IRTemp op2 = newTemp(Ity_I32);
4418
4419 assign(op1, get_gpr_w0(r1));
4420 assign(op2, get_gpr_w1(r2));
4421 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4422
4423 return "chlr";
4424}
4425
florian55085f82012-11-21 00:36:55 +00004426static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004427s390_irgen_CHF(UChar r1, IRTemp op2addr)
4428{
4429 IRTemp op1 = newTemp(Ity_I32);
4430 IRTemp op2 = newTemp(Ity_I32);
4431
4432 assign(op1, get_gpr_w0(r1));
4433 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4434 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4435
4436 return "chf";
4437}
4438
florian55085f82012-11-21 00:36:55 +00004439static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004440s390_irgen_CIH(UChar r1, UInt i2)
4441{
4442 IRTemp op1 = newTemp(Ity_I32);
4443 Int op2;
4444
4445 assign(op1, get_gpr_w0(r1));
4446 op2 = (Int)i2;
4447 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4448 mkU32((UInt)op2)));
4449
4450 return "cih";
4451}
4452
florian55085f82012-11-21 00:36:55 +00004453static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004454s390_irgen_CLR(UChar r1, UChar r2)
4455{
4456 IRTemp op1 = newTemp(Ity_I32);
4457 IRTemp op2 = newTemp(Ity_I32);
4458
4459 assign(op1, get_gpr_w1(r1));
4460 assign(op2, get_gpr_w1(r2));
4461 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4462
4463 return "clr";
4464}
4465
florian55085f82012-11-21 00:36:55 +00004466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004467s390_irgen_CLGR(UChar r1, UChar r2)
4468{
4469 IRTemp op1 = newTemp(Ity_I64);
4470 IRTemp op2 = newTemp(Ity_I64);
4471
4472 assign(op1, get_gpr_dw0(r1));
4473 assign(op2, get_gpr_dw0(r2));
4474 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4475
4476 return "clgr";
4477}
4478
florian55085f82012-11-21 00:36:55 +00004479static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004480s390_irgen_CLGFR(UChar r1, UChar r2)
4481{
4482 IRTemp op1 = newTemp(Ity_I64);
4483 IRTemp op2 = newTemp(Ity_I64);
4484
4485 assign(op1, get_gpr_dw0(r1));
4486 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4487 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4488
4489 return "clgfr";
4490}
4491
florian55085f82012-11-21 00:36:55 +00004492static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004493s390_irgen_CL(UChar r1, IRTemp op2addr)
4494{
4495 IRTemp op1 = newTemp(Ity_I32);
4496 IRTemp op2 = newTemp(Ity_I32);
4497
4498 assign(op1, get_gpr_w1(r1));
4499 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4500 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4501
4502 return "cl";
4503}
4504
florian55085f82012-11-21 00:36:55 +00004505static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004506s390_irgen_CLY(UChar r1, IRTemp op2addr)
4507{
4508 IRTemp op1 = newTemp(Ity_I32);
4509 IRTemp op2 = newTemp(Ity_I32);
4510
4511 assign(op1, get_gpr_w1(r1));
4512 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4513 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4514
4515 return "cly";
4516}
4517
florian55085f82012-11-21 00:36:55 +00004518static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004519s390_irgen_CLG(UChar r1, IRTemp op2addr)
4520{
4521 IRTemp op1 = newTemp(Ity_I64);
4522 IRTemp op2 = newTemp(Ity_I64);
4523
4524 assign(op1, get_gpr_dw0(r1));
4525 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4526 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4527
4528 return "clg";
4529}
4530
florian55085f82012-11-21 00:36:55 +00004531static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004532s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4533{
4534 IRTemp op1 = newTemp(Ity_I64);
4535 IRTemp op2 = newTemp(Ity_I64);
4536
4537 assign(op1, get_gpr_dw0(r1));
4538 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4539 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4540
4541 return "clgf";
4542}
4543
florian55085f82012-11-21 00:36:55 +00004544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004545s390_irgen_CLFI(UChar r1, UInt i2)
4546{
4547 IRTemp op1 = newTemp(Ity_I32);
4548 UInt op2;
4549
4550 assign(op1, get_gpr_w1(r1));
4551 op2 = i2;
4552 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4553 mkU32(op2)));
4554
4555 return "clfi";
4556}
4557
florian55085f82012-11-21 00:36:55 +00004558static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004559s390_irgen_CLGFI(UChar r1, UInt i2)
4560{
4561 IRTemp op1 = newTemp(Ity_I64);
4562 ULong op2;
4563
4564 assign(op1, get_gpr_dw0(r1));
4565 op2 = (ULong)i2;
4566 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4567 mkU64(op2)));
4568
4569 return "clgfi";
4570}
4571
florian55085f82012-11-21 00:36:55 +00004572static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004573s390_irgen_CLI(UChar i2, IRTemp op1addr)
4574{
4575 IRTemp op1 = newTemp(Ity_I8);
4576 UChar op2;
4577
4578 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4579 op2 = i2;
4580 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4581 mkU8(op2)));
4582
4583 return "cli";
4584}
4585
florian55085f82012-11-21 00:36:55 +00004586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004587s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4588{
4589 IRTemp op1 = newTemp(Ity_I8);
4590 UChar op2;
4591
4592 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4593 op2 = i2;
4594 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4595 mkU8(op2)));
4596
4597 return "cliy";
4598}
4599
florian55085f82012-11-21 00:36:55 +00004600static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004601s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4602{
4603 IRTemp op1 = newTemp(Ity_I32);
4604 UInt op2;
4605
4606 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4607 op2 = (UInt)i2;
4608 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4609 mkU32(op2)));
4610
4611 return "clfhsi";
4612}
4613
florian55085f82012-11-21 00:36:55 +00004614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004615s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4616{
4617 IRTemp op1 = newTemp(Ity_I64);
4618 ULong op2;
4619
4620 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4621 op2 = (ULong)i2;
4622 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4623 mkU64(op2)));
4624
4625 return "clghsi";
4626}
4627
florian55085f82012-11-21 00:36:55 +00004628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004629s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4630{
4631 IRTemp op1 = newTemp(Ity_I16);
4632 UShort op2;
4633
4634 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4635 op2 = i2;
4636 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4637 mkU16(op2)));
4638
4639 return "clhhsi";
4640}
4641
florian55085f82012-11-21 00:36:55 +00004642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004643s390_irgen_CLRL(UChar r1, UInt i2)
4644{
4645 IRTemp op1 = newTemp(Ity_I32);
4646 IRTemp op2 = newTemp(Ity_I32);
4647
4648 assign(op1, get_gpr_w1(r1));
4649 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4650 i2 << 1))));
4651 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4652
4653 return "clrl";
4654}
4655
florian55085f82012-11-21 00:36:55 +00004656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004657s390_irgen_CLGRL(UChar r1, UInt i2)
4658{
4659 IRTemp op1 = newTemp(Ity_I64);
4660 IRTemp op2 = newTemp(Ity_I64);
4661
4662 assign(op1, get_gpr_dw0(r1));
4663 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4664 i2 << 1))));
4665 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4666
4667 return "clgrl";
4668}
4669
florian55085f82012-11-21 00:36:55 +00004670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004671s390_irgen_CLGFRL(UChar r1, UInt i2)
4672{
4673 IRTemp op1 = newTemp(Ity_I64);
4674 IRTemp op2 = newTemp(Ity_I64);
4675
4676 assign(op1, get_gpr_dw0(r1));
4677 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4678 ((ULong)(Long)(Int)i2 << 1)))));
4679 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4680
4681 return "clgfrl";
4682}
4683
florian55085f82012-11-21 00:36:55 +00004684static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004685s390_irgen_CLHRL(UChar r1, UInt i2)
4686{
4687 IRTemp op1 = newTemp(Ity_I32);
4688 IRTemp op2 = newTemp(Ity_I32);
4689
4690 assign(op1, get_gpr_w1(r1));
4691 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4692 ((ULong)(Long)(Int)i2 << 1)))));
4693 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4694
4695 return "clhrl";
4696}
4697
florian55085f82012-11-21 00:36:55 +00004698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004699s390_irgen_CLGHRL(UChar r1, UInt i2)
4700{
4701 IRTemp op1 = newTemp(Ity_I64);
4702 IRTemp op2 = newTemp(Ity_I64);
4703
4704 assign(op1, get_gpr_dw0(r1));
4705 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4706 ((ULong)(Long)(Int)i2 << 1)))));
4707 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4708
4709 return "clghrl";
4710}
4711
florian55085f82012-11-21 00:36:55 +00004712static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004713s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4714{
4715 IRTemp op1 = newTemp(Ity_I32);
4716 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004717 IRTemp cond = newTemp(Ity_I32);
4718
4719 if (m3 == 0) {
4720 } else {
4721 if (m3 == 14) {
4722 always_goto(mkexpr(op4addr));
4723 } else {
4724 assign(op1, get_gpr_w1(r1));
4725 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004726 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4727 op1, op2));
florianf321da72012-07-21 20:32:57 +00004728 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4729 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004730 }
4731 }
4732
4733 return "clrb";
4734}
4735
florian55085f82012-11-21 00:36:55 +00004736static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004737s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4738{
4739 IRTemp op1 = newTemp(Ity_I64);
4740 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004741 IRTemp cond = newTemp(Ity_I32);
4742
4743 if (m3 == 0) {
4744 } else {
4745 if (m3 == 14) {
4746 always_goto(mkexpr(op4addr));
4747 } else {
4748 assign(op1, get_gpr_dw0(r1));
4749 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004750 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4751 op1, op2));
florianf321da72012-07-21 20:32:57 +00004752 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4753 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004754 }
4755 }
4756
4757 return "clgrb";
4758}
4759
florian55085f82012-11-21 00:36:55 +00004760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004761s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4762{
4763 IRTemp op1 = newTemp(Ity_I32);
4764 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004765 IRTemp cond = newTemp(Ity_I32);
4766
4767 if (m3 == 0) {
4768 } else {
4769 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004770 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004771 } else {
4772 assign(op1, get_gpr_w1(r1));
4773 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004774 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4775 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004776 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4777 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4778
4779 }
4780 }
4781
4782 return "clrj";
4783}
4784
florian55085f82012-11-21 00:36:55 +00004785static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004786s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4787{
4788 IRTemp op1 = newTemp(Ity_I64);
4789 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004790 IRTemp cond = newTemp(Ity_I32);
4791
4792 if (m3 == 0) {
4793 } else {
4794 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004795 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004796 } else {
4797 assign(op1, get_gpr_dw0(r1));
4798 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004799 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4800 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004801 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4802 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4803
4804 }
4805 }
4806
4807 return "clgrj";
4808}
4809
florian55085f82012-11-21 00:36:55 +00004810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004811s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4812{
4813 IRTemp op1 = newTemp(Ity_I32);
4814 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004815 IRTemp cond = newTemp(Ity_I32);
4816
4817 if (m3 == 0) {
4818 } else {
4819 if (m3 == 14) {
4820 always_goto(mkexpr(op4addr));
4821 } else {
4822 assign(op1, get_gpr_w1(r1));
4823 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004824 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4825 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004826 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4827 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004828 }
4829 }
4830
4831 return "clib";
4832}
4833
florian55085f82012-11-21 00:36:55 +00004834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004835s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4836{
4837 IRTemp op1 = newTemp(Ity_I64);
4838 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004839 IRTemp cond = newTemp(Ity_I32);
4840
4841 if (m3 == 0) {
4842 } else {
4843 if (m3 == 14) {
4844 always_goto(mkexpr(op4addr));
4845 } else {
4846 assign(op1, get_gpr_dw0(r1));
4847 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004848 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4849 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004850 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4851 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004852 }
4853 }
4854
4855 return "clgib";
4856}
4857
florian55085f82012-11-21 00:36:55 +00004858static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004859s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4860{
4861 IRTemp op1 = newTemp(Ity_I32);
4862 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004863 IRTemp cond = newTemp(Ity_I32);
4864
4865 if (m3 == 0) {
4866 } else {
4867 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004868 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004869 } else {
4870 assign(op1, get_gpr_w1(r1));
4871 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004872 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4873 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004874 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4875 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4876
4877 }
4878 }
4879
4880 return "clij";
4881}
4882
florian55085f82012-11-21 00:36:55 +00004883static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004884s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4885{
4886 IRTemp op1 = newTemp(Ity_I64);
4887 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004888 IRTemp cond = newTemp(Ity_I32);
4889
4890 if (m3 == 0) {
4891 } else {
4892 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004893 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004894 } else {
4895 assign(op1, get_gpr_dw0(r1));
4896 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004897 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4898 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004899 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4900 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4901
4902 }
4903 }
4904
4905 return "clgij";
4906}
4907
florian55085f82012-11-21 00:36:55 +00004908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004909s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4910{
4911 IRTemp op1 = newTemp(Ity_I32);
4912 IRTemp op2 = newTemp(Ity_I32);
4913 IRTemp b0 = newTemp(Ity_I32);
4914 IRTemp b1 = newTemp(Ity_I32);
4915 IRTemp b2 = newTemp(Ity_I32);
4916 IRTemp b3 = newTemp(Ity_I32);
4917 IRTemp c0 = newTemp(Ity_I32);
4918 IRTemp c1 = newTemp(Ity_I32);
4919 IRTemp c2 = newTemp(Ity_I32);
4920 IRTemp c3 = newTemp(Ity_I32);
4921 UChar n;
4922
4923 n = 0;
4924 if ((r3 & 8) != 0) {
4925 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4926 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4927 n = n + 1;
4928 } else {
4929 assign(b0, mkU32(0));
4930 assign(c0, mkU32(0));
4931 }
4932 if ((r3 & 4) != 0) {
4933 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4934 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4935 mkU64(n)))));
4936 n = n + 1;
4937 } else {
4938 assign(b1, mkU32(0));
4939 assign(c1, mkU32(0));
4940 }
4941 if ((r3 & 2) != 0) {
4942 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4943 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4944 mkU64(n)))));
4945 n = n + 1;
4946 } else {
4947 assign(b2, mkU32(0));
4948 assign(c2, mkU32(0));
4949 }
4950 if ((r3 & 1) != 0) {
4951 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4952 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4953 mkU64(n)))));
4954 n = n + 1;
4955 } else {
4956 assign(b3, mkU32(0));
4957 assign(c3, mkU32(0));
4958 }
4959 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4960 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4961 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4962 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4963 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4964 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4965 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4966
4967 return "clm";
4968}
4969
florian55085f82012-11-21 00:36:55 +00004970static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004971s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4972{
4973 IRTemp op1 = newTemp(Ity_I32);
4974 IRTemp op2 = newTemp(Ity_I32);
4975 IRTemp b0 = newTemp(Ity_I32);
4976 IRTemp b1 = newTemp(Ity_I32);
4977 IRTemp b2 = newTemp(Ity_I32);
4978 IRTemp b3 = newTemp(Ity_I32);
4979 IRTemp c0 = newTemp(Ity_I32);
4980 IRTemp c1 = newTemp(Ity_I32);
4981 IRTemp c2 = newTemp(Ity_I32);
4982 IRTemp c3 = newTemp(Ity_I32);
4983 UChar n;
4984
4985 n = 0;
4986 if ((r3 & 8) != 0) {
4987 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4988 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4989 n = n + 1;
4990 } else {
4991 assign(b0, mkU32(0));
4992 assign(c0, mkU32(0));
4993 }
4994 if ((r3 & 4) != 0) {
4995 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4996 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4997 mkU64(n)))));
4998 n = n + 1;
4999 } else {
5000 assign(b1, mkU32(0));
5001 assign(c1, mkU32(0));
5002 }
5003 if ((r3 & 2) != 0) {
5004 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
5005 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5006 mkU64(n)))));
5007 n = n + 1;
5008 } else {
5009 assign(b2, mkU32(0));
5010 assign(c2, mkU32(0));
5011 }
5012 if ((r3 & 1) != 0) {
5013 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
5014 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5015 mkU64(n)))));
5016 n = n + 1;
5017 } else {
5018 assign(b3, mkU32(0));
5019 assign(c3, mkU32(0));
5020 }
5021 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5022 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5023 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5024 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5025 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5026 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5027 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5028
5029 return "clmy";
5030}
5031
florian55085f82012-11-21 00:36:55 +00005032static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005033s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5034{
5035 IRTemp op1 = newTemp(Ity_I32);
5036 IRTemp op2 = newTemp(Ity_I32);
5037 IRTemp b0 = newTemp(Ity_I32);
5038 IRTemp b1 = newTemp(Ity_I32);
5039 IRTemp b2 = newTemp(Ity_I32);
5040 IRTemp b3 = newTemp(Ity_I32);
5041 IRTemp c0 = newTemp(Ity_I32);
5042 IRTemp c1 = newTemp(Ity_I32);
5043 IRTemp c2 = newTemp(Ity_I32);
5044 IRTemp c3 = newTemp(Ity_I32);
5045 UChar n;
5046
5047 n = 0;
5048 if ((r3 & 8) != 0) {
5049 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5050 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5051 n = n + 1;
5052 } else {
5053 assign(b0, mkU32(0));
5054 assign(c0, mkU32(0));
5055 }
5056 if ((r3 & 4) != 0) {
5057 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5058 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5059 mkU64(n)))));
5060 n = n + 1;
5061 } else {
5062 assign(b1, mkU32(0));
5063 assign(c1, mkU32(0));
5064 }
5065 if ((r3 & 2) != 0) {
5066 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5067 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5068 mkU64(n)))));
5069 n = n + 1;
5070 } else {
5071 assign(b2, mkU32(0));
5072 assign(c2, mkU32(0));
5073 }
5074 if ((r3 & 1) != 0) {
5075 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5076 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5077 mkU64(n)))));
5078 n = n + 1;
5079 } else {
5080 assign(b3, mkU32(0));
5081 assign(c3, mkU32(0));
5082 }
5083 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5084 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5085 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5086 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5087 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5088 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5089 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5090
5091 return "clmh";
5092}
5093
florian55085f82012-11-21 00:36:55 +00005094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005095s390_irgen_CLHHR(UChar r1, UChar r2)
5096{
5097 IRTemp op1 = newTemp(Ity_I32);
5098 IRTemp op2 = newTemp(Ity_I32);
5099
5100 assign(op1, get_gpr_w0(r1));
5101 assign(op2, get_gpr_w0(r2));
5102 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5103
5104 return "clhhr";
5105}
5106
florian55085f82012-11-21 00:36:55 +00005107static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005108s390_irgen_CLHLR(UChar r1, UChar r2)
5109{
5110 IRTemp op1 = newTemp(Ity_I32);
5111 IRTemp op2 = newTemp(Ity_I32);
5112
5113 assign(op1, get_gpr_w0(r1));
5114 assign(op2, get_gpr_w1(r2));
5115 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5116
5117 return "clhlr";
5118}
5119
florian55085f82012-11-21 00:36:55 +00005120static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005121s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5122{
5123 IRTemp op1 = newTemp(Ity_I32);
5124 IRTemp op2 = newTemp(Ity_I32);
5125
5126 assign(op1, get_gpr_w0(r1));
5127 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5128 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5129
5130 return "clhf";
5131}
5132
florian55085f82012-11-21 00:36:55 +00005133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005134s390_irgen_CLIH(UChar r1, UInt i2)
5135{
5136 IRTemp op1 = newTemp(Ity_I32);
5137 UInt op2;
5138
5139 assign(op1, get_gpr_w0(r1));
5140 op2 = i2;
5141 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5142 mkU32(op2)));
5143
5144 return "clih";
5145}
5146
florian55085f82012-11-21 00:36:55 +00005147static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005148s390_irgen_CPYA(UChar r1, UChar r2)
5149{
5150 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005151 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005152 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5153
5154 return "cpya";
5155}
5156
florian55085f82012-11-21 00:36:55 +00005157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005158s390_irgen_XR(UChar r1, UChar r2)
5159{
5160 IRTemp op1 = newTemp(Ity_I32);
5161 IRTemp op2 = newTemp(Ity_I32);
5162 IRTemp result = newTemp(Ity_I32);
5163
5164 if (r1 == r2) {
5165 assign(result, mkU32(0));
5166 } else {
5167 assign(op1, get_gpr_w1(r1));
5168 assign(op2, get_gpr_w1(r2));
5169 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5170 }
5171 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5172 put_gpr_w1(r1, mkexpr(result));
5173
5174 return "xr";
5175}
5176
florian55085f82012-11-21 00:36:55 +00005177static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005178s390_irgen_XGR(UChar r1, UChar r2)
5179{
5180 IRTemp op1 = newTemp(Ity_I64);
5181 IRTemp op2 = newTemp(Ity_I64);
5182 IRTemp result = newTemp(Ity_I64);
5183
5184 if (r1 == r2) {
5185 assign(result, mkU64(0));
5186 } else {
5187 assign(op1, get_gpr_dw0(r1));
5188 assign(op2, get_gpr_dw0(r2));
5189 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5190 }
5191 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5192 put_gpr_dw0(r1, mkexpr(result));
5193
5194 return "xgr";
5195}
5196
florian55085f82012-11-21 00:36:55 +00005197static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005198s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5199{
5200 IRTemp op2 = newTemp(Ity_I32);
5201 IRTemp op3 = newTemp(Ity_I32);
5202 IRTemp result = newTemp(Ity_I32);
5203
5204 assign(op2, get_gpr_w1(r2));
5205 assign(op3, get_gpr_w1(r3));
5206 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5207 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5208 put_gpr_w1(r1, mkexpr(result));
5209
5210 return "xrk";
5211}
5212
florian55085f82012-11-21 00:36:55 +00005213static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005214s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5215{
5216 IRTemp op2 = newTemp(Ity_I64);
5217 IRTemp op3 = newTemp(Ity_I64);
5218 IRTemp result = newTemp(Ity_I64);
5219
5220 assign(op2, get_gpr_dw0(r2));
5221 assign(op3, get_gpr_dw0(r3));
5222 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5223 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5224 put_gpr_dw0(r1, mkexpr(result));
5225
5226 return "xgrk";
5227}
5228
florian55085f82012-11-21 00:36:55 +00005229static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005230s390_irgen_X(UChar r1, IRTemp op2addr)
5231{
5232 IRTemp op1 = newTemp(Ity_I32);
5233 IRTemp op2 = newTemp(Ity_I32);
5234 IRTemp result = newTemp(Ity_I32);
5235
5236 assign(op1, get_gpr_w1(r1));
5237 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5238 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5239 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5240 put_gpr_w1(r1, mkexpr(result));
5241
5242 return "x";
5243}
5244
florian55085f82012-11-21 00:36:55 +00005245static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005246s390_irgen_XY(UChar r1, IRTemp op2addr)
5247{
5248 IRTemp op1 = newTemp(Ity_I32);
5249 IRTemp op2 = newTemp(Ity_I32);
5250 IRTemp result = newTemp(Ity_I32);
5251
5252 assign(op1, get_gpr_w1(r1));
5253 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5254 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5255 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5256 put_gpr_w1(r1, mkexpr(result));
5257
5258 return "xy";
5259}
5260
florian55085f82012-11-21 00:36:55 +00005261static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005262s390_irgen_XG(UChar r1, IRTemp op2addr)
5263{
5264 IRTemp op1 = newTemp(Ity_I64);
5265 IRTemp op2 = newTemp(Ity_I64);
5266 IRTemp result = newTemp(Ity_I64);
5267
5268 assign(op1, get_gpr_dw0(r1));
5269 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5270 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5271 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5272 put_gpr_dw0(r1, mkexpr(result));
5273
5274 return "xg";
5275}
5276
florian55085f82012-11-21 00:36:55 +00005277static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005278s390_irgen_XI(UChar i2, IRTemp op1addr)
5279{
5280 IRTemp op1 = newTemp(Ity_I8);
5281 UChar op2;
5282 IRTemp result = newTemp(Ity_I8);
5283
5284 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5285 op2 = i2;
5286 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5287 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5288 store(mkexpr(op1addr), mkexpr(result));
5289
5290 return "xi";
5291}
5292
florian55085f82012-11-21 00:36:55 +00005293static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005294s390_irgen_XIY(UChar i2, IRTemp op1addr)
5295{
5296 IRTemp op1 = newTemp(Ity_I8);
5297 UChar op2;
5298 IRTemp result = newTemp(Ity_I8);
5299
5300 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5301 op2 = i2;
5302 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5303 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5304 store(mkexpr(op1addr), mkexpr(result));
5305
5306 return "xiy";
5307}
5308
florian55085f82012-11-21 00:36:55 +00005309static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005310s390_irgen_XIHF(UChar r1, UInt i2)
5311{
5312 IRTemp op1 = newTemp(Ity_I32);
5313 UInt op2;
5314 IRTemp result = newTemp(Ity_I32);
5315
5316 assign(op1, get_gpr_w0(r1));
5317 op2 = i2;
5318 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5319 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5320 put_gpr_w0(r1, mkexpr(result));
5321
5322 return "xihf";
5323}
5324
florian55085f82012-11-21 00:36:55 +00005325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005326s390_irgen_XILF(UChar r1, UInt i2)
5327{
5328 IRTemp op1 = newTemp(Ity_I32);
5329 UInt op2;
5330 IRTemp result = newTemp(Ity_I32);
5331
5332 assign(op1, get_gpr_w1(r1));
5333 op2 = i2;
5334 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5335 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5336 put_gpr_w1(r1, mkexpr(result));
5337
5338 return "xilf";
5339}
5340
florian55085f82012-11-21 00:36:55 +00005341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005342s390_irgen_EAR(UChar r1, UChar r2)
5343{
5344 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005345 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005346 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5347
5348 return "ear";
5349}
5350
florian55085f82012-11-21 00:36:55 +00005351static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005352s390_irgen_IC(UChar r1, IRTemp op2addr)
5353{
5354 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5355
5356 return "ic";
5357}
5358
florian55085f82012-11-21 00:36:55 +00005359static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005360s390_irgen_ICY(UChar r1, IRTemp op2addr)
5361{
5362 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5363
5364 return "icy";
5365}
5366
florian55085f82012-11-21 00:36:55 +00005367static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005368s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5369{
5370 UChar n;
5371 IRTemp result = newTemp(Ity_I32);
5372 UInt mask;
5373
5374 n = 0;
5375 mask = (UInt)r3;
5376 if ((mask & 8) != 0) {
5377 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5378 n = n + 1;
5379 }
5380 if ((mask & 4) != 0) {
5381 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5382
5383 n = n + 1;
5384 }
5385 if ((mask & 2) != 0) {
5386 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5387
5388 n = n + 1;
5389 }
5390 if ((mask & 1) != 0) {
5391 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5392
5393 n = n + 1;
5394 }
5395 assign(result, get_gpr_w1(r1));
5396 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5397 mkU32(mask)));
5398
5399 return "icm";
5400}
5401
florian55085f82012-11-21 00:36:55 +00005402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005403s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5404{
5405 UChar n;
5406 IRTemp result = newTemp(Ity_I32);
5407 UInt mask;
5408
5409 n = 0;
5410 mask = (UInt)r3;
5411 if ((mask & 8) != 0) {
5412 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5413 n = n + 1;
5414 }
5415 if ((mask & 4) != 0) {
5416 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5417
5418 n = n + 1;
5419 }
5420 if ((mask & 2) != 0) {
5421 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5422
5423 n = n + 1;
5424 }
5425 if ((mask & 1) != 0) {
5426 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5427
5428 n = n + 1;
5429 }
5430 assign(result, get_gpr_w1(r1));
5431 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5432 mkU32(mask)));
5433
5434 return "icmy";
5435}
5436
florian55085f82012-11-21 00:36:55 +00005437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005438s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5439{
5440 UChar n;
5441 IRTemp result = newTemp(Ity_I32);
5442 UInt mask;
5443
5444 n = 0;
5445 mask = (UInt)r3;
5446 if ((mask & 8) != 0) {
5447 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5448 n = n + 1;
5449 }
5450 if ((mask & 4) != 0) {
5451 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5452
5453 n = n + 1;
5454 }
5455 if ((mask & 2) != 0) {
5456 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5457
5458 n = n + 1;
5459 }
5460 if ((mask & 1) != 0) {
5461 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5462
5463 n = n + 1;
5464 }
5465 assign(result, get_gpr_w0(r1));
5466 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5467 mkU32(mask)));
5468
5469 return "icmh";
5470}
5471
florian55085f82012-11-21 00:36:55 +00005472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005473s390_irgen_IIHF(UChar r1, UInt i2)
5474{
5475 put_gpr_w0(r1, mkU32(i2));
5476
5477 return "iihf";
5478}
5479
florian55085f82012-11-21 00:36:55 +00005480static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005481s390_irgen_IIHH(UChar r1, UShort i2)
5482{
5483 put_gpr_hw0(r1, mkU16(i2));
5484
5485 return "iihh";
5486}
5487
florian55085f82012-11-21 00:36:55 +00005488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005489s390_irgen_IIHL(UChar r1, UShort i2)
5490{
5491 put_gpr_hw1(r1, mkU16(i2));
5492
5493 return "iihl";
5494}
5495
florian55085f82012-11-21 00:36:55 +00005496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005497s390_irgen_IILF(UChar r1, UInt i2)
5498{
5499 put_gpr_w1(r1, mkU32(i2));
5500
5501 return "iilf";
5502}
5503
florian55085f82012-11-21 00:36:55 +00005504static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005505s390_irgen_IILH(UChar r1, UShort i2)
5506{
5507 put_gpr_hw2(r1, mkU16(i2));
5508
5509 return "iilh";
5510}
5511
florian55085f82012-11-21 00:36:55 +00005512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005513s390_irgen_IILL(UChar r1, UShort i2)
5514{
5515 put_gpr_hw3(r1, mkU16(i2));
5516
5517 return "iill";
5518}
5519
florian55085f82012-11-21 00:36:55 +00005520static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005521s390_irgen_LR(UChar r1, UChar r2)
5522{
5523 put_gpr_w1(r1, get_gpr_w1(r2));
5524
5525 return "lr";
5526}
5527
florian55085f82012-11-21 00:36:55 +00005528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005529s390_irgen_LGR(UChar r1, UChar r2)
5530{
5531 put_gpr_dw0(r1, get_gpr_dw0(r2));
5532
5533 return "lgr";
5534}
5535
florian55085f82012-11-21 00:36:55 +00005536static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005537s390_irgen_LGFR(UChar r1, UChar r2)
5538{
5539 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5540
5541 return "lgfr";
5542}
5543
florian55085f82012-11-21 00:36:55 +00005544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005545s390_irgen_L(UChar r1, IRTemp op2addr)
5546{
5547 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5548
5549 return "l";
5550}
5551
florian55085f82012-11-21 00:36:55 +00005552static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005553s390_irgen_LY(UChar r1, IRTemp op2addr)
5554{
5555 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5556
5557 return "ly";
5558}
5559
florian55085f82012-11-21 00:36:55 +00005560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005561s390_irgen_LG(UChar r1, IRTemp op2addr)
5562{
5563 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5564
5565 return "lg";
5566}
5567
florian55085f82012-11-21 00:36:55 +00005568static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005569s390_irgen_LGF(UChar r1, IRTemp op2addr)
5570{
5571 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5572
5573 return "lgf";
5574}
5575
florian55085f82012-11-21 00:36:55 +00005576static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005577s390_irgen_LGFI(UChar r1, UInt i2)
5578{
5579 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5580
5581 return "lgfi";
5582}
5583
florian55085f82012-11-21 00:36:55 +00005584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005585s390_irgen_LRL(UChar r1, UInt i2)
5586{
5587 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5588 i2 << 1))));
5589
5590 return "lrl";
5591}
5592
florian55085f82012-11-21 00:36:55 +00005593static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005594s390_irgen_LGRL(UChar r1, UInt i2)
5595{
5596 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5597 i2 << 1))));
5598
5599 return "lgrl";
5600}
5601
florian55085f82012-11-21 00:36:55 +00005602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005603s390_irgen_LGFRL(UChar r1, UInt i2)
5604{
5605 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5606 ((ULong)(Long)(Int)i2 << 1)))));
5607
5608 return "lgfrl";
5609}
5610
florian55085f82012-11-21 00:36:55 +00005611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005612s390_irgen_LA(UChar r1, IRTemp op2addr)
5613{
5614 put_gpr_dw0(r1, mkexpr(op2addr));
5615
5616 return "la";
5617}
5618
florian55085f82012-11-21 00:36:55 +00005619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005620s390_irgen_LAY(UChar r1, IRTemp op2addr)
5621{
5622 put_gpr_dw0(r1, mkexpr(op2addr));
5623
5624 return "lay";
5625}
5626
florian55085f82012-11-21 00:36:55 +00005627static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005628s390_irgen_LAE(UChar r1, IRTemp op2addr)
5629{
5630 put_gpr_dw0(r1, mkexpr(op2addr));
5631
5632 return "lae";
5633}
5634
florian55085f82012-11-21 00:36:55 +00005635static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005636s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5637{
5638 put_gpr_dw0(r1, mkexpr(op2addr));
5639
5640 return "laey";
5641}
5642
florian55085f82012-11-21 00:36:55 +00005643static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005644s390_irgen_LARL(UChar r1, UInt i2)
5645{
5646 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5647
5648 return "larl";
5649}
5650
floriana265ee72012-12-02 20:58:17 +00005651/* The IR representation of LAA and friends is an approximation of what
5652 happens natively. Essentially a loop containing a compare-and-swap is
5653 constructed which will iterate until the CAS succeeds. As a consequence,
5654 instrumenters may see more memory accesses than happen natively. See also
5655 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005656static void
5657s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005658{
floriana265ee72012-12-02 20:58:17 +00005659 IRCAS *cas;
5660 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005661 IRTemp op2 = newTemp(Ity_I32);
5662 IRTemp op3 = newTemp(Ity_I32);
5663 IRTemp result = newTemp(Ity_I32);
5664
5665 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5666 assign(op3, get_gpr_w1(r3));
5667 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005668
5669 /* Place the addition of second operand and third operand at the
5670 second-operand location everytime */
5671 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5672 Iend_BE, mkexpr(op2addr),
5673 NULL, mkexpr(op2), /* expected value */
5674 NULL, mkexpr(result) /* new value */);
5675 stmt(IRStmt_CAS(cas));
5676
florianffc94012012-12-02 21:31:15 +00005677 /* Set CC according to 32-bit addition */
5678 if (is_signed) {
5679 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5680 } else {
5681 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5682 }
floriana265ee72012-12-02 20:58:17 +00005683
5684 /* If old_mem contains the expected value, then the CAS succeeded.
5685 Otherwise, it did not */
5686 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5687 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005688}
5689
5690static void
5691s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5692{
5693 IRCAS *cas;
5694 IRTemp old_mem = newTemp(Ity_I64);
5695 IRTemp op2 = newTemp(Ity_I64);
5696 IRTemp op3 = newTemp(Ity_I64);
5697 IRTemp result = newTemp(Ity_I64);
5698
5699 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5700 assign(op3, get_gpr_dw0(r3));
5701 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5702
5703 /* Place the addition of second operand and third operand at the
5704 second-operand location everytime */
5705 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5706 Iend_BE, mkexpr(op2addr),
5707 NULL, mkexpr(op2), /* expected value */
5708 NULL, mkexpr(result) /* new value */);
5709 stmt(IRStmt_CAS(cas));
5710
5711 /* Set CC according to 64-bit addition */
5712 if (is_signed) {
5713 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5714 } else {
5715 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5716 }
5717
5718 /* If old_mem contains the expected value, then the CAS succeeded.
5719 Otherwise, it did not */
5720 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5721 put_gpr_dw0(r1, mkexpr(old_mem));
5722}
5723
5724static void
5725s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5726{
5727 IRCAS *cas;
5728 IRTemp old_mem = newTemp(Ity_I32);
5729 IRTemp op2 = newTemp(Ity_I32);
5730 IRTemp op3 = newTemp(Ity_I32);
5731 IRTemp result = newTemp(Ity_I32);
5732
5733 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5734 assign(op3, get_gpr_w1(r3));
5735 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5736
5737 /* Place the addition of second operand and third operand at the
5738 second-operand location everytime */
5739 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5740 Iend_BE, mkexpr(op2addr),
5741 NULL, mkexpr(op2), /* expected value */
5742 NULL, mkexpr(result) /* new value */);
5743 stmt(IRStmt_CAS(cas));
5744
5745 /* Set CC according to bitwise operation */
5746 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5747
5748 /* If old_mem contains the expected value, then the CAS succeeded.
5749 Otherwise, it did not */
5750 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5751 put_gpr_w1(r1, mkexpr(old_mem));
5752}
5753
5754static void
5755s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5756{
5757 IRCAS *cas;
5758 IRTemp old_mem = newTemp(Ity_I64);
5759 IRTemp op2 = newTemp(Ity_I64);
5760 IRTemp op3 = newTemp(Ity_I64);
5761 IRTemp result = newTemp(Ity_I64);
5762
5763 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5764 assign(op3, get_gpr_dw0(r3));
5765 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5766
5767 /* Place the addition of second operand and third operand at the
5768 second-operand location everytime */
5769 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5770 Iend_BE, mkexpr(op2addr),
5771 NULL, mkexpr(op2), /* expected value */
5772 NULL, mkexpr(result) /* new value */);
5773 stmt(IRStmt_CAS(cas));
5774
5775 /* Set CC according to bitwise operation */
5776 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5777
5778 /* If old_mem contains the expected value, then the CAS succeeded.
5779 Otherwise, it did not */
5780 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5781 put_gpr_dw0(r1, mkexpr(old_mem));
5782}
5783
5784static const HChar *
5785s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5786{
5787 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005788
5789 return "laa";
5790}
5791
florian55085f82012-11-21 00:36:55 +00005792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005793s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5794{
florianffc94012012-12-02 21:31:15 +00005795 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005796
5797 return "laag";
5798}
5799
florian55085f82012-11-21 00:36:55 +00005800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005801s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5802{
florianffc94012012-12-02 21:31:15 +00005803 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005804
5805 return "laal";
5806}
5807
florian55085f82012-11-21 00:36:55 +00005808static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005809s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5810{
florianffc94012012-12-02 21:31:15 +00005811 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005812
5813 return "laalg";
5814}
5815
florian55085f82012-11-21 00:36:55 +00005816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005817s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5818{
florianffc94012012-12-02 21:31:15 +00005819 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005820
5821 return "lan";
5822}
5823
florian55085f82012-11-21 00:36:55 +00005824static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005825s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5826{
florianffc94012012-12-02 21:31:15 +00005827 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005828
5829 return "lang";
5830}
5831
florian55085f82012-11-21 00:36:55 +00005832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005833s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5834{
florianffc94012012-12-02 21:31:15 +00005835 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005836
5837 return "lax";
5838}
5839
florian55085f82012-11-21 00:36:55 +00005840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005841s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5842{
florianffc94012012-12-02 21:31:15 +00005843 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005844
5845 return "laxg";
5846}
5847
florian55085f82012-11-21 00:36:55 +00005848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005849s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5850{
florianffc94012012-12-02 21:31:15 +00005851 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005852
5853 return "lao";
5854}
5855
florian55085f82012-11-21 00:36:55 +00005856static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005857s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5858{
florianffc94012012-12-02 21:31:15 +00005859 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005860
5861 return "laog";
5862}
5863
florian55085f82012-11-21 00:36:55 +00005864static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005865s390_irgen_LTR(UChar r1, UChar r2)
5866{
5867 IRTemp op2 = newTemp(Ity_I32);
5868
5869 assign(op2, get_gpr_w1(r2));
5870 put_gpr_w1(r1, mkexpr(op2));
5871 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5872
5873 return "ltr";
5874}
5875
florian55085f82012-11-21 00:36:55 +00005876static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005877s390_irgen_LTGR(UChar r1, UChar r2)
5878{
5879 IRTemp op2 = newTemp(Ity_I64);
5880
5881 assign(op2, get_gpr_dw0(r2));
5882 put_gpr_dw0(r1, mkexpr(op2));
5883 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5884
5885 return "ltgr";
5886}
5887
florian55085f82012-11-21 00:36:55 +00005888static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005889s390_irgen_LTGFR(UChar r1, UChar r2)
5890{
5891 IRTemp op2 = newTemp(Ity_I64);
5892
5893 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5894 put_gpr_dw0(r1, mkexpr(op2));
5895 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5896
5897 return "ltgfr";
5898}
5899
florian55085f82012-11-21 00:36:55 +00005900static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005901s390_irgen_LT(UChar r1, IRTemp op2addr)
5902{
5903 IRTemp op2 = newTemp(Ity_I32);
5904
5905 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5906 put_gpr_w1(r1, mkexpr(op2));
5907 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5908
5909 return "lt";
5910}
5911
florian55085f82012-11-21 00:36:55 +00005912static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005913s390_irgen_LTG(UChar r1, IRTemp op2addr)
5914{
5915 IRTemp op2 = newTemp(Ity_I64);
5916
5917 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5918 put_gpr_dw0(r1, mkexpr(op2));
5919 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5920
5921 return "ltg";
5922}
5923
florian55085f82012-11-21 00:36:55 +00005924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005925s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5926{
5927 IRTemp op2 = newTemp(Ity_I64);
5928
5929 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5930 put_gpr_dw0(r1, mkexpr(op2));
5931 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5932
5933 return "ltgf";
5934}
5935
florian55085f82012-11-21 00:36:55 +00005936static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005937s390_irgen_LBR(UChar r1, UChar r2)
5938{
5939 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5940
5941 return "lbr";
5942}
5943
florian55085f82012-11-21 00:36:55 +00005944static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005945s390_irgen_LGBR(UChar r1, UChar r2)
5946{
5947 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5948
5949 return "lgbr";
5950}
5951
florian55085f82012-11-21 00:36:55 +00005952static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005953s390_irgen_LB(UChar r1, IRTemp op2addr)
5954{
5955 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5956
5957 return "lb";
5958}
5959
florian55085f82012-11-21 00:36:55 +00005960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005961s390_irgen_LGB(UChar r1, IRTemp op2addr)
5962{
5963 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5964
5965 return "lgb";
5966}
5967
florian55085f82012-11-21 00:36:55 +00005968static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005969s390_irgen_LBH(UChar r1, IRTemp op2addr)
5970{
5971 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5972
5973 return "lbh";
5974}
5975
florian55085f82012-11-21 00:36:55 +00005976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005977s390_irgen_LCR(UChar r1, UChar r2)
5978{
5979 Int op1;
5980 IRTemp op2 = newTemp(Ity_I32);
5981 IRTemp result = newTemp(Ity_I32);
5982
5983 op1 = 0;
5984 assign(op2, get_gpr_w1(r2));
5985 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5986 put_gpr_w1(r1, mkexpr(result));
5987 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5988 op1)), op2);
5989
5990 return "lcr";
5991}
5992
florian55085f82012-11-21 00:36:55 +00005993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005994s390_irgen_LCGR(UChar r1, UChar r2)
5995{
5996 Long op1;
5997 IRTemp op2 = newTemp(Ity_I64);
5998 IRTemp result = newTemp(Ity_I64);
5999
6000 op1 = 0ULL;
6001 assign(op2, get_gpr_dw0(r2));
6002 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6003 put_gpr_dw0(r1, mkexpr(result));
6004 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6005 op1)), op2);
6006
6007 return "lcgr";
6008}
6009
florian55085f82012-11-21 00:36:55 +00006010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006011s390_irgen_LCGFR(UChar r1, UChar r2)
6012{
6013 Long op1;
6014 IRTemp op2 = newTemp(Ity_I64);
6015 IRTemp result = newTemp(Ity_I64);
6016
6017 op1 = 0ULL;
6018 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6019 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6020 put_gpr_dw0(r1, mkexpr(result));
6021 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6022 op1)), op2);
6023
6024 return "lcgfr";
6025}
6026
florian55085f82012-11-21 00:36:55 +00006027static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006028s390_irgen_LHR(UChar r1, UChar r2)
6029{
6030 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
6031
6032 return "lhr";
6033}
6034
florian55085f82012-11-21 00:36:55 +00006035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006036s390_irgen_LGHR(UChar r1, UChar r2)
6037{
6038 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6039
6040 return "lghr";
6041}
6042
florian55085f82012-11-21 00:36:55 +00006043static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006044s390_irgen_LH(UChar r1, IRTemp op2addr)
6045{
6046 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6047
6048 return "lh";
6049}
6050
florian55085f82012-11-21 00:36:55 +00006051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006052s390_irgen_LHY(UChar r1, IRTemp op2addr)
6053{
6054 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6055
6056 return "lhy";
6057}
6058
florian55085f82012-11-21 00:36:55 +00006059static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006060s390_irgen_LGH(UChar r1, IRTemp op2addr)
6061{
6062 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6063
6064 return "lgh";
6065}
6066
florian55085f82012-11-21 00:36:55 +00006067static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006068s390_irgen_LHI(UChar r1, UShort i2)
6069{
6070 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6071
6072 return "lhi";
6073}
6074
florian55085f82012-11-21 00:36:55 +00006075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006076s390_irgen_LGHI(UChar r1, UShort i2)
6077{
6078 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6079
6080 return "lghi";
6081}
6082
florian55085f82012-11-21 00:36:55 +00006083static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006084s390_irgen_LHRL(UChar r1, UInt i2)
6085{
6086 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6087 ((ULong)(Long)(Int)i2 << 1)))));
6088
6089 return "lhrl";
6090}
6091
florian55085f82012-11-21 00:36:55 +00006092static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006093s390_irgen_LGHRL(UChar r1, UInt i2)
6094{
6095 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6096 ((ULong)(Long)(Int)i2 << 1)))));
6097
6098 return "lghrl";
6099}
6100
florian55085f82012-11-21 00:36:55 +00006101static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006102s390_irgen_LHH(UChar r1, IRTemp op2addr)
6103{
6104 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6105
6106 return "lhh";
6107}
6108
florian55085f82012-11-21 00:36:55 +00006109static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006110s390_irgen_LFH(UChar r1, IRTemp op2addr)
6111{
6112 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6113
6114 return "lfh";
6115}
6116
florian55085f82012-11-21 00:36:55 +00006117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006118s390_irgen_LLGFR(UChar r1, UChar r2)
6119{
6120 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6121
6122 return "llgfr";
6123}
6124
florian55085f82012-11-21 00:36:55 +00006125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006126s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6127{
6128 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6129
6130 return "llgf";
6131}
6132
florian55085f82012-11-21 00:36:55 +00006133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006134s390_irgen_LLGFRL(UChar r1, UInt i2)
6135{
6136 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6137 ((ULong)(Long)(Int)i2 << 1)))));
6138
6139 return "llgfrl";
6140}
6141
florian55085f82012-11-21 00:36:55 +00006142static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006143s390_irgen_LLCR(UChar r1, UChar r2)
6144{
6145 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6146
6147 return "llcr";
6148}
6149
florian55085f82012-11-21 00:36:55 +00006150static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006151s390_irgen_LLGCR(UChar r1, UChar r2)
6152{
6153 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6154
6155 return "llgcr";
6156}
6157
florian55085f82012-11-21 00:36:55 +00006158static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006159s390_irgen_LLC(UChar r1, IRTemp op2addr)
6160{
6161 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6162
6163 return "llc";
6164}
6165
florian55085f82012-11-21 00:36:55 +00006166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006167s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6168{
6169 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6170
6171 return "llgc";
6172}
6173
florian55085f82012-11-21 00:36:55 +00006174static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006175s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6176{
6177 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6178
6179 return "llch";
6180}
6181
florian55085f82012-11-21 00:36:55 +00006182static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006183s390_irgen_LLHR(UChar r1, UChar r2)
6184{
6185 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6186
6187 return "llhr";
6188}
6189
florian55085f82012-11-21 00:36:55 +00006190static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006191s390_irgen_LLGHR(UChar r1, UChar r2)
6192{
6193 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6194
6195 return "llghr";
6196}
6197
florian55085f82012-11-21 00:36:55 +00006198static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006199s390_irgen_LLH(UChar r1, IRTemp op2addr)
6200{
6201 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6202
6203 return "llh";
6204}
6205
florian55085f82012-11-21 00:36:55 +00006206static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006207s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6208{
6209 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6210
6211 return "llgh";
6212}
6213
florian55085f82012-11-21 00:36:55 +00006214static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006215s390_irgen_LLHRL(UChar r1, UInt i2)
6216{
6217 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6218 ((ULong)(Long)(Int)i2 << 1)))));
6219
6220 return "llhrl";
6221}
6222
florian55085f82012-11-21 00:36:55 +00006223static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006224s390_irgen_LLGHRL(UChar r1, UInt i2)
6225{
6226 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6227 ((ULong)(Long)(Int)i2 << 1)))));
6228
6229 return "llghrl";
6230}
6231
florian55085f82012-11-21 00:36:55 +00006232static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006233s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6234{
6235 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6236
6237 return "llhh";
6238}
6239
florian55085f82012-11-21 00:36:55 +00006240static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006241s390_irgen_LLIHF(UChar r1, UInt i2)
6242{
6243 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6244
6245 return "llihf";
6246}
6247
florian55085f82012-11-21 00:36:55 +00006248static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006249s390_irgen_LLIHH(UChar r1, UShort i2)
6250{
6251 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6252
6253 return "llihh";
6254}
6255
florian55085f82012-11-21 00:36:55 +00006256static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006257s390_irgen_LLIHL(UChar r1, UShort i2)
6258{
6259 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6260
6261 return "llihl";
6262}
6263
florian55085f82012-11-21 00:36:55 +00006264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006265s390_irgen_LLILF(UChar r1, UInt i2)
6266{
6267 put_gpr_dw0(r1, mkU64(i2));
6268
6269 return "llilf";
6270}
6271
florian55085f82012-11-21 00:36:55 +00006272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006273s390_irgen_LLILH(UChar r1, UShort i2)
6274{
6275 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6276
6277 return "llilh";
6278}
6279
florian55085f82012-11-21 00:36:55 +00006280static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006281s390_irgen_LLILL(UChar r1, UShort i2)
6282{
6283 put_gpr_dw0(r1, mkU64(i2));
6284
6285 return "llill";
6286}
6287
florian55085f82012-11-21 00:36:55 +00006288static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006289s390_irgen_LLGTR(UChar r1, UChar r2)
6290{
6291 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6292 mkU32(2147483647))));
6293
6294 return "llgtr";
6295}
6296
florian55085f82012-11-21 00:36:55 +00006297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006298s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6299{
6300 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6301 mkexpr(op2addr)), mkU32(2147483647))));
6302
6303 return "llgt";
6304}
6305
florian55085f82012-11-21 00:36:55 +00006306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006307s390_irgen_LNR(UChar r1, UChar r2)
6308{
6309 IRTemp op2 = newTemp(Ity_I32);
6310 IRTemp result = newTemp(Ity_I32);
6311
6312 assign(op2, get_gpr_w1(r2));
6313 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6314 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6315 put_gpr_w1(r1, mkexpr(result));
6316 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6317
6318 return "lnr";
6319}
6320
florian55085f82012-11-21 00:36:55 +00006321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006322s390_irgen_LNGR(UChar r1, UChar r2)
6323{
6324 IRTemp op2 = newTemp(Ity_I64);
6325 IRTemp result = newTemp(Ity_I64);
6326
6327 assign(op2, get_gpr_dw0(r2));
6328 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6329 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6330 put_gpr_dw0(r1, mkexpr(result));
6331 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6332
6333 return "lngr";
6334}
6335
florian55085f82012-11-21 00:36:55 +00006336static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006337s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6338{
6339 IRTemp op2 = newTemp(Ity_I64);
6340 IRTemp result = newTemp(Ity_I64);
6341
6342 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6343 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6344 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6345 put_gpr_dw0(r1, mkexpr(result));
6346 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6347
6348 return "lngfr";
6349}
6350
florian55085f82012-11-21 00:36:55 +00006351static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006352s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6353{
florian6820ba52012-07-26 02:01:50 +00006354 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006355 put_gpr_w1(r1, get_gpr_w1(r2));
6356
6357 return "locr";
6358}
6359
florian55085f82012-11-21 00:36:55 +00006360static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006361s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6362{
florian6820ba52012-07-26 02:01:50 +00006363 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006364 put_gpr_dw0(r1, get_gpr_dw0(r2));
6365
6366 return "locgr";
6367}
6368
florian55085f82012-11-21 00:36:55 +00006369static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006370s390_irgen_LOC(UChar r1, IRTemp op2addr)
6371{
6372 /* condition is checked in format handler */
6373 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6374
6375 return "loc";
6376}
6377
florian55085f82012-11-21 00:36:55 +00006378static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006379s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6380{
6381 /* condition is checked in format handler */
6382 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6383
6384 return "locg";
6385}
6386
florian55085f82012-11-21 00:36:55 +00006387static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006388s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6389{
6390 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6391 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6392 ));
6393
6394 return "lpq";
6395}
6396
florian55085f82012-11-21 00:36:55 +00006397static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006398s390_irgen_LPR(UChar r1, UChar r2)
6399{
6400 IRTemp op2 = newTemp(Ity_I32);
6401 IRTemp result = newTemp(Ity_I32);
6402
6403 assign(op2, get_gpr_w1(r2));
6404 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6405 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6406 put_gpr_w1(r1, mkexpr(result));
6407 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6408
6409 return "lpr";
6410}
6411
florian55085f82012-11-21 00:36:55 +00006412static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006413s390_irgen_LPGR(UChar r1, UChar r2)
6414{
6415 IRTemp op2 = newTemp(Ity_I64);
6416 IRTemp result = newTemp(Ity_I64);
6417
6418 assign(op2, get_gpr_dw0(r2));
6419 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6420 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6421 put_gpr_dw0(r1, mkexpr(result));
6422 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6423
6424 return "lpgr";
6425}
6426
florian55085f82012-11-21 00:36:55 +00006427static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006428s390_irgen_LPGFR(UChar r1, UChar r2)
6429{
6430 IRTemp op2 = newTemp(Ity_I64);
6431 IRTemp result = newTemp(Ity_I64);
6432
6433 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6434 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6435 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6436 put_gpr_dw0(r1, mkexpr(result));
6437 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6438
6439 return "lpgfr";
6440}
6441
florian55085f82012-11-21 00:36:55 +00006442static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006443s390_irgen_LRVR(UChar r1, UChar r2)
6444{
6445 IRTemp b0 = newTemp(Ity_I8);
6446 IRTemp b1 = newTemp(Ity_I8);
6447 IRTemp b2 = newTemp(Ity_I8);
6448 IRTemp b3 = newTemp(Ity_I8);
6449
6450 assign(b3, get_gpr_b7(r2));
6451 assign(b2, get_gpr_b6(r2));
6452 assign(b1, get_gpr_b5(r2));
6453 assign(b0, get_gpr_b4(r2));
6454 put_gpr_b4(r1, mkexpr(b3));
6455 put_gpr_b5(r1, mkexpr(b2));
6456 put_gpr_b6(r1, mkexpr(b1));
6457 put_gpr_b7(r1, mkexpr(b0));
6458
6459 return "lrvr";
6460}
6461
florian55085f82012-11-21 00:36:55 +00006462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006463s390_irgen_LRVGR(UChar r1, UChar r2)
6464{
6465 IRTemp b0 = newTemp(Ity_I8);
6466 IRTemp b1 = newTemp(Ity_I8);
6467 IRTemp b2 = newTemp(Ity_I8);
6468 IRTemp b3 = newTemp(Ity_I8);
6469 IRTemp b4 = newTemp(Ity_I8);
6470 IRTemp b5 = newTemp(Ity_I8);
6471 IRTemp b6 = newTemp(Ity_I8);
6472 IRTemp b7 = newTemp(Ity_I8);
6473
6474 assign(b7, get_gpr_b7(r2));
6475 assign(b6, get_gpr_b6(r2));
6476 assign(b5, get_gpr_b5(r2));
6477 assign(b4, get_gpr_b4(r2));
6478 assign(b3, get_gpr_b3(r2));
6479 assign(b2, get_gpr_b2(r2));
6480 assign(b1, get_gpr_b1(r2));
6481 assign(b0, get_gpr_b0(r2));
6482 put_gpr_b0(r1, mkexpr(b7));
6483 put_gpr_b1(r1, mkexpr(b6));
6484 put_gpr_b2(r1, mkexpr(b5));
6485 put_gpr_b3(r1, mkexpr(b4));
6486 put_gpr_b4(r1, mkexpr(b3));
6487 put_gpr_b5(r1, mkexpr(b2));
6488 put_gpr_b6(r1, mkexpr(b1));
6489 put_gpr_b7(r1, mkexpr(b0));
6490
6491 return "lrvgr";
6492}
6493
florian55085f82012-11-21 00:36:55 +00006494static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006495s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6496{
6497 IRTemp op2 = newTemp(Ity_I16);
6498
6499 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6500 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6501 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6502
6503 return "lrvh";
6504}
6505
florian55085f82012-11-21 00:36:55 +00006506static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006507s390_irgen_LRV(UChar r1, IRTemp op2addr)
6508{
6509 IRTemp op2 = newTemp(Ity_I32);
6510
6511 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6512 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6513 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6514 mkU8(8)), mkU32(255))));
6515 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6516 mkU8(16)), mkU32(255))));
6517 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6518 mkU8(24)), mkU32(255))));
6519
6520 return "lrv";
6521}
6522
florian55085f82012-11-21 00:36:55 +00006523static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006524s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6525{
6526 IRTemp op2 = newTemp(Ity_I64);
6527
6528 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6529 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6530 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6531 mkU8(8)), mkU64(255))));
6532 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6533 mkU8(16)), mkU64(255))));
6534 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6535 mkU8(24)), mkU64(255))));
6536 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6537 mkU8(32)), mkU64(255))));
6538 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6539 mkU8(40)), mkU64(255))));
6540 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6541 mkU8(48)), mkU64(255))));
6542 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6543 mkU8(56)), mkU64(255))));
6544
6545 return "lrvg";
6546}
6547
florian55085f82012-11-21 00:36:55 +00006548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006549s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6550{
6551 store(mkexpr(op1addr), mkU16(i2));
6552
6553 return "mvhhi";
6554}
6555
florian55085f82012-11-21 00:36:55 +00006556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006557s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6558{
6559 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6560
6561 return "mvhi";
6562}
6563
florian55085f82012-11-21 00:36:55 +00006564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006565s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6566{
6567 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6568
6569 return "mvghi";
6570}
6571
florian55085f82012-11-21 00:36:55 +00006572static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006573s390_irgen_MVI(UChar i2, IRTemp op1addr)
6574{
6575 store(mkexpr(op1addr), mkU8(i2));
6576
6577 return "mvi";
6578}
6579
florian55085f82012-11-21 00:36:55 +00006580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006581s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6582{
6583 store(mkexpr(op1addr), mkU8(i2));
6584
6585 return "mviy";
6586}
6587
florian55085f82012-11-21 00:36:55 +00006588static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006589s390_irgen_MR(UChar r1, UChar r2)
6590{
6591 IRTemp op1 = newTemp(Ity_I32);
6592 IRTemp op2 = newTemp(Ity_I32);
6593 IRTemp result = newTemp(Ity_I64);
6594
6595 assign(op1, get_gpr_w1(r1 + 1));
6596 assign(op2, get_gpr_w1(r2));
6597 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6598 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6599 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6600
6601 return "mr";
6602}
6603
florian55085f82012-11-21 00:36:55 +00006604static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006605s390_irgen_M(UChar r1, IRTemp op2addr)
6606{
6607 IRTemp op1 = newTemp(Ity_I32);
6608 IRTemp op2 = newTemp(Ity_I32);
6609 IRTemp result = newTemp(Ity_I64);
6610
6611 assign(op1, get_gpr_w1(r1 + 1));
6612 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6613 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6614 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6615 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6616
6617 return "m";
6618}
6619
florian55085f82012-11-21 00:36:55 +00006620static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006621s390_irgen_MFY(UChar r1, IRTemp op2addr)
6622{
6623 IRTemp op1 = newTemp(Ity_I32);
6624 IRTemp op2 = newTemp(Ity_I32);
6625 IRTemp result = newTemp(Ity_I64);
6626
6627 assign(op1, get_gpr_w1(r1 + 1));
6628 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6629 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6630 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6631 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6632
6633 return "mfy";
6634}
6635
florian55085f82012-11-21 00:36:55 +00006636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006637s390_irgen_MH(UChar r1, IRTemp op2addr)
6638{
6639 IRTemp op1 = newTemp(Ity_I32);
6640 IRTemp op2 = newTemp(Ity_I16);
6641 IRTemp result = newTemp(Ity_I64);
6642
6643 assign(op1, get_gpr_w1(r1));
6644 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6645 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6646 ));
6647 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6648
6649 return "mh";
6650}
6651
florian55085f82012-11-21 00:36:55 +00006652static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006653s390_irgen_MHY(UChar r1, IRTemp op2addr)
6654{
6655 IRTemp op1 = newTemp(Ity_I32);
6656 IRTemp op2 = newTemp(Ity_I16);
6657 IRTemp result = newTemp(Ity_I64);
6658
6659 assign(op1, get_gpr_w1(r1));
6660 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6661 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6662 ));
6663 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6664
6665 return "mhy";
6666}
6667
florian55085f82012-11-21 00:36:55 +00006668static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006669s390_irgen_MHI(UChar r1, UShort i2)
6670{
6671 IRTemp op1 = newTemp(Ity_I32);
6672 Short op2;
6673 IRTemp result = newTemp(Ity_I64);
6674
6675 assign(op1, get_gpr_w1(r1));
6676 op2 = (Short)i2;
6677 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6678 mkU16((UShort)op2))));
6679 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6680
6681 return "mhi";
6682}
6683
florian55085f82012-11-21 00:36:55 +00006684static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006685s390_irgen_MGHI(UChar r1, UShort i2)
6686{
6687 IRTemp op1 = newTemp(Ity_I64);
6688 Short op2;
6689 IRTemp result = newTemp(Ity_I128);
6690
6691 assign(op1, get_gpr_dw0(r1));
6692 op2 = (Short)i2;
6693 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6694 mkU16((UShort)op2))));
6695 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6696
6697 return "mghi";
6698}
6699
florian55085f82012-11-21 00:36:55 +00006700static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006701s390_irgen_MLR(UChar r1, UChar r2)
6702{
6703 IRTemp op1 = newTemp(Ity_I32);
6704 IRTemp op2 = newTemp(Ity_I32);
6705 IRTemp result = newTemp(Ity_I64);
6706
6707 assign(op1, get_gpr_w1(r1 + 1));
6708 assign(op2, get_gpr_w1(r2));
6709 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6710 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6711 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6712
6713 return "mlr";
6714}
6715
florian55085f82012-11-21 00:36:55 +00006716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006717s390_irgen_MLGR(UChar r1, UChar r2)
6718{
6719 IRTemp op1 = newTemp(Ity_I64);
6720 IRTemp op2 = newTemp(Ity_I64);
6721 IRTemp result = newTemp(Ity_I128);
6722
6723 assign(op1, get_gpr_dw0(r1 + 1));
6724 assign(op2, get_gpr_dw0(r2));
6725 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6726 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6727 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6728
6729 return "mlgr";
6730}
6731
florian55085f82012-11-21 00:36:55 +00006732static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006733s390_irgen_ML(UChar r1, IRTemp op2addr)
6734{
6735 IRTemp op1 = newTemp(Ity_I32);
6736 IRTemp op2 = newTemp(Ity_I32);
6737 IRTemp result = newTemp(Ity_I64);
6738
6739 assign(op1, get_gpr_w1(r1 + 1));
6740 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6741 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6742 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6743 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6744
6745 return "ml";
6746}
6747
florian55085f82012-11-21 00:36:55 +00006748static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006749s390_irgen_MLG(UChar r1, IRTemp op2addr)
6750{
6751 IRTemp op1 = newTemp(Ity_I64);
6752 IRTemp op2 = newTemp(Ity_I64);
6753 IRTemp result = newTemp(Ity_I128);
6754
6755 assign(op1, get_gpr_dw0(r1 + 1));
6756 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6757 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6758 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6759 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6760
6761 return "mlg";
6762}
6763
florian55085f82012-11-21 00:36:55 +00006764static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006765s390_irgen_MSR(UChar r1, UChar r2)
6766{
6767 IRTemp op1 = newTemp(Ity_I32);
6768 IRTemp op2 = newTemp(Ity_I32);
6769 IRTemp result = newTemp(Ity_I64);
6770
6771 assign(op1, get_gpr_w1(r1));
6772 assign(op2, get_gpr_w1(r2));
6773 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6774 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6775
6776 return "msr";
6777}
6778
florian55085f82012-11-21 00:36:55 +00006779static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006780s390_irgen_MSGR(UChar r1, UChar r2)
6781{
6782 IRTemp op1 = newTemp(Ity_I64);
6783 IRTemp op2 = newTemp(Ity_I64);
6784 IRTemp result = newTemp(Ity_I128);
6785
6786 assign(op1, get_gpr_dw0(r1));
6787 assign(op2, get_gpr_dw0(r2));
6788 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6789 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6790
6791 return "msgr";
6792}
6793
florian55085f82012-11-21 00:36:55 +00006794static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006795s390_irgen_MSGFR(UChar r1, UChar r2)
6796{
6797 IRTemp op1 = newTemp(Ity_I64);
6798 IRTemp op2 = newTemp(Ity_I32);
6799 IRTemp result = newTemp(Ity_I128);
6800
6801 assign(op1, get_gpr_dw0(r1));
6802 assign(op2, get_gpr_w1(r2));
6803 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6804 ));
6805 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6806
6807 return "msgfr";
6808}
6809
florian55085f82012-11-21 00:36:55 +00006810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006811s390_irgen_MS(UChar r1, IRTemp op2addr)
6812{
6813 IRTemp op1 = newTemp(Ity_I32);
6814 IRTemp op2 = newTemp(Ity_I32);
6815 IRTemp result = newTemp(Ity_I64);
6816
6817 assign(op1, get_gpr_w1(r1));
6818 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6819 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6820 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6821
6822 return "ms";
6823}
6824
florian55085f82012-11-21 00:36:55 +00006825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006826s390_irgen_MSY(UChar r1, IRTemp op2addr)
6827{
6828 IRTemp op1 = newTemp(Ity_I32);
6829 IRTemp op2 = newTemp(Ity_I32);
6830 IRTemp result = newTemp(Ity_I64);
6831
6832 assign(op1, get_gpr_w1(r1));
6833 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6834 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6835 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6836
6837 return "msy";
6838}
6839
florian55085f82012-11-21 00:36:55 +00006840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006841s390_irgen_MSG(UChar r1, IRTemp op2addr)
6842{
6843 IRTemp op1 = newTemp(Ity_I64);
6844 IRTemp op2 = newTemp(Ity_I64);
6845 IRTemp result = newTemp(Ity_I128);
6846
6847 assign(op1, get_gpr_dw0(r1));
6848 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6849 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6850 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6851
6852 return "msg";
6853}
6854
florian55085f82012-11-21 00:36:55 +00006855static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006856s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6857{
6858 IRTemp op1 = newTemp(Ity_I64);
6859 IRTemp op2 = newTemp(Ity_I32);
6860 IRTemp result = newTemp(Ity_I128);
6861
6862 assign(op1, get_gpr_dw0(r1));
6863 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6864 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6865 ));
6866 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6867
6868 return "msgf";
6869}
6870
florian55085f82012-11-21 00:36:55 +00006871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006872s390_irgen_MSFI(UChar r1, UInt i2)
6873{
6874 IRTemp op1 = newTemp(Ity_I32);
6875 Int op2;
6876 IRTemp result = newTemp(Ity_I64);
6877
6878 assign(op1, get_gpr_w1(r1));
6879 op2 = (Int)i2;
6880 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6881 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6882
6883 return "msfi";
6884}
6885
florian55085f82012-11-21 00:36:55 +00006886static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006887s390_irgen_MSGFI(UChar r1, UInt i2)
6888{
6889 IRTemp op1 = newTemp(Ity_I64);
6890 Int op2;
6891 IRTemp result = newTemp(Ity_I128);
6892
6893 assign(op1, get_gpr_dw0(r1));
6894 op2 = (Int)i2;
6895 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6896 op2))));
6897 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6898
6899 return "msgfi";
6900}
6901
florian55085f82012-11-21 00:36:55 +00006902static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006903s390_irgen_OR(UChar r1, UChar r2)
6904{
6905 IRTemp op1 = newTemp(Ity_I32);
6906 IRTemp op2 = newTemp(Ity_I32);
6907 IRTemp result = newTemp(Ity_I32);
6908
6909 assign(op1, get_gpr_w1(r1));
6910 assign(op2, get_gpr_w1(r2));
6911 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6912 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6913 put_gpr_w1(r1, mkexpr(result));
6914
6915 return "or";
6916}
6917
florian55085f82012-11-21 00:36:55 +00006918static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006919s390_irgen_OGR(UChar r1, UChar r2)
6920{
6921 IRTemp op1 = newTemp(Ity_I64);
6922 IRTemp op2 = newTemp(Ity_I64);
6923 IRTemp result = newTemp(Ity_I64);
6924
6925 assign(op1, get_gpr_dw0(r1));
6926 assign(op2, get_gpr_dw0(r2));
6927 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6928 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6929 put_gpr_dw0(r1, mkexpr(result));
6930
6931 return "ogr";
6932}
6933
florian55085f82012-11-21 00:36:55 +00006934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006935s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6936{
6937 IRTemp op2 = newTemp(Ity_I32);
6938 IRTemp op3 = newTemp(Ity_I32);
6939 IRTemp result = newTemp(Ity_I32);
6940
6941 assign(op2, get_gpr_w1(r2));
6942 assign(op3, get_gpr_w1(r3));
6943 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6944 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6945 put_gpr_w1(r1, mkexpr(result));
6946
6947 return "ork";
6948}
6949
florian55085f82012-11-21 00:36:55 +00006950static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006951s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6952{
6953 IRTemp op2 = newTemp(Ity_I64);
6954 IRTemp op3 = newTemp(Ity_I64);
6955 IRTemp result = newTemp(Ity_I64);
6956
6957 assign(op2, get_gpr_dw0(r2));
6958 assign(op3, get_gpr_dw0(r3));
6959 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6960 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6961 put_gpr_dw0(r1, mkexpr(result));
6962
6963 return "ogrk";
6964}
6965
florian55085f82012-11-21 00:36:55 +00006966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006967s390_irgen_O(UChar r1, IRTemp op2addr)
6968{
6969 IRTemp op1 = newTemp(Ity_I32);
6970 IRTemp op2 = newTemp(Ity_I32);
6971 IRTemp result = newTemp(Ity_I32);
6972
6973 assign(op1, get_gpr_w1(r1));
6974 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6975 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6976 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6977 put_gpr_w1(r1, mkexpr(result));
6978
6979 return "o";
6980}
6981
florian55085f82012-11-21 00:36:55 +00006982static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006983s390_irgen_OY(UChar r1, IRTemp op2addr)
6984{
6985 IRTemp op1 = newTemp(Ity_I32);
6986 IRTemp op2 = newTemp(Ity_I32);
6987 IRTemp result = newTemp(Ity_I32);
6988
6989 assign(op1, get_gpr_w1(r1));
6990 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6991 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6992 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6993 put_gpr_w1(r1, mkexpr(result));
6994
6995 return "oy";
6996}
6997
florian55085f82012-11-21 00:36:55 +00006998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006999s390_irgen_OG(UChar r1, IRTemp op2addr)
7000{
7001 IRTemp op1 = newTemp(Ity_I64);
7002 IRTemp op2 = newTemp(Ity_I64);
7003 IRTemp result = newTemp(Ity_I64);
7004
7005 assign(op1, get_gpr_dw0(r1));
7006 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7007 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
7008 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7009 put_gpr_dw0(r1, mkexpr(result));
7010
7011 return "og";
7012}
7013
florian55085f82012-11-21 00:36:55 +00007014static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007015s390_irgen_OI(UChar i2, IRTemp op1addr)
7016{
7017 IRTemp op1 = newTemp(Ity_I8);
7018 UChar op2;
7019 IRTemp result = newTemp(Ity_I8);
7020
7021 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7022 op2 = i2;
7023 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7024 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7025 store(mkexpr(op1addr), mkexpr(result));
7026
7027 return "oi";
7028}
7029
florian55085f82012-11-21 00:36:55 +00007030static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007031s390_irgen_OIY(UChar i2, IRTemp op1addr)
7032{
7033 IRTemp op1 = newTemp(Ity_I8);
7034 UChar op2;
7035 IRTemp result = newTemp(Ity_I8);
7036
7037 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7038 op2 = i2;
7039 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7040 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7041 store(mkexpr(op1addr), mkexpr(result));
7042
7043 return "oiy";
7044}
7045
florian55085f82012-11-21 00:36:55 +00007046static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007047s390_irgen_OIHF(UChar r1, UInt i2)
7048{
7049 IRTemp op1 = newTemp(Ity_I32);
7050 UInt op2;
7051 IRTemp result = newTemp(Ity_I32);
7052
7053 assign(op1, get_gpr_w0(r1));
7054 op2 = i2;
7055 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7056 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7057 put_gpr_w0(r1, mkexpr(result));
7058
7059 return "oihf";
7060}
7061
florian55085f82012-11-21 00:36:55 +00007062static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007063s390_irgen_OIHH(UChar r1, UShort i2)
7064{
7065 IRTemp op1 = newTemp(Ity_I16);
7066 UShort op2;
7067 IRTemp result = newTemp(Ity_I16);
7068
7069 assign(op1, get_gpr_hw0(r1));
7070 op2 = i2;
7071 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7072 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7073 put_gpr_hw0(r1, mkexpr(result));
7074
7075 return "oihh";
7076}
7077
florian55085f82012-11-21 00:36:55 +00007078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007079s390_irgen_OIHL(UChar r1, UShort i2)
7080{
7081 IRTemp op1 = newTemp(Ity_I16);
7082 UShort op2;
7083 IRTemp result = newTemp(Ity_I16);
7084
7085 assign(op1, get_gpr_hw1(r1));
7086 op2 = i2;
7087 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7088 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7089 put_gpr_hw1(r1, mkexpr(result));
7090
7091 return "oihl";
7092}
7093
florian55085f82012-11-21 00:36:55 +00007094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007095s390_irgen_OILF(UChar r1, UInt i2)
7096{
7097 IRTemp op1 = newTemp(Ity_I32);
7098 UInt op2;
7099 IRTemp result = newTemp(Ity_I32);
7100
7101 assign(op1, get_gpr_w1(r1));
7102 op2 = i2;
7103 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7104 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7105 put_gpr_w1(r1, mkexpr(result));
7106
7107 return "oilf";
7108}
7109
florian55085f82012-11-21 00:36:55 +00007110static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007111s390_irgen_OILH(UChar r1, UShort i2)
7112{
7113 IRTemp op1 = newTemp(Ity_I16);
7114 UShort op2;
7115 IRTemp result = newTemp(Ity_I16);
7116
7117 assign(op1, get_gpr_hw2(r1));
7118 op2 = i2;
7119 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7120 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7121 put_gpr_hw2(r1, mkexpr(result));
7122
7123 return "oilh";
7124}
7125
florian55085f82012-11-21 00:36:55 +00007126static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007127s390_irgen_OILL(UChar r1, UShort i2)
7128{
7129 IRTemp op1 = newTemp(Ity_I16);
7130 UShort op2;
7131 IRTemp result = newTemp(Ity_I16);
7132
7133 assign(op1, get_gpr_hw3(r1));
7134 op2 = i2;
7135 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7136 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7137 put_gpr_hw3(r1, mkexpr(result));
7138
7139 return "oill";
7140}
7141
florian55085f82012-11-21 00:36:55 +00007142static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007143s390_irgen_PFD(void)
7144{
7145
7146 return "pfd";
7147}
7148
florian55085f82012-11-21 00:36:55 +00007149static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007150s390_irgen_PFDRL(void)
7151{
7152
7153 return "pfdrl";
7154}
7155
florian78d5ef72013-05-11 15:02:58 +00007156static IRExpr *
7157get_rounding_mode_from_gr0(void)
7158{
7159 IRTemp rm_bits = newTemp(Ity_I32);
7160 IRExpr *s390rm;
7161 IRExpr *irrm;
7162
florian78d5ef72013-05-11 15:02:58 +00007163 /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7164 when PFPO insn is called. So, extract the bits at [60:63] */
7165 assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7166 s390rm = mkexpr(rm_bits);
7167 irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7168 mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7169 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7170 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7171 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7172 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7173 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7174 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7175 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7176 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7177 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7178 mkexpr(encode_dfp_rounding_mode(
7179 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7180 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7181 mkexpr(encode_dfp_rounding_mode(
7182 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7183 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7184 mkexpr(encode_dfp_rounding_mode(
7185 S390_DFP_ROUND_AWAY_0)),
7186 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7187 mkexpr(encode_dfp_rounding_mode(
7188 S390_DFP_ROUND_PREPARE_SHORT_15)),
7189 /* if rounding mode is 0 or invalid (2-7)
7190 set S390_DFP_ROUND_PER_FPC_0 */
7191 mkexpr(encode_dfp_rounding_mode(
7192 S390_DFP_ROUND_PER_FPC_0)))))))))));
7193
7194 return irrm;
7195}
7196
7197static IRExpr *
7198s390_call_pfpo_helper(IRExpr *gr0)
7199{
7200 IRExpr **args, *call;
7201
7202 args = mkIRExprVec_1(gr0);
7203 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7204 "s390_do_pfpo", &s390_do_pfpo, args);
7205 /* Nothing is excluded from definedness checking. */
7206 call->Iex.CCall.cee->mcx_mask = 0;
7207
7208 return call;
7209}
7210
7211static const HChar *
7212s390_irgen_PFPO(void)
7213{
7214 IRTemp gr0 = newTemp(Ity_I32); /* word 1 [32:63] of GR 0 */
7215 IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7216 IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */
7217 IRTemp ef = newTemp(Ity_I32); /* Emulation Failure */
florian7ab421d2013-06-17 21:03:56 +00007218 IRTemp src1 = newTemp(Ity_F32);
7219 IRTemp dst1 = newTemp(Ity_D32);
7220 IRTemp src2 = newTemp(Ity_F32);
7221 IRTemp dst2 = newTemp(Ity_D64);
7222 IRTemp src3 = newTemp(Ity_F32);
florian78d5ef72013-05-11 15:02:58 +00007223 IRTemp dst3 = newTemp(Ity_D128);
florian7ab421d2013-06-17 21:03:56 +00007224 IRTemp src4 = newTemp(Ity_F64);
7225 IRTemp dst4 = newTemp(Ity_D32);
7226 IRTemp src5 = newTemp(Ity_F64);
7227 IRTemp dst5 = newTemp(Ity_D64);
7228 IRTemp src6 = newTemp(Ity_F64);
7229 IRTemp dst6 = newTemp(Ity_D128);
7230 IRTemp src7 = newTemp(Ity_F128);
7231 IRTemp dst7 = newTemp(Ity_D32);
7232 IRTemp src8 = newTemp(Ity_F128);
7233 IRTemp dst8 = newTemp(Ity_D64);
7234 IRTemp src9 = newTemp(Ity_F128);
7235 IRTemp dst9 = newTemp(Ity_D128);
7236 IRTemp src10 = newTemp(Ity_D32);
7237 IRTemp dst10 = newTemp(Ity_F32);
7238 IRTemp src11 = newTemp(Ity_D32);
7239 IRTemp dst11 = newTemp(Ity_F64);
7240 IRTemp src12 = newTemp(Ity_D32);
7241 IRTemp dst12 = newTemp(Ity_F128);
7242 IRTemp src13 = newTemp(Ity_D64);
7243 IRTemp dst13 = newTemp(Ity_F32);
7244 IRTemp src14 = newTemp(Ity_D64);
7245 IRTemp dst14 = newTemp(Ity_F64);
7246 IRTemp src15 = newTemp(Ity_D64);
7247 IRTemp dst15 = newTemp(Ity_F128);
7248 IRTemp src16 = newTemp(Ity_D128);
7249 IRTemp dst16 = newTemp(Ity_F32);
7250 IRTemp src17 = newTemp(Ity_D128);
7251 IRTemp dst17 = newTemp(Ity_F64);
7252 IRTemp src18 = newTemp(Ity_D128);
7253 IRTemp dst18 = newTemp(Ity_F128);
florian78d5ef72013-05-11 15:02:58 +00007254 IRExpr *irrm;
7255
florianad00ea92014-12-05 18:55:39 +00007256 if (! s390_host_has_pfpo) {
7257 emulation_failure(EmFail_S390X_pfpo);
7258 goto done;
7259 }
florian78d5ef72013-05-11 15:02:58 +00007260
7261 assign(gr0, get_gpr_w1(0));
7262 /* get function code */
7263 assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7264 mkU32(0x7fffff)));
7265 /* get validity test bit */
7266 assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7267 mkU32(0x1)));
7268 irrm = get_rounding_mode_from_gr0();
7269
7270 /* test_bit is 1 */
florian7ab421d2013-06-17 21:03:56 +00007271 assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
florian78d5ef72013-05-11 15:02:58 +00007272 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7273
7274 /* Return code set in GR1 is usually 0. Non-zero value is set only
7275 when exceptions are raised. See Programming Notes point 5 in the
7276 instrcution description of pfpo in POP. Since valgrind does not
7277 model exception, it might be safe to just set 0 to GR 1. */
7278 put_gpr_w1(1, mkU32(0x0));
7279 next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7280
7281 /* Check validity of function code in GR 0 */
7282 assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
florianafa3f042014-09-06 21:43:28 +00007283 emulation_failure_with_expr(mkexpr(ef));
florian78d5ef72013-05-11 15:02:58 +00007284
7285 stmt(
7286 IRStmt_Exit(
7287 binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7288 Ijk_EmFail,
7289 IRConst_U64(guest_IA_next_instr),
7290 S390X_GUEST_OFFSET(guest_IA)
7291 )
7292 );
7293
florian7ab421d2013-06-17 21:03:56 +00007294 /* F32 -> D32 */
florian78d5ef72013-05-11 15:02:58 +00007295 /* get source from FPR 4,6 - already set in src1 */
florian7ab421d2013-06-17 21:03:56 +00007296 assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
7297 put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007298 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007299 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
7300 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
florian78d5ef72013-05-11 15:02:58 +00007301
florian7ab421d2013-06-17 21:03:56 +00007302 /* F32 -> D64 */
7303 assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
7304 assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
7305 put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007306 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007307 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
7308 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007309
florian7ab421d2013-06-17 21:03:56 +00007310 /* F32 -> D128 */
7311 assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
7312 assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
florian78d5ef72013-05-11 15:02:58 +00007313 put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7314 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007315 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
7316 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
7317
7318 /* F64 -> D32 */
7319 assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7320 assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
7321 put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7322 put_gpr_w1(1, mkU32(0x0));
7323 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
7324 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
7325
7326 /* F64 -> D64 */
7327 assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7328 assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
7329 put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7330 put_gpr_w1(1, mkU32(0x0));
7331 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
7332 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7333
7334 /* F64 -> D128 */
7335 assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7336 assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
7337 put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7338 put_gpr_w1(1, mkU32(0x0));
7339 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
florian78d5ef72013-05-11 15:02:58 +00007340 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7341
florian7ab421d2013-06-17 21:03:56 +00007342 /* F128 -> D32 */
7343 assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
7344 assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
7345 put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007346 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007347 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
7348 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
7349
7350 /* F128 -> D64 */
7351 assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
7352 assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
7353 put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
7354 put_gpr_w1(1, mkU32(0x0));
7355 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
7356 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007357
7358 /* F128 -> D128 */
florian7ab421d2013-06-17 21:03:56 +00007359 assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
7360 assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
7361 put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007362 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007363 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
florian78d5ef72013-05-11 15:02:58 +00007364 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7365
florian7ab421d2013-06-17 21:03:56 +00007366 /* D32 -> F32 */
7367 assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
7368 assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
7369 put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007370 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007371 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
7372 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
7373
7374 /* D32 -> F64 */
7375 assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
7376 assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
7377 put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
7378 put_gpr_w1(1, mkU32(0x0));
7379 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
7380 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
7381
7382 /* D32 -> F128 */
7383 assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
7384 assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
7385 put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
7386 put_gpr_w1(1, mkU32(0x0));
7387 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
7388 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
7389
7390 /* D64 -> F32 */
7391 assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7392 assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
7393 put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
7394 put_gpr_w1(1, mkU32(0x0));
7395 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
7396 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
7397
7398 /* D64 -> F64 */
7399 assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7400 assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
7401 put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
7402 put_gpr_w1(1, mkU32(0x0));
7403 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
7404 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7405
7406 /* D64 -> F128 */
7407 assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7408 assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
7409 put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
7410 put_gpr_w1(1, mkU32(0x0));
7411 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
7412 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
7413
7414 /* D128 -> F32 */
7415 assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
7416 assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
7417 put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
7418 put_gpr_w1(1, mkU32(0x0));
7419 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
7420 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
7421
7422 /* D128 -> F64 */
7423 assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
7424 assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
7425 put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
7426 put_gpr_w1(1, mkU32(0x0));
7427 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
7428 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7429
7430 /* D128 -> F128 */
7431 assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
7432 assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
7433 put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
7434 put_gpr_w1(1, mkU32(0x0));
7435 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
florian78d5ef72013-05-11 15:02:58 +00007436 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7437
florianad00ea92014-12-05 18:55:39 +00007438 done:
florian78d5ef72013-05-11 15:02:58 +00007439 return "pfpo";
7440}
7441
florian55085f82012-11-21 00:36:55 +00007442static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007443s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7444{
7445 IRTemp amount = newTemp(Ity_I64);
7446 IRTemp op = newTemp(Ity_I32);
7447
7448 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7449 assign(op, get_gpr_w1(r3));
7450 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7451 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7452 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7453
7454 return "rll";
7455}
7456
florian55085f82012-11-21 00:36:55 +00007457static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007458s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7459{
7460 IRTemp amount = newTemp(Ity_I64);
7461 IRTemp op = newTemp(Ity_I64);
7462
7463 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7464 assign(op, get_gpr_dw0(r3));
7465 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7466 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7467 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7468
7469 return "rllg";
7470}
7471
florian55085f82012-11-21 00:36:55 +00007472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007473s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7474{
7475 UChar from;
7476 UChar to;
7477 UChar rot;
7478 UChar t_bit;
7479 ULong mask;
7480 ULong maskc;
7481 IRTemp result = newTemp(Ity_I64);
7482 IRTemp op2 = newTemp(Ity_I64);
7483
7484 from = i3 & 63;
7485 to = i4 & 63;
7486 rot = i5 & 63;
7487 t_bit = i3 & 128;
7488 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7489 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7490 mkU8(64 - rot))));
7491 if (from <= to) {
7492 mask = ~0ULL;
7493 mask = (mask >> from) & (mask << (63 - to));
7494 maskc = ~mask;
7495 } else {
7496 maskc = ~0ULL;
7497 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7498 mask = ~maskc;
7499 }
7500 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7501 ), mkU64(mask)));
7502 if (t_bit == 0) {
7503 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7504 mkU64(maskc)), mkexpr(result)));
7505 }
7506 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7507
7508 return "rnsbg";
7509}
7510
florian55085f82012-11-21 00:36:55 +00007511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007512s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7513{
7514 UChar from;
7515 UChar to;
7516 UChar rot;
7517 UChar t_bit;
7518 ULong mask;
7519 ULong maskc;
7520 IRTemp result = newTemp(Ity_I64);
7521 IRTemp op2 = newTemp(Ity_I64);
7522
7523 from = i3 & 63;
7524 to = i4 & 63;
7525 rot = i5 & 63;
7526 t_bit = i3 & 128;
7527 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7528 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7529 mkU8(64 - rot))));
7530 if (from <= to) {
7531 mask = ~0ULL;
7532 mask = (mask >> from) & (mask << (63 - to));
7533 maskc = ~mask;
7534 } else {
7535 maskc = ~0ULL;
7536 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7537 mask = ~maskc;
7538 }
7539 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7540 ), mkU64(mask)));
7541 if (t_bit == 0) {
7542 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7543 mkU64(maskc)), mkexpr(result)));
7544 }
7545 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7546
7547 return "rxsbg";
7548}
7549
florian55085f82012-11-21 00:36:55 +00007550static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007551s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7552{
7553 UChar from;
7554 UChar to;
7555 UChar rot;
7556 UChar t_bit;
7557 ULong mask;
7558 ULong maskc;
7559 IRTemp result = newTemp(Ity_I64);
7560 IRTemp op2 = newTemp(Ity_I64);
7561
7562 from = i3 & 63;
7563 to = i4 & 63;
7564 rot = i5 & 63;
7565 t_bit = i3 & 128;
7566 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7567 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7568 mkU8(64 - rot))));
7569 if (from <= to) {
7570 mask = ~0ULL;
7571 mask = (mask >> from) & (mask << (63 - to));
7572 maskc = ~mask;
7573 } else {
7574 maskc = ~0ULL;
7575 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7576 mask = ~maskc;
7577 }
7578 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7579 ), mkU64(mask)));
7580 if (t_bit == 0) {
7581 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7582 mkU64(maskc)), mkexpr(result)));
7583 }
7584 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7585
7586 return "rosbg";
7587}
7588
florian55085f82012-11-21 00:36:55 +00007589static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007590s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7591{
7592 UChar from;
7593 UChar to;
7594 UChar rot;
7595 UChar z_bit;
7596 ULong mask;
7597 ULong maskc;
7598 IRTemp op2 = newTemp(Ity_I64);
7599 IRTemp result = newTemp(Ity_I64);
7600
7601 from = i3 & 63;
7602 to = i4 & 63;
7603 rot = i5 & 63;
7604 z_bit = i4 & 128;
7605 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7606 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7607 mkU8(64 - rot))));
7608 if (from <= to) {
7609 mask = ~0ULL;
7610 mask = (mask >> from) & (mask << (63 - to));
7611 maskc = ~mask;
7612 } else {
7613 maskc = ~0ULL;
7614 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7615 mask = ~maskc;
7616 }
7617 if (z_bit == 0) {
7618 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7619 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7620 } else {
7621 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7622 }
7623 assign(result, get_gpr_dw0(r1));
cborntrae03b6002013-11-07 21:37:28 +00007624 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
sewardj2019a972011-03-07 16:04:07 +00007625
7626 return "risbg";
7627}
7628
florian55085f82012-11-21 00:36:55 +00007629static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007630s390_irgen_SAR(UChar r1, UChar r2)
7631{
7632 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007633 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007634 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7635
7636 return "sar";
7637}
7638
florian55085f82012-11-21 00:36:55 +00007639static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007640s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7641{
7642 IRTemp p1 = newTemp(Ity_I64);
7643 IRTemp p2 = newTemp(Ity_I64);
7644 IRTemp op = newTemp(Ity_I64);
7645 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007646 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007647 IRTemp shift_amount = newTemp(Ity_I64);
7648
7649 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7650 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7651 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7652 ));
7653 sign_mask = 1ULL << 63;
7654 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7655 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007656 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7657 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007658 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7659 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7660 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7661
7662 return "slda";
7663}
7664
florian55085f82012-11-21 00:36:55 +00007665static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007666s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7667{
7668 IRTemp p1 = newTemp(Ity_I64);
7669 IRTemp p2 = newTemp(Ity_I64);
7670 IRTemp result = newTemp(Ity_I64);
7671
7672 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7673 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7674 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7675 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7676 mkexpr(op2addr), mkU64(63)))));
7677 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7678 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7679
7680 return "sldl";
7681}
7682
florian55085f82012-11-21 00:36:55 +00007683static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007684s390_irgen_SLA(UChar r1, IRTemp op2addr)
7685{
7686 IRTemp uop = newTemp(Ity_I32);
7687 IRTemp result = newTemp(Ity_I32);
7688 UInt sign_mask;
7689 IRTemp shift_amount = newTemp(Ity_I64);
7690 IRTemp op = newTemp(Ity_I32);
7691
7692 assign(op, get_gpr_w1(r1));
7693 assign(uop, get_gpr_w1(r1));
7694 sign_mask = 2147483648U;
7695 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7696 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7697 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7698 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7699 put_gpr_w1(r1, mkexpr(result));
7700 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7701
7702 return "sla";
7703}
7704
florian55085f82012-11-21 00:36:55 +00007705static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007706s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7707{
7708 IRTemp uop = newTemp(Ity_I32);
7709 IRTemp result = newTemp(Ity_I32);
7710 UInt sign_mask;
7711 IRTemp shift_amount = newTemp(Ity_I64);
7712 IRTemp op = newTemp(Ity_I32);
7713
7714 assign(op, get_gpr_w1(r3));
7715 assign(uop, get_gpr_w1(r3));
7716 sign_mask = 2147483648U;
7717 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7718 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7719 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7720 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7721 put_gpr_w1(r1, mkexpr(result));
7722 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7723
7724 return "slak";
7725}
7726
florian55085f82012-11-21 00:36:55 +00007727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007728s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7729{
7730 IRTemp uop = newTemp(Ity_I64);
7731 IRTemp result = newTemp(Ity_I64);
7732 ULong sign_mask;
7733 IRTemp shift_amount = newTemp(Ity_I64);
7734 IRTemp op = newTemp(Ity_I64);
7735
7736 assign(op, get_gpr_dw0(r3));
7737 assign(uop, get_gpr_dw0(r3));
7738 sign_mask = 9223372036854775808ULL;
7739 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7740 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7741 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7742 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7743 put_gpr_dw0(r1, mkexpr(result));
7744 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7745
7746 return "slag";
7747}
7748
florian55085f82012-11-21 00:36:55 +00007749static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007750s390_irgen_SLL(UChar r1, IRTemp op2addr)
7751{
7752 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7753 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7754
7755 return "sll";
7756}
7757
florian55085f82012-11-21 00:36:55 +00007758static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007759s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7760{
7761 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7762 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7763
7764 return "sllk";
7765}
7766
florian55085f82012-11-21 00:36:55 +00007767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007768s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7769{
7770 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7771 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7772
7773 return "sllg";
7774}
7775
florian55085f82012-11-21 00:36:55 +00007776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007777s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7778{
7779 IRTemp p1 = newTemp(Ity_I64);
7780 IRTemp p2 = newTemp(Ity_I64);
7781 IRTemp result = newTemp(Ity_I64);
7782
7783 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7784 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7785 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7786 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7787 mkexpr(op2addr), mkU64(63)))));
7788 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7789 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7790 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7791
7792 return "srda";
7793}
7794
florian55085f82012-11-21 00:36:55 +00007795static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007796s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7797{
7798 IRTemp p1 = newTemp(Ity_I64);
7799 IRTemp p2 = newTemp(Ity_I64);
7800 IRTemp result = newTemp(Ity_I64);
7801
7802 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7803 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7804 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7805 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7806 mkexpr(op2addr), mkU64(63)))));
7807 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7808 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7809
7810 return "srdl";
7811}
7812
florian55085f82012-11-21 00:36:55 +00007813static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007814s390_irgen_SRA(UChar r1, IRTemp op2addr)
7815{
7816 IRTemp result = newTemp(Ity_I32);
7817 IRTemp op = newTemp(Ity_I32);
7818
7819 assign(op, get_gpr_w1(r1));
7820 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7821 mkexpr(op2addr), mkU64(63)))));
7822 put_gpr_w1(r1, mkexpr(result));
7823 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7824
7825 return "sra";
7826}
7827
florian55085f82012-11-21 00:36:55 +00007828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007829s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7830{
7831 IRTemp result = newTemp(Ity_I32);
7832 IRTemp op = newTemp(Ity_I32);
7833
7834 assign(op, get_gpr_w1(r3));
7835 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7836 mkexpr(op2addr), mkU64(63)))));
7837 put_gpr_w1(r1, mkexpr(result));
7838 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7839
7840 return "srak";
7841}
7842
florian55085f82012-11-21 00:36:55 +00007843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007844s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7845{
7846 IRTemp result = newTemp(Ity_I64);
7847 IRTemp op = newTemp(Ity_I64);
7848
7849 assign(op, get_gpr_dw0(r3));
7850 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7851 mkexpr(op2addr), mkU64(63)))));
7852 put_gpr_dw0(r1, mkexpr(result));
7853 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7854
7855 return "srag";
7856}
7857
florian55085f82012-11-21 00:36:55 +00007858static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007859s390_irgen_SRL(UChar r1, IRTemp op2addr)
7860{
7861 IRTemp op = newTemp(Ity_I32);
7862
7863 assign(op, get_gpr_w1(r1));
7864 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7865 mkexpr(op2addr), mkU64(63)))));
7866
7867 return "srl";
7868}
7869
florian55085f82012-11-21 00:36:55 +00007870static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007871s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7872{
7873 IRTemp op = newTemp(Ity_I32);
7874
7875 assign(op, get_gpr_w1(r3));
7876 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7877 mkexpr(op2addr), mkU64(63)))));
7878
7879 return "srlk";
7880}
7881
florian55085f82012-11-21 00:36:55 +00007882static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007883s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7884{
7885 IRTemp op = newTemp(Ity_I64);
7886
7887 assign(op, get_gpr_dw0(r3));
7888 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7889 mkexpr(op2addr), mkU64(63)))));
7890
7891 return "srlg";
7892}
7893
florian55085f82012-11-21 00:36:55 +00007894static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007895s390_irgen_ST(UChar r1, IRTemp op2addr)
7896{
7897 store(mkexpr(op2addr), get_gpr_w1(r1));
7898
7899 return "st";
7900}
7901
florian55085f82012-11-21 00:36:55 +00007902static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007903s390_irgen_STY(UChar r1, IRTemp op2addr)
7904{
7905 store(mkexpr(op2addr), get_gpr_w1(r1));
7906
7907 return "sty";
7908}
7909
florian55085f82012-11-21 00:36:55 +00007910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007911s390_irgen_STG(UChar r1, IRTemp op2addr)
7912{
7913 store(mkexpr(op2addr), get_gpr_dw0(r1));
7914
7915 return "stg";
7916}
7917
florian55085f82012-11-21 00:36:55 +00007918static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007919s390_irgen_STRL(UChar r1, UInt i2)
7920{
7921 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7922 get_gpr_w1(r1));
7923
7924 return "strl";
7925}
7926
florian55085f82012-11-21 00:36:55 +00007927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007928s390_irgen_STGRL(UChar r1, UInt i2)
7929{
7930 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7931 get_gpr_dw0(r1));
7932
7933 return "stgrl";
7934}
7935
florian55085f82012-11-21 00:36:55 +00007936static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007937s390_irgen_STC(UChar r1, IRTemp op2addr)
7938{
7939 store(mkexpr(op2addr), get_gpr_b7(r1));
7940
7941 return "stc";
7942}
7943
florian55085f82012-11-21 00:36:55 +00007944static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007945s390_irgen_STCY(UChar r1, IRTemp op2addr)
7946{
7947 store(mkexpr(op2addr), get_gpr_b7(r1));
7948
7949 return "stcy";
7950}
7951
florian55085f82012-11-21 00:36:55 +00007952static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007953s390_irgen_STCH(UChar r1, IRTemp op2addr)
7954{
7955 store(mkexpr(op2addr), get_gpr_b3(r1));
7956
7957 return "stch";
7958}
7959
florian55085f82012-11-21 00:36:55 +00007960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007961s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7962{
7963 UChar mask;
7964 UChar n;
7965
7966 mask = (UChar)r3;
7967 n = 0;
7968 if ((mask & 8) != 0) {
7969 store(mkexpr(op2addr), get_gpr_b4(r1));
7970 n = n + 1;
7971 }
7972 if ((mask & 4) != 0) {
7973 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7974 n = n + 1;
7975 }
7976 if ((mask & 2) != 0) {
7977 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7978 n = n + 1;
7979 }
7980 if ((mask & 1) != 0) {
7981 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7982 }
7983
7984 return "stcm";
7985}
7986
florian55085f82012-11-21 00:36:55 +00007987static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007988s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7989{
7990 UChar mask;
7991 UChar n;
7992
7993 mask = (UChar)r3;
7994 n = 0;
7995 if ((mask & 8) != 0) {
7996 store(mkexpr(op2addr), get_gpr_b4(r1));
7997 n = n + 1;
7998 }
7999 if ((mask & 4) != 0) {
8000 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
8001 n = n + 1;
8002 }
8003 if ((mask & 2) != 0) {
8004 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
8005 n = n + 1;
8006 }
8007 if ((mask & 1) != 0) {
8008 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
8009 }
8010
8011 return "stcmy";
8012}
8013
florian55085f82012-11-21 00:36:55 +00008014static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008015s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
8016{
8017 UChar mask;
8018 UChar n;
8019
8020 mask = (UChar)r3;
8021 n = 0;
8022 if ((mask & 8) != 0) {
8023 store(mkexpr(op2addr), get_gpr_b0(r1));
8024 n = n + 1;
8025 }
8026 if ((mask & 4) != 0) {
8027 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
8028 n = n + 1;
8029 }
8030 if ((mask & 2) != 0) {
8031 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
8032 n = n + 1;
8033 }
8034 if ((mask & 1) != 0) {
8035 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
8036 }
8037
8038 return "stcmh";
8039}
8040
florian55085f82012-11-21 00:36:55 +00008041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008042s390_irgen_STH(UChar r1, IRTemp op2addr)
8043{
8044 store(mkexpr(op2addr), get_gpr_hw3(r1));
8045
8046 return "sth";
8047}
8048
florian55085f82012-11-21 00:36:55 +00008049static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008050s390_irgen_STHY(UChar r1, IRTemp op2addr)
8051{
8052 store(mkexpr(op2addr), get_gpr_hw3(r1));
8053
8054 return "sthy";
8055}
8056
florian55085f82012-11-21 00:36:55 +00008057static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008058s390_irgen_STHRL(UChar r1, UInt i2)
8059{
8060 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8061 get_gpr_hw3(r1));
8062
8063 return "sthrl";
8064}
8065
florian55085f82012-11-21 00:36:55 +00008066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008067s390_irgen_STHH(UChar r1, IRTemp op2addr)
8068{
8069 store(mkexpr(op2addr), get_gpr_hw1(r1));
8070
8071 return "sthh";
8072}
8073
florian55085f82012-11-21 00:36:55 +00008074static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008075s390_irgen_STFH(UChar r1, IRTemp op2addr)
8076{
8077 store(mkexpr(op2addr), get_gpr_w0(r1));
8078
8079 return "stfh";
8080}
8081
florian55085f82012-11-21 00:36:55 +00008082static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008083s390_irgen_STOC(UChar r1, IRTemp op2addr)
8084{
8085 /* condition is checked in format handler */
8086 store(mkexpr(op2addr), get_gpr_w1(r1));
8087
8088 return "stoc";
8089}
8090
florian55085f82012-11-21 00:36:55 +00008091static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008092s390_irgen_STOCG(UChar r1, IRTemp op2addr)
8093{
8094 /* condition is checked in format handler */
8095 store(mkexpr(op2addr), get_gpr_dw0(r1));
8096
8097 return "stocg";
8098}
8099
florian55085f82012-11-21 00:36:55 +00008100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008101s390_irgen_STPQ(UChar r1, IRTemp op2addr)
8102{
8103 store(mkexpr(op2addr), get_gpr_dw0(r1));
8104 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
8105
8106 return "stpq";
8107}
8108
florian55085f82012-11-21 00:36:55 +00008109static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008110s390_irgen_STRVH(UChar r1, IRTemp op2addr)
8111{
8112 store(mkexpr(op2addr), get_gpr_b7(r1));
8113 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8114
8115 return "strvh";
8116}
8117
florian55085f82012-11-21 00:36:55 +00008118static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008119s390_irgen_STRV(UChar r1, IRTemp op2addr)
8120{
8121 store(mkexpr(op2addr), get_gpr_b7(r1));
8122 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8123 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8124 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8125
8126 return "strv";
8127}
8128
florian55085f82012-11-21 00:36:55 +00008129static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008130s390_irgen_STRVG(UChar r1, IRTemp op2addr)
8131{
8132 store(mkexpr(op2addr), get_gpr_b7(r1));
8133 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8134 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8135 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8136 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
8137 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
8138 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
8139 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
8140
8141 return "strvg";
8142}
8143
florian55085f82012-11-21 00:36:55 +00008144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008145s390_irgen_SR(UChar r1, UChar r2)
8146{
8147 IRTemp op1 = newTemp(Ity_I32);
8148 IRTemp op2 = newTemp(Ity_I32);
8149 IRTemp result = newTemp(Ity_I32);
8150
8151 assign(op1, get_gpr_w1(r1));
8152 assign(op2, get_gpr_w1(r2));
8153 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8154 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8155 put_gpr_w1(r1, mkexpr(result));
8156
8157 return "sr";
8158}
8159
florian55085f82012-11-21 00:36:55 +00008160static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008161s390_irgen_SGR(UChar r1, UChar r2)
8162{
8163 IRTemp op1 = newTemp(Ity_I64);
8164 IRTemp op2 = newTemp(Ity_I64);
8165 IRTemp result = newTemp(Ity_I64);
8166
8167 assign(op1, get_gpr_dw0(r1));
8168 assign(op2, get_gpr_dw0(r2));
8169 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8170 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8171 put_gpr_dw0(r1, mkexpr(result));
8172
8173 return "sgr";
8174}
8175
florian55085f82012-11-21 00:36:55 +00008176static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008177s390_irgen_SGFR(UChar r1, UChar r2)
8178{
8179 IRTemp op1 = newTemp(Ity_I64);
8180 IRTemp op2 = newTemp(Ity_I64);
8181 IRTemp result = newTemp(Ity_I64);
8182
8183 assign(op1, get_gpr_dw0(r1));
8184 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8185 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8186 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8187 put_gpr_dw0(r1, mkexpr(result));
8188
8189 return "sgfr";
8190}
8191
florian55085f82012-11-21 00:36:55 +00008192static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008193s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8194{
8195 IRTemp op2 = newTemp(Ity_I32);
8196 IRTemp op3 = newTemp(Ity_I32);
8197 IRTemp result = newTemp(Ity_I32);
8198
8199 assign(op2, get_gpr_w1(r2));
8200 assign(op3, get_gpr_w1(r3));
8201 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8202 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8203 put_gpr_w1(r1, mkexpr(result));
8204
8205 return "srk";
8206}
8207
florian55085f82012-11-21 00:36:55 +00008208static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008209s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8210{
8211 IRTemp op2 = newTemp(Ity_I64);
8212 IRTemp op3 = newTemp(Ity_I64);
8213 IRTemp result = newTemp(Ity_I64);
8214
8215 assign(op2, get_gpr_dw0(r2));
8216 assign(op3, get_gpr_dw0(r3));
8217 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8218 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8219 put_gpr_dw0(r1, mkexpr(result));
8220
8221 return "sgrk";
8222}
8223
florian55085f82012-11-21 00:36:55 +00008224static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008225s390_irgen_S(UChar r1, IRTemp op2addr)
8226{
8227 IRTemp op1 = newTemp(Ity_I32);
8228 IRTemp op2 = newTemp(Ity_I32);
8229 IRTemp result = newTemp(Ity_I32);
8230
8231 assign(op1, get_gpr_w1(r1));
8232 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8233 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8234 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8235 put_gpr_w1(r1, mkexpr(result));
8236
8237 return "s";
8238}
8239
florian55085f82012-11-21 00:36:55 +00008240static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008241s390_irgen_SY(UChar r1, IRTemp op2addr)
8242{
8243 IRTemp op1 = newTemp(Ity_I32);
8244 IRTemp op2 = newTemp(Ity_I32);
8245 IRTemp result = newTemp(Ity_I32);
8246
8247 assign(op1, get_gpr_w1(r1));
8248 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8249 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8250 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8251 put_gpr_w1(r1, mkexpr(result));
8252
8253 return "sy";
8254}
8255
florian55085f82012-11-21 00:36:55 +00008256static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008257s390_irgen_SG(UChar r1, IRTemp op2addr)
8258{
8259 IRTemp op1 = newTemp(Ity_I64);
8260 IRTemp op2 = newTemp(Ity_I64);
8261 IRTemp result = newTemp(Ity_I64);
8262
8263 assign(op1, get_gpr_dw0(r1));
8264 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8265 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8266 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8267 put_gpr_dw0(r1, mkexpr(result));
8268
8269 return "sg";
8270}
8271
florian55085f82012-11-21 00:36:55 +00008272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008273s390_irgen_SGF(UChar r1, IRTemp op2addr)
8274{
8275 IRTemp op1 = newTemp(Ity_I64);
8276 IRTemp op2 = newTemp(Ity_I64);
8277 IRTemp result = newTemp(Ity_I64);
8278
8279 assign(op1, get_gpr_dw0(r1));
8280 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8281 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8282 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8283 put_gpr_dw0(r1, mkexpr(result));
8284
8285 return "sgf";
8286}
8287
florian55085f82012-11-21 00:36:55 +00008288static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008289s390_irgen_SH(UChar r1, IRTemp op2addr)
8290{
8291 IRTemp op1 = newTemp(Ity_I32);
8292 IRTemp op2 = newTemp(Ity_I32);
8293 IRTemp result = newTemp(Ity_I32);
8294
8295 assign(op1, get_gpr_w1(r1));
8296 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8297 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8298 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8299 put_gpr_w1(r1, mkexpr(result));
8300
8301 return "sh";
8302}
8303
florian55085f82012-11-21 00:36:55 +00008304static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008305s390_irgen_SHY(UChar r1, IRTemp op2addr)
8306{
8307 IRTemp op1 = newTemp(Ity_I32);
8308 IRTemp op2 = newTemp(Ity_I32);
8309 IRTemp result = newTemp(Ity_I32);
8310
8311 assign(op1, get_gpr_w1(r1));
8312 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8313 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8314 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8315 put_gpr_w1(r1, mkexpr(result));
8316
8317 return "shy";
8318}
8319
florian55085f82012-11-21 00:36:55 +00008320static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008321s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8322{
8323 IRTemp op2 = newTemp(Ity_I32);
8324 IRTemp op3 = newTemp(Ity_I32);
8325 IRTemp result = newTemp(Ity_I32);
8326
8327 assign(op2, get_gpr_w0(r1));
8328 assign(op3, get_gpr_w0(r2));
8329 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8330 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8331 put_gpr_w0(r1, mkexpr(result));
8332
8333 return "shhhr";
8334}
8335
florian55085f82012-11-21 00:36:55 +00008336static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008337s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8338{
8339 IRTemp op2 = newTemp(Ity_I32);
8340 IRTemp op3 = newTemp(Ity_I32);
8341 IRTemp result = newTemp(Ity_I32);
8342
8343 assign(op2, get_gpr_w0(r1));
8344 assign(op3, get_gpr_w1(r2));
8345 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8346 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8347 put_gpr_w0(r1, mkexpr(result));
8348
8349 return "shhlr";
8350}
8351
florian55085f82012-11-21 00:36:55 +00008352static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008353s390_irgen_SLR(UChar r1, UChar r2)
8354{
8355 IRTemp op1 = newTemp(Ity_I32);
8356 IRTemp op2 = newTemp(Ity_I32);
8357 IRTemp result = newTemp(Ity_I32);
8358
8359 assign(op1, get_gpr_w1(r1));
8360 assign(op2, get_gpr_w1(r2));
8361 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8362 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8363 put_gpr_w1(r1, mkexpr(result));
8364
8365 return "slr";
8366}
8367
florian55085f82012-11-21 00:36:55 +00008368static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008369s390_irgen_SLGR(UChar r1, UChar r2)
8370{
8371 IRTemp op1 = newTemp(Ity_I64);
8372 IRTemp op2 = newTemp(Ity_I64);
8373 IRTemp result = newTemp(Ity_I64);
8374
8375 assign(op1, get_gpr_dw0(r1));
8376 assign(op2, get_gpr_dw0(r2));
8377 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8378 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8379 put_gpr_dw0(r1, mkexpr(result));
8380
8381 return "slgr";
8382}
8383
florian55085f82012-11-21 00:36:55 +00008384static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008385s390_irgen_SLGFR(UChar r1, UChar r2)
8386{
8387 IRTemp op1 = newTemp(Ity_I64);
8388 IRTemp op2 = newTemp(Ity_I64);
8389 IRTemp result = newTemp(Ity_I64);
8390
8391 assign(op1, get_gpr_dw0(r1));
8392 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8393 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8394 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8395 put_gpr_dw0(r1, mkexpr(result));
8396
8397 return "slgfr";
8398}
8399
florian55085f82012-11-21 00:36:55 +00008400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008401s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8402{
8403 IRTemp op2 = newTemp(Ity_I32);
8404 IRTemp op3 = newTemp(Ity_I32);
8405 IRTemp result = newTemp(Ity_I32);
8406
8407 assign(op2, get_gpr_w1(r2));
8408 assign(op3, get_gpr_w1(r3));
8409 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8410 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8411 put_gpr_w1(r1, mkexpr(result));
8412
8413 return "slrk";
8414}
8415
florian55085f82012-11-21 00:36:55 +00008416static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008417s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8418{
8419 IRTemp op2 = newTemp(Ity_I64);
8420 IRTemp op3 = newTemp(Ity_I64);
8421 IRTemp result = newTemp(Ity_I64);
8422
8423 assign(op2, get_gpr_dw0(r2));
8424 assign(op3, get_gpr_dw0(r3));
8425 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8426 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8427 put_gpr_dw0(r1, mkexpr(result));
8428
8429 return "slgrk";
8430}
8431
florian55085f82012-11-21 00:36:55 +00008432static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008433s390_irgen_SL(UChar r1, IRTemp op2addr)
8434{
8435 IRTemp op1 = newTemp(Ity_I32);
8436 IRTemp op2 = newTemp(Ity_I32);
8437 IRTemp result = newTemp(Ity_I32);
8438
8439 assign(op1, get_gpr_w1(r1));
8440 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8441 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8442 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8443 put_gpr_w1(r1, mkexpr(result));
8444
8445 return "sl";
8446}
8447
florian55085f82012-11-21 00:36:55 +00008448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008449s390_irgen_SLY(UChar r1, IRTemp op2addr)
8450{
8451 IRTemp op1 = newTemp(Ity_I32);
8452 IRTemp op2 = newTemp(Ity_I32);
8453 IRTemp result = newTemp(Ity_I32);
8454
8455 assign(op1, get_gpr_w1(r1));
8456 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8457 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8458 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8459 put_gpr_w1(r1, mkexpr(result));
8460
8461 return "sly";
8462}
8463
florian55085f82012-11-21 00:36:55 +00008464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008465s390_irgen_SLG(UChar r1, IRTemp op2addr)
8466{
8467 IRTemp op1 = newTemp(Ity_I64);
8468 IRTemp op2 = newTemp(Ity_I64);
8469 IRTemp result = newTemp(Ity_I64);
8470
8471 assign(op1, get_gpr_dw0(r1));
8472 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8473 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8474 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8475 put_gpr_dw0(r1, mkexpr(result));
8476
8477 return "slg";
8478}
8479
florian55085f82012-11-21 00:36:55 +00008480static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008481s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8482{
8483 IRTemp op1 = newTemp(Ity_I64);
8484 IRTemp op2 = newTemp(Ity_I64);
8485 IRTemp result = newTemp(Ity_I64);
8486
8487 assign(op1, get_gpr_dw0(r1));
8488 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8489 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8490 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8491 put_gpr_dw0(r1, mkexpr(result));
8492
8493 return "slgf";
8494}
8495
florian55085f82012-11-21 00:36:55 +00008496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008497s390_irgen_SLFI(UChar r1, UInt i2)
8498{
8499 IRTemp op1 = newTemp(Ity_I32);
8500 UInt op2;
8501 IRTemp result = newTemp(Ity_I32);
8502
8503 assign(op1, get_gpr_w1(r1));
8504 op2 = i2;
8505 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8506 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8507 mkU32(op2)));
8508 put_gpr_w1(r1, mkexpr(result));
8509
8510 return "slfi";
8511}
8512
florian55085f82012-11-21 00:36:55 +00008513static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008514s390_irgen_SLGFI(UChar r1, UInt i2)
8515{
8516 IRTemp op1 = newTemp(Ity_I64);
8517 ULong op2;
8518 IRTemp result = newTemp(Ity_I64);
8519
8520 assign(op1, get_gpr_dw0(r1));
8521 op2 = (ULong)i2;
8522 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8523 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8524 mkU64(op2)));
8525 put_gpr_dw0(r1, mkexpr(result));
8526
8527 return "slgfi";
8528}
8529
florian55085f82012-11-21 00:36:55 +00008530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008531s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8532{
8533 IRTemp op2 = newTemp(Ity_I32);
8534 IRTemp op3 = newTemp(Ity_I32);
8535 IRTemp result = newTemp(Ity_I32);
8536
8537 assign(op2, get_gpr_w0(r1));
8538 assign(op3, get_gpr_w0(r2));
8539 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8540 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8541 put_gpr_w0(r1, mkexpr(result));
8542
8543 return "slhhhr";
8544}
8545
florian55085f82012-11-21 00:36:55 +00008546static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008547s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8548{
8549 IRTemp op2 = newTemp(Ity_I32);
8550 IRTemp op3 = newTemp(Ity_I32);
8551 IRTemp result = newTemp(Ity_I32);
8552
8553 assign(op2, get_gpr_w0(r1));
8554 assign(op3, get_gpr_w1(r2));
8555 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8556 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8557 put_gpr_w0(r1, mkexpr(result));
8558
8559 return "slhhlr";
8560}
8561
florian55085f82012-11-21 00:36:55 +00008562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008563s390_irgen_SLBR(UChar r1, UChar r2)
8564{
8565 IRTemp op1 = newTemp(Ity_I32);
8566 IRTemp op2 = newTemp(Ity_I32);
8567 IRTemp result = newTemp(Ity_I32);
8568 IRTemp borrow_in = newTemp(Ity_I32);
8569
8570 assign(op1, get_gpr_w1(r1));
8571 assign(op2, get_gpr_w1(r2));
8572 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8573 s390_call_calculate_cc(), mkU8(1))));
8574 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8575 mkexpr(borrow_in)));
8576 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8577 put_gpr_w1(r1, mkexpr(result));
8578
8579 return "slbr";
8580}
8581
florian55085f82012-11-21 00:36:55 +00008582static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008583s390_irgen_SLBGR(UChar r1, UChar r2)
8584{
8585 IRTemp op1 = newTemp(Ity_I64);
8586 IRTemp op2 = newTemp(Ity_I64);
8587 IRTemp result = newTemp(Ity_I64);
8588 IRTemp borrow_in = newTemp(Ity_I64);
8589
8590 assign(op1, get_gpr_dw0(r1));
8591 assign(op2, get_gpr_dw0(r2));
8592 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8593 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8594 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8595 mkexpr(borrow_in)));
8596 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8597 put_gpr_dw0(r1, mkexpr(result));
8598
8599 return "slbgr";
8600}
8601
florian55085f82012-11-21 00:36:55 +00008602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008603s390_irgen_SLB(UChar r1, IRTemp op2addr)
8604{
8605 IRTemp op1 = newTemp(Ity_I32);
8606 IRTemp op2 = newTemp(Ity_I32);
8607 IRTemp result = newTemp(Ity_I32);
8608 IRTemp borrow_in = newTemp(Ity_I32);
8609
8610 assign(op1, get_gpr_w1(r1));
8611 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8612 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8613 s390_call_calculate_cc(), mkU8(1))));
8614 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8615 mkexpr(borrow_in)));
8616 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8617 put_gpr_w1(r1, mkexpr(result));
8618
8619 return "slb";
8620}
8621
florian55085f82012-11-21 00:36:55 +00008622static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008623s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8624{
8625 IRTemp op1 = newTemp(Ity_I64);
8626 IRTemp op2 = newTemp(Ity_I64);
8627 IRTemp result = newTemp(Ity_I64);
8628 IRTemp borrow_in = newTemp(Ity_I64);
8629
8630 assign(op1, get_gpr_dw0(r1));
8631 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8632 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8633 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8634 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8635 mkexpr(borrow_in)));
8636 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8637 put_gpr_dw0(r1, mkexpr(result));
8638
8639 return "slbg";
8640}
8641
florian55085f82012-11-21 00:36:55 +00008642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008643s390_irgen_SVC(UChar i)
8644{
8645 IRTemp sysno = newTemp(Ity_I64);
8646
8647 if (i != 0) {
8648 assign(sysno, mkU64(i));
8649 } else {
8650 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8651 }
8652 system_call(mkexpr(sysno));
8653
8654 return "svc";
8655}
8656
florian55085f82012-11-21 00:36:55 +00008657static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008658s390_irgen_TM(UChar i2, IRTemp op1addr)
8659{
8660 UChar mask;
8661 IRTemp value = newTemp(Ity_I8);
8662
8663 mask = i2;
8664 assign(value, load(Ity_I8, mkexpr(op1addr)));
8665 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8666 mkU8(mask)));
8667
8668 return "tm";
8669}
8670
florian55085f82012-11-21 00:36:55 +00008671static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008672s390_irgen_TMY(UChar i2, IRTemp op1addr)
8673{
8674 UChar mask;
8675 IRTemp value = newTemp(Ity_I8);
8676
8677 mask = i2;
8678 assign(value, load(Ity_I8, mkexpr(op1addr)));
8679 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8680 mkU8(mask)));
8681
8682 return "tmy";
8683}
8684
florian55085f82012-11-21 00:36:55 +00008685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008686s390_irgen_TMHH(UChar r1, UShort i2)
8687{
8688 UShort mask;
8689 IRTemp value = newTemp(Ity_I16);
8690
8691 mask = i2;
8692 assign(value, get_gpr_hw0(r1));
8693 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8694 mkU16(mask)));
8695
8696 return "tmhh";
8697}
8698
florian55085f82012-11-21 00:36:55 +00008699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008700s390_irgen_TMHL(UChar r1, UShort i2)
8701{
8702 UShort mask;
8703 IRTemp value = newTemp(Ity_I16);
8704
8705 mask = i2;
8706 assign(value, get_gpr_hw1(r1));
8707 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8708 mkU16(mask)));
8709
8710 return "tmhl";
8711}
8712
florian55085f82012-11-21 00:36:55 +00008713static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008714s390_irgen_TMLH(UChar r1, UShort i2)
8715{
8716 UShort mask;
8717 IRTemp value = newTemp(Ity_I16);
8718
8719 mask = i2;
8720 assign(value, get_gpr_hw2(r1));
8721 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8722 mkU16(mask)));
8723
8724 return "tmlh";
8725}
8726
florian55085f82012-11-21 00:36:55 +00008727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008728s390_irgen_TMLL(UChar r1, UShort i2)
8729{
8730 UShort mask;
8731 IRTemp value = newTemp(Ity_I16);
8732
8733 mask = i2;
8734 assign(value, get_gpr_hw3(r1));
8735 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8736 mkU16(mask)));
8737
8738 return "tmll";
8739}
8740
florian55085f82012-11-21 00:36:55 +00008741static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008742s390_irgen_EFPC(UChar r1)
8743{
8744 put_gpr_w1(r1, get_fpc_w0());
8745
8746 return "efpc";
8747}
8748
florian55085f82012-11-21 00:36:55 +00008749static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008750s390_irgen_LER(UChar r1, UChar r2)
8751{
8752 put_fpr_w0(r1, get_fpr_w0(r2));
8753
8754 return "ler";
8755}
8756
florian55085f82012-11-21 00:36:55 +00008757static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008758s390_irgen_LDR(UChar r1, UChar r2)
8759{
8760 put_fpr_dw0(r1, get_fpr_dw0(r2));
8761
8762 return "ldr";
8763}
8764
florian55085f82012-11-21 00:36:55 +00008765static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008766s390_irgen_LXR(UChar r1, UChar r2)
8767{
8768 put_fpr_dw0(r1, get_fpr_dw0(r2));
8769 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8770
8771 return "lxr";
8772}
8773
florian55085f82012-11-21 00:36:55 +00008774static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008775s390_irgen_LE(UChar r1, IRTemp op2addr)
8776{
8777 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8778
8779 return "le";
8780}
8781
florian55085f82012-11-21 00:36:55 +00008782static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008783s390_irgen_LD(UChar r1, IRTemp op2addr)
8784{
8785 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8786
8787 return "ld";
8788}
8789
florian55085f82012-11-21 00:36:55 +00008790static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008791s390_irgen_LEY(UChar r1, IRTemp op2addr)
8792{
8793 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8794
8795 return "ley";
8796}
8797
florian55085f82012-11-21 00:36:55 +00008798static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008799s390_irgen_LDY(UChar r1, IRTemp op2addr)
8800{
8801 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8802
8803 return "ldy";
8804}
8805
florian55085f82012-11-21 00:36:55 +00008806static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008807s390_irgen_LFPC(IRTemp op2addr)
8808{
8809 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8810
8811 return "lfpc";
8812}
8813
florian55085f82012-11-21 00:36:55 +00008814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008815s390_irgen_LZER(UChar r1)
8816{
8817 put_fpr_w0(r1, mkF32i(0x0));
8818
8819 return "lzer";
8820}
8821
florian55085f82012-11-21 00:36:55 +00008822static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008823s390_irgen_LZDR(UChar r1)
8824{
8825 put_fpr_dw0(r1, mkF64i(0x0));
8826
8827 return "lzdr";
8828}
8829
florian55085f82012-11-21 00:36:55 +00008830static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008831s390_irgen_LZXR(UChar r1)
8832{
8833 put_fpr_dw0(r1, mkF64i(0x0));
8834 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8835
8836 return "lzxr";
8837}
8838
florian55085f82012-11-21 00:36:55 +00008839static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008840s390_irgen_SRNM(IRTemp op2addr)
8841{
florianf0fa1be2012-09-18 20:24:38 +00008842 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008843
florianf0fa1be2012-09-18 20:24:38 +00008844 input_mask = 3;
8845 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008846
florianf0fa1be2012-09-18 20:24:38 +00008847 put_fpc_w0(binop(Iop_Or32,
8848 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8849 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8850 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008851 return "srnm";
8852}
8853
florian55085f82012-11-21 00:36:55 +00008854static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008855s390_irgen_SRNMB(IRTemp op2addr)
8856{
8857 UInt input_mask, fpc_mask;
8858
8859 input_mask = 7;
8860 fpc_mask = 7;
8861
8862 put_fpc_w0(binop(Iop_Or32,
8863 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8864 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8865 mkU32(input_mask))));
8866 return "srnmb";
8867}
8868
florian81a4bfe2012-09-20 01:25:28 +00008869static void
florianf0fa1be2012-09-18 20:24:38 +00008870s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8871{
8872 if (b2 == 0) { /* This is the typical case */
8873 if (d2 > 3) {
8874 if (s390_host_has_fpext && d2 == 7) {
8875 /* ok */
8876 } else {
8877 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008878 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008879 }
8880 }
8881 }
8882
8883 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8884}
8885
florian82cdba62013-03-12 01:31:24 +00008886/* Wrapper to validate the parameter as in SRNMB is not required, as all
8887 the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8888static const HChar *
8889s390_irgen_SRNMT(IRTemp op2addr)
8890{
8891 UInt input_mask, fpc_mask;
8892
8893 input_mask = 7;
8894 fpc_mask = 0x70;
8895
8896 /* fpc[25:27] <- op2addr[61:63]
8897 fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8898 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8899 binop(Iop_Shl32, binop(Iop_And32,
8900 unop(Iop_64to32, mkexpr(op2addr)),
8901 mkU32(input_mask)), mkU8(4))));
8902 return "srnmt";
8903}
8904
florianf0fa1be2012-09-18 20:24:38 +00008905
florian55085f82012-11-21 00:36:55 +00008906static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008907s390_irgen_SFPC(UChar r1)
8908{
8909 put_fpc_w0(get_gpr_w1(r1));
8910
8911 return "sfpc";
8912}
8913
florian55085f82012-11-21 00:36:55 +00008914static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008915s390_irgen_STE(UChar r1, IRTemp op2addr)
8916{
8917 store(mkexpr(op2addr), get_fpr_w0(r1));
8918
8919 return "ste";
8920}
8921
florian55085f82012-11-21 00:36:55 +00008922static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008923s390_irgen_STD(UChar r1, IRTemp op2addr)
8924{
8925 store(mkexpr(op2addr), get_fpr_dw0(r1));
8926
8927 return "std";
8928}
8929
florian55085f82012-11-21 00:36:55 +00008930static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008931s390_irgen_STEY(UChar r1, IRTemp op2addr)
8932{
8933 store(mkexpr(op2addr), get_fpr_w0(r1));
8934
8935 return "stey";
8936}
8937
florian55085f82012-11-21 00:36:55 +00008938static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008939s390_irgen_STDY(UChar r1, IRTemp op2addr)
8940{
8941 store(mkexpr(op2addr), get_fpr_dw0(r1));
8942
8943 return "stdy";
8944}
8945
florian55085f82012-11-21 00:36:55 +00008946static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008947s390_irgen_STFPC(IRTemp op2addr)
8948{
8949 store(mkexpr(op2addr), get_fpc_w0());
8950
8951 return "stfpc";
8952}
8953
florian55085f82012-11-21 00:36:55 +00008954static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008955s390_irgen_AEBR(UChar r1, UChar r2)
8956{
8957 IRTemp op1 = newTemp(Ity_F32);
8958 IRTemp op2 = newTemp(Ity_F32);
8959 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008960 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008961
8962 assign(op1, get_fpr_w0(r1));
8963 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008964 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008965 mkexpr(op2)));
8966 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8967 put_fpr_w0(r1, mkexpr(result));
8968
8969 return "aebr";
8970}
8971
florian55085f82012-11-21 00:36:55 +00008972static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008973s390_irgen_ADBR(UChar r1, UChar r2)
8974{
8975 IRTemp op1 = newTemp(Ity_F64);
8976 IRTemp op2 = newTemp(Ity_F64);
8977 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008978 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008979
8980 assign(op1, get_fpr_dw0(r1));
8981 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008982 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008983 mkexpr(op2)));
8984 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8985 put_fpr_dw0(r1, mkexpr(result));
8986
8987 return "adbr";
8988}
8989
florian55085f82012-11-21 00:36:55 +00008990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008991s390_irgen_AEB(UChar r1, IRTemp op2addr)
8992{
8993 IRTemp op1 = newTemp(Ity_F32);
8994 IRTemp op2 = newTemp(Ity_F32);
8995 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008996 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008997
8998 assign(op1, get_fpr_w0(r1));
8999 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009000 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009001 mkexpr(op2)));
9002 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9003 put_fpr_w0(r1, mkexpr(result));
9004
9005 return "aeb";
9006}
9007
florian55085f82012-11-21 00:36:55 +00009008static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009009s390_irgen_ADB(UChar r1, IRTemp op2addr)
9010{
9011 IRTemp op1 = newTemp(Ity_F64);
9012 IRTemp op2 = newTemp(Ity_F64);
9013 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009014 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009015
9016 assign(op1, get_fpr_dw0(r1));
9017 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009018 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009019 mkexpr(op2)));
9020 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9021 put_fpr_dw0(r1, mkexpr(result));
9022
9023 return "adb";
9024}
9025
florian55085f82012-11-21 00:36:55 +00009026static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009027s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
9028 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009029{
florian125e20d2012-10-07 15:42:37 +00009030 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009031 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009032 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009033 }
sewardj2019a972011-03-07 16:04:07 +00009034 IRTemp op2 = newTemp(Ity_I32);
9035
9036 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009037 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009038 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009039
9040 return "cefbr";
9041}
9042
florian55085f82012-11-21 00:36:55 +00009043static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009044s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
9045 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009046{
9047 IRTemp op2 = newTemp(Ity_I32);
9048
9049 assign(op2, get_gpr_w1(r2));
9050 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
9051
9052 return "cdfbr";
9053}
9054
florian55085f82012-11-21 00:36:55 +00009055static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009056s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
9057 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009058{
florian125e20d2012-10-07 15:42:37 +00009059 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009060 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009061 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009062 }
sewardj2019a972011-03-07 16:04:07 +00009063 IRTemp op2 = newTemp(Ity_I64);
9064
9065 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009066 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009067 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009068
9069 return "cegbr";
9070}
9071
florian55085f82012-11-21 00:36:55 +00009072static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009073s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
9074 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009075{
florian125e20d2012-10-07 15:42:37 +00009076 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009077 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009078 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009079 }
sewardj2019a972011-03-07 16:04:07 +00009080 IRTemp op2 = newTemp(Ity_I64);
9081
9082 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009083 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009084 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009085
9086 return "cdgbr";
9087}
9088
florian55085f82012-11-21 00:36:55 +00009089static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009090s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
9091 UChar r1, UChar r2)
9092{
floriane75dafa2012-09-01 17:54:09 +00009093 if (! s390_host_has_fpext) {
9094 emulation_failure(EmFail_S390X_fpext);
9095 } else {
9096 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009097
floriane75dafa2012-09-01 17:54:09 +00009098 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009099 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009100 mkexpr(op2)));
9101 }
florian1c8f7ff2012-09-01 00:12:11 +00009102 return "celfbr";
9103}
9104
florian55085f82012-11-21 00:36:55 +00009105static const HChar *
floriand2129202012-09-01 20:01:39 +00009106s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
9107 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00009108{
floriane75dafa2012-09-01 17:54:09 +00009109 if (! s390_host_has_fpext) {
9110 emulation_failure(EmFail_S390X_fpext);
9111 } else {
9112 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009113
floriane75dafa2012-09-01 17:54:09 +00009114 assign(op2, get_gpr_w1(r2));
9115 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
9116 }
florian1c8f7ff2012-09-01 00:12:11 +00009117 return "cdlfbr";
9118}
9119
florian55085f82012-11-21 00:36:55 +00009120static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009121s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
9122 UChar r1, UChar r2)
9123{
floriane75dafa2012-09-01 17:54:09 +00009124 if (! s390_host_has_fpext) {
9125 emulation_failure(EmFail_S390X_fpext);
9126 } else {
9127 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009128
floriane75dafa2012-09-01 17:54:09 +00009129 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009130 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009131 mkexpr(op2)));
9132 }
florian1c8f7ff2012-09-01 00:12:11 +00009133 return "celgbr";
9134}
9135
florian55085f82012-11-21 00:36:55 +00009136static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009137s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
9138 UChar r1, UChar r2)
9139{
floriane75dafa2012-09-01 17:54:09 +00009140 if (! s390_host_has_fpext) {
9141 emulation_failure(EmFail_S390X_fpext);
9142 } else {
9143 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009144
floriane75dafa2012-09-01 17:54:09 +00009145 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009146 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
9147 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009148 mkexpr(op2)));
9149 }
florian1c8f7ff2012-09-01 00:12:11 +00009150 return "cdlgbr";
9151}
9152
florian55085f82012-11-21 00:36:55 +00009153static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009154s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9155 UChar r1, UChar r2)
9156{
floriane75dafa2012-09-01 17:54:09 +00009157 if (! s390_host_has_fpext) {
9158 emulation_failure(EmFail_S390X_fpext);
9159 } else {
9160 IRTemp op = newTemp(Ity_F32);
9161 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009162 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009163
floriane75dafa2012-09-01 17:54:09 +00009164 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009165 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009166 mkexpr(op)));
9167 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009168 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009169 }
florian1c8f7ff2012-09-01 00:12:11 +00009170 return "clfebr";
9171}
9172
florian55085f82012-11-21 00:36:55 +00009173static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009174s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9175 UChar r1, UChar r2)
9176{
floriane75dafa2012-09-01 17:54:09 +00009177 if (! s390_host_has_fpext) {
9178 emulation_failure(EmFail_S390X_fpext);
9179 } else {
9180 IRTemp op = newTemp(Ity_F64);
9181 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009182 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009183
floriane75dafa2012-09-01 17:54:09 +00009184 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009185 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009186 mkexpr(op)));
9187 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009188 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009189 }
florian1c8f7ff2012-09-01 00:12:11 +00009190 return "clfdbr";
9191}
9192
florian55085f82012-11-21 00:36:55 +00009193static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009194s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9195 UChar r1, UChar r2)
9196{
floriane75dafa2012-09-01 17:54:09 +00009197 if (! s390_host_has_fpext) {
9198 emulation_failure(EmFail_S390X_fpext);
9199 } else {
9200 IRTemp op = newTemp(Ity_F32);
9201 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009202 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009203
floriane75dafa2012-09-01 17:54:09 +00009204 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009205 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009206 mkexpr(op)));
9207 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009208 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009209 }
florian1c8f7ff2012-09-01 00:12:11 +00009210 return "clgebr";
9211}
9212
florian55085f82012-11-21 00:36:55 +00009213static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009214s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9215 UChar r1, UChar r2)
9216{
floriane75dafa2012-09-01 17:54:09 +00009217 if (! s390_host_has_fpext) {
9218 emulation_failure(EmFail_S390X_fpext);
9219 } else {
9220 IRTemp op = newTemp(Ity_F64);
9221 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009222 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009223
floriane75dafa2012-09-01 17:54:09 +00009224 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009225 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009226 mkexpr(op)));
9227 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009228 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009229 }
florian1c8f7ff2012-09-01 00:12:11 +00009230 return "clgdbr";
9231}
9232
florian55085f82012-11-21 00:36:55 +00009233static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009234s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9235 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009236{
9237 IRTemp op = newTemp(Ity_F32);
9238 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009239 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009240
9241 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009242 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009243 mkexpr(op)));
9244 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009245 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009246
9247 return "cfebr";
9248}
9249
florian55085f82012-11-21 00:36:55 +00009250static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009251s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9252 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009253{
9254 IRTemp op = newTemp(Ity_F64);
9255 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009256 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009257
9258 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009259 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009260 mkexpr(op)));
9261 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009262 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009263
9264 return "cfdbr";
9265}
9266
florian55085f82012-11-21 00:36:55 +00009267static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009268s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9269 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009270{
9271 IRTemp op = newTemp(Ity_F32);
9272 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009273 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009274
9275 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009276 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009277 mkexpr(op)));
9278 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009279 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009280
9281 return "cgebr";
9282}
9283
florian55085f82012-11-21 00:36:55 +00009284static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009285s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9286 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009287{
9288 IRTemp op = newTemp(Ity_F64);
9289 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009290 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009291
9292 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009293 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009294 mkexpr(op)));
9295 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009296 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009297
9298 return "cgdbr";
9299}
9300
florian55085f82012-11-21 00:36:55 +00009301static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009302s390_irgen_DEBR(UChar r1, UChar r2)
9303{
9304 IRTemp op1 = newTemp(Ity_F32);
9305 IRTemp op2 = newTemp(Ity_F32);
9306 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009307 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009308
9309 assign(op1, get_fpr_w0(r1));
9310 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009311 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009312 mkexpr(op2)));
9313 put_fpr_w0(r1, mkexpr(result));
9314
9315 return "debr";
9316}
9317
florian55085f82012-11-21 00:36:55 +00009318static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009319s390_irgen_DDBR(UChar r1, UChar r2)
9320{
9321 IRTemp op1 = newTemp(Ity_F64);
9322 IRTemp op2 = newTemp(Ity_F64);
9323 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009324 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009325
9326 assign(op1, get_fpr_dw0(r1));
9327 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009328 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009329 mkexpr(op2)));
9330 put_fpr_dw0(r1, mkexpr(result));
9331
9332 return "ddbr";
9333}
9334
florian55085f82012-11-21 00:36:55 +00009335static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009336s390_irgen_DEB(UChar r1, IRTemp op2addr)
9337{
9338 IRTemp op1 = newTemp(Ity_F32);
9339 IRTemp op2 = newTemp(Ity_F32);
9340 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009341 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009342
9343 assign(op1, get_fpr_w0(r1));
9344 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009345 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009346 mkexpr(op2)));
9347 put_fpr_w0(r1, mkexpr(result));
9348
9349 return "deb";
9350}
9351
florian55085f82012-11-21 00:36:55 +00009352static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009353s390_irgen_DDB(UChar r1, IRTemp op2addr)
9354{
9355 IRTemp op1 = newTemp(Ity_F64);
9356 IRTemp op2 = newTemp(Ity_F64);
9357 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009358 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009359
9360 assign(op1, get_fpr_dw0(r1));
9361 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009362 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009363 mkexpr(op2)));
9364 put_fpr_dw0(r1, mkexpr(result));
9365
9366 return "ddb";
9367}
9368
florian55085f82012-11-21 00:36:55 +00009369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009370s390_irgen_LTEBR(UChar r1, UChar r2)
9371{
9372 IRTemp result = newTemp(Ity_F32);
9373
9374 assign(result, get_fpr_w0(r2));
9375 put_fpr_w0(r1, mkexpr(result));
9376 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9377
9378 return "ltebr";
9379}
9380
florian55085f82012-11-21 00:36:55 +00009381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009382s390_irgen_LTDBR(UChar r1, UChar r2)
9383{
9384 IRTemp result = newTemp(Ity_F64);
9385
9386 assign(result, get_fpr_dw0(r2));
9387 put_fpr_dw0(r1, mkexpr(result));
9388 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9389
9390 return "ltdbr";
9391}
9392
florian55085f82012-11-21 00:36:55 +00009393static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009394s390_irgen_LCEBR(UChar r1, UChar r2)
9395{
9396 IRTemp result = newTemp(Ity_F32);
9397
9398 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9399 put_fpr_w0(r1, mkexpr(result));
9400 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9401
9402 return "lcebr";
9403}
9404
florian55085f82012-11-21 00:36:55 +00009405static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009406s390_irgen_LCDBR(UChar r1, UChar r2)
9407{
9408 IRTemp result = newTemp(Ity_F64);
9409
9410 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9411 put_fpr_dw0(r1, mkexpr(result));
9412 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9413
9414 return "lcdbr";
9415}
9416
florian55085f82012-11-21 00:36:55 +00009417static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009418s390_irgen_LDEBR(UChar r1, UChar r2)
9419{
9420 IRTemp op = newTemp(Ity_F32);
9421
9422 assign(op, get_fpr_w0(r2));
9423 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9424
9425 return "ldebr";
9426}
9427
florian55085f82012-11-21 00:36:55 +00009428static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009429s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9430{
9431 IRTemp op = newTemp(Ity_F32);
9432
9433 assign(op, load(Ity_F32, mkexpr(op2addr)));
9434 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9435
9436 return "ldeb";
9437}
9438
florian55085f82012-11-21 00:36:55 +00009439static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009440s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9441 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009442{
florian125e20d2012-10-07 15:42:37 +00009443 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009444 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009445 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009446 }
sewardj2019a972011-03-07 16:04:07 +00009447 IRTemp op = newTemp(Ity_F64);
9448
9449 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009450 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009451 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009452
9453 return "ledbr";
9454}
9455
florian55085f82012-11-21 00:36:55 +00009456static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009457s390_irgen_MEEBR(UChar r1, UChar r2)
9458{
9459 IRTemp op1 = newTemp(Ity_F32);
9460 IRTemp op2 = newTemp(Ity_F32);
9461 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009462 IRRoundingMode rounding_mode =
9463 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009464
9465 assign(op1, get_fpr_w0(r1));
9466 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009467 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009468 mkexpr(op2)));
9469 put_fpr_w0(r1, mkexpr(result));
9470
9471 return "meebr";
9472}
9473
florian55085f82012-11-21 00:36:55 +00009474static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009475s390_irgen_MDBR(UChar r1, UChar r2)
9476{
9477 IRTemp op1 = newTemp(Ity_F64);
9478 IRTemp op2 = newTemp(Ity_F64);
9479 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009480 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009481
9482 assign(op1, get_fpr_dw0(r1));
9483 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009484 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009485 mkexpr(op2)));
9486 put_fpr_dw0(r1, mkexpr(result));
9487
9488 return "mdbr";
9489}
9490
florian55085f82012-11-21 00:36:55 +00009491static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009492s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9493{
9494 IRTemp op1 = newTemp(Ity_F32);
9495 IRTemp op2 = newTemp(Ity_F32);
9496 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009497 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009498
9499 assign(op1, get_fpr_w0(r1));
9500 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009501 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009502 mkexpr(op2)));
9503 put_fpr_w0(r1, mkexpr(result));
9504
9505 return "meeb";
9506}
9507
florian55085f82012-11-21 00:36:55 +00009508static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009509s390_irgen_MDB(UChar r1, IRTemp op2addr)
9510{
9511 IRTemp op1 = newTemp(Ity_F64);
9512 IRTemp op2 = newTemp(Ity_F64);
9513 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009514 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009515
9516 assign(op1, get_fpr_dw0(r1));
9517 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009518 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009519 mkexpr(op2)));
9520 put_fpr_dw0(r1, mkexpr(result));
9521
9522 return "mdb";
9523}
9524
florian55085f82012-11-21 00:36:55 +00009525static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009526s390_irgen_SEBR(UChar r1, UChar r2)
9527{
9528 IRTemp op1 = newTemp(Ity_F32);
9529 IRTemp op2 = newTemp(Ity_F32);
9530 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009531 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009532
9533 assign(op1, get_fpr_w0(r1));
9534 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009535 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009536 mkexpr(op2)));
9537 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9538 put_fpr_w0(r1, mkexpr(result));
9539
9540 return "sebr";
9541}
9542
florian55085f82012-11-21 00:36:55 +00009543static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009544s390_irgen_SDBR(UChar r1, UChar r2)
9545{
9546 IRTemp op1 = newTemp(Ity_F64);
9547 IRTemp op2 = newTemp(Ity_F64);
9548 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009549 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009550
9551 assign(op1, get_fpr_dw0(r1));
9552 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009553 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009554 mkexpr(op2)));
9555 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9556 put_fpr_dw0(r1, mkexpr(result));
9557
9558 return "sdbr";
9559}
9560
florian55085f82012-11-21 00:36:55 +00009561static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009562s390_irgen_SEB(UChar r1, IRTemp op2addr)
9563{
9564 IRTemp op1 = newTemp(Ity_F32);
9565 IRTemp op2 = newTemp(Ity_F32);
9566 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009567 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009568
9569 assign(op1, get_fpr_w0(r1));
9570 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009571 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009572 mkexpr(op2)));
9573 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9574 put_fpr_w0(r1, mkexpr(result));
9575
9576 return "seb";
9577}
9578
florian55085f82012-11-21 00:36:55 +00009579static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009580s390_irgen_SDB(UChar r1, IRTemp op2addr)
9581{
9582 IRTemp op1 = newTemp(Ity_F64);
9583 IRTemp op2 = newTemp(Ity_F64);
9584 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009585 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009586
9587 assign(op1, get_fpr_dw0(r1));
9588 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009589 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009590 mkexpr(op2)));
9591 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9592 put_fpr_dw0(r1, mkexpr(result));
9593
9594 return "sdb";
9595}
9596
florian55085f82012-11-21 00:36:55 +00009597static const HChar *
florian12390202012-11-10 22:34:14 +00009598s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9599{
9600 IRTemp op1 = newTemp(Ity_D64);
9601 IRTemp op2 = newTemp(Ity_D64);
9602 IRTemp result = newTemp(Ity_D64);
9603 IRTemp rounding_mode;
9604
9605 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009606
9607 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9608 emulation_warning(EmWarn_S390X_fpext_rounding);
9609 m4 = S390_DFP_ROUND_PER_FPC_0;
9610 }
9611
florian12390202012-11-10 22:34:14 +00009612 rounding_mode = encode_dfp_rounding_mode(m4);
9613 assign(op1, get_dpr_dw0(r2));
9614 assign(op2, get_dpr_dw0(r3));
9615 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9616 mkexpr(op2)));
9617 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9618 put_dpr_dw0(r1, mkexpr(result));
9619
9620 return (m4 == 0) ? "adtr" : "adtra";
9621}
9622
florian55085f82012-11-21 00:36:55 +00009623static const HChar *
floriane38f6412012-12-21 17:32:12 +00009624s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9625{
9626 IRTemp op1 = newTemp(Ity_D128);
9627 IRTemp op2 = newTemp(Ity_D128);
9628 IRTemp result = newTemp(Ity_D128);
9629 IRTemp rounding_mode;
9630
9631 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009632
9633 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9634 emulation_warning(EmWarn_S390X_fpext_rounding);
9635 m4 = S390_DFP_ROUND_PER_FPC_0;
9636 }
9637
floriane38f6412012-12-21 17:32:12 +00009638 rounding_mode = encode_dfp_rounding_mode(m4);
9639 assign(op1, get_dpr_pair(r2));
9640 assign(op2, get_dpr_pair(r3));
9641 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9642 mkexpr(op2)));
9643 put_dpr_pair(r1, mkexpr(result));
9644
9645 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9646
9647 return (m4 == 0) ? "axtr" : "axtra";
9648}
9649
9650static const HChar *
9651s390_irgen_CDTR(UChar r1, UChar r2)
9652{
9653 IRTemp op1 = newTemp(Ity_D64);
9654 IRTemp op2 = newTemp(Ity_D64);
9655 IRTemp cc_vex = newTemp(Ity_I32);
9656 IRTemp cc_s390 = newTemp(Ity_I32);
9657
9658 assign(op1, get_dpr_dw0(r1));
9659 assign(op2, get_dpr_dw0(r2));
9660 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9661
florian2d3d87f2012-12-21 21:05:17 +00009662 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009663 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9664
9665 return "cdtr";
9666}
9667
9668static const HChar *
9669s390_irgen_CXTR(UChar r1, UChar r2)
9670{
9671 IRTemp op1 = newTemp(Ity_D128);
9672 IRTemp op2 = newTemp(Ity_D128);
9673 IRTemp cc_vex = newTemp(Ity_I32);
9674 IRTemp cc_s390 = newTemp(Ity_I32);
9675
9676 assign(op1, get_dpr_pair(r1));
9677 assign(op2, get_dpr_pair(r2));
9678 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9679
florian2d3d87f2012-12-21 21:05:17 +00009680 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009681 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9682
9683 return "cxtr";
9684}
9685
9686static const HChar *
florian5f034622013-01-13 02:29:05 +00009687s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9688 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9689{
9690 vassert(s390_host_has_dfp);
9691
9692 if (! s390_host_has_fpext) {
9693 emulation_failure(EmFail_S390X_fpext);
9694 } else {
9695 IRTemp op2 = newTemp(Ity_I32);
9696
9697 assign(op2, get_gpr_w1(r2));
9698 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9699 }
9700 return "cdftr";
9701}
9702
9703static const HChar *
9704s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9705 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9706{
9707 vassert(s390_host_has_dfp);
9708
9709 if (! s390_host_has_fpext) {
9710 emulation_failure(EmFail_S390X_fpext);
9711 } else {
9712 IRTemp op2 = newTemp(Ity_I32);
9713
9714 assign(op2, get_gpr_w1(r2));
9715 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9716 }
9717 return "cxftr";
9718}
9719
9720static const HChar *
floriana887acd2013-02-08 23:32:54 +00009721s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9722 UChar r1, UChar r2)
9723{
9724 IRTemp op2 = newTemp(Ity_I64);
9725
9726 vassert(s390_host_has_dfp);
9727 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9728 emulation_warning(EmWarn_S390X_fpext_rounding);
9729 m3 = S390_DFP_ROUND_PER_FPC_0;
9730 }
9731
9732 assign(op2, get_gpr_dw0(r2));
9733 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9734 mkexpr(op2)));
9735
9736 return (m3 == 0) ? "cdgtr" : "cdgtra";
9737}
9738
9739static const HChar *
9740s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9741 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9742{
9743 IRTemp op2 = newTemp(Ity_I64);
9744
9745 vassert(s390_host_has_dfp);
9746
florian1bb7f6f2013-02-11 00:03:27 +00009747 /* No emulation warning here about an non-zero m3 on hosts without
9748 floating point extension facility. No rounding is performed */
9749
floriana887acd2013-02-08 23:32:54 +00009750 assign(op2, get_gpr_dw0(r2));
9751 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9752
9753 return "cxgtr";
9754}
9755
9756static const HChar *
florian5f034622013-01-13 02:29:05 +00009757s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9758 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9759{
9760 vassert(s390_host_has_dfp);
9761
9762 if (! s390_host_has_fpext) {
9763 emulation_failure(EmFail_S390X_fpext);
9764 } else {
9765 IRTemp op2 = newTemp(Ity_I32);
9766
9767 assign(op2, get_gpr_w1(r2));
9768 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9769 }
9770 return "cdlftr";
9771}
9772
9773static const HChar *
9774s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9775 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9776{
9777 vassert(s390_host_has_dfp);
9778
9779 if (! s390_host_has_fpext) {
9780 emulation_failure(EmFail_S390X_fpext);
9781 } else {
9782 IRTemp op2 = newTemp(Ity_I32);
9783
9784 assign(op2, get_gpr_w1(r2));
9785 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9786 }
9787 return "cxlftr";
9788}
9789
9790static const HChar *
9791s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9792 UChar r1, UChar r2)
9793{
9794 vassert(s390_host_has_dfp);
9795
9796 if (! s390_host_has_fpext) {
9797 emulation_failure(EmFail_S390X_fpext);
9798 } else {
9799 IRTemp op2 = newTemp(Ity_I64);
9800
9801 assign(op2, get_gpr_dw0(r2));
9802 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9803 mkexpr(encode_dfp_rounding_mode(m3)),
9804 mkexpr(op2)));
9805 }
9806 return "cdlgtr";
9807}
9808
9809static const HChar *
9810s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9811 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9812{
9813 vassert(s390_host_has_dfp);
9814
9815 if (! s390_host_has_fpext) {
9816 emulation_failure(EmFail_S390X_fpext);
9817 } else {
9818 IRTemp op2 = newTemp(Ity_I64);
9819
9820 assign(op2, get_gpr_dw0(r2));
9821 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9822 }
9823 return "cxlgtr";
9824}
9825
9826static const HChar *
9827s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9828 UChar r1, UChar r2)
9829{
9830 vassert(s390_host_has_dfp);
9831
9832 if (! s390_host_has_fpext) {
9833 emulation_failure(EmFail_S390X_fpext);
9834 } else {
9835 IRTemp op = newTemp(Ity_D64);
9836 IRTemp result = newTemp(Ity_I32);
9837 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9838
9839 assign(op, get_dpr_dw0(r2));
9840 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9841 mkexpr(op)));
9842 put_gpr_w1(r1, mkexpr(result));
9843 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9844 }
9845 return "cfdtr";
9846}
9847
9848static const HChar *
9849s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9850 UChar r1, UChar r2)
9851{
9852 vassert(s390_host_has_dfp);
9853
9854 if (! s390_host_has_fpext) {
9855 emulation_failure(EmFail_S390X_fpext);
9856 } else {
9857 IRTemp op = newTemp(Ity_D128);
9858 IRTemp result = newTemp(Ity_I32);
9859 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9860
9861 assign(op, get_dpr_pair(r2));
9862 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9863 mkexpr(op)));
9864 put_gpr_w1(r1, mkexpr(result));
9865 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
9866 }
9867 return "cfxtr";
9868}
9869
9870static const HChar *
floriana887acd2013-02-08 23:32:54 +00009871s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9872 UChar r1, UChar r2)
9873{
9874 IRTemp op = newTemp(Ity_D64);
9875 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9876
9877 vassert(s390_host_has_dfp);
9878
9879 /* If fpext is not installed and m3 is in 1:7,
9880 rounding mode performed is unpredictable */
9881 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9882 emulation_warning(EmWarn_S390X_fpext_rounding);
9883 m3 = S390_DFP_ROUND_PER_FPC_0;
9884 }
9885
9886 assign(op, get_dpr_dw0(r2));
9887 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9888 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9889
9890 return "cgdtr";
9891}
9892
9893static const HChar *
9894s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9895 UChar r1, UChar r2)
9896{
9897 IRTemp op = newTemp(Ity_D128);
9898 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9899
9900 vassert(s390_host_has_dfp);
9901
9902 /* If fpext is not installed and m3 is in 1:7,
9903 rounding mode performed is unpredictable */
9904 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9905 emulation_warning(EmWarn_S390X_fpext_rounding);
9906 m3 = S390_DFP_ROUND_PER_FPC_0;
9907 }
9908 assign(op, get_dpr_pair(r2));
9909 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9910 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9911
9912 return "cgxtr";
9913}
9914
9915static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009916s390_irgen_CEDTR(UChar r1, UChar r2)
9917{
9918 IRTemp op1 = newTemp(Ity_D64);
9919 IRTemp op2 = newTemp(Ity_D64);
9920 IRTemp cc_vex = newTemp(Ity_I32);
9921 IRTemp cc_s390 = newTemp(Ity_I32);
9922
9923 vassert(s390_host_has_dfp);
9924 assign(op1, get_dpr_dw0(r1));
9925 assign(op2, get_dpr_dw0(r2));
9926 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9927
9928 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9929 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9930
9931 return "cedtr";
9932}
9933
9934static const HChar *
9935s390_irgen_CEXTR(UChar r1, UChar r2)
9936{
9937 IRTemp op1 = newTemp(Ity_D128);
9938 IRTemp op2 = newTemp(Ity_D128);
9939 IRTemp cc_vex = newTemp(Ity_I32);
9940 IRTemp cc_s390 = newTemp(Ity_I32);
9941
9942 vassert(s390_host_has_dfp);
9943 assign(op1, get_dpr_pair(r1));
9944 assign(op2, get_dpr_pair(r2));
9945 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9946
9947 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9948 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9949
9950 return "cextr";
9951}
9952
9953static const HChar *
florian5f034622013-01-13 02:29:05 +00009954s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9955 UChar r1, UChar r2)
9956{
9957 vassert(s390_host_has_dfp);
9958
9959 if (! s390_host_has_fpext) {
9960 emulation_failure(EmFail_S390X_fpext);
9961 } else {
9962 IRTemp op = newTemp(Ity_D64);
9963 IRTemp result = newTemp(Ity_I32);
9964 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9965
9966 assign(op, get_dpr_dw0(r2));
9967 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9968 mkexpr(op)));
9969 put_gpr_w1(r1, mkexpr(result));
9970 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9971 }
9972 return "clfdtr";
9973}
9974
9975static const HChar *
9976s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9977 UChar r1, UChar r2)
9978{
9979 vassert(s390_host_has_dfp);
9980
9981 if (! s390_host_has_fpext) {
9982 emulation_failure(EmFail_S390X_fpext);
9983 } else {
9984 IRTemp op = newTemp(Ity_D128);
9985 IRTemp result = newTemp(Ity_I32);
9986 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9987
9988 assign(op, get_dpr_pair(r2));
9989 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
9990 mkexpr(op)));
9991 put_gpr_w1(r1, mkexpr(result));
9992 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
9993 }
9994 return "clfxtr";
9995}
9996
9997static const HChar *
9998s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
9999 UChar r1, UChar r2)
10000{
10001 vassert(s390_host_has_dfp);
10002
10003 if (! s390_host_has_fpext) {
10004 emulation_failure(EmFail_S390X_fpext);
10005 } else {
10006 IRTemp op = newTemp(Ity_D64);
10007 IRTemp result = newTemp(Ity_I64);
10008 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10009
10010 assign(op, get_dpr_dw0(r2));
10011 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
10012 mkexpr(op)));
10013 put_gpr_dw0(r1, mkexpr(result));
10014 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
10015 }
10016 return "clgdtr";
10017}
10018
10019static const HChar *
10020s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
10021 UChar r1, UChar r2)
10022{
10023 vassert(s390_host_has_dfp);
10024
10025 if (! s390_host_has_fpext) {
10026 emulation_failure(EmFail_S390X_fpext);
10027 } else {
10028 IRTemp op = newTemp(Ity_D128);
10029 IRTemp result = newTemp(Ity_I64);
10030 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10031
10032 assign(op, get_dpr_pair(r2));
10033 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
10034 mkexpr(op)));
10035 put_gpr_dw0(r1, mkexpr(result));
10036 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
10037 rounding_mode);
10038 }
10039 return "clgxtr";
10040}
10041
10042static const HChar *
florian12390202012-11-10 22:34:14 +000010043s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10044{
10045 IRTemp op1 = newTemp(Ity_D64);
10046 IRTemp op2 = newTemp(Ity_D64);
10047 IRTemp result = newTemp(Ity_D64);
10048 IRTemp rounding_mode;
10049
10050 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010051
10052 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10053 emulation_warning(EmWarn_S390X_fpext_rounding);
10054 m4 = S390_DFP_ROUND_PER_FPC_0;
10055 }
10056
florian12390202012-11-10 22:34:14 +000010057 rounding_mode = encode_dfp_rounding_mode(m4);
10058 assign(op1, get_dpr_dw0(r2));
10059 assign(op2, get_dpr_dw0(r3));
10060 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
10061 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +000010062 put_dpr_dw0(r1, mkexpr(result));
10063
10064 return (m4 == 0) ? "ddtr" : "ddtra";
10065}
10066
florian55085f82012-11-21 00:36:55 +000010067static const HChar *
floriane38f6412012-12-21 17:32:12 +000010068s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10069{
10070 IRTemp op1 = newTemp(Ity_D128);
10071 IRTemp op2 = newTemp(Ity_D128);
10072 IRTemp result = newTemp(Ity_D128);
10073 IRTemp rounding_mode;
10074
10075 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010076
10077 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10078 emulation_warning(EmWarn_S390X_fpext_rounding);
10079 m4 = S390_DFP_ROUND_PER_FPC_0;
10080 }
10081
floriane38f6412012-12-21 17:32:12 +000010082 rounding_mode = encode_dfp_rounding_mode(m4);
10083 assign(op1, get_dpr_pair(r2));
10084 assign(op2, get_dpr_pair(r3));
10085 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
10086 mkexpr(op2)));
10087 put_dpr_pair(r1, mkexpr(result));
10088
10089 return (m4 == 0) ? "dxtr" : "dxtra";
10090}
10091
10092static const HChar *
florian5c539732013-02-14 14:27:12 +000010093s390_irgen_EEDTR(UChar r1, UChar r2)
10094{
10095 vassert(s390_host_has_dfp);
10096
10097 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
10098 return "eedtr";
10099}
10100
10101static const HChar *
10102s390_irgen_EEXTR(UChar r1, UChar r2)
10103{
10104 vassert(s390_host_has_dfp);
10105
10106 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
10107 return "eextr";
10108}
10109
10110static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010111s390_irgen_ESDTR(UChar r1, UChar r2)
10112{
10113 vassert(s390_host_has_dfp);
10114 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
10115 return "esdtr";
10116}
10117
10118static const HChar *
10119s390_irgen_ESXTR(UChar r1, UChar r2)
10120{
10121 vassert(s390_host_has_dfp);
10122 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
10123 return "esxtr";
10124}
10125
10126static const HChar *
florian5c539732013-02-14 14:27:12 +000010127s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
10128{
10129 IRTemp op1 = newTemp(Ity_I64);
10130 IRTemp op2 = newTemp(Ity_D64);
10131 IRTemp result = newTemp(Ity_D64);
10132
10133 vassert(s390_host_has_dfp);
10134
10135 assign(op1, get_gpr_dw0(r2));
10136 assign(op2, get_dpr_dw0(r3));
10137 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
10138 put_dpr_dw0(r1, mkexpr(result));
10139
10140 return "iedtr";
10141}
10142
10143static const HChar *
10144s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
10145{
10146 IRTemp op1 = newTemp(Ity_I64);
10147 IRTemp op2 = newTemp(Ity_D128);
10148 IRTemp result = newTemp(Ity_D128);
10149
10150 vassert(s390_host_has_dfp);
10151
10152 assign(op1, get_gpr_dw0(r2));
10153 assign(op2, get_dpr_pair(r3));
10154 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10155 put_dpr_pair(r1, mkexpr(result));
10156
10157 return "iextr";
10158}
10159
10160static const HChar *
floriane38f6412012-12-21 17:32:12 +000010161s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10162{
10163 IRTemp op = newTemp(Ity_D32);
10164
10165 vassert(s390_host_has_dfp);
10166
10167 assign(op, get_dpr_w0(r2));
10168 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10169
10170 return "ldetr";
10171}
10172
10173static const HChar *
10174s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10175{
10176 IRTemp op = newTemp(Ity_D64);
10177
10178 assign(op, get_dpr_dw0(r2));
10179 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10180
10181 return "lxdtr";
10182}
10183
10184static const HChar *
10185s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10186 UChar r1, UChar r2)
10187{
10188 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010189
10190 /* If fpext is not installed and m3 is in 1:7,
10191 rounding mode performed is unpredictable */
10192 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010193 emulation_warning(EmWarn_S390X_fpext_rounding);
10194 m3 = S390_DFP_ROUND_PER_FPC_0;
10195 }
10196 IRTemp result = newTemp(Ity_D64);
10197
10198 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10199 get_dpr_pair(r2)));
10200 put_dpr_dw0(r1, mkexpr(result));
10201
10202 return "ldxtr";
10203}
10204
10205static const HChar *
10206s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10207 UChar r1, UChar r2)
10208{
10209 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010210
10211 /* If fpext is not installed and m3 is in 1:7,
10212 rounding mode performed is unpredictable */
10213 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010214 emulation_warning(EmWarn_S390X_fpext_rounding);
10215 m3 = S390_DFP_ROUND_PER_FPC_0;
10216 }
10217 IRTemp op = newTemp(Ity_D64);
10218
10219 assign(op, get_dpr_dw0(r2));
10220 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10221 mkexpr(op)));
10222
10223 return "ledtr";
10224}
10225
10226static const HChar *
10227s390_irgen_LTDTR(UChar r1, UChar r2)
10228{
10229 IRTemp result = newTemp(Ity_D64);
10230
10231 assign(result, get_dpr_dw0(r2));
10232 put_dpr_dw0(r1, mkexpr(result));
10233 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10234
10235 return "ltdtr";
10236}
10237
10238static const HChar *
10239s390_irgen_LTXTR(UChar r1, UChar r2)
10240{
10241 IRTemp result = newTemp(Ity_D128);
10242
10243 assign(result, get_dpr_pair(r2));
10244 put_dpr_pair(r1, mkexpr(result));
10245 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10246
10247 return "ltxtr";
10248}
10249
10250static const HChar *
florian12390202012-11-10 22:34:14 +000010251s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10252{
10253 IRTemp op1 = newTemp(Ity_D64);
10254 IRTemp op2 = newTemp(Ity_D64);
10255 IRTemp result = newTemp(Ity_D64);
10256 IRTemp rounding_mode;
10257
10258 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010259
10260 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10261 emulation_warning(EmWarn_S390X_fpext_rounding);
10262 m4 = S390_DFP_ROUND_PER_FPC_0;
10263 }
10264
florian12390202012-11-10 22:34:14 +000010265 rounding_mode = encode_dfp_rounding_mode(m4);
10266 assign(op1, get_dpr_dw0(r2));
10267 assign(op2, get_dpr_dw0(r3));
10268 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10269 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +000010270 put_dpr_dw0(r1, mkexpr(result));
10271
10272 return (m4 == 0) ? "mdtr" : "mdtra";
10273}
10274
florian55085f82012-11-21 00:36:55 +000010275static const HChar *
floriane38f6412012-12-21 17:32:12 +000010276s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10277{
10278 IRTemp op1 = newTemp(Ity_D128);
10279 IRTemp op2 = newTemp(Ity_D128);
10280 IRTemp result = newTemp(Ity_D128);
10281 IRTemp rounding_mode;
10282
10283 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010284
10285 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10286 emulation_warning(EmWarn_S390X_fpext_rounding);
10287 m4 = S390_DFP_ROUND_PER_FPC_0;
10288 }
10289
floriane38f6412012-12-21 17:32:12 +000010290 rounding_mode = encode_dfp_rounding_mode(m4);
10291 assign(op1, get_dpr_pair(r2));
10292 assign(op2, get_dpr_pair(r3));
10293 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10294 mkexpr(op2)));
10295 put_dpr_pair(r1, mkexpr(result));
10296
10297 return (m4 == 0) ? "mxtr" : "mxtra";
10298}
10299
10300static const HChar *
florian5c539732013-02-14 14:27:12 +000010301s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10302{
10303 IRTemp op1 = newTemp(Ity_D64);
10304 IRTemp op2 = newTemp(Ity_D64);
10305 IRTemp result = newTemp(Ity_D64);
10306 IRTemp rounding_mode;
10307
10308 vassert(s390_host_has_dfp);
10309 /* If fpext is not installed and m4 is in 1:7,
10310 rounding mode performed is unpredictable */
10311 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10312 emulation_warning(EmWarn_S390X_fpext_rounding);
10313 m4 = S390_DFP_ROUND_PER_FPC_0;
10314 }
10315
10316 rounding_mode = encode_dfp_rounding_mode(m4);
10317 assign(op1, get_dpr_dw0(r2));
10318 assign(op2, get_dpr_dw0(r3));
10319 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10320 mkexpr(op2)));
10321 put_dpr_dw0(r1, mkexpr(result));
10322
10323 return "qadtr";
10324}
10325
10326static const HChar *
10327s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10328{
10329 IRTemp op1 = newTemp(Ity_D128);
10330 IRTemp op2 = newTemp(Ity_D128);
10331 IRTemp result = newTemp(Ity_D128);
10332 IRTemp rounding_mode;
10333
10334 vassert(s390_host_has_dfp);
10335 /* If fpext is not installed and m4 is in 1:7,
10336 rounding mode performed is unpredictable */
10337 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10338 emulation_warning(EmWarn_S390X_fpext_rounding);
10339 m4 = S390_DFP_ROUND_PER_FPC_0;
10340 }
10341
10342 rounding_mode = encode_dfp_rounding_mode(m4);
10343 assign(op1, get_dpr_pair(r2));
10344 assign(op2, get_dpr_pair(r3));
10345 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10346 mkexpr(op2)));
10347 put_dpr_pair(r1, mkexpr(result));
10348
10349 return "qaxtr";
10350}
10351
10352static const HChar *
10353s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10354{
10355 IRTemp op1 = newTemp(Ity_I8);
10356 IRTemp op2 = newTemp(Ity_D64);
10357 IRTemp result = newTemp(Ity_D64);
10358 IRTemp rounding_mode;
10359
10360 vassert(s390_host_has_dfp);
10361 /* If fpext is not installed and m4 is in 1:7,
10362 rounding mode performed is unpredictable */
10363 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10364 emulation_warning(EmWarn_S390X_fpext_rounding);
10365 m4 = S390_DFP_ROUND_PER_FPC_0;
10366 }
10367
10368 rounding_mode = encode_dfp_rounding_mode(m4);
10369 assign(op1, get_gpr_b7(r2));
10370 assign(op2, get_dpr_dw0(r3));
10371 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10372 mkexpr(op1), mkexpr(op2)));
10373 put_dpr_dw0(r1, mkexpr(result));
10374
10375 return "rrdtr";
10376}
10377
10378static const HChar *
10379s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10380{
10381 IRTemp op1 = newTemp(Ity_I8);
10382 IRTemp op2 = newTemp(Ity_D128);
10383 IRTemp result = newTemp(Ity_D128);
10384 IRTemp rounding_mode;
10385
10386 vassert(s390_host_has_dfp);
10387 /* If fpext is not installed and m4 is in 1:7,
10388 rounding mode performed is unpredictable */
10389 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10390 emulation_warning(EmWarn_S390X_fpext_rounding);
10391 m4 = S390_DFP_ROUND_PER_FPC_0;
10392 }
10393
10394 rounding_mode = encode_dfp_rounding_mode(m4);
10395 assign(op1, get_gpr_b7(r2));
10396 assign(op2, get_dpr_pair(r3));
10397 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10398 mkexpr(op1), mkexpr(op2)));
10399 put_dpr_pair(r1, mkexpr(result));
10400
10401 return "rrxtr";
10402}
10403
10404static const HChar *
florian12390202012-11-10 22:34:14 +000010405s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10406{
10407 IRTemp op1 = newTemp(Ity_D64);
10408 IRTemp op2 = newTemp(Ity_D64);
10409 IRTemp result = newTemp(Ity_D64);
10410 IRTemp rounding_mode;
10411
10412 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010413
10414 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10415 emulation_warning(EmWarn_S390X_fpext_rounding);
10416 m4 = S390_DFP_ROUND_PER_FPC_0;
10417 }
10418
florian12390202012-11-10 22:34:14 +000010419 rounding_mode = encode_dfp_rounding_mode(m4);
10420 assign(op1, get_dpr_dw0(r2));
10421 assign(op2, get_dpr_dw0(r3));
10422 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10423 mkexpr(op2)));
10424 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10425 put_dpr_dw0(r1, mkexpr(result));
10426
10427 return (m4 == 0) ? "sdtr" : "sdtra";
10428}
10429
floriane38f6412012-12-21 17:32:12 +000010430static const HChar *
10431s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10432{
10433 IRTemp op1 = newTemp(Ity_D128);
10434 IRTemp op2 = newTemp(Ity_D128);
10435 IRTemp result = newTemp(Ity_D128);
10436 IRTemp rounding_mode;
10437
10438 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010439
10440 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10441 emulation_warning(EmWarn_S390X_fpext_rounding);
10442 m4 = S390_DFP_ROUND_PER_FPC_0;
10443 }
10444
floriane38f6412012-12-21 17:32:12 +000010445 rounding_mode = encode_dfp_rounding_mode(m4);
10446 assign(op1, get_dpr_pair(r2));
10447 assign(op2, get_dpr_pair(r3));
10448 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10449 mkexpr(op2)));
10450 put_dpr_pair(r1, mkexpr(result));
10451
10452 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10453
10454 return (m4 == 0) ? "sxtr" : "sxtra";
10455}
sewardj2019a972011-03-07 16:04:07 +000010456
florian55085f82012-11-21 00:36:55 +000010457static const HChar *
florian1b901d42013-01-01 22:19:24 +000010458s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10459{
10460 IRTemp op = newTemp(Ity_D64);
10461
10462 vassert(s390_host_has_dfp);
10463
10464 assign(op, get_dpr_dw0(r3));
10465 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
10466 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10467
10468 return "sldt";
10469}
10470
10471static const HChar *
10472s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10473{
10474 IRTemp op = newTemp(Ity_D128);
10475
10476 vassert(s390_host_has_dfp);
10477
10478 assign(op, get_dpr_pair(r3));
10479 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
10480 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10481
10482 return "slxt";
10483}
10484
10485static const HChar *
10486s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10487{
10488 IRTemp op = newTemp(Ity_D64);
10489
10490 vassert(s390_host_has_dfp);
10491
10492 assign(op, get_dpr_dw0(r3));
10493 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
10494 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10495
10496 return "srdt";
10497}
10498
10499static const HChar *
10500s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10501{
10502 IRTemp op = newTemp(Ity_D128);
10503
10504 vassert(s390_host_has_dfp);
10505
10506 assign(op, get_dpr_pair(r3));
10507 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
10508 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10509
10510 return "srxt";
10511}
10512
10513static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010514s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10515{
10516 IRTemp value = newTemp(Ity_D32);
10517
10518 vassert(s390_host_has_dfp);
10519 assign(value, get_dpr_w0(r1));
10520
10521 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10522
10523 return "tdcet";
10524}
10525
10526static const HChar *
10527s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10528{
10529 IRTemp value = newTemp(Ity_D64);
10530
10531 vassert(s390_host_has_dfp);
10532 assign(value, get_dpr_dw0(r1));
10533
10534 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10535
10536 return "tdcdt";
10537}
10538
10539static const HChar *
10540s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10541{
10542 IRTemp value = newTemp(Ity_D128);
10543
10544 vassert(s390_host_has_dfp);
10545 assign(value, get_dpr_pair(r1));
10546
10547 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10548
10549 return "tdcxt";
10550}
10551
10552static const HChar *
10553s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10554{
10555 IRTemp value = newTemp(Ity_D32);
10556
10557 vassert(s390_host_has_dfp);
10558 assign(value, get_dpr_w0(r1));
10559
10560 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10561
10562 return "tdget";
10563}
10564
10565static const HChar *
10566s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10567{
10568 IRTemp value = newTemp(Ity_D64);
10569
10570 vassert(s390_host_has_dfp);
10571 assign(value, get_dpr_dw0(r1));
10572
10573 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10574
10575 return "tdgdt";
10576}
10577
10578static const HChar *
10579s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10580{
10581 IRTemp value = newTemp(Ity_D128);
10582
10583 vassert(s390_host_has_dfp);
10584 assign(value, get_dpr_pair(r1));
10585
10586 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10587
10588 return "tdgxt";
10589}
10590
10591static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010592s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10593{
florian79e839e2012-05-05 02:20:30 +000010594 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010595
florian79e839e2012-05-05 02:20:30 +000010596 assign(len, mkU64(length));
10597 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010598
10599 return "clc";
10600}
10601
florian55085f82012-11-21 00:36:55 +000010602static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010603s390_irgen_CLCL(UChar r1, UChar r2)
10604{
10605 IRTemp addr1 = newTemp(Ity_I64);
10606 IRTemp addr2 = newTemp(Ity_I64);
10607 IRTemp addr1_load = newTemp(Ity_I64);
10608 IRTemp addr2_load = newTemp(Ity_I64);
10609 IRTemp len1 = newTemp(Ity_I32);
10610 IRTemp len2 = newTemp(Ity_I32);
10611 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10612 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10613 IRTemp single1 = newTemp(Ity_I8);
10614 IRTemp single2 = newTemp(Ity_I8);
10615 IRTemp pad = newTemp(Ity_I8);
10616
10617 assign(addr1, get_gpr_dw0(r1));
10618 assign(r1p1, get_gpr_w1(r1 + 1));
10619 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10620 assign(addr2, get_gpr_dw0(r2));
10621 assign(r2p1, get_gpr_w1(r2 + 1));
10622 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10623 assign(pad, get_gpr_b4(r2 + 1));
10624
10625 /* len1 == 0 and len2 == 0? Exit */
10626 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010627 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10628 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010629
10630 /* Because mkite evaluates both the then-clause and the else-clause
10631 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10632 may be NULL and loading from there would segfault. So we provide a
10633 valid dummy address in that case. Loading from there does no harm and
10634 the value will be discarded at runtime. */
10635 assign(addr1_load,
10636 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10637 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10638 assign(single1,
10639 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10640 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10641
10642 assign(addr2_load,
10643 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10644 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10645 assign(single2,
10646 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10647 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10648
10649 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10650 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010651 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010652
10653 /* Update len1 and addr1, unless len1 == 0. */
10654 put_gpr_dw0(r1,
10655 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10656 mkexpr(addr1),
10657 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10658
10659 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10660 put_gpr_w1(r1 + 1,
10661 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10662 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10663 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10664
10665 /* Update len2 and addr2, unless len2 == 0. */
10666 put_gpr_dw0(r2,
10667 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10668 mkexpr(addr2),
10669 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10670
10671 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10672 put_gpr_w1(r2 + 1,
10673 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10674 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10675 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10676
florian6820ba52012-07-26 02:01:50 +000010677 iterate();
florianb0c9a132011-09-08 15:37:39 +000010678
10679 return "clcl";
10680}
10681
florian55085f82012-11-21 00:36:55 +000010682static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010683s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10684{
10685 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10686
10687 addr1 = newTemp(Ity_I64);
10688 addr3 = newTemp(Ity_I64);
10689 addr1_load = newTemp(Ity_I64);
10690 addr3_load = newTemp(Ity_I64);
10691 len1 = newTemp(Ity_I64);
10692 len3 = newTemp(Ity_I64);
10693 single1 = newTemp(Ity_I8);
10694 single3 = newTemp(Ity_I8);
10695
10696 assign(addr1, get_gpr_dw0(r1));
10697 assign(len1, get_gpr_dw0(r1 + 1));
10698 assign(addr3, get_gpr_dw0(r3));
10699 assign(len3, get_gpr_dw0(r3 + 1));
10700
10701 /* len1 == 0 and len3 == 0? Exit */
10702 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010703 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10704 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010705
10706 /* A mux requires both ways to be possible. This is a way to prevent clcle
10707 from reading from addr1 if it should read from the pad. Since the pad
10708 has no address, just read from the instruction, we discard that anyway */
10709 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010710 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10711 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010712
10713 /* same for addr3 */
10714 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010715 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10716 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010717
10718 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010719 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10720 unop(Iop_64to8, mkexpr(pad2)),
10721 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010722
10723 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010724 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10725 unop(Iop_64to8, mkexpr(pad2)),
10726 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010727
10728 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10729 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010730 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010731
10732 /* If a length in 0 we must not change this length and the address */
10733 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010734 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10735 mkexpr(addr1),
10736 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010737
10738 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010739 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10740 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010741
10742 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010743 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10744 mkexpr(addr3),
10745 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010746
10747 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010748 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10749 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010750
florian6820ba52012-07-26 02:01:50 +000010751 iterate();
sewardj2019a972011-03-07 16:04:07 +000010752
10753 return "clcle";
10754}
floriana64c2432011-07-16 02:11:50 +000010755
florianb0bf6602012-05-05 00:01:16 +000010756
sewardj2019a972011-03-07 16:04:07 +000010757static void
10758s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10759{
florianb0bf6602012-05-05 00:01:16 +000010760 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10761}
sewardj2019a972011-03-07 16:04:07 +000010762
sewardj2019a972011-03-07 16:04:07 +000010763
florianb0bf6602012-05-05 00:01:16 +000010764static void
10765s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10766{
10767 s390_irgen_xonc(Iop_And8, length, start1, start2);
10768}
sewardj2019a972011-03-07 16:04:07 +000010769
sewardj2019a972011-03-07 16:04:07 +000010770
florianb0bf6602012-05-05 00:01:16 +000010771static void
10772s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10773{
10774 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010775}
10776
10777
10778static void
10779s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10780{
10781 IRTemp current1 = newTemp(Ity_I8);
10782 IRTemp current2 = newTemp(Ity_I8);
10783 IRTemp counter = newTemp(Ity_I64);
10784
10785 assign(counter, get_counter_dw0());
10786 put_counter_dw0(mkU64(0));
10787
10788 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10789 mkexpr(counter))));
10790 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10791 mkexpr(counter))));
10792 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10793 False);
10794
10795 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010796 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010797
10798 /* Check for end of field */
10799 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010800 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010801 put_counter_dw0(mkU64(0));
10802}
10803
10804static void
10805s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10806{
10807 IRTemp counter = newTemp(Ity_I64);
10808
10809 assign(counter, get_counter_dw0());
10810
10811 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10812 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10813
10814 /* Check for end of field */
10815 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010816 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010817 put_counter_dw0(mkU64(0));
10818}
10819
florianf87d4fb2012-05-05 02:55:24 +000010820static void
10821s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10822{
10823 IRTemp op = newTemp(Ity_I8);
10824 IRTemp op1 = newTemp(Ity_I8);
10825 IRTemp result = newTemp(Ity_I64);
10826 IRTemp counter = newTemp(Ity_I64);
10827
10828 assign(counter, get_counter_dw0());
10829
10830 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10831
10832 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10833
10834 assign(op1, load(Ity_I8, mkexpr(result)));
10835 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10836
10837 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010838 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010839 put_counter_dw0(mkU64(0));
10840}
sewardj2019a972011-03-07 16:04:07 +000010841
10842
10843static void
10844s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010845 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010846 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010847{
10848 struct SS {
10849 unsigned int op : 8;
10850 unsigned int l : 8;
10851 unsigned int b1 : 4;
10852 unsigned int d1 : 12;
10853 unsigned int b2 : 4;
10854 unsigned int d2 : 12;
10855 };
10856 union {
10857 struct SS dec;
10858 unsigned long bytes;
10859 } ss;
10860 IRTemp cond;
10861 IRDirty *d;
10862 IRTemp torun;
10863
10864 IRTemp start1 = newTemp(Ity_I64);
10865 IRTemp start2 = newTemp(Ity_I64);
10866 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10867 cond = newTemp(Ity_I1);
10868 torun = newTemp(Ity_I64);
10869
10870 assign(torun, load(Ity_I64, mkexpr(addr2)));
10871 /* Start with a check that the saved code is still correct */
10872 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10873 /* If not, save the new value */
10874 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10875 mkIRExprVec_1(mkexpr(torun)));
10876 d->guard = mkexpr(cond);
10877 stmt(IRStmt_Dirty(d));
10878
10879 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000010880 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian428dfdd2012-03-27 03:09:49 +000010881 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000010882 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010883 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010884
10885 ss.bytes = last_execute_target;
10886 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10887 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10888 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10889 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10890 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10891 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10892 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010893
sewardj2019a972011-03-07 16:04:07 +000010894 last_execute_target = 0;
10895}
10896
florian55085f82012-11-21 00:36:55 +000010897static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010898s390_irgen_EX(UChar r1, IRTemp addr2)
10899{
10900 switch(last_execute_target & 0xff00000000000000ULL) {
10901 case 0:
10902 {
10903 /* no code information yet */
10904 IRDirty *d;
10905
10906 /* so safe the code... */
10907 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10908 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10909 stmt(IRStmt_Dirty(d));
10910 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000010911 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian428dfdd2012-03-27 03:09:49 +000010912 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000010913 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010914 restart_if(IRExpr_Const(IRConst_U1(True)));
10915
sewardj2019a972011-03-07 16:04:07 +000010916 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010917 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010918 dis_res->whatNext = Dis_StopHere;
sewardj05f5e012014-05-04 10:52:11 +000010919 dis_res->jk_StopHere = Ijk_InvalICache;
sewardj2019a972011-03-07 16:04:07 +000010920 break;
10921 }
10922
10923 case 0xd200000000000000ULL:
10924 /* special case MVC */
10925 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010926 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010927
10928 case 0xd500000000000000ULL:
10929 /* special case CLC */
10930 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010931 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010932
10933 case 0xd700000000000000ULL:
10934 /* special case XC */
10935 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010936 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010937
florianb0bf6602012-05-05 00:01:16 +000010938 case 0xd600000000000000ULL:
10939 /* special case OC */
10940 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010941 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010942
10943 case 0xd400000000000000ULL:
10944 /* special case NC */
10945 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010946 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010947
florianf87d4fb2012-05-05 02:55:24 +000010948 case 0xdc00000000000000ULL:
10949 /* special case TR */
10950 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010951 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010952
sewardj2019a972011-03-07 16:04:07 +000010953 default:
10954 {
10955 /* everything else will get a self checking prefix that also checks the
10956 register content */
10957 IRDirty *d;
10958 UChar *bytes;
10959 IRTemp cond;
10960 IRTemp orperand;
10961 IRTemp torun;
10962
10963 cond = newTemp(Ity_I1);
10964 orperand = newTemp(Ity_I64);
10965 torun = newTemp(Ity_I64);
10966
10967 if (r1 == 0)
10968 assign(orperand, mkU64(0));
10969 else
10970 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10971 /* This code is going to be translated */
10972 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10973 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10974
10975 /* Start with a check that saved code is still correct */
10976 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10977 mkU64(last_execute_target)));
10978 /* If not, save the new value */
10979 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10980 mkIRExprVec_1(mkexpr(torun)));
10981 d->guard = mkexpr(cond);
10982 stmt(IRStmt_Dirty(d));
10983
10984 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000010985 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART), mkU64(guest_IA_curr_instr)));
10986 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010987 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010988
10989 /* Now comes the actual translation */
10990 bytes = (UChar *) &last_execute_target;
10991 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10992 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010993 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010994 vex_printf(" which was executed by\n");
10995 /* dont make useless translations in the next execute */
10996 last_execute_target = 0;
10997 }
10998 }
10999 return "ex";
11000}
11001
florian55085f82012-11-21 00:36:55 +000011002static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011003s390_irgen_EXRL(UChar r1, UInt offset)
11004{
11005 IRTemp addr = newTemp(Ity_I64);
11006 /* we might save one round trip because we know the target */
11007 if (!last_execute_target)
11008 last_execute_target = *(ULong *)(HWord)
11009 (guest_IA_curr_instr + offset * 2UL);
11010 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
11011 s390_irgen_EX(r1, addr);
11012 return "exrl";
11013}
11014
florian55085f82012-11-21 00:36:55 +000011015static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011016s390_irgen_IPM(UChar r1)
11017{
11018 // As long as we dont support SPM, lets just assume 0 as program mask
11019 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
11020 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
11021
11022 return "ipm";
11023}
11024
11025
florian55085f82012-11-21 00:36:55 +000011026static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011027s390_irgen_SRST(UChar r1, UChar r2)
11028{
11029 IRTemp address = newTemp(Ity_I64);
11030 IRTemp next = newTemp(Ity_I64);
11031 IRTemp delim = newTemp(Ity_I8);
11032 IRTemp counter = newTemp(Ity_I64);
11033 IRTemp byte = newTemp(Ity_I8);
11034
11035 assign(address, get_gpr_dw0(r2));
11036 assign(next, get_gpr_dw0(r1));
11037
11038 assign(counter, get_counter_dw0());
11039 put_counter_dw0(mkU64(0));
11040
11041 // start = next? CC=2 and out r1 and r2 unchanged
11042 s390_cc_set(2);
11043 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011044 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000011045
11046 assign(byte, load(Ity_I8, mkexpr(address)));
11047 assign(delim, get_gpr_b7(0));
11048
11049 // byte = delim? CC=1, R1=address
11050 s390_cc_set(1);
11051 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000011052 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011053
11054 // else: all equal, no end yet, loop
11055 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11056 put_gpr_dw0(r1, mkexpr(next));
11057 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011058
florian6820ba52012-07-26 02:01:50 +000011059 iterate();
sewardj2019a972011-03-07 16:04:07 +000011060
11061 return "srst";
11062}
11063
florian55085f82012-11-21 00:36:55 +000011064static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011065s390_irgen_CLST(UChar r1, UChar r2)
11066{
11067 IRTemp address1 = newTemp(Ity_I64);
11068 IRTemp address2 = newTemp(Ity_I64);
11069 IRTemp end = newTemp(Ity_I8);
11070 IRTemp counter = newTemp(Ity_I64);
11071 IRTemp byte1 = newTemp(Ity_I8);
11072 IRTemp byte2 = newTemp(Ity_I8);
11073
11074 assign(address1, get_gpr_dw0(r1));
11075 assign(address2, get_gpr_dw0(r2));
11076 assign(end, get_gpr_b7(0));
11077 assign(counter, get_counter_dw0());
11078 put_counter_dw0(mkU64(0));
11079 assign(byte1, load(Ity_I8, mkexpr(address1)));
11080 assign(byte2, load(Ity_I8, mkexpr(address2)));
11081
11082 // end in both? all equal, reset r1 and r2 to start values
11083 s390_cc_set(0);
11084 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
11085 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011086 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
11087 binop(Iop_Or8,
11088 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
11089 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000011090
11091 put_gpr_dw0(r1, mkexpr(address1));
11092 put_gpr_dw0(r2, mkexpr(address2));
11093
11094 // End found in string1
11095 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011096 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000011097
11098 // End found in string2
11099 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011100 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000011101
11102 // string1 < string2
11103 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011104 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
11105 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000011106
11107 // string2 < string1
11108 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011109 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
11110 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000011111
11112 // else: all equal, no end yet, loop
11113 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11114 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
11115 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011116
florian6820ba52012-07-26 02:01:50 +000011117 iterate();
sewardj2019a972011-03-07 16:04:07 +000011118
11119 return "clst";
11120}
11121
11122static void
11123s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11124{
11125 UChar reg;
11126 IRTemp addr = newTemp(Ity_I64);
11127
11128 assign(addr, mkexpr(op2addr));
11129 reg = r1;
11130 do {
11131 IRTemp old = addr;
11132
11133 reg %= 16;
11134 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
11135 addr = newTemp(Ity_I64);
11136 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11137 reg++;
11138 } while (reg != (r3 + 1));
11139}
11140
florian55085f82012-11-21 00:36:55 +000011141static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011142s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
11143{
11144 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11145
11146 return "lm";
11147}
11148
florian55085f82012-11-21 00:36:55 +000011149static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011150s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11151{
11152 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11153
11154 return "lmy";
11155}
11156
florian55085f82012-11-21 00:36:55 +000011157static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011158s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11159{
11160 UChar reg;
11161 IRTemp addr = newTemp(Ity_I64);
11162
11163 assign(addr, mkexpr(op2addr));
11164 reg = r1;
11165 do {
11166 IRTemp old = addr;
11167
11168 reg %= 16;
11169 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11170 addr = newTemp(Ity_I64);
11171 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11172 reg++;
11173 } while (reg != (r3 + 1));
11174
11175 return "lmh";
11176}
11177
florian55085f82012-11-21 00:36:55 +000011178static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011179s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11180{
11181 UChar reg;
11182 IRTemp addr = newTemp(Ity_I64);
11183
11184 assign(addr, mkexpr(op2addr));
11185 reg = r1;
11186 do {
11187 IRTemp old = addr;
11188
11189 reg %= 16;
11190 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11191 addr = newTemp(Ity_I64);
11192 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11193 reg++;
11194 } while (reg != (r3 + 1));
11195
11196 return "lmg";
11197}
11198
11199static void
11200s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11201{
11202 UChar reg;
11203 IRTemp addr = newTemp(Ity_I64);
11204
11205 assign(addr, mkexpr(op2addr));
11206 reg = r1;
11207 do {
11208 IRTemp old = addr;
11209
11210 reg %= 16;
11211 store(mkexpr(addr), get_gpr_w1(reg));
11212 addr = newTemp(Ity_I64);
11213 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11214 reg++;
11215 } while( reg != (r3 + 1));
11216}
11217
florian55085f82012-11-21 00:36:55 +000011218static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011219s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11220{
11221 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11222
11223 return "stm";
11224}
11225
florian55085f82012-11-21 00:36:55 +000011226static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011227s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11228{
11229 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11230
11231 return "stmy";
11232}
11233
florian55085f82012-11-21 00:36:55 +000011234static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011235s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11236{
11237 UChar reg;
11238 IRTemp addr = newTemp(Ity_I64);
11239
11240 assign(addr, mkexpr(op2addr));
11241 reg = r1;
11242 do {
11243 IRTemp old = addr;
11244
11245 reg %= 16;
11246 store(mkexpr(addr), get_gpr_w0(reg));
11247 addr = newTemp(Ity_I64);
11248 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11249 reg++;
11250 } while( reg != (r3 + 1));
11251
11252 return "stmh";
11253}
11254
florian55085f82012-11-21 00:36:55 +000011255static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011256s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11257{
11258 UChar reg;
11259 IRTemp addr = newTemp(Ity_I64);
11260
11261 assign(addr, mkexpr(op2addr));
11262 reg = r1;
11263 do {
11264 IRTemp old = addr;
11265
11266 reg %= 16;
11267 store(mkexpr(addr), get_gpr_dw0(reg));
11268 addr = newTemp(Ity_I64);
11269 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11270 reg++;
11271 } while( reg != (r3 + 1));
11272
11273 return "stmg";
11274}
11275
11276static void
florianb0bf6602012-05-05 00:01:16 +000011277s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000011278{
11279 IRTemp old1 = newTemp(Ity_I8);
11280 IRTemp old2 = newTemp(Ity_I8);
11281 IRTemp new1 = newTemp(Ity_I8);
11282 IRTemp counter = newTemp(Ity_I32);
11283 IRTemp addr1 = newTemp(Ity_I64);
11284
11285 assign(counter, get_counter_w0());
11286
11287 assign(addr1, binop(Iop_Add64, mkexpr(start1),
11288 unop(Iop_32Uto64, mkexpr(counter))));
11289
11290 assign(old1, load(Ity_I8, mkexpr(addr1)));
11291 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11292 unop(Iop_32Uto64,mkexpr(counter)))));
11293 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11294
11295 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000011296 if (op == Iop_Xor8) {
11297 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000011298 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11299 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000011300 } else
11301 store(mkexpr(addr1), mkexpr(new1));
11302 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11303 get_counter_w1()));
11304
11305 /* Check for end of field */
11306 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011307 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000011308 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11309 False);
11310 put_counter_dw0(mkU64(0));
11311}
11312
florian55085f82012-11-21 00:36:55 +000011313static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011314s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11315{
florianb0bf6602012-05-05 00:01:16 +000011316 IRTemp len = newTemp(Ity_I32);
11317
11318 assign(len, mkU32(length));
11319 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011320
11321 return "xc";
11322}
11323
sewardjb63967e2011-03-24 08:50:04 +000011324static void
11325s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11326{
11327 IRTemp counter = newTemp(Ity_I32);
11328 IRTemp start = newTemp(Ity_I64);
11329 IRTemp addr = newTemp(Ity_I64);
11330
11331 assign(start,
11332 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11333
11334 if (length < 8) {
11335 UInt i;
11336
11337 for (i = 0; i <= length; ++i) {
11338 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11339 }
11340 } else {
11341 assign(counter, get_counter_w0());
11342
11343 assign(addr, binop(Iop_Add64, mkexpr(start),
11344 unop(Iop_32Uto64, mkexpr(counter))));
11345
11346 store(mkexpr(addr), mkU8(0));
11347
11348 /* Check for end of field */
11349 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011350 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000011351
11352 /* Reset counter */
11353 put_counter_dw0(mkU64(0));
11354 }
11355
11356 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11357
sewardj7ee97522011-05-09 21:45:04 +000011358 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000011359 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11360}
11361
florian55085f82012-11-21 00:36:55 +000011362static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011363s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11364{
florianb0bf6602012-05-05 00:01:16 +000011365 IRTemp len = newTemp(Ity_I32);
11366
11367 assign(len, mkU32(length));
11368 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011369
11370 return "nc";
11371}
11372
florian55085f82012-11-21 00:36:55 +000011373static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011374s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11375{
florianb0bf6602012-05-05 00:01:16 +000011376 IRTemp len = newTemp(Ity_I32);
11377
11378 assign(len, mkU32(length));
11379 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011380
11381 return "oc";
11382}
11383
11384
florian55085f82012-11-21 00:36:55 +000011385static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011386s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11387{
florian79e839e2012-05-05 02:20:30 +000011388 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000011389
florian79e839e2012-05-05 02:20:30 +000011390 assign(len, mkU64(length));
11391 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011392
11393 return "mvc";
11394}
11395
florian55085f82012-11-21 00:36:55 +000011396static const HChar *
florianb0c9a132011-09-08 15:37:39 +000011397s390_irgen_MVCL(UChar r1, UChar r2)
11398{
11399 IRTemp addr1 = newTemp(Ity_I64);
11400 IRTemp addr2 = newTemp(Ity_I64);
11401 IRTemp addr2_load = newTemp(Ity_I64);
11402 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
11403 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
11404 IRTemp len1 = newTemp(Ity_I32);
11405 IRTemp len2 = newTemp(Ity_I32);
11406 IRTemp pad = newTemp(Ity_I8);
11407 IRTemp single = newTemp(Ity_I8);
11408
11409 assign(addr1, get_gpr_dw0(r1));
11410 assign(r1p1, get_gpr_w1(r1 + 1));
11411 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11412 assign(addr2, get_gpr_dw0(r2));
11413 assign(r2p1, get_gpr_w1(r2 + 1));
11414 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11415 assign(pad, get_gpr_b4(r2 + 1));
11416
11417 /* len1 == 0 ? */
11418 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011419 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000011420
11421 /* Check for destructive overlap:
11422 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11423 s390_cc_set(3);
11424 IRTemp cond1 = newTemp(Ity_I32);
11425 assign(cond1, unop(Iop_1Uto32,
11426 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11427 IRTemp cond2 = newTemp(Ity_I32);
11428 assign(cond2, unop(Iop_1Uto32,
11429 binop(Iop_CmpLT64U, mkexpr(addr1),
11430 binop(Iop_Add64, mkexpr(addr2),
11431 unop(Iop_32Uto64, mkexpr(len1))))));
11432 IRTemp cond3 = newTemp(Ity_I32);
11433 assign(cond3, unop(Iop_1Uto32,
11434 binop(Iop_CmpLT64U,
11435 mkexpr(addr1),
11436 binop(Iop_Add64, mkexpr(addr2),
11437 unop(Iop_32Uto64, mkexpr(len2))))));
11438
florian6820ba52012-07-26 02:01:50 +000011439 next_insn_if(binop(Iop_CmpEQ32,
11440 binop(Iop_And32,
11441 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11442 mkexpr(cond3)),
11443 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011444
11445 /* See s390_irgen_CLCL for explanation why we cannot load directly
11446 and need two steps. */
11447 assign(addr2_load,
11448 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11449 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11450 assign(single,
11451 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11452 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11453
11454 store(mkexpr(addr1), mkexpr(single));
11455
11456 /* Update addr1 and len1 */
11457 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11458 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11459
11460 /* Update addr2 and len2 */
11461 put_gpr_dw0(r2,
11462 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11463 mkexpr(addr2),
11464 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11465
11466 /* When updating len2 we must not modify bits (r2+1)[0:39] */
11467 put_gpr_w1(r2 + 1,
11468 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11469 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11470 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11471
11472 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011473 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011474
11475 return "mvcl";
11476}
11477
11478
florian55085f82012-11-21 00:36:55 +000011479static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011480s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11481{
11482 IRTemp addr1, addr3, addr3_load, len1, len3, single;
11483
11484 addr1 = newTemp(Ity_I64);
11485 addr3 = newTemp(Ity_I64);
11486 addr3_load = newTemp(Ity_I64);
11487 len1 = newTemp(Ity_I64);
11488 len3 = newTemp(Ity_I64);
11489 single = newTemp(Ity_I8);
11490
11491 assign(addr1, get_gpr_dw0(r1));
11492 assign(len1, get_gpr_dw0(r1 + 1));
11493 assign(addr3, get_gpr_dw0(r3));
11494 assign(len3, get_gpr_dw0(r3 + 1));
11495
11496 // len1 == 0 ?
11497 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011498 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000011499
11500 /* This is a hack to prevent mvcle from reading from addr3 if it
11501 should read from the pad. Since the pad has no address, just
11502 read from the instruction, we discard that anyway */
11503 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000011504 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11505 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000011506
11507 assign(single,
florian6ad49522011-09-09 02:38:55 +000011508 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11509 unop(Iop_64to8, mkexpr(pad2)),
11510 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000011511 store(mkexpr(addr1), mkexpr(single));
11512
11513 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11514
11515 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11516
11517 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000011518 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11519 mkexpr(addr3),
11520 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011521
11522 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000011523 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11524 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011525
sewardj2019a972011-03-07 16:04:07 +000011526 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011527 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000011528
11529 return "mvcle";
11530}
11531
florian55085f82012-11-21 00:36:55 +000011532static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011533s390_irgen_MVST(UChar r1, UChar r2)
11534{
11535 IRTemp addr1 = newTemp(Ity_I64);
11536 IRTemp addr2 = newTemp(Ity_I64);
11537 IRTemp end = newTemp(Ity_I8);
11538 IRTemp byte = newTemp(Ity_I8);
11539 IRTemp counter = newTemp(Ity_I64);
11540
11541 assign(addr1, get_gpr_dw0(r1));
11542 assign(addr2, get_gpr_dw0(r2));
11543 assign(counter, get_counter_dw0());
11544 assign(end, get_gpr_b7(0));
11545 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11546 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11547
11548 // We use unlimited as cpu-determined number
11549 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011550 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011551
11552 // and always set cc=1 at the end + update r1
11553 s390_cc_set(1);
11554 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11555 put_counter_dw0(mkU64(0));
11556
11557 return "mvst";
11558}
11559
11560static void
11561s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11562{
11563 IRTemp op1 = newTemp(Ity_I64);
11564 IRTemp result = newTemp(Ity_I64);
11565
11566 assign(op1, binop(Iop_32HLto64,
11567 get_gpr_w1(r1), // high 32 bits
11568 get_gpr_w1(r1 + 1))); // low 32 bits
11569 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11570 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11571 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11572}
11573
11574static void
11575s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11576{
11577 IRTemp op1 = newTemp(Ity_I128);
11578 IRTemp result = newTemp(Ity_I128);
11579
11580 assign(op1, binop(Iop_64HLto128,
11581 get_gpr_dw0(r1), // high 64 bits
11582 get_gpr_dw0(r1 + 1))); // low 64 bits
11583 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11584 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11585 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11586}
11587
11588static void
11589s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11590{
11591 IRTemp op1 = newTemp(Ity_I64);
11592 IRTemp result = newTemp(Ity_I128);
11593
11594 assign(op1, get_gpr_dw0(r1 + 1));
11595 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11596 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11597 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11598}
11599
florian55085f82012-11-21 00:36:55 +000011600static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011601s390_irgen_DR(UChar r1, UChar r2)
11602{
11603 IRTemp op2 = newTemp(Ity_I32);
11604
11605 assign(op2, get_gpr_w1(r2));
11606
11607 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11608
11609 return "dr";
11610}
11611
florian55085f82012-11-21 00:36:55 +000011612static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011613s390_irgen_D(UChar r1, IRTemp op2addr)
11614{
11615 IRTemp op2 = newTemp(Ity_I32);
11616
11617 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11618
11619 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11620
11621 return "d";
11622}
11623
florian55085f82012-11-21 00:36:55 +000011624static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011625s390_irgen_DLR(UChar r1, UChar r2)
11626{
11627 IRTemp op2 = newTemp(Ity_I32);
11628
11629 assign(op2, get_gpr_w1(r2));
11630
11631 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11632
florian7cd1cde2012-08-16 23:57:43 +000011633 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011634}
11635
florian55085f82012-11-21 00:36:55 +000011636static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011637s390_irgen_DL(UChar r1, IRTemp op2addr)
11638{
11639 IRTemp op2 = newTemp(Ity_I32);
11640
11641 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11642
11643 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11644
11645 return "dl";
11646}
11647
florian55085f82012-11-21 00:36:55 +000011648static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011649s390_irgen_DLG(UChar r1, IRTemp op2addr)
11650{
11651 IRTemp op2 = newTemp(Ity_I64);
11652
11653 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11654
11655 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11656
11657 return "dlg";
11658}
11659
florian55085f82012-11-21 00:36:55 +000011660static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011661s390_irgen_DLGR(UChar r1, UChar r2)
11662{
11663 IRTemp op2 = newTemp(Ity_I64);
11664
11665 assign(op2, get_gpr_dw0(r2));
11666
11667 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11668
11669 return "dlgr";
11670}
11671
florian55085f82012-11-21 00:36:55 +000011672static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011673s390_irgen_DSGR(UChar r1, UChar r2)
11674{
11675 IRTemp op2 = newTemp(Ity_I64);
11676
11677 assign(op2, get_gpr_dw0(r2));
11678
11679 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11680
11681 return "dsgr";
11682}
11683
florian55085f82012-11-21 00:36:55 +000011684static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011685s390_irgen_DSG(UChar r1, IRTemp op2addr)
11686{
11687 IRTemp op2 = newTemp(Ity_I64);
11688
11689 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11690
11691 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11692
11693 return "dsg";
11694}
11695
florian55085f82012-11-21 00:36:55 +000011696static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011697s390_irgen_DSGFR(UChar r1, UChar r2)
11698{
11699 IRTemp op2 = newTemp(Ity_I64);
11700
11701 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11702
11703 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11704
11705 return "dsgfr";
11706}
11707
florian55085f82012-11-21 00:36:55 +000011708static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011709s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11710{
11711 IRTemp op2 = newTemp(Ity_I64);
11712
11713 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11714
11715 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11716
11717 return "dsgf";
11718}
11719
11720static void
11721s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11722{
11723 UChar reg;
11724 IRTemp addr = newTemp(Ity_I64);
11725
11726 assign(addr, mkexpr(op2addr));
11727 reg = r1;
11728 do {
11729 IRTemp old = addr;
11730
11731 reg %= 16;
11732 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11733 addr = newTemp(Ity_I64);
11734 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11735 reg++;
11736 } while (reg != (r3 + 1));
11737}
11738
florian55085f82012-11-21 00:36:55 +000011739static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011740s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11741{
11742 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11743
11744 return "lam";
11745}
11746
florian55085f82012-11-21 00:36:55 +000011747static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011748s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11749{
11750 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11751
11752 return "lamy";
11753}
11754
11755static void
11756s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11757{
11758 UChar reg;
11759 IRTemp addr = newTemp(Ity_I64);
11760
11761 assign(addr, mkexpr(op2addr));
11762 reg = r1;
11763 do {
11764 IRTemp old = addr;
11765
11766 reg %= 16;
11767 store(mkexpr(addr), get_ar_w0(reg));
11768 addr = newTemp(Ity_I64);
11769 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11770 reg++;
11771 } while (reg != (r3 + 1));
11772}
11773
florian55085f82012-11-21 00:36:55 +000011774static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011775s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11776{
11777 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11778
11779 return "stam";
11780}
11781
florian55085f82012-11-21 00:36:55 +000011782static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011783s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11784{
11785 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11786
11787 return "stamy";
11788}
11789
11790
11791/* Implementation for 32-bit compare-and-swap */
11792static void
11793s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11794{
11795 IRCAS *cas;
11796 IRTemp op1 = newTemp(Ity_I32);
11797 IRTemp old_mem = newTemp(Ity_I32);
11798 IRTemp op3 = newTemp(Ity_I32);
11799 IRTemp result = newTemp(Ity_I32);
11800 IRTemp nequal = newTemp(Ity_I1);
11801
11802 assign(op1, get_gpr_w1(r1));
11803 assign(op3, get_gpr_w1(r3));
11804
11805 /* The first and second operands are compared. If they are equal,
11806 the third operand is stored at the second- operand location. */
11807 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11808 Iend_BE, mkexpr(op2addr),
11809 NULL, mkexpr(op1), /* expected value */
11810 NULL, mkexpr(op3) /* new value */);
11811 stmt(IRStmt_CAS(cas));
11812
11813 /* Set CC. Operands compared equal -> 0, else 1. */
11814 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11815 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11816
11817 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11818 Otherwise, store the old_value from memory in r1 and yield. */
11819 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11820 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011821 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011822}
11823
florian55085f82012-11-21 00:36:55 +000011824static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011825s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11826{
11827 s390_irgen_cas_32(r1, r3, op2addr);
11828
11829 return "cs";
11830}
11831
florian55085f82012-11-21 00:36:55 +000011832static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011833s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11834{
11835 s390_irgen_cas_32(r1, r3, op2addr);
11836
11837 return "csy";
11838}
11839
florian55085f82012-11-21 00:36:55 +000011840static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011841s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11842{
11843 IRCAS *cas;
11844 IRTemp op1 = newTemp(Ity_I64);
11845 IRTemp old_mem = newTemp(Ity_I64);
11846 IRTemp op3 = newTemp(Ity_I64);
11847 IRTemp result = newTemp(Ity_I64);
11848 IRTemp nequal = newTemp(Ity_I1);
11849
11850 assign(op1, get_gpr_dw0(r1));
11851 assign(op3, get_gpr_dw0(r3));
11852
11853 /* The first and second operands are compared. If they are equal,
11854 the third operand is stored at the second- operand location. */
11855 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11856 Iend_BE, mkexpr(op2addr),
11857 NULL, mkexpr(op1), /* expected value */
11858 NULL, mkexpr(op3) /* new value */);
11859 stmt(IRStmt_CAS(cas));
11860
11861 /* Set CC. Operands compared equal -> 0, else 1. */
11862 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11863 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11864
11865 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11866 Otherwise, store the old_value from memory in r1 and yield. */
11867 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11868 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011869 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011870
11871 return "csg";
11872}
11873
florian448cbba2012-06-06 02:26:01 +000011874/* Implementation for 32-bit compare-double-and-swap */
11875static void
11876s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11877{
11878 IRCAS *cas;
11879 IRTemp op1_high = newTemp(Ity_I32);
11880 IRTemp op1_low = newTemp(Ity_I32);
11881 IRTemp old_mem_high = newTemp(Ity_I32);
11882 IRTemp old_mem_low = newTemp(Ity_I32);
11883 IRTemp op3_high = newTemp(Ity_I32);
11884 IRTemp op3_low = newTemp(Ity_I32);
11885 IRTemp result = newTemp(Ity_I32);
11886 IRTemp nequal = newTemp(Ity_I1);
11887
11888 assign(op1_high, get_gpr_w1(r1));
11889 assign(op1_low, get_gpr_w1(r1+1));
11890 assign(op3_high, get_gpr_w1(r3));
11891 assign(op3_low, get_gpr_w1(r3+1));
11892
11893 /* The first and second operands are compared. If they are equal,
11894 the third operand is stored at the second-operand location. */
11895 cas = mkIRCAS(old_mem_high, old_mem_low,
11896 Iend_BE, mkexpr(op2addr),
11897 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11898 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11899 stmt(IRStmt_CAS(cas));
11900
11901 /* Set CC. Operands compared equal -> 0, else 1. */
11902 assign(result, unop(Iop_1Uto32,
11903 binop(Iop_CmpNE32,
11904 binop(Iop_Or32,
11905 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11906 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11907 mkU32(0))));
11908
11909 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11910
11911 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11912 Otherwise, store the old_value from memory in r1 and yield. */
11913 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11914 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11915 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011916 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011917}
11918
florian55085f82012-11-21 00:36:55 +000011919static const HChar *
florian448cbba2012-06-06 02:26:01 +000011920s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11921{
11922 s390_irgen_cdas_32(r1, r3, op2addr);
11923
11924 return "cds";
11925}
11926
florian55085f82012-11-21 00:36:55 +000011927static const HChar *
florian448cbba2012-06-06 02:26:01 +000011928s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11929{
11930 s390_irgen_cdas_32(r1, r3, op2addr);
11931
11932 return "cdsy";
11933}
11934
florian55085f82012-11-21 00:36:55 +000011935static const HChar *
florian448cbba2012-06-06 02:26:01 +000011936s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11937{
11938 IRCAS *cas;
11939 IRTemp op1_high = newTemp(Ity_I64);
11940 IRTemp op1_low = newTemp(Ity_I64);
11941 IRTemp old_mem_high = newTemp(Ity_I64);
11942 IRTemp old_mem_low = newTemp(Ity_I64);
11943 IRTemp op3_high = newTemp(Ity_I64);
11944 IRTemp op3_low = newTemp(Ity_I64);
11945 IRTemp result = newTemp(Ity_I64);
11946 IRTemp nequal = newTemp(Ity_I1);
11947
11948 assign(op1_high, get_gpr_dw0(r1));
11949 assign(op1_low, get_gpr_dw0(r1+1));
11950 assign(op3_high, get_gpr_dw0(r3));
11951 assign(op3_low, get_gpr_dw0(r3+1));
11952
11953 /* The first and second operands are compared. If they are equal,
11954 the third operand is stored at the second-operand location. */
11955 cas = mkIRCAS(old_mem_high, old_mem_low,
11956 Iend_BE, mkexpr(op2addr),
11957 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11958 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11959 stmt(IRStmt_CAS(cas));
11960
11961 /* Set CC. Operands compared equal -> 0, else 1. */
11962 assign(result, unop(Iop_1Uto64,
11963 binop(Iop_CmpNE64,
11964 binop(Iop_Or64,
11965 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11966 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11967 mkU64(0))));
11968
11969 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11970
11971 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11972 Otherwise, store the old_value from memory in r1 and yield. */
11973 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11974 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11975 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011976 yield_if(mkexpr(nequal));
11977
florian448cbba2012-06-06 02:26:01 +000011978 return "cdsg";
11979}
11980
sewardj2019a972011-03-07 16:04:07 +000011981
11982/* Binary floating point */
11983
florian55085f82012-11-21 00:36:55 +000011984static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011985s390_irgen_AXBR(UChar r1, UChar r2)
11986{
11987 IRTemp op1 = newTemp(Ity_F128);
11988 IRTemp op2 = newTemp(Ity_F128);
11989 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011990 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011991
11992 assign(op1, get_fpr_pair(r1));
11993 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011994 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011995 mkexpr(op2)));
11996 put_fpr_pair(r1, mkexpr(result));
11997
11998 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11999
12000 return "axbr";
12001}
12002
florian55085f82012-11-21 00:36:55 +000012003static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012004s390_irgen_CEBR(UChar r1, UChar r2)
12005{
12006 IRTemp op1 = newTemp(Ity_F32);
12007 IRTemp op2 = newTemp(Ity_F32);
12008 IRTemp cc_vex = newTemp(Ity_I32);
12009 IRTemp cc_s390 = newTemp(Ity_I32);
12010
12011 assign(op1, get_fpr_w0(r1));
12012 assign(op2, get_fpr_w0(r2));
12013 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12014
florian2d3d87f2012-12-21 21:05:17 +000012015 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012016 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12017
12018 return "cebr";
12019}
12020
florian55085f82012-11-21 00:36:55 +000012021static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012022s390_irgen_CDBR(UChar r1, UChar r2)
12023{
12024 IRTemp op1 = newTemp(Ity_F64);
12025 IRTemp op2 = newTemp(Ity_F64);
12026 IRTemp cc_vex = newTemp(Ity_I32);
12027 IRTemp cc_s390 = newTemp(Ity_I32);
12028
12029 assign(op1, get_fpr_dw0(r1));
12030 assign(op2, get_fpr_dw0(r2));
12031 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12032
florian2d3d87f2012-12-21 21:05:17 +000012033 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012034 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12035
12036 return "cdbr";
12037}
12038
florian55085f82012-11-21 00:36:55 +000012039static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012040s390_irgen_CXBR(UChar r1, UChar r2)
12041{
12042 IRTemp op1 = newTemp(Ity_F128);
12043 IRTemp op2 = newTemp(Ity_F128);
12044 IRTemp cc_vex = newTemp(Ity_I32);
12045 IRTemp cc_s390 = newTemp(Ity_I32);
12046
12047 assign(op1, get_fpr_pair(r1));
12048 assign(op2, get_fpr_pair(r2));
12049 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
12050
florian2d3d87f2012-12-21 21:05:17 +000012051 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012052 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12053
12054 return "cxbr";
12055}
12056
florian55085f82012-11-21 00:36:55 +000012057static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012058s390_irgen_CEB(UChar r1, IRTemp op2addr)
12059{
12060 IRTemp op1 = newTemp(Ity_F32);
12061 IRTemp op2 = newTemp(Ity_F32);
12062 IRTemp cc_vex = newTemp(Ity_I32);
12063 IRTemp cc_s390 = newTemp(Ity_I32);
12064
12065 assign(op1, get_fpr_w0(r1));
12066 assign(op2, load(Ity_F32, mkexpr(op2addr)));
12067 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12068
florian2d3d87f2012-12-21 21:05:17 +000012069 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012070 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12071
12072 return "ceb";
12073}
12074
florian55085f82012-11-21 00:36:55 +000012075static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012076s390_irgen_CDB(UChar r1, IRTemp op2addr)
12077{
12078 IRTemp op1 = newTemp(Ity_F64);
12079 IRTemp op2 = newTemp(Ity_F64);
12080 IRTemp cc_vex = newTemp(Ity_I32);
12081 IRTemp cc_s390 = newTemp(Ity_I32);
12082
12083 assign(op1, get_fpr_dw0(r1));
12084 assign(op2, load(Ity_F64, mkexpr(op2addr)));
12085 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12086
florian2d3d87f2012-12-21 21:05:17 +000012087 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012088 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12089
12090 return "cdb";
12091}
12092
florian55085f82012-11-21 00:36:55 +000012093static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012094s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
12095 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012096{
12097 IRTemp op2 = newTemp(Ity_I32);
12098
12099 assign(op2, get_gpr_w1(r2));
12100 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
12101
12102 return "cxfbr";
12103}
12104
florian55085f82012-11-21 00:36:55 +000012105static const HChar *
floriand2129202012-09-01 20:01:39 +000012106s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
12107 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012108{
floriane75dafa2012-09-01 17:54:09 +000012109 if (! s390_host_has_fpext) {
12110 emulation_failure(EmFail_S390X_fpext);
12111 } else {
12112 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000012113
floriane75dafa2012-09-01 17:54:09 +000012114 assign(op2, get_gpr_w1(r2));
12115 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
12116 }
florian1c8f7ff2012-09-01 00:12:11 +000012117 return "cxlfbr";
12118}
12119
12120
florian55085f82012-11-21 00:36:55 +000012121static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012122s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
12123 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012124{
12125 IRTemp op2 = newTemp(Ity_I64);
12126
12127 assign(op2, get_gpr_dw0(r2));
12128 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
12129
12130 return "cxgbr";
12131}
12132
florian55085f82012-11-21 00:36:55 +000012133static const HChar *
floriand2129202012-09-01 20:01:39 +000012134s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
12135 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012136{
floriane75dafa2012-09-01 17:54:09 +000012137 if (! s390_host_has_fpext) {
12138 emulation_failure(EmFail_S390X_fpext);
12139 } else {
12140 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000012141
floriane75dafa2012-09-01 17:54:09 +000012142 assign(op2, get_gpr_dw0(r2));
12143 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
12144 }
florian1c8f7ff2012-09-01 00:12:11 +000012145 return "cxlgbr";
12146}
12147
florian55085f82012-11-21 00:36:55 +000012148static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012149s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
12150 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012151{
12152 IRTemp op = newTemp(Ity_F128);
12153 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012154 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012155
12156 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012157 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012158 mkexpr(op)));
12159 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012160 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012161
12162 return "cfxbr";
12163}
12164
florian55085f82012-11-21 00:36:55 +000012165static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012166s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12167 UChar r1, UChar r2)
12168{
floriane75dafa2012-09-01 17:54:09 +000012169 if (! s390_host_has_fpext) {
12170 emulation_failure(EmFail_S390X_fpext);
12171 } else {
12172 IRTemp op = newTemp(Ity_F128);
12173 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012174 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012175
floriane75dafa2012-09-01 17:54:09 +000012176 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012177 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012178 mkexpr(op)));
12179 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012180 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012181 }
florian1c8f7ff2012-09-01 00:12:11 +000012182 return "clfxbr";
12183}
12184
12185
florian55085f82012-11-21 00:36:55 +000012186static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012187s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12188 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012189{
12190 IRTemp op = newTemp(Ity_F128);
12191 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012192 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012193
12194 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012195 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012196 mkexpr(op)));
12197 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012198 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012199
12200 return "cgxbr";
12201}
12202
florian55085f82012-11-21 00:36:55 +000012203static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012204s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12205 UChar r1, UChar r2)
12206{
floriane75dafa2012-09-01 17:54:09 +000012207 if (! s390_host_has_fpext) {
12208 emulation_failure(EmFail_S390X_fpext);
12209 } else {
12210 IRTemp op = newTemp(Ity_F128);
12211 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012212 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012213
floriane75dafa2012-09-01 17:54:09 +000012214 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012215 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012216 mkexpr(op)));
12217 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012218 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12219 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012220 }
florian1c8f7ff2012-09-01 00:12:11 +000012221 return "clgxbr";
12222}
12223
florian55085f82012-11-21 00:36:55 +000012224static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012225s390_irgen_DXBR(UChar r1, UChar r2)
12226{
12227 IRTemp op1 = newTemp(Ity_F128);
12228 IRTemp op2 = newTemp(Ity_F128);
12229 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012230 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012231
12232 assign(op1, get_fpr_pair(r1));
12233 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012234 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012235 mkexpr(op2)));
12236 put_fpr_pair(r1, mkexpr(result));
12237
12238 return "dxbr";
12239}
12240
florian55085f82012-11-21 00:36:55 +000012241static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012242s390_irgen_LTXBR(UChar r1, UChar r2)
12243{
12244 IRTemp result = newTemp(Ity_F128);
12245
12246 assign(result, get_fpr_pair(r2));
12247 put_fpr_pair(r1, mkexpr(result));
12248 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12249
12250 return "ltxbr";
12251}
12252
florian55085f82012-11-21 00:36:55 +000012253static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012254s390_irgen_LCXBR(UChar r1, UChar r2)
12255{
12256 IRTemp result = newTemp(Ity_F128);
12257
12258 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
12259 put_fpr_pair(r1, mkexpr(result));
12260 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12261
12262 return "lcxbr";
12263}
12264
florian55085f82012-11-21 00:36:55 +000012265static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012266s390_irgen_LXDBR(UChar r1, UChar r2)
12267{
12268 IRTemp op = newTemp(Ity_F64);
12269
12270 assign(op, get_fpr_dw0(r2));
12271 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12272
12273 return "lxdbr";
12274}
12275
florian55085f82012-11-21 00:36:55 +000012276static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012277s390_irgen_LXEBR(UChar r1, UChar r2)
12278{
12279 IRTemp op = newTemp(Ity_F32);
12280
12281 assign(op, get_fpr_w0(r2));
12282 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12283
12284 return "lxebr";
12285}
12286
florian55085f82012-11-21 00:36:55 +000012287static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012288s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12289{
12290 IRTemp op = newTemp(Ity_F64);
12291
12292 assign(op, load(Ity_F64, mkexpr(op2addr)));
12293 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12294
12295 return "lxdb";
12296}
12297
florian55085f82012-11-21 00:36:55 +000012298static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012299s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12300{
12301 IRTemp op = newTemp(Ity_F32);
12302
12303 assign(op, load(Ity_F32, mkexpr(op2addr)));
12304 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12305
12306 return "lxeb";
12307}
12308
florian55085f82012-11-21 00:36:55 +000012309static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012310s390_irgen_LNEBR(UChar r1, UChar r2)
12311{
12312 IRTemp result = newTemp(Ity_F32);
12313
12314 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12315 put_fpr_w0(r1, mkexpr(result));
12316 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12317
12318 return "lnebr";
12319}
12320
florian55085f82012-11-21 00:36:55 +000012321static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012322s390_irgen_LNDBR(UChar r1, UChar r2)
12323{
12324 IRTemp result = newTemp(Ity_F64);
12325
12326 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12327 put_fpr_dw0(r1, mkexpr(result));
12328 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12329
12330 return "lndbr";
12331}
12332
florian55085f82012-11-21 00:36:55 +000012333static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012334s390_irgen_LNXBR(UChar r1, UChar r2)
12335{
12336 IRTemp result = newTemp(Ity_F128);
12337
12338 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12339 put_fpr_pair(r1, mkexpr(result));
12340 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12341
12342 return "lnxbr";
12343}
12344
florian55085f82012-11-21 00:36:55 +000012345static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012346s390_irgen_LPEBR(UChar r1, UChar r2)
12347{
12348 IRTemp result = newTemp(Ity_F32);
12349
12350 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12351 put_fpr_w0(r1, mkexpr(result));
12352 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12353
12354 return "lpebr";
12355}
12356
florian55085f82012-11-21 00:36:55 +000012357static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012358s390_irgen_LPDBR(UChar r1, UChar r2)
12359{
12360 IRTemp result = newTemp(Ity_F64);
12361
12362 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12363 put_fpr_dw0(r1, mkexpr(result));
12364 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12365
12366 return "lpdbr";
12367}
12368
florian55085f82012-11-21 00:36:55 +000012369static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012370s390_irgen_LPXBR(UChar r1, UChar r2)
12371{
12372 IRTemp result = newTemp(Ity_F128);
12373
12374 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12375 put_fpr_pair(r1, mkexpr(result));
12376 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12377
12378 return "lpxbr";
12379}
12380
florian55085f82012-11-21 00:36:55 +000012381static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012382s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12383 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012384{
florian125e20d2012-10-07 15:42:37 +000012385 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012386 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012387 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012388 }
sewardj2019a972011-03-07 16:04:07 +000012389 IRTemp result = newTemp(Ity_F64);
12390
floriandb4fcaa2012-09-05 19:54:08 +000012391 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012392 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012393 put_fpr_dw0(r1, mkexpr(result));
12394
12395 return "ldxbr";
12396}
12397
florian55085f82012-11-21 00:36:55 +000012398static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012399s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12400 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012401{
florian125e20d2012-10-07 15:42:37 +000012402 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012403 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012404 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012405 }
sewardj2019a972011-03-07 16:04:07 +000012406 IRTemp result = newTemp(Ity_F32);
12407
floriandb4fcaa2012-09-05 19:54:08 +000012408 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012409 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012410 put_fpr_w0(r1, mkexpr(result));
12411
12412 return "lexbr";
12413}
12414
florian55085f82012-11-21 00:36:55 +000012415static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012416s390_irgen_MXBR(UChar r1, UChar r2)
12417{
12418 IRTemp op1 = newTemp(Ity_F128);
12419 IRTemp op2 = newTemp(Ity_F128);
12420 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012421 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012422
12423 assign(op1, get_fpr_pair(r1));
12424 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012425 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012426 mkexpr(op2)));
12427 put_fpr_pair(r1, mkexpr(result));
12428
12429 return "mxbr";
12430}
12431
florian55085f82012-11-21 00:36:55 +000012432static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012433s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12434{
florian125e20d2012-10-07 15:42:37 +000012435 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012436
floriandb4fcaa2012-09-05 19:54:08 +000012437 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012438 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012439
12440 return "maebr";
12441}
12442
florian55085f82012-11-21 00:36:55 +000012443static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012444s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12445{
florian125e20d2012-10-07 15:42:37 +000012446 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012447
floriandb4fcaa2012-09-05 19:54:08 +000012448 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012449 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012450
12451 return "madbr";
12452}
12453
florian55085f82012-11-21 00:36:55 +000012454static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012455s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12456{
12457 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012458 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012459
floriandb4fcaa2012-09-05 19:54:08 +000012460 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012461 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012462
12463 return "maeb";
12464}
12465
florian55085f82012-11-21 00:36:55 +000012466static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012467s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12468{
12469 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012470 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012471
floriandb4fcaa2012-09-05 19:54:08 +000012472 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012473 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012474
12475 return "madb";
12476}
12477
florian55085f82012-11-21 00:36:55 +000012478static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012479s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12480{
florian125e20d2012-10-07 15:42:37 +000012481 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012482
floriandb4fcaa2012-09-05 19:54:08 +000012483 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012484 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012485
12486 return "msebr";
12487}
12488
florian55085f82012-11-21 00:36:55 +000012489static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012490s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12491{
florian125e20d2012-10-07 15:42:37 +000012492 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012493
floriandb4fcaa2012-09-05 19:54:08 +000012494 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012495 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012496
12497 return "msdbr";
12498}
12499
florian55085f82012-11-21 00:36:55 +000012500static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012501s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12502{
12503 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012504 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012505
floriandb4fcaa2012-09-05 19:54:08 +000012506 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012507 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012508
12509 return "mseb";
12510}
12511
florian55085f82012-11-21 00:36:55 +000012512static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012513s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12514{
12515 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012516 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012517
floriandb4fcaa2012-09-05 19:54:08 +000012518 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012519 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012520
12521 return "msdb";
12522}
12523
florian55085f82012-11-21 00:36:55 +000012524static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012525s390_irgen_SQEBR(UChar r1, UChar r2)
12526{
12527 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012528 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012529
floriandb4fcaa2012-09-05 19:54:08 +000012530 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012531 put_fpr_w0(r1, mkexpr(result));
12532
12533 return "sqebr";
12534}
12535
florian55085f82012-11-21 00:36:55 +000012536static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012537s390_irgen_SQDBR(UChar r1, UChar r2)
12538{
12539 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012540 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012541
floriandb4fcaa2012-09-05 19:54:08 +000012542 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012543 put_fpr_dw0(r1, mkexpr(result));
12544
12545 return "sqdbr";
12546}
12547
florian55085f82012-11-21 00:36:55 +000012548static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012549s390_irgen_SQXBR(UChar r1, UChar r2)
12550{
12551 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012552 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012553
floriandb4fcaa2012-09-05 19:54:08 +000012554 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12555 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012556 put_fpr_pair(r1, mkexpr(result));
12557
12558 return "sqxbr";
12559}
12560
florian55085f82012-11-21 00:36:55 +000012561static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012562s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12563{
12564 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012565 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012566
12567 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012568 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012569
12570 return "sqeb";
12571}
12572
florian55085f82012-11-21 00:36:55 +000012573static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012574s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12575{
12576 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012577 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012578
12579 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012580 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012581
12582 return "sqdb";
12583}
12584
florian55085f82012-11-21 00:36:55 +000012585static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012586s390_irgen_SXBR(UChar r1, UChar r2)
12587{
12588 IRTemp op1 = newTemp(Ity_F128);
12589 IRTemp op2 = newTemp(Ity_F128);
12590 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012591 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012592
12593 assign(op1, get_fpr_pair(r1));
12594 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012595 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012596 mkexpr(op2)));
12597 put_fpr_pair(r1, mkexpr(result));
12598 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12599
12600 return "sxbr";
12601}
12602
florian55085f82012-11-21 00:36:55 +000012603static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012604s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12605{
12606 IRTemp value = newTemp(Ity_F32);
12607
12608 assign(value, get_fpr_w0(r1));
12609
12610 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12611
12612 return "tceb";
12613}
12614
florian55085f82012-11-21 00:36:55 +000012615static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012616s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12617{
12618 IRTemp value = newTemp(Ity_F64);
12619
12620 assign(value, get_fpr_dw0(r1));
12621
12622 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12623
12624 return "tcdb";
12625}
12626
florian55085f82012-11-21 00:36:55 +000012627static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012628s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12629{
12630 IRTemp value = newTemp(Ity_F128);
12631
12632 assign(value, get_fpr_pair(r1));
12633
12634 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12635
12636 return "tcxb";
12637}
12638
florian55085f82012-11-21 00:36:55 +000012639static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012640s390_irgen_LCDFR(UChar r1, UChar r2)
12641{
12642 IRTemp result = newTemp(Ity_F64);
12643
12644 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12645 put_fpr_dw0(r1, mkexpr(result));
12646
12647 return "lcdfr";
12648}
12649
florian55085f82012-11-21 00:36:55 +000012650static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012651s390_irgen_LNDFR(UChar r1, UChar r2)
12652{
12653 IRTemp result = newTemp(Ity_F64);
12654
12655 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12656 put_fpr_dw0(r1, mkexpr(result));
12657
12658 return "lndfr";
12659}
12660
florian55085f82012-11-21 00:36:55 +000012661static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012662s390_irgen_LPDFR(UChar r1, UChar r2)
12663{
12664 IRTemp result = newTemp(Ity_F64);
12665
12666 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12667 put_fpr_dw0(r1, mkexpr(result));
12668
12669 return "lpdfr";
12670}
12671
florian55085f82012-11-21 00:36:55 +000012672static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012673s390_irgen_LDGR(UChar r1, UChar r2)
12674{
12675 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12676
12677 return "ldgr";
12678}
12679
florian55085f82012-11-21 00:36:55 +000012680static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012681s390_irgen_LGDR(UChar r1, UChar r2)
12682{
12683 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12684
12685 return "lgdr";
12686}
12687
12688
florian55085f82012-11-21 00:36:55 +000012689static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012690s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12691{
12692 IRTemp sign = newTemp(Ity_I64);
12693 IRTemp value = newTemp(Ity_I64);
12694
12695 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12696 mkU64(1ULL << 63)));
12697 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12698 mkU64((1ULL << 63) - 1)));
12699 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12700 mkexpr(sign))));
12701
12702 return "cpsdr";
12703}
12704
12705
sewardj2019a972011-03-07 16:04:07 +000012706static IRExpr *
12707s390_call_cvb(IRExpr *in)
12708{
12709 IRExpr **args, *call;
12710
12711 args = mkIRExprVec_1(in);
12712 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12713 "s390_do_cvb", &s390_do_cvb, args);
12714
12715 /* Nothing is excluded from definedness checking. */
12716 call->Iex.CCall.cee->mcx_mask = 0;
12717
12718 return call;
12719}
12720
florian55085f82012-11-21 00:36:55 +000012721static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012722s390_irgen_CVB(UChar r1, IRTemp op2addr)
12723{
12724 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12725
12726 return "cvb";
12727}
12728
florian55085f82012-11-21 00:36:55 +000012729static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012730s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12731{
12732 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12733
12734 return "cvby";
12735}
12736
12737
sewardj2019a972011-03-07 16:04:07 +000012738static IRExpr *
12739s390_call_cvd(IRExpr *in)
12740{
12741 IRExpr **args, *call;
12742
12743 args = mkIRExprVec_1(in);
12744 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12745 "s390_do_cvd", &s390_do_cvd, args);
12746
12747 /* Nothing is excluded from definedness checking. */
12748 call->Iex.CCall.cee->mcx_mask = 0;
12749
12750 return call;
12751}
12752
florian55085f82012-11-21 00:36:55 +000012753static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012754s390_irgen_CVD(UChar r1, IRTemp op2addr)
12755{
florian11b8ee82012-08-06 13:35:33 +000012756 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012757
12758 return "cvd";
12759}
12760
florian55085f82012-11-21 00:36:55 +000012761static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012762s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12763{
12764 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12765
12766 return "cvdy";
12767}
12768
florian55085f82012-11-21 00:36:55 +000012769static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012770s390_irgen_FLOGR(UChar r1, UChar r2)
12771{
12772 IRTemp input = newTemp(Ity_I64);
12773 IRTemp not_zero = newTemp(Ity_I64);
12774 IRTemp tmpnum = newTemp(Ity_I64);
12775 IRTemp num = newTemp(Ity_I64);
12776 IRTemp shift_amount = newTemp(Ity_I8);
12777
12778 /* We use the "count leading zeroes" operator because the number of
12779 leading zeroes is identical with the bit position of the first '1' bit.
12780 However, that operator does not work when the input value is zero.
12781 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12782 the modified value. If input == 0, then the result is 64. Otherwise,
12783 the result of Clz64 is what we want. */
12784
12785 assign(input, get_gpr_dw0(r2));
12786 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12787 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12788
12789 /* num = (input == 0) ? 64 : tmpnum */
12790 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12791 /* == 0 */ mkU64(64),
12792 /* != 0 */ mkexpr(tmpnum)));
12793
12794 put_gpr_dw0(r1, mkexpr(num));
12795
12796 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12797 is to first shift the input value by NUM + 1 bits to the left which
12798 causes the leftmost '1' bit to disappear. Then we shift logically to
12799 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12800 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12801 the width of the value-to-be-shifted, we need to special case
12802 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12803 For both such INPUT values the result will be 0. */
12804
12805 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12806 mkU64(1))));
12807
12808 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012809 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12810 /* == 0 || == 1*/ mkU64(0),
12811 /* otherwise */
12812 binop(Iop_Shr64,
12813 binop(Iop_Shl64, mkexpr(input),
12814 mkexpr(shift_amount)),
12815 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012816
12817 /* Compare the original value as an unsigned integer with 0. */
12818 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12819 mktemp(Ity_I64, mkU64(0)), False);
12820
12821 return "flogr";
12822}
12823
florian55085f82012-11-21 00:36:55 +000012824static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012825s390_irgen_STCK(IRTemp op2addr)
12826{
12827 IRDirty *d;
12828 IRTemp cc = newTemp(Ity_I64);
12829
12830 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12831 &s390x_dirtyhelper_STCK,
12832 mkIRExprVec_1(mkexpr(op2addr)));
12833 d->mFx = Ifx_Write;
12834 d->mAddr = mkexpr(op2addr);
12835 d->mSize = 8;
12836 stmt(IRStmt_Dirty(d));
12837 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12838 mkexpr(cc), mkU64(0), mkU64(0));
12839 return "stck";
12840}
12841
florian55085f82012-11-21 00:36:55 +000012842static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012843s390_irgen_STCKF(IRTemp op2addr)
12844{
florianc5c669b2012-08-26 14:32:28 +000012845 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012846 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012847 } else {
12848 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012849
florianc5c669b2012-08-26 14:32:28 +000012850 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12851 &s390x_dirtyhelper_STCKF,
12852 mkIRExprVec_1(mkexpr(op2addr)));
12853 d->mFx = Ifx_Write;
12854 d->mAddr = mkexpr(op2addr);
12855 d->mSize = 8;
12856 stmt(IRStmt_Dirty(d));
12857 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12858 mkexpr(cc), mkU64(0), mkU64(0));
12859 }
sewardj1e5fea62011-05-17 16:18:36 +000012860 return "stckf";
12861}
12862
florian55085f82012-11-21 00:36:55 +000012863static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012864s390_irgen_STCKE(IRTemp op2addr)
12865{
12866 IRDirty *d;
12867 IRTemp cc = newTemp(Ity_I64);
12868
12869 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12870 &s390x_dirtyhelper_STCKE,
12871 mkIRExprVec_1(mkexpr(op2addr)));
12872 d->mFx = Ifx_Write;
12873 d->mAddr = mkexpr(op2addr);
12874 d->mSize = 16;
12875 stmt(IRStmt_Dirty(d));
12876 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12877 mkexpr(cc), mkU64(0), mkU64(0));
12878 return "stcke";
12879}
12880
florian55085f82012-11-21 00:36:55 +000012881static const HChar *
florian933065d2011-07-11 01:48:02 +000012882s390_irgen_STFLE(IRTemp op2addr)
12883{
florian4e0083e2012-08-26 03:41:56 +000012884 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012885 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012886 return "stfle";
12887 }
12888
florian933065d2011-07-11 01:48:02 +000012889 IRDirty *d;
12890 IRTemp cc = newTemp(Ity_I64);
12891
florian90419562013-08-15 20:54:52 +000012892 /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper */
florian933065d2011-07-11 01:48:02 +000012893 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12894 &s390x_dirtyhelper_STFLE,
florian90419562013-08-15 20:54:52 +000012895 mkIRExprVec_2(IRExpr_BBPTR(), mkexpr(op2addr)));
florian933065d2011-07-11 01:48:02 +000012896
sewardjc9069f22012-06-01 16:09:50 +000012897 d->nFxState = 1;
12898 vex_bzero(&d->fxState, sizeof(d->fxState));
12899
florian933065d2011-07-11 01:48:02 +000012900 d->fxState[0].fx = Ifx_Modify; /* read then write */
12901 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12902 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012903
12904 d->mAddr = mkexpr(op2addr);
12905 /* Pretend all double words are written */
12906 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12907 d->mFx = Ifx_Write;
12908
12909 stmt(IRStmt_Dirty(d));
12910
12911 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12912
12913 return "stfle";
12914}
12915
florian55085f82012-11-21 00:36:55 +000012916static const HChar *
floriana4384a32011-08-11 16:58:45 +000012917s390_irgen_CKSM(UChar r1,UChar r2)
12918{
12919 IRTemp addr = newTemp(Ity_I64);
12920 IRTemp op = newTemp(Ity_I32);
12921 IRTemp len = newTemp(Ity_I64);
12922 IRTemp oldval = newTemp(Ity_I32);
12923 IRTemp mask = newTemp(Ity_I32);
12924 IRTemp newop = newTemp(Ity_I32);
12925 IRTemp result = newTemp(Ity_I32);
12926 IRTemp result1 = newTemp(Ity_I32);
12927 IRTemp inc = newTemp(Ity_I64);
12928
12929 assign(oldval, get_gpr_w1(r1));
12930 assign(addr, get_gpr_dw0(r2));
12931 assign(len, get_gpr_dw0(r2+1));
12932
12933 /* Condition code is always zero. */
12934 s390_cc_set(0);
12935
12936 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012937 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012938
12939 /* Assiging the increment variable to adjust address and length
12940 later on. */
12941 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12942 mkexpr(len), mkU64(4)));
12943
12944 /* If length < 4 the final 4-byte 2nd operand value is computed by
12945 appending the remaining bytes to the right with 0. This is done
12946 by AND'ing the 4 bytes loaded from memory with an appropriate
12947 mask. If length >= 4, that mask is simply 0xffffffff. */
12948
12949 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12950 /* Mask computation when len < 4:
12951 0xffffffff << (32 - (len % 4)*8) */
12952 binop(Iop_Shl32, mkU32(0xffffffff),
12953 unop(Iop_32to8,
12954 binop(Iop_Sub32, mkU32(32),
12955 binop(Iop_Shl32,
12956 unop(Iop_64to32,
12957 binop(Iop_And64,
12958 mkexpr(len), mkU64(3))),
12959 mkU8(3))))),
12960 mkU32(0xffffffff)));
12961
12962 assign(op, load(Ity_I32, mkexpr(addr)));
12963 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12964 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12965
12966 /* Checking for carry */
12967 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12968 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12969 mkexpr(result)));
12970
12971 put_gpr_w1(r1, mkexpr(result1));
12972 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12973 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12974
florian6820ba52012-07-26 02:01:50 +000012975 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012976
12977 return "cksm";
12978}
12979
florian55085f82012-11-21 00:36:55 +000012980static const HChar *
florian9af37692012-01-15 21:01:16 +000012981s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12982{
12983 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12984 src_addr = newTemp(Ity_I64);
12985 des_addr = newTemp(Ity_I64);
12986 tab_addr = newTemp(Ity_I64);
12987 test_byte = newTemp(Ity_I8);
12988 src_len = newTemp(Ity_I64);
12989
12990 assign(src_addr, get_gpr_dw0(r2));
12991 assign(des_addr, get_gpr_dw0(r1));
12992 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012993 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012994 assign(test_byte, get_gpr_b7(0));
12995
12996 IRTemp op = newTemp(Ity_I8);
12997 IRTemp op1 = newTemp(Ity_I8);
12998 IRTemp result = newTemp(Ity_I64);
12999
13000 /* End of source string? We're done; proceed to next insn */
13001 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013002 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000013003
13004 /* Load character from source string, index translation table and
13005 store translated character in op1. */
13006 assign(op, load(Ity_I8, mkexpr(src_addr)));
13007
13008 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13009 mkexpr(tab_addr)));
13010 assign(op1, load(Ity_I8, mkexpr(result)));
13011
13012 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13013 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013014 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000013015 }
13016 store(get_gpr_dw0(r1), mkexpr(op1));
13017
13018 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13019 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13020 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13021
florian6820ba52012-07-26 02:01:50 +000013022 iterate();
florian9af37692012-01-15 21:01:16 +000013023
13024 return "troo";
13025}
13026
florian55085f82012-11-21 00:36:55 +000013027static const HChar *
florian730448f2012-02-04 17:07:07 +000013028s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
13029{
13030 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13031 src_addr = newTemp(Ity_I64);
13032 des_addr = newTemp(Ity_I64);
13033 tab_addr = newTemp(Ity_I64);
13034 test_byte = newTemp(Ity_I8);
13035 src_len = newTemp(Ity_I64);
13036
13037 assign(src_addr, get_gpr_dw0(r2));
13038 assign(des_addr, get_gpr_dw0(r1));
13039 assign(tab_addr, get_gpr_dw0(1));
13040 assign(src_len, get_gpr_dw0(r1+1));
13041 assign(test_byte, get_gpr_b7(0));
13042
13043 IRTemp op = newTemp(Ity_I16);
13044 IRTemp op1 = newTemp(Ity_I8);
13045 IRTemp result = newTemp(Ity_I64);
13046
13047 /* End of source string? We're done; proceed to next insn */
13048 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013049 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013050
13051 /* Load character from source string, index translation table and
13052 store translated character in op1. */
13053 assign(op, load(Ity_I16, mkexpr(src_addr)));
13054
13055 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13056 mkexpr(tab_addr)));
13057
13058 assign(op1, load(Ity_I8, mkexpr(result)));
13059
13060 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13061 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013062 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013063 }
13064 store(get_gpr_dw0(r1), mkexpr(op1));
13065
13066 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13067 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13068 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13069
florian6820ba52012-07-26 02:01:50 +000013070 iterate();
florian730448f2012-02-04 17:07:07 +000013071
13072 return "trto";
13073}
13074
florian55085f82012-11-21 00:36:55 +000013075static const HChar *
florian730448f2012-02-04 17:07:07 +000013076s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
13077{
13078 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13079 src_addr = newTemp(Ity_I64);
13080 des_addr = newTemp(Ity_I64);
13081 tab_addr = newTemp(Ity_I64);
13082 test_byte = newTemp(Ity_I16);
13083 src_len = newTemp(Ity_I64);
13084
13085 assign(src_addr, get_gpr_dw0(r2));
13086 assign(des_addr, get_gpr_dw0(r1));
13087 assign(tab_addr, get_gpr_dw0(1));
13088 assign(src_len, get_gpr_dw0(r1+1));
13089 assign(test_byte, get_gpr_hw3(0));
13090
13091 IRTemp op = newTemp(Ity_I8);
13092 IRTemp op1 = newTemp(Ity_I16);
13093 IRTemp result = newTemp(Ity_I64);
13094
13095 /* End of source string? We're done; proceed to next insn */
13096 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013097 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013098
13099 /* Load character from source string, index translation table and
13100 store translated character in op1. */
13101 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
13102
13103 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13104 mkexpr(tab_addr)));
13105 assign(op1, load(Ity_I16, mkexpr(result)));
13106
13107 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13108 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013109 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013110 }
13111 store(get_gpr_dw0(r1), mkexpr(op1));
13112
13113 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13114 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13115 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13116
florian6820ba52012-07-26 02:01:50 +000013117 iterate();
florian730448f2012-02-04 17:07:07 +000013118
13119 return "trot";
13120}
13121
florian55085f82012-11-21 00:36:55 +000013122static const HChar *
florian730448f2012-02-04 17:07:07 +000013123s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
13124{
13125 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13126 src_addr = newTemp(Ity_I64);
13127 des_addr = newTemp(Ity_I64);
13128 tab_addr = newTemp(Ity_I64);
13129 test_byte = newTemp(Ity_I16);
13130 src_len = newTemp(Ity_I64);
13131
13132 assign(src_addr, get_gpr_dw0(r2));
13133 assign(des_addr, get_gpr_dw0(r1));
13134 assign(tab_addr, get_gpr_dw0(1));
13135 assign(src_len, get_gpr_dw0(r1+1));
13136 assign(test_byte, get_gpr_hw3(0));
13137
13138 IRTemp op = newTemp(Ity_I16);
13139 IRTemp op1 = newTemp(Ity_I16);
13140 IRTemp result = newTemp(Ity_I64);
13141
13142 /* End of source string? We're done; proceed to next insn */
13143 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013144 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013145
13146 /* Load character from source string, index translation table and
13147 store translated character in op1. */
13148 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
13149
13150 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13151 mkexpr(tab_addr)));
13152 assign(op1, load(Ity_I16, mkexpr(result)));
13153
13154 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13155 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013156 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013157 }
13158
13159 store(get_gpr_dw0(r1), mkexpr(op1));
13160
13161 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13162 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13163 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13164
florian6820ba52012-07-26 02:01:50 +000013165 iterate();
florian730448f2012-02-04 17:07:07 +000013166
13167 return "trtt";
13168}
13169
florian55085f82012-11-21 00:36:55 +000013170static const HChar *
florian730448f2012-02-04 17:07:07 +000013171s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13172{
florianf87d4fb2012-05-05 02:55:24 +000013173 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000013174
florianf87d4fb2012-05-05 02:55:24 +000013175 assign(len, mkU64(length));
13176 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000013177
13178 return "tr";
13179}
13180
florian55085f82012-11-21 00:36:55 +000013181static const HChar *
florian730448f2012-02-04 17:07:07 +000013182s390_irgen_TRE(UChar r1,UChar r2)
13183{
13184 IRTemp src_addr, tab_addr, src_len, test_byte;
13185 src_addr = newTemp(Ity_I64);
13186 tab_addr = newTemp(Ity_I64);
13187 src_len = newTemp(Ity_I64);
13188 test_byte = newTemp(Ity_I8);
13189
13190 assign(src_addr, get_gpr_dw0(r1));
13191 assign(src_len, get_gpr_dw0(r1+1));
13192 assign(tab_addr, get_gpr_dw0(r2));
13193 assign(test_byte, get_gpr_b7(0));
13194
13195 IRTemp op = newTemp(Ity_I8);
13196 IRTemp op1 = newTemp(Ity_I8);
13197 IRTemp result = newTemp(Ity_I64);
13198
13199 /* End of source string? We're done; proceed to next insn */
13200 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013201 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013202
13203 /* Load character from source string and compare with test byte */
13204 assign(op, load(Ity_I8, mkexpr(src_addr)));
13205
13206 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013207 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013208
13209 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13210 mkexpr(tab_addr)));
13211
13212 assign(op1, load(Ity_I8, mkexpr(result)));
13213
13214 store(get_gpr_dw0(r1), mkexpr(op1));
13215 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13216 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13217
florian6820ba52012-07-26 02:01:50 +000013218 iterate();
florian730448f2012-02-04 17:07:07 +000013219
13220 return "tre";
13221}
13222
floriana0100c92012-07-20 00:06:35 +000013223static IRExpr *
13224s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13225{
13226 IRExpr **args, *call;
13227 args = mkIRExprVec_2(srcval, low_surrogate);
13228 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13229 "s390_do_cu21", &s390_do_cu21, args);
13230
13231 /* Nothing is excluded from definedness checking. */
13232 call->Iex.CCall.cee->mcx_mask = 0;
13233
13234 return call;
13235}
13236
florian55085f82012-11-21 00:36:55 +000013237static const HChar *
floriana0100c92012-07-20 00:06:35 +000013238s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13239{
13240 IRTemp addr1 = newTemp(Ity_I64);
13241 IRTemp addr2 = newTemp(Ity_I64);
13242 IRTemp len1 = newTemp(Ity_I64);
13243 IRTemp len2 = newTemp(Ity_I64);
13244
13245 assign(addr1, get_gpr_dw0(r1));
13246 assign(addr2, get_gpr_dw0(r2));
13247 assign(len1, get_gpr_dw0(r1 + 1));
13248 assign(len2, get_gpr_dw0(r2 + 1));
13249
13250 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13251 there are less than 2 bytes left, then the 2nd operand is exhausted
13252 and we're done here. cc = 0 */
13253 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013254 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000013255
13256 /* There are at least two bytes there. Read them. */
13257 IRTemp srcval = newTemp(Ity_I32);
13258 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13259
13260 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13261 inside the interval [0xd800 - 0xdbff] */
13262 IRTemp is_high_surrogate = newTemp(Ity_I32);
13263 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13264 mkU32(1), mkU32(0));
13265 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13266 mkU32(1), mkU32(0));
13267 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13268
13269 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13270 then the 2nd operand is exhausted and we're done here. cc = 0 */
13271 IRExpr *not_enough_bytes =
13272 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13273
florian6820ba52012-07-26 02:01:50 +000013274 next_insn_if(binop(Iop_CmpEQ32,
13275 binop(Iop_And32, mkexpr(is_high_surrogate),
13276 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000013277
13278 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13279 surrogate, read the next two bytes (low surrogate). */
13280 IRTemp low_surrogate = newTemp(Ity_I32);
13281 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13282
13283 assign(low_surrogate,
13284 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13285 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13286 mkU32(0))); // any value is fine; it will not be used
13287
13288 /* Call the helper */
13289 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013290 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13291 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000013292
13293 /* Before we can test whether the 1st operand is exhausted we need to
13294 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13295 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13296 IRExpr *invalid_low_surrogate =
13297 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13298
13299 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013300 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000013301 }
13302
13303 /* Now test whether the 1st operand is exhausted */
13304 IRTemp num_bytes = newTemp(Ity_I64);
13305 assign(num_bytes, binop(Iop_And64,
13306 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13307 mkU64(0xff)));
13308 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013309 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000013310
13311 /* Extract the bytes to be stored at addr1 */
13312 IRTemp data = newTemp(Ity_I64);
13313 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13314
13315 /* To store the bytes construct 4 dirty helper calls. The helper calls
13316 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13317 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013318 UInt i;
floriana0100c92012-07-20 00:06:35 +000013319 for (i = 1; i <= 4; ++i) {
13320 IRDirty *d;
13321
13322 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13323 &s390x_dirtyhelper_CUxy,
13324 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13325 mkexpr(num_bytes)));
13326 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13327 d->mFx = Ifx_Write;
13328 d->mAddr = mkexpr(addr1);
13329 d->mSize = i;
13330 stmt(IRStmt_Dirty(d));
13331 }
13332
13333 /* Update source address and length */
13334 IRTemp num_src_bytes = newTemp(Ity_I64);
13335 assign(num_src_bytes,
13336 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13337 mkU64(4), mkU64(2)));
13338 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13339 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13340
13341 /* Update destination address and length */
13342 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13343 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13344
florian6820ba52012-07-26 02:01:50 +000013345 iterate();
floriana0100c92012-07-20 00:06:35 +000013346
13347 return "cu21";
13348}
13349
florian2a415a12012-07-21 17:41:36 +000013350static IRExpr *
13351s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13352{
13353 IRExpr **args, *call;
13354 args = mkIRExprVec_2(srcval, low_surrogate);
13355 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13356 "s390_do_cu24", &s390_do_cu24, args);
13357
13358 /* Nothing is excluded from definedness checking. */
13359 call->Iex.CCall.cee->mcx_mask = 0;
13360
13361 return call;
13362}
13363
florian55085f82012-11-21 00:36:55 +000013364static const HChar *
florian2a415a12012-07-21 17:41:36 +000013365s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13366{
13367 IRTemp addr1 = newTemp(Ity_I64);
13368 IRTemp addr2 = newTemp(Ity_I64);
13369 IRTemp len1 = newTemp(Ity_I64);
13370 IRTemp len2 = newTemp(Ity_I64);
13371
13372 assign(addr1, get_gpr_dw0(r1));
13373 assign(addr2, get_gpr_dw0(r2));
13374 assign(len1, get_gpr_dw0(r1 + 1));
13375 assign(len2, get_gpr_dw0(r2 + 1));
13376
13377 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13378 there are less than 2 bytes left, then the 2nd operand is exhausted
13379 and we're done here. cc = 0 */
13380 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013381 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000013382
13383 /* There are at least two bytes there. Read them. */
13384 IRTemp srcval = newTemp(Ity_I32);
13385 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13386
13387 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13388 inside the interval [0xd800 - 0xdbff] */
13389 IRTemp is_high_surrogate = newTemp(Ity_I32);
13390 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13391 mkU32(1), mkU32(0));
13392 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13393 mkU32(1), mkU32(0));
13394 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13395
13396 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13397 then the 2nd operand is exhausted and we're done here. cc = 0 */
13398 IRExpr *not_enough_bytes =
13399 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13400
florian6820ba52012-07-26 02:01:50 +000013401 next_insn_if(binop(Iop_CmpEQ32,
13402 binop(Iop_And32, mkexpr(is_high_surrogate),
13403 not_enough_bytes),
13404 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000013405
13406 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13407 surrogate, read the next two bytes (low surrogate). */
13408 IRTemp low_surrogate = newTemp(Ity_I32);
13409 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13410
13411 assign(low_surrogate,
13412 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13413 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13414 mkU32(0))); // any value is fine; it will not be used
13415
13416 /* Call the helper */
13417 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013418 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13419 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000013420
13421 /* Before we can test whether the 1st operand is exhausted we need to
13422 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13423 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13424 IRExpr *invalid_low_surrogate =
13425 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13426
13427 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013428 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000013429 }
13430
13431 /* Now test whether the 1st operand is exhausted */
13432 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013433 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000013434
13435 /* Extract the bytes to be stored at addr1 */
13436 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13437
13438 store(mkexpr(addr1), data);
13439
13440 /* Update source address and length */
13441 IRTemp num_src_bytes = newTemp(Ity_I64);
13442 assign(num_src_bytes,
13443 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13444 mkU64(4), mkU64(2)));
13445 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13446 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13447
13448 /* Update destination address and length */
13449 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13450 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
13451
florian6820ba52012-07-26 02:01:50 +000013452 iterate();
florian2a415a12012-07-21 17:41:36 +000013453
13454 return "cu24";
13455}
floriana4384a32011-08-11 16:58:45 +000013456
florian956194b2012-07-28 22:18:32 +000013457static IRExpr *
13458s390_call_cu42(IRExpr *srcval)
13459{
13460 IRExpr **args, *call;
13461 args = mkIRExprVec_1(srcval);
13462 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13463 "s390_do_cu42", &s390_do_cu42, args);
13464
13465 /* Nothing is excluded from definedness checking. */
13466 call->Iex.CCall.cee->mcx_mask = 0;
13467
13468 return call;
13469}
13470
florian55085f82012-11-21 00:36:55 +000013471static const HChar *
florian956194b2012-07-28 22:18:32 +000013472s390_irgen_CU42(UChar r1, UChar r2)
13473{
13474 IRTemp addr1 = newTemp(Ity_I64);
13475 IRTemp addr2 = newTemp(Ity_I64);
13476 IRTemp len1 = newTemp(Ity_I64);
13477 IRTemp len2 = newTemp(Ity_I64);
13478
13479 assign(addr1, get_gpr_dw0(r1));
13480 assign(addr2, get_gpr_dw0(r2));
13481 assign(len1, get_gpr_dw0(r1 + 1));
13482 assign(len2, get_gpr_dw0(r2 + 1));
13483
13484 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13485 there are less than 4 bytes left, then the 2nd operand is exhausted
13486 and we're done here. cc = 0 */
13487 s390_cc_set(0);
13488 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13489
13490 /* Read the 2nd operand. */
13491 IRTemp srcval = newTemp(Ity_I32);
13492 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13493
13494 /* Call the helper */
13495 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013496 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000013497
13498 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13499 cc=2 outranks cc=1 (1st operand exhausted) */
13500 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13501
13502 s390_cc_set(2);
13503 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13504
13505 /* Now test whether the 1st operand is exhausted */
13506 IRTemp num_bytes = newTemp(Ity_I64);
13507 assign(num_bytes, binop(Iop_And64,
13508 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13509 mkU64(0xff)));
13510 s390_cc_set(1);
13511 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13512
13513 /* Extract the bytes to be stored at addr1 */
13514 IRTemp data = newTemp(Ity_I64);
13515 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13516
13517 /* To store the bytes construct 2 dirty helper calls. The helper calls
13518 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13519 that only one of them will be called at runtime. */
13520
13521 Int i;
13522 for (i = 2; i <= 4; ++i) {
13523 IRDirty *d;
13524
13525 if (i == 3) continue; // skip this one
13526
13527 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13528 &s390x_dirtyhelper_CUxy,
13529 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13530 mkexpr(num_bytes)));
13531 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13532 d->mFx = Ifx_Write;
13533 d->mAddr = mkexpr(addr1);
13534 d->mSize = i;
13535 stmt(IRStmt_Dirty(d));
13536 }
13537
13538 /* Update source address and length */
13539 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13540 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13541
13542 /* Update destination address and length */
13543 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13544 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13545
13546 iterate();
13547
13548 return "cu42";
13549}
13550
florian6d9b9b22012-08-03 18:35:39 +000013551static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000013552s390_call_cu41(IRExpr *srcval)
13553{
13554 IRExpr **args, *call;
13555 args = mkIRExprVec_1(srcval);
13556 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13557 "s390_do_cu41", &s390_do_cu41, args);
13558
13559 /* Nothing is excluded from definedness checking. */
13560 call->Iex.CCall.cee->mcx_mask = 0;
13561
13562 return call;
13563}
13564
florian55085f82012-11-21 00:36:55 +000013565static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013566s390_irgen_CU41(UChar r1, UChar r2)
13567{
13568 IRTemp addr1 = newTemp(Ity_I64);
13569 IRTemp addr2 = newTemp(Ity_I64);
13570 IRTemp len1 = newTemp(Ity_I64);
13571 IRTemp len2 = newTemp(Ity_I64);
13572
13573 assign(addr1, get_gpr_dw0(r1));
13574 assign(addr2, get_gpr_dw0(r2));
13575 assign(len1, get_gpr_dw0(r1 + 1));
13576 assign(len2, get_gpr_dw0(r2 + 1));
13577
13578 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13579 there are less than 4 bytes left, then the 2nd operand is exhausted
13580 and we're done here. cc = 0 */
13581 s390_cc_set(0);
13582 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13583
13584 /* Read the 2nd operand. */
13585 IRTemp srcval = newTemp(Ity_I32);
13586 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13587
13588 /* Call the helper */
13589 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013590 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013591
13592 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13593 cc=2 outranks cc=1 (1st operand exhausted) */
13594 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13595
13596 s390_cc_set(2);
13597 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13598
13599 /* Now test whether the 1st operand is exhausted */
13600 IRTemp num_bytes = newTemp(Ity_I64);
13601 assign(num_bytes, binop(Iop_And64,
13602 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13603 mkU64(0xff)));
13604 s390_cc_set(1);
13605 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13606
13607 /* Extract the bytes to be stored at addr1 */
13608 IRTemp data = newTemp(Ity_I64);
13609 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13610
13611 /* To store the bytes construct 4 dirty helper calls. The helper calls
13612 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13613 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013614 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013615 for (i = 1; i <= 4; ++i) {
13616 IRDirty *d;
13617
13618 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13619 &s390x_dirtyhelper_CUxy,
13620 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13621 mkexpr(num_bytes)));
13622 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13623 d->mFx = Ifx_Write;
13624 d->mAddr = mkexpr(addr1);
13625 d->mSize = i;
13626 stmt(IRStmt_Dirty(d));
13627 }
13628
13629 /* Update source address and length */
13630 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13631 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13632
13633 /* Update destination address and length */
13634 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13635 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13636
13637 iterate();
13638
13639 return "cu41";
13640}
13641
13642static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013643s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013644{
13645 IRExpr **args, *call;
13646 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013647 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13648 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013649
13650 /* Nothing is excluded from definedness checking. */
13651 call->Iex.CCall.cee->mcx_mask = 0;
13652
13653 return call;
13654}
13655
13656static IRExpr *
13657s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13658 IRExpr *byte4, IRExpr *stuff)
13659{
13660 IRExpr **args, *call;
13661 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13662 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13663 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13664
13665 /* Nothing is excluded from definedness checking. */
13666 call->Iex.CCall.cee->mcx_mask = 0;
13667
13668 return call;
13669}
13670
florian3f8a96a2012-08-05 02:59:55 +000013671static IRExpr *
13672s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13673 IRExpr *byte4, IRExpr *stuff)
13674{
13675 IRExpr **args, *call;
13676 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13677 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13678 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13679
13680 /* Nothing is excluded from definedness checking. */
13681 call->Iex.CCall.cee->mcx_mask = 0;
13682
13683 return call;
13684}
13685
13686static void
13687s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013688{
13689 IRTemp addr1 = newTemp(Ity_I64);
13690 IRTemp addr2 = newTemp(Ity_I64);
13691 IRTemp len1 = newTemp(Ity_I64);
13692 IRTemp len2 = newTemp(Ity_I64);
13693
13694 assign(addr1, get_gpr_dw0(r1));
13695 assign(addr2, get_gpr_dw0(r2));
13696 assign(len1, get_gpr_dw0(r1 + 1));
13697 assign(len2, get_gpr_dw0(r2 + 1));
13698
13699 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13700
13701 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13702 there is less than 1 byte left, then the 2nd operand is exhausted
13703 and we're done here. cc = 0 */
13704 s390_cc_set(0);
13705 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13706
13707 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013708 IRTemp byte1 = newTemp(Ity_I64);
13709 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013710
13711 /* Call the helper to get number of bytes and invalid byte indicator */
13712 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013713 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013714 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013715
13716 /* Check for invalid 1st byte */
13717 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13718 s390_cc_set(2);
13719 next_insn_if(is_invalid);
13720
13721 /* How many bytes do we have to read? */
13722 IRTemp num_src_bytes = newTemp(Ity_I64);
13723 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13724
13725 /* Now test whether the 2nd operand is exhausted */
13726 s390_cc_set(0);
13727 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13728
13729 /* Read the remaining bytes */
13730 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13731
13732 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13733 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013734 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013735 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13736 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013737 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013738 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13739 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013740 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013741
13742 /* Call the helper to get the converted value and invalid byte indicator.
13743 We can pass at most 5 arguments; therefore some encoding is needed
13744 here */
13745 IRExpr *stuff = binop(Iop_Or64,
13746 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13747 mkU64(extended_checking));
13748 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013749
13750 if (is_cu12) {
13751 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13752 byte4, stuff));
13753 } else {
13754 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13755 byte4, stuff));
13756 }
florian6d9b9b22012-08-03 18:35:39 +000013757
13758 /* Check for invalid character */
13759 s390_cc_set(2);
13760 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13761 next_insn_if(is_invalid);
13762
13763 /* Now test whether the 1st operand is exhausted */
13764 IRTemp num_bytes = newTemp(Ity_I64);
13765 assign(num_bytes, binop(Iop_And64,
13766 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13767 mkU64(0xff)));
13768 s390_cc_set(1);
13769 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13770
13771 /* Extract the bytes to be stored at addr1 */
13772 IRTemp data = newTemp(Ity_I64);
13773 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13774
florian3f8a96a2012-08-05 02:59:55 +000013775 if (is_cu12) {
13776 /* To store the bytes construct 2 dirty helper calls. The helper calls
13777 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13778 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013779
florian3f8a96a2012-08-05 02:59:55 +000013780 Int i;
13781 for (i = 2; i <= 4; ++i) {
13782 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013783
florian3f8a96a2012-08-05 02:59:55 +000013784 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013785
florian3f8a96a2012-08-05 02:59:55 +000013786 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13787 &s390x_dirtyhelper_CUxy,
13788 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13789 mkexpr(num_bytes)));
13790 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13791 d->mFx = Ifx_Write;
13792 d->mAddr = mkexpr(addr1);
13793 d->mSize = i;
13794 stmt(IRStmt_Dirty(d));
13795 }
13796 } else {
13797 // cu14
13798 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013799 }
13800
13801 /* Update source address and length */
13802 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13803 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13804
13805 /* Update destination address and length */
13806 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13807 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13808
13809 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013810}
13811
florian55085f82012-11-21 00:36:55 +000013812static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013813s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13814{
13815 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013816
13817 return "cu12";
13818}
13819
florian55085f82012-11-21 00:36:55 +000013820static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013821s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13822{
13823 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13824
13825 return "cu14";
13826}
13827
florian8c88cb62012-08-26 18:58:13 +000013828static IRExpr *
13829s390_call_ecag(IRExpr *op2addr)
13830{
13831 IRExpr **args, *call;
13832
13833 args = mkIRExprVec_1(op2addr);
13834 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13835 "s390_do_ecag", &s390_do_ecag, args);
13836
13837 /* Nothing is excluded from definedness checking. */
13838 call->Iex.CCall.cee->mcx_mask = 0;
13839
13840 return call;
13841}
13842
florian55085f82012-11-21 00:36:55 +000013843static const HChar *
floriand2129202012-09-01 20:01:39 +000013844s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013845{
13846 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013847 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013848 } else {
13849 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13850 }
13851
13852 return "ecag";
13853}
13854
13855
florianb7def222012-12-04 04:45:32 +000013856/* New insns are added here.
13857 If an insn is contingent on a facility being installed also
13858 check whether the list of supported facilities in function
13859 s390x_dirtyhelper_STFLE needs updating */
13860
sewardj2019a972011-03-07 16:04:07 +000013861/*------------------------------------------------------------*/
13862/*--- Build IR for special instructions ---*/
13863/*------------------------------------------------------------*/
13864
florianb4df7682011-07-05 02:09:01 +000013865static void
sewardj2019a972011-03-07 16:04:07 +000013866s390_irgen_client_request(void)
13867{
13868 if (0)
13869 vex_printf("%%R3 = client_request ( %%R2 )\n");
13870
florianf9e1ed72012-04-17 02:41:56 +000013871 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13872 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013873
florianf9e1ed72012-04-17 02:41:56 +000013874 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013875 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013876
13877 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013878}
13879
florianb4df7682011-07-05 02:09:01 +000013880static void
sewardj2019a972011-03-07 16:04:07 +000013881s390_irgen_guest_NRADDR(void)
13882{
13883 if (0)
13884 vex_printf("%%R3 = guest_NRADDR\n");
13885
floriane88b3c92011-07-05 02:48:39 +000013886 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013887}
13888
florianb4df7682011-07-05 02:09:01 +000013889static void
sewardj2019a972011-03-07 16:04:07 +000013890s390_irgen_call_noredir(void)
13891{
florianf9e1ed72012-04-17 02:41:56 +000013892 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13893 + S390_SPECIAL_OP_SIZE;
13894
sewardj2019a972011-03-07 16:04:07 +000013895 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013896 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013897
13898 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013899 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013900
13901 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013902 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013903}
13904
13905/* Force proper alignment for the structures below. */
13906#pragma pack(1)
13907
13908
13909static s390_decode_t
florian8462d112014-09-24 15:18:09 +000013910s390_decode_2byte_and_irgen(const UChar *bytes)
sewardj2019a972011-03-07 16:04:07 +000013911{
13912 typedef union {
13913 struct {
13914 unsigned int op : 16;
13915 } E;
13916 struct {
13917 unsigned int op : 8;
13918 unsigned int i : 8;
13919 } I;
13920 struct {
13921 unsigned int op : 8;
13922 unsigned int r1 : 4;
13923 unsigned int r2 : 4;
13924 } RR;
13925 } formats;
13926 union {
13927 formats fmt;
13928 UShort value;
13929 } ovl;
13930
13931 vassert(sizeof(formats) == 2);
13932
florianffbd84d2012-12-09 02:06:29 +000013933 ((UChar *)(&ovl.value))[0] = bytes[0];
13934 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013935
13936 switch (ovl.value & 0xffff) {
13937 case 0x0101: /* PR */ goto unimplemented;
13938 case 0x0102: /* UPT */ goto unimplemented;
13939 case 0x0104: /* PTFF */ goto unimplemented;
13940 case 0x0107: /* SCKPF */ goto unimplemented;
florian78d5ef72013-05-11 15:02:58 +000013941 case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013942 case 0x010b: /* TAM */ goto unimplemented;
13943 case 0x010c: /* SAM24 */ goto unimplemented;
13944 case 0x010d: /* SAM31 */ goto unimplemented;
13945 case 0x010e: /* SAM64 */ goto unimplemented;
13946 case 0x01ff: /* TRAP2 */ goto unimplemented;
13947 }
13948
13949 switch ((ovl.value & 0xff00) >> 8) {
13950 case 0x04: /* SPM */ goto unimplemented;
13951 case 0x05: /* BALR */ goto unimplemented;
13952 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13953 goto ok;
13954 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13955 goto ok;
13956 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13957 case 0x0b: /* BSM */ goto unimplemented;
13958 case 0x0c: /* BASSM */ goto unimplemented;
13959 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13960 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013961 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13962 goto ok;
13963 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13964 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013965 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13966 goto ok;
13967 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13968 goto ok;
13969 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13970 goto ok;
13971 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13972 goto ok;
13973 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13974 goto ok;
13975 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13976 goto ok;
13977 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13978 goto ok;
13979 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13980 goto ok;
13981 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13982 goto ok;
13983 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13984 goto ok;
13985 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13986 goto ok;
13987 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13988 goto ok;
13989 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13990 goto ok;
13991 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13992 goto ok;
13993 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13994 goto ok;
13995 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13996 goto ok;
13997 case 0x20: /* LPDR */ goto unimplemented;
13998 case 0x21: /* LNDR */ goto unimplemented;
13999 case 0x22: /* LTDR */ goto unimplemented;
14000 case 0x23: /* LCDR */ goto unimplemented;
14001 case 0x24: /* HDR */ goto unimplemented;
14002 case 0x25: /* LDXR */ goto unimplemented;
14003 case 0x26: /* MXR */ goto unimplemented;
14004 case 0x27: /* MXDR */ goto unimplemented;
14005 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14006 goto ok;
14007 case 0x29: /* CDR */ goto unimplemented;
14008 case 0x2a: /* ADR */ goto unimplemented;
14009 case 0x2b: /* SDR */ goto unimplemented;
14010 case 0x2c: /* MDR */ goto unimplemented;
14011 case 0x2d: /* DDR */ goto unimplemented;
14012 case 0x2e: /* AWR */ goto unimplemented;
14013 case 0x2f: /* SWR */ goto unimplemented;
14014 case 0x30: /* LPER */ goto unimplemented;
14015 case 0x31: /* LNER */ goto unimplemented;
14016 case 0x32: /* LTER */ goto unimplemented;
14017 case 0x33: /* LCER */ goto unimplemented;
14018 case 0x34: /* HER */ goto unimplemented;
14019 case 0x35: /* LEDR */ goto unimplemented;
14020 case 0x36: /* AXR */ goto unimplemented;
14021 case 0x37: /* SXR */ goto unimplemented;
14022 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14023 goto ok;
14024 case 0x39: /* CER */ goto unimplemented;
14025 case 0x3a: /* AER */ goto unimplemented;
14026 case 0x3b: /* SER */ goto unimplemented;
14027 case 0x3c: /* MDER */ goto unimplemented;
14028 case 0x3d: /* DER */ goto unimplemented;
14029 case 0x3e: /* AUR */ goto unimplemented;
14030 case 0x3f: /* SUR */ goto unimplemented;
14031 }
14032
14033 return S390_DECODE_UNKNOWN_INSN;
14034
14035ok:
14036 return S390_DECODE_OK;
14037
14038unimplemented:
14039 return S390_DECODE_UNIMPLEMENTED_INSN;
14040}
14041
14042static s390_decode_t
florian8462d112014-09-24 15:18:09 +000014043s390_decode_4byte_and_irgen(const UChar *bytes)
sewardj2019a972011-03-07 16:04:07 +000014044{
14045 typedef union {
14046 struct {
14047 unsigned int op1 : 8;
14048 unsigned int r1 : 4;
14049 unsigned int op2 : 4;
14050 unsigned int i2 : 16;
14051 } RI;
14052 struct {
14053 unsigned int op : 16;
14054 unsigned int : 8;
14055 unsigned int r1 : 4;
14056 unsigned int r2 : 4;
14057 } RRE;
14058 struct {
14059 unsigned int op : 16;
14060 unsigned int r1 : 4;
14061 unsigned int : 4;
14062 unsigned int r3 : 4;
14063 unsigned int r2 : 4;
14064 } RRF;
14065 struct {
14066 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000014067 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000014068 unsigned int m4 : 4;
14069 unsigned int r1 : 4;
14070 unsigned int r2 : 4;
14071 } RRF2;
14072 struct {
14073 unsigned int op : 16;
14074 unsigned int r3 : 4;
14075 unsigned int : 4;
14076 unsigned int r1 : 4;
14077 unsigned int r2 : 4;
14078 } RRF3;
14079 struct {
14080 unsigned int op : 16;
14081 unsigned int r3 : 4;
14082 unsigned int : 4;
14083 unsigned int r1 : 4;
14084 unsigned int r2 : 4;
14085 } RRR;
14086 struct {
14087 unsigned int op : 16;
14088 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000014089 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000014090 unsigned int r1 : 4;
14091 unsigned int r2 : 4;
14092 } RRF4;
14093 struct {
floriane38f6412012-12-21 17:32:12 +000014094 unsigned int op : 16;
14095 unsigned int : 4;
14096 unsigned int m4 : 4;
14097 unsigned int r1 : 4;
14098 unsigned int r2 : 4;
14099 } RRF5;
14100 struct {
sewardj2019a972011-03-07 16:04:07 +000014101 unsigned int op : 8;
14102 unsigned int r1 : 4;
14103 unsigned int r3 : 4;
14104 unsigned int b2 : 4;
14105 unsigned int d2 : 12;
14106 } RS;
14107 struct {
14108 unsigned int op : 8;
14109 unsigned int r1 : 4;
14110 unsigned int r3 : 4;
14111 unsigned int i2 : 16;
14112 } RSI;
14113 struct {
14114 unsigned int op : 8;
14115 unsigned int r1 : 4;
14116 unsigned int x2 : 4;
14117 unsigned int b2 : 4;
14118 unsigned int d2 : 12;
14119 } RX;
14120 struct {
14121 unsigned int op : 16;
14122 unsigned int b2 : 4;
14123 unsigned int d2 : 12;
14124 } S;
14125 struct {
14126 unsigned int op : 8;
14127 unsigned int i2 : 8;
14128 unsigned int b1 : 4;
14129 unsigned int d1 : 12;
14130 } SI;
14131 } formats;
14132 union {
14133 formats fmt;
14134 UInt value;
14135 } ovl;
14136
14137 vassert(sizeof(formats) == 4);
14138
florianffbd84d2012-12-09 02:06:29 +000014139 ((UChar *)(&ovl.value))[0] = bytes[0];
14140 ((UChar *)(&ovl.value))[1] = bytes[1];
14141 ((UChar *)(&ovl.value))[2] = bytes[2];
14142 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000014143
14144 switch ((ovl.value & 0xff0f0000) >> 16) {
14145 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
14146 ovl.fmt.RI.i2); goto ok;
14147 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
14148 ovl.fmt.RI.i2); goto ok;
14149 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14150 ovl.fmt.RI.i2); goto ok;
14151 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14152 ovl.fmt.RI.i2); goto ok;
14153 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14154 ovl.fmt.RI.i2); goto ok;
14155 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14156 ovl.fmt.RI.i2); goto ok;
14157 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14158 ovl.fmt.RI.i2); goto ok;
14159 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14160 ovl.fmt.RI.i2); goto ok;
14161 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14162 ovl.fmt.RI.i2); goto ok;
14163 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14164 ovl.fmt.RI.i2); goto ok;
14165 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14166 ovl.fmt.RI.i2); goto ok;
14167 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14168 ovl.fmt.RI.i2); goto ok;
14169 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14170 ovl.fmt.RI.i2); goto ok;
14171 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14172 ovl.fmt.RI.i2); goto ok;
14173 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14174 ovl.fmt.RI.i2); goto ok;
14175 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14176 ovl.fmt.RI.i2); goto ok;
14177 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14178 ovl.fmt.RI.i2); goto ok;
14179 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14180 ovl.fmt.RI.i2); goto ok;
14181 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14182 ovl.fmt.RI.i2); goto ok;
14183 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14184 ovl.fmt.RI.i2); goto ok;
14185 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14186 goto ok;
14187 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14188 ovl.fmt.RI.i2); goto ok;
14189 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14190 ovl.fmt.RI.i2); goto ok;
14191 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14192 ovl.fmt.RI.i2); goto ok;
14193 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14194 goto ok;
14195 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14196 ovl.fmt.RI.i2); goto ok;
14197 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14198 goto ok;
14199 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14200 ovl.fmt.RI.i2); goto ok;
14201 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14202 goto ok;
14203 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14204 ovl.fmt.RI.i2); goto ok;
14205 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14206 goto ok;
14207 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14208 ovl.fmt.RI.i2); goto ok;
14209 }
14210
14211 switch ((ovl.value & 0xffff0000) >> 16) {
14212 case 0x8000: /* SSM */ goto unimplemented;
14213 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014214 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014215 case 0xb202: /* STIDP */ goto unimplemented;
14216 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014217 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14218 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014219 case 0xb206: /* SCKC */ goto unimplemented;
14220 case 0xb207: /* STCKC */ goto unimplemented;
14221 case 0xb208: /* SPT */ goto unimplemented;
14222 case 0xb209: /* STPT */ goto unimplemented;
14223 case 0xb20a: /* SPKA */ goto unimplemented;
14224 case 0xb20b: /* IPK */ goto unimplemented;
14225 case 0xb20d: /* PTLB */ goto unimplemented;
14226 case 0xb210: /* SPX */ goto unimplemented;
14227 case 0xb211: /* STPX */ goto unimplemented;
14228 case 0xb212: /* STAP */ goto unimplemented;
14229 case 0xb214: /* SIE */ goto unimplemented;
14230 case 0xb218: /* PC */ goto unimplemented;
14231 case 0xb219: /* SAC */ goto unimplemented;
14232 case 0xb21a: /* CFC */ goto unimplemented;
14233 case 0xb221: /* IPTE */ goto unimplemented;
14234 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
14235 case 0xb223: /* IVSK */ goto unimplemented;
14236 case 0xb224: /* IAC */ goto unimplemented;
14237 case 0xb225: /* SSAR */ goto unimplemented;
14238 case 0xb226: /* EPAR */ goto unimplemented;
14239 case 0xb227: /* ESAR */ goto unimplemented;
14240 case 0xb228: /* PT */ goto unimplemented;
14241 case 0xb229: /* ISKE */ goto unimplemented;
14242 case 0xb22a: /* RRBE */ goto unimplemented;
14243 case 0xb22b: /* SSKE */ goto unimplemented;
14244 case 0xb22c: /* TB */ goto unimplemented;
14245 case 0xb22d: /* DXR */ goto unimplemented;
14246 case 0xb22e: /* PGIN */ goto unimplemented;
14247 case 0xb22f: /* PGOUT */ goto unimplemented;
14248 case 0xb230: /* CSCH */ goto unimplemented;
14249 case 0xb231: /* HSCH */ goto unimplemented;
14250 case 0xb232: /* MSCH */ goto unimplemented;
14251 case 0xb233: /* SSCH */ goto unimplemented;
14252 case 0xb234: /* STSCH */ goto unimplemented;
14253 case 0xb235: /* TSCH */ goto unimplemented;
14254 case 0xb236: /* TPI */ goto unimplemented;
14255 case 0xb237: /* SAL */ goto unimplemented;
14256 case 0xb238: /* RSCH */ goto unimplemented;
14257 case 0xb239: /* STCRW */ goto unimplemented;
14258 case 0xb23a: /* STCPS */ goto unimplemented;
14259 case 0xb23b: /* RCHP */ goto unimplemented;
14260 case 0xb23c: /* SCHM */ goto unimplemented;
14261 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000014262 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14263 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014264 case 0xb244: /* SQDR */ goto unimplemented;
14265 case 0xb245: /* SQER */ goto unimplemented;
14266 case 0xb246: /* STURA */ goto unimplemented;
14267 case 0xb247: /* MSTA */ goto unimplemented;
14268 case 0xb248: /* PALB */ goto unimplemented;
14269 case 0xb249: /* EREG */ goto unimplemented;
14270 case 0xb24a: /* ESTA */ goto unimplemented;
14271 case 0xb24b: /* LURA */ goto unimplemented;
14272 case 0xb24c: /* TAR */ goto unimplemented;
14273 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14274 ovl.fmt.RRE.r2); goto ok;
14275 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14276 goto ok;
14277 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14278 goto ok;
14279 case 0xb250: /* CSP */ goto unimplemented;
14280 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14281 ovl.fmt.RRE.r2); goto ok;
14282 case 0xb254: /* MVPG */ goto unimplemented;
14283 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14284 ovl.fmt.RRE.r2); goto ok;
14285 case 0xb257: /* CUSE */ goto unimplemented;
14286 case 0xb258: /* BSG */ goto unimplemented;
14287 case 0xb25a: /* BSA */ goto unimplemented;
14288 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14289 ovl.fmt.RRE.r2); goto ok;
14290 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14291 ovl.fmt.RRE.r2); goto ok;
14292 case 0xb263: /* CMPSC */ goto unimplemented;
14293 case 0xb274: /* SIGA */ goto unimplemented;
14294 case 0xb276: /* XSCH */ goto unimplemented;
14295 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014296 case 0xb278: s390_format_S_RD(s390_irgen_STCKE, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
sewardj2019a972011-03-07 16:04:07 +000014297 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014298 case 0xb27c: s390_format_S_RD(s390_irgen_STCKF, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok;
sewardj2019a972011-03-07 16:04:07 +000014299 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014300 case 0xb280: /* LPP */ goto unimplemented;
14301 case 0xb284: /* LCCTL */ goto unimplemented;
14302 case 0xb285: /* LPCTL */ goto unimplemented;
14303 case 0xb286: /* QSI */ goto unimplemented;
14304 case 0xb287: /* LSCTL */ goto unimplemented;
14305 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014306 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14307 goto ok;
14308 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14309 goto ok;
14310 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14311 goto ok;
florian730448f2012-02-04 17:07:07 +000014312 case 0xb2a5: s390_format_RRE_FF(s390_irgen_TRE, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2); goto ok;
floriana0100c92012-07-20 00:06:35 +000014313 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14314 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14315 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000014316 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14317 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14318 goto ok;
florian933065d2011-07-11 01:48:02 +000014319 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14320 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014321 case 0xb2b1: /* STFL */ goto unimplemented;
14322 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000014323 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14324 goto ok;
florian82cdba62013-03-12 01:31:24 +000014325 case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14326 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014327 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014328 case 0xb2e0: /* SCCTR */ goto unimplemented;
14329 case 0xb2e1: /* SPCTR */ goto unimplemented;
14330 case 0xb2e4: /* ECCTR */ goto unimplemented;
14331 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014332 case 0xb2e8: /* PPA */ goto unimplemented;
14333 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014334 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014335 case 0xb2f8: /* TEND */ goto unimplemented;
14336 case 0xb2fa: /* NIAI */ goto unimplemented;
14337 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014338 case 0xb2ff: /* TRAP4 */ goto unimplemented;
14339 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14340 ovl.fmt.RRE.r2); goto ok;
14341 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14342 ovl.fmt.RRE.r2); goto ok;
14343 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14344 ovl.fmt.RRE.r2); goto ok;
14345 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14346 ovl.fmt.RRE.r2); goto ok;
14347 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14348 ovl.fmt.RRE.r2); goto ok;
14349 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14350 ovl.fmt.RRE.r2); goto ok;
14351 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14352 ovl.fmt.RRE.r2); goto ok;
14353 case 0xb307: /* MXDBR */ goto unimplemented;
14354 case 0xb308: /* KEBR */ goto unimplemented;
14355 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14356 ovl.fmt.RRE.r2); goto ok;
14357 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14358 ovl.fmt.RRE.r2); goto ok;
14359 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14360 ovl.fmt.RRE.r2); goto ok;
14361 case 0xb30c: /* MDEBR */ goto unimplemented;
14362 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14363 ovl.fmt.RRE.r2); goto ok;
14364 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14365 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14366 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14367 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14368 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14369 ovl.fmt.RRE.r2); goto ok;
14370 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14371 ovl.fmt.RRE.r2); goto ok;
14372 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14373 ovl.fmt.RRE.r2); goto ok;
14374 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14375 ovl.fmt.RRE.r2); goto ok;
14376 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14377 ovl.fmt.RRE.r2); goto ok;
14378 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14379 ovl.fmt.RRE.r2); goto ok;
14380 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14381 ovl.fmt.RRE.r2); goto ok;
14382 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14383 ovl.fmt.RRE.r2); goto ok;
14384 case 0xb318: /* KDBR */ goto unimplemented;
14385 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14386 ovl.fmt.RRE.r2); goto ok;
14387 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14388 ovl.fmt.RRE.r2); goto ok;
14389 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14390 ovl.fmt.RRE.r2); goto ok;
14391 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14392 ovl.fmt.RRE.r2); goto ok;
14393 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14394 ovl.fmt.RRE.r2); goto ok;
14395 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14396 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14397 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14398 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14399 case 0xb324: /* LDER */ goto unimplemented;
14400 case 0xb325: /* LXDR */ goto unimplemented;
14401 case 0xb326: /* LXER */ goto unimplemented;
14402 case 0xb32e: /* MAER */ goto unimplemented;
14403 case 0xb32f: /* MSER */ goto unimplemented;
14404 case 0xb336: /* SQXR */ goto unimplemented;
14405 case 0xb337: /* MEER */ goto unimplemented;
14406 case 0xb338: /* MAYLR */ goto unimplemented;
14407 case 0xb339: /* MYLR */ goto unimplemented;
14408 case 0xb33a: /* MAYR */ goto unimplemented;
14409 case 0xb33b: /* MYR */ goto unimplemented;
14410 case 0xb33c: /* MAYHR */ goto unimplemented;
14411 case 0xb33d: /* MYHR */ goto unimplemented;
14412 case 0xb33e: /* MADR */ goto unimplemented;
14413 case 0xb33f: /* MSDR */ goto unimplemented;
14414 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14415 ovl.fmt.RRE.r2); goto ok;
14416 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14417 ovl.fmt.RRE.r2); goto ok;
14418 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14419 ovl.fmt.RRE.r2); goto ok;
14420 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14421 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014422 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14423 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14424 ovl.fmt.RRF2.r2); goto ok;
14425 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14426 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14427 ovl.fmt.RRF2.r2); goto ok;
14428 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14429 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14430 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014431 case 0xb347: /* FIXBR */ goto unimplemented;
14432 case 0xb348: /* KXBR */ goto unimplemented;
14433 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14434 ovl.fmt.RRE.r2); goto ok;
14435 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14436 ovl.fmt.RRE.r2); goto ok;
14437 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14438 ovl.fmt.RRE.r2); goto ok;
14439 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14440 ovl.fmt.RRE.r2); goto ok;
14441 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14442 ovl.fmt.RRE.r2); goto ok;
14443 case 0xb350: /* TBEDR */ goto unimplemented;
14444 case 0xb351: /* TBDR */ goto unimplemented;
14445 case 0xb353: /* DIEBR */ goto unimplemented;
14446 case 0xb357: /* FIEBR */ goto unimplemented;
14447 case 0xb358: /* THDER */ goto unimplemented;
14448 case 0xb359: /* THDR */ goto unimplemented;
14449 case 0xb35b: /* DIDBR */ goto unimplemented;
14450 case 0xb35f: /* FIDBR */ goto unimplemented;
14451 case 0xb360: /* LPXR */ goto unimplemented;
14452 case 0xb361: /* LNXR */ goto unimplemented;
14453 case 0xb362: /* LTXR */ goto unimplemented;
14454 case 0xb363: /* LCXR */ goto unimplemented;
14455 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14456 ovl.fmt.RRE.r2); goto ok;
14457 case 0xb366: /* LEXR */ goto unimplemented;
14458 case 0xb367: /* FIXR */ goto unimplemented;
14459 case 0xb369: /* CXR */ goto unimplemented;
14460 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14461 ovl.fmt.RRE.r2); goto ok;
14462 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14463 ovl.fmt.RRE.r2); goto ok;
14464 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14465 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14466 goto ok;
14467 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14468 ovl.fmt.RRE.r2); goto ok;
14469 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
14470 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
14471 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
14472 case 0xb377: /* FIER */ goto unimplemented;
14473 case 0xb37f: /* FIDR */ goto unimplemented;
14474 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
14475 case 0xb385: /* SFASR */ goto unimplemented;
14476 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014477 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14478 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14479 ovl.fmt.RRF2.r2); goto ok;
14480 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14481 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14482 ovl.fmt.RRF2.r2); goto ok;
14483 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14484 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14485 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014486 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14487 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14488 ovl.fmt.RRF2.r2); goto ok;
14489 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14490 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14491 ovl.fmt.RRF2.r2); goto ok;
14492 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14493 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14494 ovl.fmt.RRF2.r2); goto ok;
14495 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14496 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14497 ovl.fmt.RRF2.r2); goto ok;
14498 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14499 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14500 ovl.fmt.RRF2.r2); goto ok;
14501 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14502 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14503 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014504 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14505 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14506 ovl.fmt.RRF2.r2); goto ok;
14507 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14508 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14509 ovl.fmt.RRF2.r2); goto ok;
14510 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14511 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14512 ovl.fmt.RRF2.r2); goto ok;
14513 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14514 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14515 ovl.fmt.RRF2.r2); goto ok;
14516 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14517 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14518 ovl.fmt.RRF2.r2); goto ok;
14519 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14520 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14521 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014522 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14523 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14524 ovl.fmt.RRF2.r2); goto ok;
14525 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14526 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14527 ovl.fmt.RRF2.r2); goto ok;
14528 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14529 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14530 ovl.fmt.RRF2.r2); goto ok;
14531 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14532 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14533 ovl.fmt.RRF2.r2); goto ok;
14534 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14535 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14536 ovl.fmt.RRF2.r2); goto ok;
14537 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14538 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14539 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014540 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14541 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14542 ovl.fmt.RRF2.r2); goto ok;
14543 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14544 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14545 ovl.fmt.RRF2.r2); goto ok;
14546 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14547 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14548 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014549 case 0xb3b4: /* CEFR */ goto unimplemented;
14550 case 0xb3b5: /* CDFR */ goto unimplemented;
14551 case 0xb3b6: /* CXFR */ goto unimplemented;
14552 case 0xb3b8: /* CFER */ goto unimplemented;
14553 case 0xb3b9: /* CFDR */ goto unimplemented;
14554 case 0xb3ba: /* CFXR */ goto unimplemented;
14555 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14556 ovl.fmt.RRE.r2); goto ok;
14557 case 0xb3c4: /* CEGR */ goto unimplemented;
14558 case 0xb3c5: /* CDGR */ goto unimplemented;
14559 case 0xb3c6: /* CXGR */ goto unimplemented;
14560 case 0xb3c8: /* CGER */ goto unimplemented;
14561 case 0xb3c9: /* CGDR */ goto unimplemented;
14562 case 0xb3ca: /* CGXR */ goto unimplemented;
14563 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14564 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014565 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14566 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14567 ovl.fmt.RRF4.r2); goto ok;
14568 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14569 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14570 ovl.fmt.RRF4.r2); goto ok;
14571 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14572 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14573 ovl.fmt.RRF4.r2); goto ok;
14574 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14575 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14576 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014577 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14578 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14579 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14580 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14581 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014582 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14583 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014584 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014585 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14586 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14587 ovl.fmt.RRF4.r2); goto ok;
14588 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14589 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14590 ovl.fmt.RRF4.r2); goto ok;
14591 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14592 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14593 ovl.fmt.RRF4.r2); goto ok;
14594 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14595 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14596 ovl.fmt.RRF4.r2); goto ok;
14597 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14598 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14599 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14600 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14601 ovl.fmt.RRF2.r2); goto ok;
14602 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14603 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014604 case 0xb3df: /* FIXTR */ goto unimplemented;
14605 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014606 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14607 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14608 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014609 case 0xb3e2: /* CUDTR */ goto unimplemented;
14610 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014611 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14612 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014613 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14614 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014615 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14616 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014617 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014618 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14619 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14620 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014621 case 0xb3ea: /* CUXTR */ goto unimplemented;
14622 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014623 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14624 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014625 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14626 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014627 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14628 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014629 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14630 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14631 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014632 case 0xb3f2: /* CDUTR */ goto unimplemented;
14633 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014634 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14635 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014636 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14637 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14638 ovl.fmt.RRF4.r2); goto ok;
14639 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14640 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14641 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14642 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14643 ovl.fmt.RRF4.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014644 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14645 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14646 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014647 case 0xb3fa: /* CXUTR */ goto unimplemented;
14648 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014649 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14650 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014651 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14652 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14653 ovl.fmt.RRF4.r2); goto ok;
14654 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14655 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14656 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14657 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14658 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014659 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14660 ovl.fmt.RRE.r2); goto ok;
14661 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14662 ovl.fmt.RRE.r2); goto ok;
14663 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14664 ovl.fmt.RRE.r2); goto ok;
14665 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14666 ovl.fmt.RRE.r2); goto ok;
14667 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14668 ovl.fmt.RRE.r2); goto ok;
14669 case 0xb905: /* LURAG */ goto unimplemented;
14670 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14671 ovl.fmt.RRE.r2); goto ok;
14672 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14673 ovl.fmt.RRE.r2); goto ok;
14674 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14675 ovl.fmt.RRE.r2); goto ok;
14676 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14677 ovl.fmt.RRE.r2); goto ok;
14678 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14679 ovl.fmt.RRE.r2); goto ok;
14680 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14681 ovl.fmt.RRE.r2); goto ok;
14682 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14683 ovl.fmt.RRE.r2); goto ok;
14684 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14685 ovl.fmt.RRE.r2); goto ok;
14686 case 0xb90e: /* EREGG */ goto unimplemented;
14687 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14688 ovl.fmt.RRE.r2); goto ok;
14689 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14690 ovl.fmt.RRE.r2); goto ok;
14691 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14692 ovl.fmt.RRE.r2); goto ok;
14693 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14694 ovl.fmt.RRE.r2); goto ok;
14695 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14696 ovl.fmt.RRE.r2); goto ok;
14697 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14698 ovl.fmt.RRE.r2); goto ok;
14699 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14700 ovl.fmt.RRE.r2); goto ok;
14701 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14702 ovl.fmt.RRE.r2); goto ok;
14703 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14704 ovl.fmt.RRE.r2); goto ok;
14705 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14706 ovl.fmt.RRE.r2); goto ok;
14707 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14708 ovl.fmt.RRE.r2); goto ok;
14709 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14710 ovl.fmt.RRE.r2); goto ok;
14711 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14712 ovl.fmt.RRE.r2); goto ok;
14713 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14714 ovl.fmt.RRE.r2); goto ok;
14715 case 0xb91e: /* KMAC */ goto unimplemented;
14716 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14717 ovl.fmt.RRE.r2); goto ok;
14718 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14719 ovl.fmt.RRE.r2); goto ok;
14720 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14721 ovl.fmt.RRE.r2); goto ok;
14722 case 0xb925: /* STURG */ goto unimplemented;
14723 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14724 ovl.fmt.RRE.r2); goto ok;
14725 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14726 ovl.fmt.RRE.r2); goto ok;
14727 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014728 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014729 case 0xb92b: /* KMO */ goto unimplemented;
14730 case 0xb92c: /* PCC */ goto unimplemented;
14731 case 0xb92d: /* KMCTR */ goto unimplemented;
14732 case 0xb92e: /* KM */ goto unimplemented;
14733 case 0xb92f: /* KMC */ goto unimplemented;
14734 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14735 ovl.fmt.RRE.r2); goto ok;
14736 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14737 ovl.fmt.RRE.r2); goto ok;
14738 case 0xb93e: /* KIMD */ goto unimplemented;
14739 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014740 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14741 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14742 ovl.fmt.RRF2.r2); goto ok;
14743 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14744 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14745 ovl.fmt.RRF2.r2); goto ok;
14746 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14747 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14748 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014749 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14750 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014751 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14752 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14753 ovl.fmt.RRF2.r2); goto ok;
14754 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14755 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14756 ovl.fmt.RRF2.r2); goto ok;
14757 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14758 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14759 ovl.fmt.RRF2.r2); goto ok;
14760 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14761 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14762 ovl.fmt.RRF2.r2); goto ok;
14763 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14764 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14765 ovl.fmt.RRF2.r2); goto ok;
14766 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14767 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14768 ovl.fmt.RRF2.r2); goto ok;
14769 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14770 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14771 ovl.fmt.RRF2.r2); goto ok;
14772 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14773 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14774 ovl.fmt.RRF2.r2); goto ok;
14775 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14776 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14777 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014778 case 0xb960: /* CGRT */ goto unimplemented;
14779 case 0xb961: /* CLGRT */ goto unimplemented;
14780 case 0xb972: /* CRT */ goto unimplemented;
14781 case 0xb973: /* CLRT */ goto unimplemented;
14782 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14783 ovl.fmt.RRE.r2); goto ok;
14784 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14785 ovl.fmt.RRE.r2); goto ok;
14786 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14787 ovl.fmt.RRE.r2); goto ok;
14788 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14789 ovl.fmt.RRE.r2); goto ok;
14790 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14791 ovl.fmt.RRE.r2); goto ok;
14792 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14793 ovl.fmt.RRE.r2); goto ok;
14794 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14795 ovl.fmt.RRE.r2); goto ok;
14796 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14797 ovl.fmt.RRE.r2); goto ok;
14798 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14799 ovl.fmt.RRE.r2); goto ok;
14800 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14801 ovl.fmt.RRE.r2); goto ok;
14802 case 0xb98a: /* CSPG */ goto unimplemented;
14803 case 0xb98d: /* EPSW */ goto unimplemented;
14804 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014805 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014806 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14807 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14808 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14809 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14810 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14811 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014812 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14813 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014814 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14815 ovl.fmt.RRE.r2); goto ok;
14816 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14817 ovl.fmt.RRE.r2); goto ok;
14818 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14819 ovl.fmt.RRE.r2); goto ok;
14820 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14821 ovl.fmt.RRE.r2); goto ok;
14822 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14823 ovl.fmt.RRE.r2); goto ok;
14824 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14825 ovl.fmt.RRE.r2); goto ok;
14826 case 0xb99a: /* EPAIR */ goto unimplemented;
14827 case 0xb99b: /* ESAIR */ goto unimplemented;
14828 case 0xb99d: /* ESEA */ goto unimplemented;
14829 case 0xb99e: /* PTI */ goto unimplemented;
14830 case 0xb99f: /* SSAIR */ goto unimplemented;
14831 case 0xb9a2: /* PTF */ goto unimplemented;
14832 case 0xb9aa: /* LPTEA */ goto unimplemented;
14833 case 0xb9ae: /* RRBM */ goto unimplemented;
14834 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014835 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14836 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14837 goto ok;
florian2a415a12012-07-21 17:41:36 +000014838 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14839 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14840 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014841 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14842 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014843 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14844 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014845 case 0xb9bd: /* TRTRE */ goto unimplemented;
14846 case 0xb9be: /* SRSTU */ goto unimplemented;
14847 case 0xb9bf: /* TRTE */ goto unimplemented;
14848 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14849 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14850 goto ok;
14851 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14852 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14853 goto ok;
14854 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14855 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14856 goto ok;
14857 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14858 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14859 goto ok;
14860 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14861 ovl.fmt.RRE.r2); goto ok;
14862 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14863 ovl.fmt.RRE.r2); goto ok;
14864 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14865 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14866 goto ok;
14867 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14868 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14869 goto ok;
14870 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14871 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14872 goto ok;
14873 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14874 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14875 goto ok;
14876 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14877 ovl.fmt.RRE.r2); goto ok;
14878 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14879 ovl.fmt.RRE.r2); goto ok;
14880 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014881 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14882 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14883 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014884 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14885 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14886 goto ok;
14887 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14888 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14889 goto ok;
14890 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14891 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14892 goto ok;
14893 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14894 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14895 goto ok;
14896 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14897 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14898 goto ok;
14899 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14900 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14901 goto ok;
14902 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14903 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14904 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014905 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14906 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14907 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014908 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14909 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14910 goto ok;
14911 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14912 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14913 goto ok;
14914 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14915 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14916 goto ok;
14917 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14918 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14919 goto ok;
14920 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14921 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14922 goto ok;
14923 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
14924 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14925 goto ok;
14926 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14927 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14928 goto ok;
14929 }
14930
14931 switch ((ovl.value & 0xff000000) >> 24) {
14932 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14933 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14934 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14935 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14936 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14937 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14938 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14939 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14940 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14941 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14942 case 0x45: /* BAL */ goto unimplemented;
14943 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14944 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14945 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14946 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14947 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14948 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14949 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14950 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14951 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14952 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14953 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14954 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14955 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14956 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14957 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14958 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14959 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14960 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14961 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14962 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14963 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14964 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14965 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14966 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14967 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14968 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14969 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14970 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14971 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14972 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14973 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14974 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14975 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14976 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14977 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14978 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14979 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14980 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14981 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14982 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14983 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14984 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14985 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14986 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14987 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14988 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14989 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14990 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14991 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14992 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14993 case 0x67: /* MXD */ goto unimplemented;
14994 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14995 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14996 case 0x69: /* CD */ goto unimplemented;
14997 case 0x6a: /* AD */ goto unimplemented;
14998 case 0x6b: /* SD */ goto unimplemented;
14999 case 0x6c: /* MD */ goto unimplemented;
15000 case 0x6d: /* DD */ goto unimplemented;
15001 case 0x6e: /* AW */ goto unimplemented;
15002 case 0x6f: /* SW */ goto unimplemented;
15003 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15004 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15005 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15006 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15007 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15008 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15009 case 0x79: /* CE */ goto unimplemented;
15010 case 0x7a: /* AE */ goto unimplemented;
15011 case 0x7b: /* SE */ goto unimplemented;
15012 case 0x7c: /* MDE */ goto unimplemented;
15013 case 0x7d: /* DE */ goto unimplemented;
15014 case 0x7e: /* AU */ goto unimplemented;
15015 case 0x7f: /* SU */ goto unimplemented;
15016 case 0x83: /* DIAG */ goto unimplemented;
15017 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
15018 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15019 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
15020 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15021 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15022 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15023 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15024 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15025 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15026 ovl.fmt.RS.d2); goto ok;
15027 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15028 ovl.fmt.RS.d2); goto ok;
15029 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15030 ovl.fmt.RS.d2); goto ok;
15031 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15032 ovl.fmt.RS.d2); goto ok;
15033 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15034 ovl.fmt.RS.d2); goto ok;
15035 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15036 ovl.fmt.RS.d2); goto ok;
15037 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15038 ovl.fmt.RS.d2); goto ok;
15039 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15040 ovl.fmt.RS.d2); goto ok;
15041 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15042 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15043 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15044 ovl.fmt.SI.d1); goto ok;
15045 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15046 ovl.fmt.SI.d1); goto ok;
15047 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15048 ovl.fmt.SI.d1); goto ok;
15049 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15050 ovl.fmt.SI.d1); goto ok;
15051 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15052 ovl.fmt.SI.d1); goto ok;
15053 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15054 ovl.fmt.SI.d1); goto ok;
15055 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15056 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15057 case 0x99: /* TRACE */ goto unimplemented;
15058 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15059 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15060 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15061 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15062 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
15063 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15064 goto ok;
15065 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
15066 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15067 goto ok;
15068 case 0xac: /* STNSM */ goto unimplemented;
15069 case 0xad: /* STOSM */ goto unimplemented;
15070 case 0xae: /* SIGP */ goto unimplemented;
15071 case 0xaf: /* MC */ goto unimplemented;
15072 case 0xb1: /* LRA */ goto unimplemented;
15073 case 0xb6: /* STCTL */ goto unimplemented;
15074 case 0xb7: /* LCTL */ goto unimplemented;
15075 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15076 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015077 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15078 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015079 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15080 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15081 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15082 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15083 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15084 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15085 }
15086
15087 return S390_DECODE_UNKNOWN_INSN;
15088
15089ok:
15090 return S390_DECODE_OK;
15091
15092unimplemented:
15093 return S390_DECODE_UNIMPLEMENTED_INSN;
15094}
15095
15096static s390_decode_t
florian8462d112014-09-24 15:18:09 +000015097s390_decode_6byte_and_irgen(const UChar *bytes)
sewardj2019a972011-03-07 16:04:07 +000015098{
15099 typedef union {
15100 struct {
15101 unsigned int op1 : 8;
15102 unsigned int r1 : 4;
15103 unsigned int r3 : 4;
15104 unsigned int i2 : 16;
15105 unsigned int : 8;
15106 unsigned int op2 : 8;
15107 } RIE;
15108 struct {
15109 unsigned int op1 : 8;
15110 unsigned int r1 : 4;
15111 unsigned int r2 : 4;
15112 unsigned int i3 : 8;
15113 unsigned int i4 : 8;
15114 unsigned int i5 : 8;
15115 unsigned int op2 : 8;
15116 } RIE_RRUUU;
15117 struct {
15118 unsigned int op1 : 8;
15119 unsigned int r1 : 4;
15120 unsigned int : 4;
15121 unsigned int i2 : 16;
15122 unsigned int m3 : 4;
15123 unsigned int : 4;
15124 unsigned int op2 : 8;
15125 } RIEv1;
15126 struct {
15127 unsigned int op1 : 8;
15128 unsigned int r1 : 4;
15129 unsigned int r2 : 4;
15130 unsigned int i4 : 16;
15131 unsigned int m3 : 4;
15132 unsigned int : 4;
15133 unsigned int op2 : 8;
15134 } RIE_RRPU;
15135 struct {
15136 unsigned int op1 : 8;
15137 unsigned int r1 : 4;
15138 unsigned int m3 : 4;
15139 unsigned int i4 : 16;
15140 unsigned int i2 : 8;
15141 unsigned int op2 : 8;
15142 } RIEv3;
15143 struct {
15144 unsigned int op1 : 8;
15145 unsigned int r1 : 4;
15146 unsigned int op2 : 4;
15147 unsigned int i2 : 32;
15148 } RIL;
15149 struct {
15150 unsigned int op1 : 8;
15151 unsigned int r1 : 4;
15152 unsigned int m3 : 4;
15153 unsigned int b4 : 4;
15154 unsigned int d4 : 12;
15155 unsigned int i2 : 8;
15156 unsigned int op2 : 8;
15157 } RIS;
15158 struct {
15159 unsigned int op1 : 8;
15160 unsigned int r1 : 4;
15161 unsigned int r2 : 4;
15162 unsigned int b4 : 4;
15163 unsigned int d4 : 12;
15164 unsigned int m3 : 4;
15165 unsigned int : 4;
15166 unsigned int op2 : 8;
15167 } RRS;
15168 struct {
15169 unsigned int op1 : 8;
15170 unsigned int l1 : 4;
15171 unsigned int : 4;
15172 unsigned int b1 : 4;
15173 unsigned int d1 : 12;
15174 unsigned int : 8;
15175 unsigned int op2 : 8;
15176 } RSL;
15177 struct {
15178 unsigned int op1 : 8;
15179 unsigned int r1 : 4;
15180 unsigned int r3 : 4;
15181 unsigned int b2 : 4;
15182 unsigned int dl2 : 12;
15183 unsigned int dh2 : 8;
15184 unsigned int op2 : 8;
15185 } RSY;
15186 struct {
15187 unsigned int op1 : 8;
15188 unsigned int r1 : 4;
15189 unsigned int x2 : 4;
15190 unsigned int b2 : 4;
15191 unsigned int d2 : 12;
15192 unsigned int : 8;
15193 unsigned int op2 : 8;
15194 } RXE;
15195 struct {
15196 unsigned int op1 : 8;
15197 unsigned int r3 : 4;
15198 unsigned int x2 : 4;
15199 unsigned int b2 : 4;
15200 unsigned int d2 : 12;
15201 unsigned int r1 : 4;
15202 unsigned int : 4;
15203 unsigned int op2 : 8;
15204 } RXF;
15205 struct {
15206 unsigned int op1 : 8;
15207 unsigned int r1 : 4;
15208 unsigned int x2 : 4;
15209 unsigned int b2 : 4;
15210 unsigned int dl2 : 12;
15211 unsigned int dh2 : 8;
15212 unsigned int op2 : 8;
15213 } RXY;
15214 struct {
15215 unsigned int op1 : 8;
15216 unsigned int i2 : 8;
15217 unsigned int b1 : 4;
15218 unsigned int dl1 : 12;
15219 unsigned int dh1 : 8;
15220 unsigned int op2 : 8;
15221 } SIY;
15222 struct {
15223 unsigned int op : 8;
15224 unsigned int l : 8;
15225 unsigned int b1 : 4;
15226 unsigned int d1 : 12;
15227 unsigned int b2 : 4;
15228 unsigned int d2 : 12;
15229 } SS;
15230 struct {
15231 unsigned int op : 8;
15232 unsigned int l1 : 4;
15233 unsigned int l2 : 4;
15234 unsigned int b1 : 4;
15235 unsigned int d1 : 12;
15236 unsigned int b2 : 4;
15237 unsigned int d2 : 12;
15238 } SS_LLRDRD;
15239 struct {
15240 unsigned int op : 8;
15241 unsigned int r1 : 4;
15242 unsigned int r3 : 4;
15243 unsigned int b2 : 4;
15244 unsigned int d2 : 12;
15245 unsigned int b4 : 4;
15246 unsigned int d4 : 12;
15247 } SS_RRRDRD2;
15248 struct {
15249 unsigned int op : 16;
15250 unsigned int b1 : 4;
15251 unsigned int d1 : 12;
15252 unsigned int b2 : 4;
15253 unsigned int d2 : 12;
15254 } SSE;
15255 struct {
15256 unsigned int op1 : 8;
15257 unsigned int r3 : 4;
15258 unsigned int op2 : 4;
15259 unsigned int b1 : 4;
15260 unsigned int d1 : 12;
15261 unsigned int b2 : 4;
15262 unsigned int d2 : 12;
15263 } SSF;
15264 struct {
15265 unsigned int op : 16;
15266 unsigned int b1 : 4;
15267 unsigned int d1 : 12;
15268 unsigned int i2 : 16;
15269 } SIL;
15270 } formats;
15271 union {
15272 formats fmt;
15273 ULong value;
15274 } ovl;
15275
15276 vassert(sizeof(formats) == 6);
15277
florianffbd84d2012-12-09 02:06:29 +000015278 ((UChar *)(&ovl.value))[0] = bytes[0];
15279 ((UChar *)(&ovl.value))[1] = bytes[1];
15280 ((UChar *)(&ovl.value))[2] = bytes[2];
15281 ((UChar *)(&ovl.value))[3] = bytes[3];
15282 ((UChar *)(&ovl.value))[4] = bytes[4];
15283 ((UChar *)(&ovl.value))[5] = bytes[5];
15284 ((UChar *)(&ovl.value))[6] = 0x0;
15285 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000015286
15287 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15288 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15289 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15290 ovl.fmt.RXY.dl2,
15291 ovl.fmt.RXY.dh2); goto ok;
15292 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15293 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15294 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15295 ovl.fmt.RXY.dl2,
15296 ovl.fmt.RXY.dh2); goto ok;
15297 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15298 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15299 ovl.fmt.RXY.dl2,
15300 ovl.fmt.RXY.dh2); goto ok;
15301 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15302 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15303 ovl.fmt.RXY.dl2,
15304 ovl.fmt.RXY.dh2); goto ok;
15305 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15306 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15307 ovl.fmt.RXY.dl2,
15308 ovl.fmt.RXY.dh2); goto ok;
15309 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15310 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15311 ovl.fmt.RXY.dl2,
15312 ovl.fmt.RXY.dh2); goto ok;
15313 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15314 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15315 ovl.fmt.RXY.dl2,
15316 ovl.fmt.RXY.dh2); goto ok;
15317 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15318 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15319 ovl.fmt.RXY.dl2,
15320 ovl.fmt.RXY.dh2); goto ok;
15321 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15322 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15323 ovl.fmt.RXY.dl2,
15324 ovl.fmt.RXY.dh2); goto ok;
15325 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15326 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
15327 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15328 ovl.fmt.RXY.dl2,
15329 ovl.fmt.RXY.dh2); goto ok;
15330 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
15331 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15332 ovl.fmt.RXY.dl2,
15333 ovl.fmt.RXY.dh2); goto ok;
15334 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15335 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15336 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15337 ovl.fmt.RXY.dl2,
15338 ovl.fmt.RXY.dh2); goto ok;
15339 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15340 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15341 ovl.fmt.RXY.dl2,
15342 ovl.fmt.RXY.dh2); goto ok;
15343 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15344 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15345 ovl.fmt.RXY.dl2,
15346 ovl.fmt.RXY.dh2); goto ok;
15347 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15348 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15349 ovl.fmt.RXY.dl2,
15350 ovl.fmt.RXY.dh2); goto ok;
15351 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15352 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15353 ovl.fmt.RXY.dl2,
15354 ovl.fmt.RXY.dh2); goto ok;
15355 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15356 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15357 ovl.fmt.RXY.dl2,
15358 ovl.fmt.RXY.dh2); goto ok;
15359 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15360 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15361 ovl.fmt.RXY.dl2,
15362 ovl.fmt.RXY.dh2); goto ok;
15363 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15364 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15365 ovl.fmt.RXY.dl2,
15366 ovl.fmt.RXY.dh2); goto ok;
15367 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15368 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15369 ovl.fmt.RXY.dl2,
15370 ovl.fmt.RXY.dh2); goto ok;
15371 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15372 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15373 ovl.fmt.RXY.dl2,
15374 ovl.fmt.RXY.dh2); goto ok;
15375 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15376 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15377 ovl.fmt.RXY.dl2,
15378 ovl.fmt.RXY.dh2); goto ok;
15379 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15380 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15381 ovl.fmt.RXY.dl2,
15382 ovl.fmt.RXY.dh2); goto ok;
15383 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15384 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15385 ovl.fmt.RXY.dl2,
15386 ovl.fmt.RXY.dh2); goto ok;
15387 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15388 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15389 ovl.fmt.RXY.dl2,
15390 ovl.fmt.RXY.dh2); goto ok;
15391 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15392 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15393 ovl.fmt.RXY.dl2,
15394 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015395 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015396 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15397 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15398 ovl.fmt.RXY.dl2,
15399 ovl.fmt.RXY.dh2); goto ok;
15400 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15401 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15402 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15403 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15404 ovl.fmt.RXY.dh2); goto ok;
15405 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15406 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15407 ovl.fmt.RXY.dl2,
15408 ovl.fmt.RXY.dh2); goto ok;
15409 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15410 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15411 ovl.fmt.RXY.dl2,
15412 ovl.fmt.RXY.dh2); goto ok;
15413 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15414 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15415 ovl.fmt.RXY.dl2,
15416 ovl.fmt.RXY.dh2); goto ok;
15417 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15418 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15419 ovl.fmt.RXY.dl2,
15420 ovl.fmt.RXY.dh2); goto ok;
15421 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15422 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15423 ovl.fmt.RXY.dl2,
15424 ovl.fmt.RXY.dh2); goto ok;
15425 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15426 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15427 ovl.fmt.RXY.dl2,
15428 ovl.fmt.RXY.dh2); goto ok;
15429 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15430 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15431 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15432 ovl.fmt.RXY.dh2); goto ok;
15433 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15434 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15435 ovl.fmt.RXY.dl2,
15436 ovl.fmt.RXY.dh2); goto ok;
15437 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15438 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15439 ovl.fmt.RXY.dl2,
15440 ovl.fmt.RXY.dh2); goto ok;
15441 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15442 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15443 ovl.fmt.RXY.dl2,
15444 ovl.fmt.RXY.dh2); goto ok;
15445 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15446 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15447 ovl.fmt.RXY.dl2,
15448 ovl.fmt.RXY.dh2); goto ok;
15449 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15450 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15451 ovl.fmt.RXY.dl2,
15452 ovl.fmt.RXY.dh2); goto ok;
15453 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15454 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15455 ovl.fmt.RXY.dl2,
15456 ovl.fmt.RXY.dh2); goto ok;
15457 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15458 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15459 ovl.fmt.RXY.dl2,
15460 ovl.fmt.RXY.dh2); goto ok;
15461 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15462 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15463 ovl.fmt.RXY.dl2,
15464 ovl.fmt.RXY.dh2); goto ok;
15465 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15466 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15467 ovl.fmt.RXY.dl2,
15468 ovl.fmt.RXY.dh2); goto ok;
15469 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15470 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15471 ovl.fmt.RXY.dl2,
15472 ovl.fmt.RXY.dh2); goto ok;
15473 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15474 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15475 ovl.fmt.RXY.dl2,
15476 ovl.fmt.RXY.dh2); goto ok;
15477 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15478 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15479 ovl.fmt.RXY.dl2,
15480 ovl.fmt.RXY.dh2); goto ok;
15481 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15482 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15483 ovl.fmt.RXY.dl2,
15484 ovl.fmt.RXY.dh2); goto ok;
15485 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15486 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15487 ovl.fmt.RXY.dl2,
15488 ovl.fmt.RXY.dh2); goto ok;
15489 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15490 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15491 ovl.fmt.RXY.dl2,
15492 ovl.fmt.RXY.dh2); goto ok;
15493 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15494 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15495 ovl.fmt.RXY.dl2,
15496 ovl.fmt.RXY.dh2); goto ok;
15497 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15498 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15499 ovl.fmt.RXY.dl2,
15500 ovl.fmt.RXY.dh2); goto ok;
15501 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15502 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15503 ovl.fmt.RXY.dl2,
15504 ovl.fmt.RXY.dh2); goto ok;
15505 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15506 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15507 ovl.fmt.RXY.dl2,
15508 ovl.fmt.RXY.dh2); goto ok;
15509 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15510 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15511 ovl.fmt.RXY.dl2,
15512 ovl.fmt.RXY.dh2); goto ok;
15513 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15514 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15515 ovl.fmt.RXY.dl2,
15516 ovl.fmt.RXY.dh2); goto ok;
15517 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15518 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15519 ovl.fmt.RXY.dl2,
15520 ovl.fmt.RXY.dh2); goto ok;
15521 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15522 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15523 ovl.fmt.RXY.dl2,
15524 ovl.fmt.RXY.dh2); goto ok;
15525 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15526 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15527 ovl.fmt.RXY.dl2,
15528 ovl.fmt.RXY.dh2); goto ok;
15529 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15530 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15531 ovl.fmt.RXY.dl2,
15532 ovl.fmt.RXY.dh2); goto ok;
15533 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15534 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15535 ovl.fmt.RXY.dl2,
15536 ovl.fmt.RXY.dh2); goto ok;
15537 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15538 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15539 ovl.fmt.RXY.dl2,
15540 ovl.fmt.RXY.dh2); goto ok;
15541 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15542 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15543 ovl.fmt.RXY.dl2,
15544 ovl.fmt.RXY.dh2); goto ok;
15545 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15546 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15547 ovl.fmt.RXY.dl2,
15548 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015549 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015550 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15551 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15552 ovl.fmt.RXY.dl2,
15553 ovl.fmt.RXY.dh2); goto ok;
15554 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15555 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15556 ovl.fmt.RXY.dl2,
15557 ovl.fmt.RXY.dh2); goto ok;
15558 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15559 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15560 ovl.fmt.RXY.dl2,
15561 ovl.fmt.RXY.dh2); goto ok;
15562 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15563 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15564 ovl.fmt.RXY.dl2,
15565 ovl.fmt.RXY.dh2); goto ok;
15566 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15567 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15568 ovl.fmt.RXY.dl2,
15569 ovl.fmt.RXY.dh2); goto ok;
15570 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15571 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15572 ovl.fmt.RXY.dl2,
15573 ovl.fmt.RXY.dh2); goto ok;
15574 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15575 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15576 ovl.fmt.RXY.dl2,
15577 ovl.fmt.RXY.dh2); goto ok;
15578 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15579 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15580 ovl.fmt.RXY.dl2,
15581 ovl.fmt.RXY.dh2); goto ok;
15582 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15583 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15584 ovl.fmt.RXY.dl2,
15585 ovl.fmt.RXY.dh2); goto ok;
15586 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15587 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15588 ovl.fmt.RXY.dl2,
15589 ovl.fmt.RXY.dh2); goto ok;
15590 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15591 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15592 ovl.fmt.RXY.dl2,
15593 ovl.fmt.RXY.dh2); goto ok;
15594 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15595 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15596 ovl.fmt.RXY.dl2,
15597 ovl.fmt.RXY.dh2); goto ok;
15598 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15599 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15600 ovl.fmt.RXY.dl2,
15601 ovl.fmt.RXY.dh2); goto ok;
15602 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15603 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15604 ovl.fmt.RXY.dl2,
15605 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015606 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15607 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15608 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015609 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15610 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15611 ovl.fmt.RXY.dl2,
15612 ovl.fmt.RXY.dh2); goto ok;
15613 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15614 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15615 ovl.fmt.RXY.dl2,
15616 ovl.fmt.RXY.dh2); goto ok;
15617 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15618 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15619 ovl.fmt.RXY.dl2,
15620 ovl.fmt.RXY.dh2); goto ok;
15621 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15622 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15623 ovl.fmt.RXY.dl2,
15624 ovl.fmt.RXY.dh2); goto ok;
15625 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15626 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15627 ovl.fmt.RXY.dl2,
15628 ovl.fmt.RXY.dh2); goto ok;
15629 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15630 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15631 ovl.fmt.RXY.dl2,
15632 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015633 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015634 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15635 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15636 ovl.fmt.RXY.dl2,
15637 ovl.fmt.RXY.dh2); goto ok;
15638 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15639 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15640 ovl.fmt.RXY.dl2,
15641 ovl.fmt.RXY.dh2); goto ok;
15642 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15643 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15644 ovl.fmt.RXY.dl2,
15645 ovl.fmt.RXY.dh2); goto ok;
15646 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15647 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15648 ovl.fmt.RXY.dl2,
15649 ovl.fmt.RXY.dh2); goto ok;
15650 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15651 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15652 ovl.fmt.RSY.dl2,
15653 ovl.fmt.RSY.dh2); goto ok;
15654 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15655 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15656 ovl.fmt.RSY.dl2,
15657 ovl.fmt.RSY.dh2); goto ok;
15658 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15659 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15660 ovl.fmt.RSY.dl2,
15661 ovl.fmt.RSY.dh2); goto ok;
15662 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15663 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15664 ovl.fmt.RSY.dl2,
15665 ovl.fmt.RSY.dh2); goto ok;
15666 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15667 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15668 ovl.fmt.RSY.dl2,
15669 ovl.fmt.RSY.dh2); goto ok;
15670 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15671 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15672 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15673 ovl.fmt.RSY.dl2,
15674 ovl.fmt.RSY.dh2); goto ok;
15675 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15676 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15677 ovl.fmt.RSY.dl2,
15678 ovl.fmt.RSY.dh2); goto ok;
15679 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15680 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15681 ovl.fmt.RSY.dl2,
15682 ovl.fmt.RSY.dh2); goto ok;
15683 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15684 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15685 ovl.fmt.RSY.dl2,
15686 ovl.fmt.RSY.dh2); goto ok;
15687 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15688 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15689 ovl.fmt.RSY.dl2,
15690 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015691 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015692 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15693 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15694 ovl.fmt.RSY.dl2,
15695 ovl.fmt.RSY.dh2); goto ok;
15696 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15697 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15698 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15699 ovl.fmt.RSY.dl2,
15700 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015701 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015702 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15703 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15704 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15705 ovl.fmt.RSY.dh2); goto ok;
15706 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15707 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15708 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15709 ovl.fmt.RSY.dh2); goto ok;
15710 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15711 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15712 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15713 ovl.fmt.RSY.dl2,
15714 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015715 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15716 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15717 ovl.fmt.RSY.dl2,
15718 ovl.fmt.RSY.dh2); goto ok;
15719 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15720 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15721 ovl.fmt.RSY.dl2,
15722 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015723 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15724 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15725 ovl.fmt.RSY.dl2,
15726 ovl.fmt.RSY.dh2); goto ok;
15727 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15728 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15729 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15730 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015731 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15732 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15733 ovl.fmt.RSY.dl2,
15734 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015735 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15736 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15737 ovl.fmt.SIY.dh1); goto ok;
15738 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15739 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15740 ovl.fmt.SIY.dh1); goto ok;
15741 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15742 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15743 ovl.fmt.SIY.dh1); goto ok;
15744 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15745 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15746 ovl.fmt.SIY.dh1); goto ok;
15747 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15748 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15749 ovl.fmt.SIY.dh1); goto ok;
15750 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15751 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15752 ovl.fmt.SIY.dh1); goto ok;
15753 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15754 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15755 ovl.fmt.SIY.dh1); goto ok;
15756 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15757 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15758 ovl.fmt.SIY.dh1); goto ok;
15759 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15760 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15761 ovl.fmt.SIY.dh1); goto ok;
15762 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15763 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15764 ovl.fmt.SIY.dh1); goto ok;
15765 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15766 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15767 ovl.fmt.RSY.dl2,
15768 ovl.fmt.RSY.dh2); goto ok;
15769 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15770 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15771 ovl.fmt.RSY.dl2,
15772 ovl.fmt.RSY.dh2); goto ok;
15773 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15774 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15775 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15776 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15777 ovl.fmt.RSY.dl2,
15778 ovl.fmt.RSY.dh2); goto ok;
15779 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15780 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15781 ovl.fmt.RSY.dl2,
15782 ovl.fmt.RSY.dh2); goto ok;
15783 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15784 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15785 ovl.fmt.RSY.dl2,
15786 ovl.fmt.RSY.dh2); goto ok;
15787 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15788 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15789 ovl.fmt.RSY.dl2,
15790 ovl.fmt.RSY.dh2); goto ok;
15791 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15792 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15793 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15794 ovl.fmt.RSY.dh2); goto ok;
15795 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15796 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15797 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15798 ovl.fmt.RSY.dl2,
15799 ovl.fmt.RSY.dh2); goto ok;
15800 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15801 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15802 ovl.fmt.RSY.dl2,
15803 ovl.fmt.RSY.dh2); goto ok;
15804 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15805 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15806 ovl.fmt.RSY.dl2,
15807 ovl.fmt.RSY.dh2); goto ok;
15808 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15809 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15810 ovl.fmt.RSY.dl2,
15811 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015812 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15813 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15814 ovl.fmt.RSY.dl2,
15815 ovl.fmt.RSY.dh2,
15816 S390_XMNM_LOCG); goto ok;
15817 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15818 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15819 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15820 ovl.fmt.RSY.dh2,
15821 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015822 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15823 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15824 ovl.fmt.RSY.dl2,
15825 ovl.fmt.RSY.dh2); goto ok;
15826 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15827 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15828 ovl.fmt.RSY.dl2,
15829 ovl.fmt.RSY.dh2); goto ok;
15830 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15831 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15832 ovl.fmt.RSY.dl2,
15833 ovl.fmt.RSY.dh2); goto ok;
15834 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15835 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15836 ovl.fmt.RSY.dl2,
15837 ovl.fmt.RSY.dh2); goto ok;
15838 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15839 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15840 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15841 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015842 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15843 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15844 ovl.fmt.RSY.dl2,
15845 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15846 goto ok;
15847 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15848 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15849 ovl.fmt.RSY.dl2,
15850 ovl.fmt.RSY.dh2,
15851 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015852 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15853 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15854 ovl.fmt.RSY.dl2,
15855 ovl.fmt.RSY.dh2); goto ok;
15856 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15857 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15858 ovl.fmt.RSY.dl2,
15859 ovl.fmt.RSY.dh2); goto ok;
15860 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15861 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15862 ovl.fmt.RSY.dl2,
15863 ovl.fmt.RSY.dh2); goto ok;
15864 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15865 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15866 ovl.fmt.RSY.dl2,
15867 ovl.fmt.RSY.dh2); goto ok;
15868 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15869 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15870 ovl.fmt.RSY.dl2,
15871 ovl.fmt.RSY.dh2); goto ok;
15872 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15873 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15874 goto ok;
15875 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15876 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15877 goto ok;
15878 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15879 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15880 ovl.fmt.RIE_RRUUU.r1,
15881 ovl.fmt.RIE_RRUUU.r2,
15882 ovl.fmt.RIE_RRUUU.i3,
15883 ovl.fmt.RIE_RRUUU.i4,
15884 ovl.fmt.RIE_RRUUU.i5);
15885 goto ok;
15886 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15887 ovl.fmt.RIE_RRUUU.r1,
15888 ovl.fmt.RIE_RRUUU.r2,
15889 ovl.fmt.RIE_RRUUU.i3,
15890 ovl.fmt.RIE_RRUUU.i4,
15891 ovl.fmt.RIE_RRUUU.i5);
15892 goto ok;
15893 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15894 ovl.fmt.RIE_RRUUU.r1,
15895 ovl.fmt.RIE_RRUUU.r2,
15896 ovl.fmt.RIE_RRUUU.i3,
15897 ovl.fmt.RIE_RRUUU.i4,
15898 ovl.fmt.RIE_RRUUU.i5);
15899 goto ok;
15900 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15901 ovl.fmt.RIE_RRUUU.r1,
15902 ovl.fmt.RIE_RRUUU.r2,
15903 ovl.fmt.RIE_RRUUU.i3,
15904 ovl.fmt.RIE_RRUUU.i4,
15905 ovl.fmt.RIE_RRUUU.i5);
15906 goto ok;
florian2289cd42012-12-05 04:23:42 +000015907 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015908 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15909 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15910 ovl.fmt.RIE_RRPU.r1,
15911 ovl.fmt.RIE_RRPU.r2,
15912 ovl.fmt.RIE_RRPU.i4,
15913 ovl.fmt.RIE_RRPU.m3); goto ok;
15914 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15915 ovl.fmt.RIE_RRPU.r1,
15916 ovl.fmt.RIE_RRPU.r2,
15917 ovl.fmt.RIE_RRPU.i4,
15918 ovl.fmt.RIE_RRPU.m3); goto ok;
15919 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15920 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15921 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15922 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
15923 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
15924 ovl.fmt.RIE_RRPU.r1,
15925 ovl.fmt.RIE_RRPU.r2,
15926 ovl.fmt.RIE_RRPU.i4,
15927 ovl.fmt.RIE_RRPU.m3); goto ok;
15928 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15929 ovl.fmt.RIE_RRPU.r1,
15930 ovl.fmt.RIE_RRPU.r2,
15931 ovl.fmt.RIE_RRPU.i4,
15932 ovl.fmt.RIE_RRPU.m3); goto ok;
15933 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15934 ovl.fmt.RIEv3.r1,
15935 ovl.fmt.RIEv3.m3,
15936 ovl.fmt.RIEv3.i4,
15937 ovl.fmt.RIEv3.i2); goto ok;
15938 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15939 ovl.fmt.RIEv3.r1,
15940 ovl.fmt.RIEv3.m3,
15941 ovl.fmt.RIEv3.i4,
15942 ovl.fmt.RIEv3.i2); goto ok;
15943 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15944 ovl.fmt.RIEv3.r1,
15945 ovl.fmt.RIEv3.m3,
15946 ovl.fmt.RIEv3.i4,
15947 ovl.fmt.RIEv3.i2); goto ok;
15948 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15949 ovl.fmt.RIEv3.r1,
15950 ovl.fmt.RIEv3.m3,
15951 ovl.fmt.RIEv3.i4,
15952 ovl.fmt.RIEv3.i2); goto ok;
15953 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15954 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15955 goto ok;
15956 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15957 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15958 ovl.fmt.RIE.i2); goto ok;
15959 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15960 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15961 ovl.fmt.RIE.i2); goto ok;
15962 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15963 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15964 ovl.fmt.RIE.i2); goto ok;
15965 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15966 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15967 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15968 goto ok;
15969 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15970 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15971 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15972 goto ok;
15973 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15974 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15975 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15976 goto ok;
15977 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15978 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15979 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15980 goto ok;
15981 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15982 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15983 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15984 ovl.fmt.RIS.i2); goto ok;
15985 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15986 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15987 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15988 ovl.fmt.RIS.i2); goto ok;
15989 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15990 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15991 ovl.fmt.RIS.d4,
15992 ovl.fmt.RIS.i2); goto ok;
15993 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15994 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15995 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15996 ovl.fmt.RIS.i2); goto ok;
15997 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15998 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15999 ovl.fmt.RXE.d2); goto ok;
16000 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
16001 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16002 ovl.fmt.RXE.d2); goto ok;
16003 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
16004 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16005 ovl.fmt.RXE.d2); goto ok;
16006 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
16007 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
16008 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
16009 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16010 ovl.fmt.RXE.d2); goto ok;
16011 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
16012 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16013 ovl.fmt.RXE.d2); goto ok;
16014 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
16015 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16016 ovl.fmt.RXE.d2); goto ok;
16017 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
16018 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
16019 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16020 ovl.fmt.RXE.d2); goto ok;
16021 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
16022 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16023 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16024 ovl.fmt.RXF.r1); goto ok;
16025 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
16026 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16027 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16028 ovl.fmt.RXF.r1); goto ok;
16029 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
16030 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16031 ovl.fmt.RXE.d2); goto ok;
16032 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
16033 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16034 ovl.fmt.RXE.d2); goto ok;
16035 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
16036 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16037 ovl.fmt.RXE.d2); goto ok;
16038 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
16039 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16040 ovl.fmt.RXE.d2); goto ok;
16041 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
16042 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16043 ovl.fmt.RXE.d2); goto ok;
16044 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
16045 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16046 ovl.fmt.RXE.d2); goto ok;
16047 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
16048 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
16049 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16050 ovl.fmt.RXE.d2); goto ok;
16051 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
16052 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16053 ovl.fmt.RXE.d2); goto ok;
16054 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
16055 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16056 ovl.fmt.RXE.d2); goto ok;
16057 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
16058 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16059 ovl.fmt.RXE.d2); goto ok;
16060 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
16061 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16062 ovl.fmt.RXE.d2); goto ok;
16063 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
16064 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16065 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16066 ovl.fmt.RXF.r1); goto ok;
16067 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
16068 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16069 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16070 ovl.fmt.RXF.r1); goto ok;
16071 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
16072 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
16073 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
16074 case 0xed000000002eULL: /* MAE */ goto unimplemented;
16075 case 0xed000000002fULL: /* MSE */ goto unimplemented;
16076 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
16077 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
16078 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
16079 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
16080 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
16081 case 0xed000000003aULL: /* MAY */ goto unimplemented;
16082 case 0xed000000003bULL: /* MY */ goto unimplemented;
16083 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
16084 case 0xed000000003dULL: /* MYH */ goto unimplemented;
16085 case 0xed000000003eULL: /* MAD */ goto unimplemented;
16086 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000016087 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
16088 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16089 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16090 ovl.fmt.RXF.r1); goto ok;
16091 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
16092 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16093 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16094 ovl.fmt.RXF.r1); goto ok;
16095 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
16096 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16097 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16098 ovl.fmt.RXF.r1); goto ok;
16099 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
16100 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16101 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16102 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000016103 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
16104 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16105 ovl.fmt.RXE.d2); goto ok;
16106 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
16107 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16108 ovl.fmt.RXE.d2); goto ok;
16109 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
16110 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16111 ovl.fmt.RXE.d2); goto ok;
16112 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
16113 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16114 ovl.fmt.RXE.d2); goto ok;
16115 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
16116 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16117 ovl.fmt.RXE.d2); goto ok;
16118 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
16119 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16120 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016121 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
16122 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16123 ovl.fmt.RXY.dl2,
16124 ovl.fmt.RXY.dh2); goto ok;
16125 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
16126 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16127 ovl.fmt.RXY.dl2,
16128 ovl.fmt.RXY.dh2); goto ok;
16129 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
16130 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16131 ovl.fmt.RXY.dl2,
16132 ovl.fmt.RXY.dh2); goto ok;
16133 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
16134 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16135 ovl.fmt.RXY.dl2,
16136 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000016137 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
16138 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
16139 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
16140 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016141 }
16142
16143 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
16144 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
16145 ovl.fmt.RIL.i2); goto ok;
16146 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
16147 ovl.fmt.RIL.i2); goto ok;
16148 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
16149 ovl.fmt.RIL.i2); goto ok;
16150 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16151 ovl.fmt.RIL.i2); goto ok;
16152 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16153 ovl.fmt.RIL.i2); goto ok;
16154 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16155 ovl.fmt.RIL.i2); goto ok;
16156 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16157 ovl.fmt.RIL.i2); goto ok;
16158 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16159 ovl.fmt.RIL.i2); goto ok;
16160 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16161 ovl.fmt.RIL.i2); goto ok;
16162 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16163 ovl.fmt.RIL.i2); goto ok;
16164 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16165 ovl.fmt.RIL.i2); goto ok;
16166 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16167 ovl.fmt.RIL.i2); goto ok;
16168 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16169 ovl.fmt.RIL.i2); goto ok;
16170 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16171 ovl.fmt.RIL.i2); goto ok;
16172 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16173 ovl.fmt.RIL.i2); goto ok;
16174 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16175 ovl.fmt.RIL.i2); goto ok;
16176 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16177 ovl.fmt.RIL.i2); goto ok;
16178 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16179 ovl.fmt.RIL.i2); goto ok;
16180 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16181 ovl.fmt.RIL.i2); goto ok;
16182 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16183 ovl.fmt.RIL.i2); goto ok;
16184 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16185 ovl.fmt.RIL.i2); goto ok;
16186 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16187 ovl.fmt.RIL.i2); goto ok;
16188 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16189 ovl.fmt.RIL.i2); goto ok;
16190 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16191 ovl.fmt.RIL.i2); goto ok;
16192 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16193 ovl.fmt.RIL.i2); goto ok;
16194 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16195 ovl.fmt.RIL.i2); goto ok;
16196 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16197 ovl.fmt.RIL.i2); goto ok;
16198 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16199 ovl.fmt.RIL.i2); goto ok;
16200 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16201 ovl.fmt.RIL.i2); goto ok;
16202 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16203 ovl.fmt.RIL.i2); goto ok;
16204 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16205 ovl.fmt.RIL.i2); goto ok;
16206 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16207 ovl.fmt.RIL.i2); goto ok;
16208 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16209 ovl.fmt.RIL.i2); goto ok;
16210 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16211 ovl.fmt.RIL.i2); goto ok;
16212 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16213 ovl.fmt.RIL.i2); goto ok;
16214 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16215 ovl.fmt.RIL.i2); goto ok;
16216 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16217 ovl.fmt.RIL.i2); goto ok;
16218 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16219 ovl.fmt.RIL.i2); goto ok;
16220 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16221 ovl.fmt.RIL.i2); goto ok;
16222 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16223 ovl.fmt.RIL.i2); goto ok;
16224 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16225 ovl.fmt.RIL.i2); goto ok;
16226 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16227 ovl.fmt.RIL.i2); goto ok;
16228 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16229 ovl.fmt.RIL.i2); goto ok;
16230 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16231 ovl.fmt.RIL.i2); goto ok;
16232 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16233 ovl.fmt.RIL.i2); goto ok;
16234 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16235 ovl.fmt.RIL.i2); goto ok;
16236 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16237 ovl.fmt.RIL.i2); goto ok;
16238 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16239 ovl.fmt.RIL.i2); goto ok;
16240 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16241 ovl.fmt.RIL.i2); goto ok;
16242 case 0xc800ULL: /* MVCOS */ goto unimplemented;
16243 case 0xc801ULL: /* ECTG */ goto unimplemented;
16244 case 0xc802ULL: /* CSST */ goto unimplemented;
16245 case 0xc804ULL: /* LPD */ goto unimplemented;
16246 case 0xc805ULL: /* LPDG */ goto unimplemented;
16247 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
16248 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16249 ovl.fmt.RIL.i2); goto ok;
16250 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16251 ovl.fmt.RIL.i2); goto ok;
16252 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16253 ovl.fmt.RIL.i2); goto ok;
16254 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16255 ovl.fmt.RIL.i2); goto ok;
16256 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16257 ovl.fmt.RIL.i2); goto ok;
16258 }
16259
16260 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000016261 case 0xc5ULL: /* BPRP */ goto unimplemented;
16262 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016263 case 0xd0ULL: /* TRTR */ goto unimplemented;
16264 case 0xd1ULL: /* MVN */ goto unimplemented;
16265 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16266 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16267 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16268 case 0xd3ULL: /* MVZ */ goto unimplemented;
16269 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16270 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16271 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16272 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16273 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16274 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16275 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16276 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16277 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000016278 case 0xd7ULL:
16279 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16280 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16281 else
16282 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16283 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16284 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16285 goto ok;
sewardj2019a972011-03-07 16:04:07 +000016286 case 0xd9ULL: /* MVCK */ goto unimplemented;
16287 case 0xdaULL: /* MVCP */ goto unimplemented;
16288 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000016289 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16290 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16291 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016292 case 0xddULL: /* TRT */ goto unimplemented;
16293 case 0xdeULL: /* ED */ goto unimplemented;
16294 case 0xdfULL: /* EDMK */ goto unimplemented;
16295 case 0xe1ULL: /* PKU */ goto unimplemented;
16296 case 0xe2ULL: /* UNPKU */ goto unimplemented;
16297 case 0xe8ULL: /* MVCIN */ goto unimplemented;
16298 case 0xe9ULL: /* PKA */ goto unimplemented;
16299 case 0xeaULL: /* UNPKA */ goto unimplemented;
16300 case 0xeeULL: /* PLO */ goto unimplemented;
16301 case 0xefULL: /* LMD */ goto unimplemented;
16302 case 0xf0ULL: /* SRP */ goto unimplemented;
16303 case 0xf1ULL: /* MVO */ goto unimplemented;
16304 case 0xf2ULL: /* PACK */ goto unimplemented;
16305 case 0xf3ULL: /* UNPK */ goto unimplemented;
16306 case 0xf8ULL: /* ZAP */ goto unimplemented;
16307 case 0xf9ULL: /* CP */ goto unimplemented;
16308 case 0xfaULL: /* AP */ goto unimplemented;
16309 case 0xfbULL: /* SP */ goto unimplemented;
16310 case 0xfcULL: /* MP */ goto unimplemented;
16311 case 0xfdULL: /* DP */ goto unimplemented;
16312 }
16313
16314 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16315 case 0xe500ULL: /* LASP */ goto unimplemented;
16316 case 0xe501ULL: /* TPROT */ goto unimplemented;
16317 case 0xe502ULL: /* STRAG */ goto unimplemented;
16318 case 0xe50eULL: /* MVCSK */ goto unimplemented;
16319 case 0xe50fULL: /* MVCDK */ goto unimplemented;
16320 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16321 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16322 goto ok;
16323 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16324 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16325 goto ok;
16326 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16327 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16328 goto ok;
16329 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16330 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16331 goto ok;
16332 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16333 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16334 goto ok;
16335 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16336 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16337 goto ok;
16338 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16339 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16340 goto ok;
16341 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16342 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16343 goto ok;
16344 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16345 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16346 goto ok;
florian2289cd42012-12-05 04:23:42 +000016347 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16348 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016349 }
16350
16351 return S390_DECODE_UNKNOWN_INSN;
16352
16353ok:
16354 return S390_DECODE_OK;
16355
16356unimplemented:
16357 return S390_DECODE_UNIMPLEMENTED_INSN;
16358}
16359
16360/* Handle "special" instructions. */
16361static s390_decode_t
florian8462d112014-09-24 15:18:09 +000016362s390_decode_special_and_irgen(const UChar *bytes)
sewardj2019a972011-03-07 16:04:07 +000016363{
16364 s390_decode_t status = S390_DECODE_OK;
16365
16366 /* Got a "Special" instruction preamble. Which one is it? */
16367 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16368 s390_irgen_client_request();
16369 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16370 s390_irgen_guest_NRADDR();
16371 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16372 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000016373 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16374 vex_inject_ir(irsb, Iend_BE);
16375
16376 /* Invalidate the current insn. The reason is that the IRop we're
16377 injecting here can change. In which case the translation has to
16378 be redone. For ease of handling, we simply invalidate all the
16379 time. */
sewardj05f5e012014-05-04 10:52:11 +000016380 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian2245ce92012-08-28 16:49:30 +000016381 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000016382 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN),
florian2245ce92012-08-28 16:49:30 +000016383 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16384 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16385 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16386
16387 put_IA(mkaddr_expr(guest_IA_next_instr));
16388 dis_res->whatNext = Dis_StopHere;
sewardj05f5e012014-05-04 10:52:11 +000016389 dis_res->jk_StopHere = Ijk_InvalICache;
sewardj2019a972011-03-07 16:04:07 +000016390 } else {
16391 /* We don't know what it is. */
16392 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16393 }
16394
16395 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16396
16397 return status;
16398}
16399
16400
16401/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000016402static UInt
florian8462d112014-09-24 15:18:09 +000016403s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres)
sewardj2019a972011-03-07 16:04:07 +000016404{
16405 s390_decode_t status;
16406
16407 dis_res = dres;
16408
16409 /* Spot the 8-byte preamble: 18ff lr r15,r15
16410 1811 lr r1,r1
16411 1822 lr r2,r2
16412 1833 lr r3,r3 */
16413 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16414 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16415 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16416
16417 /* Handle special instruction that follows that preamble. */
16418 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000016419
16420 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16421 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16422
16423 status =
16424 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000016425 } else {
16426 /* Handle normal instructions. */
16427 switch (insn_length) {
16428 case 2:
16429 status = s390_decode_2byte_and_irgen(bytes);
16430 break;
16431
16432 case 4:
16433 status = s390_decode_4byte_and_irgen(bytes);
16434 break;
16435
16436 case 6:
16437 status = s390_decode_6byte_and_irgen(bytes);
16438 break;
16439
16440 default:
16441 status = S390_DECODE_ERROR;
16442 break;
16443 }
16444 }
florian5fcbba22011-07-27 20:40:22 +000016445 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000016446 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16447 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000016448 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000016449 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000016450 }
16451
16452 if (status == S390_DECODE_OK) return insn_length; /* OK */
16453
16454 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000016455 if (sigill_diag) {
16456 vex_printf("vex s390->IR: ");
16457 switch (status) {
16458 case S390_DECODE_UNKNOWN_INSN:
16459 vex_printf("unknown insn: ");
16460 break;
sewardj2019a972011-03-07 16:04:07 +000016461
sewardj442e51a2012-12-06 18:08:04 +000016462 case S390_DECODE_UNIMPLEMENTED_INSN:
16463 vex_printf("unimplemented insn: ");
16464 break;
sewardj2019a972011-03-07 16:04:07 +000016465
sewardj442e51a2012-12-06 18:08:04 +000016466 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16467 vex_printf("unimplemented special insn: ");
16468 break;
sewardj2019a972011-03-07 16:04:07 +000016469
sewardj442e51a2012-12-06 18:08:04 +000016470 case S390_DECODE_ERROR:
16471 vex_printf("decoding error: ");
16472 break;
florian2580da42014-09-16 21:49:45 +000016473
16474 default:
16475 vpanic("s390_decode_and_irgen");
sewardj442e51a2012-12-06 18:08:04 +000016476 }
16477
16478 vex_printf("%02x%02x", bytes[0], bytes[1]);
16479 if (insn_length > 2) {
16480 vex_printf(" %02x%02x", bytes[2], bytes[3]);
16481 }
16482 if (insn_length > 4) {
16483 vex_printf(" %02x%02x", bytes[4], bytes[5]);
16484 }
16485 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000016486 }
16487
sewardj2019a972011-03-07 16:04:07 +000016488 return 0; /* Failed */
16489}
16490
16491
sewardj2019a972011-03-07 16:04:07 +000016492/* Disassemble a single instruction INSN into IR. */
16493static DisResult
florian8462d112014-09-24 15:18:09 +000016494disInstr_S390_WRK(const UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000016495{
16496 UChar byte;
16497 UInt insn_length;
16498 DisResult dres;
16499
16500 /* ---------------------------------------------------- */
16501 /* --- Compute instruction length -- */
16502 /* ---------------------------------------------------- */
16503
16504 /* Get the first byte of the insn. */
16505 byte = insn[0];
16506
16507 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16508 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16509 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16510
16511 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16512
16513 /* ---------------------------------------------------- */
16514 /* --- Initialise the DisResult data -- */
16515 /* ---------------------------------------------------- */
16516 dres.whatNext = Dis_Continue;
16517 dres.len = insn_length;
16518 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016519 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000016520
floriana99f20e2011-07-17 14:16:41 +000016521 /* fixs390: consider chasing of conditional jumps */
16522
sewardj2019a972011-03-07 16:04:07 +000016523 /* Normal and special instruction handling starts here. */
16524 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16525 /* All decode failures end up here. The decoder has already issued an
16526 error message.
16527 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000016528 not been executed, and (is currently) the next to be executed.
16529 The insn address in the guest state needs to be set to
16530 guest_IA_curr_instr, otherwise the complaint will report an
16531 incorrect address. */
16532 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000016533
philippe2faf5912014-08-11 22:45:47 +000016534 dres.len = 0;
florian8844a632012-04-13 04:04:06 +000016535 dres.whatNext = Dis_StopHere;
16536 dres.jk_StopHere = Ijk_NoDecode;
16537 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016538 } else {
16539 /* Decode success */
16540 switch (dres.whatNext) {
16541 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000016542 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000016543 break;
16544 case Dis_ResteerU:
16545 case Dis_ResteerC:
16546 put_IA(mkaddr_expr(dres.continueAt));
16547 break;
16548 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000016549 if (dres.jk_StopHere == Ijk_EmWarn ||
16550 dres.jk_StopHere == Ijk_EmFail) {
16551 /* We assume here, that emulation warnings are not given for
16552 insns that transfer control. There is no good way to
16553 do that. */
16554 put_IA(mkaddr_expr(guest_IA_next_instr));
16555 }
florian8844a632012-04-13 04:04:06 +000016556 break;
16557 default:
florian2580da42014-09-16 21:49:45 +000016558 vpanic("disInstr_S390_WRK");
florian8844a632012-04-13 04:04:06 +000016559 }
sewardj2019a972011-03-07 16:04:07 +000016560 }
16561
16562 return dres;
16563}
16564
16565
16566/*------------------------------------------------------------*/
16567/*--- Top-level fn ---*/
16568/*------------------------------------------------------------*/
16569
16570/* Disassemble a single instruction into IR. The instruction
16571 is located in host memory at &guest_code[delta]. */
16572
16573DisResult
16574disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000016575 Bool (*resteerOkFn)(void *, Addr64),
16576 Bool resteerCisOk,
16577 void *callback_opaque,
florian8462d112014-09-24 15:18:09 +000016578 const UChar *guest_code,
sewardj2019a972011-03-07 16:04:07 +000016579 Long delta,
16580 Addr64 guest_IP,
16581 VexArch guest_arch,
16582 VexArchInfo *archinfo,
16583 VexAbiInfo *abiinfo,
sewardj9b769162014-07-24 12:42:03 +000016584 VexEndness host_endness,
sewardj442e51a2012-12-06 18:08:04 +000016585 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016586{
16587 vassert(guest_arch == VexArchS390X);
16588
16589 /* The instruction decoder requires a big-endian machine. */
sewardj9b769162014-07-24 12:42:03 +000016590 vassert(host_endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +000016591
16592 /* Set globals (see top of this file) */
16593 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016594 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016595 resteer_fn = resteerOkFn;
16596 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016597 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016598
florian420c5012011-07-22 02:12:28 +000016599 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016600}
16601
16602/*---------------------------------------------------------------*/
16603/*--- end guest_s390_toIR.c ---*/
16604/*---------------------------------------------------------------*/