blob: 14c8950826abd21f26b112aecc929f4d286291ef [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
Elliott Hughesed398002017-06-21 14:41:24 -070011 Copyright IBM Corp. 2010-2017
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 */
florianbeac5302014-12-31 12:09:38 +000074static Bool (*resteer_fn)(void *, Addr);
floriana64c2432011-07-16 02:11:50 +000075static 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
sewardj2019a972011-03-07 16:04:07 +000097/* Add a statement to the current irsb. */
98static __inline__ void
99stmt(IRStmt *st)
100{
101 addStmtToIRSB(irsb, st);
102}
103
104/* Allocate a new temporary of the given type. */
105static __inline__ IRTemp
106newTemp(IRType type)
107{
108 vassert(isPlausibleIRType(type));
109
110 return newIRTemp(irsb->tyenv, type);
111}
112
113/* Create an expression node for a temporary */
114static __inline__ IRExpr *
115mkexpr(IRTemp tmp)
116{
117 return IRExpr_RdTmp(tmp);
118}
119
florian8844a632012-04-13 04:04:06 +0000120/* Generate an expression node for an address. */
121static __inline__ IRExpr *
122mkaddr_expr(Addr64 addr)
123{
124 return IRExpr_Const(IRConst_U64(addr));
125}
126
sewardj2019a972011-03-07 16:04:07 +0000127/* Add a statement that assigns to a temporary */
128static __inline__ void
129assign(IRTemp dst, IRExpr *expr)
130{
131 stmt(IRStmt_WrTmp(dst, expr));
132}
133
florian8844a632012-04-13 04:04:06 +0000134/* Write an address into the guest_IA */
135static __inline__ void
136put_IA(IRExpr *address)
137{
138 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
139}
140
sewardj2019a972011-03-07 16:04:07 +0000141/* Create a temporary of the given type and assign the expression to it */
142static __inline__ IRTemp
143mktemp(IRType type, IRExpr *expr)
144{
145 IRTemp temp = newTemp(type);
146
147 assign(temp, expr);
148
149 return temp;
150}
151
152/* Create a unary expression */
153static __inline__ IRExpr *
154unop(IROp kind, IRExpr *op)
155{
156 return IRExpr_Unop(kind, op);
157}
158
159/* Create a binary expression */
160static __inline__ IRExpr *
161binop(IROp kind, IRExpr *op1, IRExpr *op2)
162{
163 return IRExpr_Binop(kind, op1, op2);
164}
165
166/* Create a ternary expression */
167static __inline__ IRExpr *
168triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
169{
170 return IRExpr_Triop(kind, op1, op2, op3);
171}
172
173/* Create a quaternary expression */
174static __inline__ IRExpr *
175qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
176{
177 return IRExpr_Qop(kind, op1, op2, op3, op4);
178}
179
180/* Create an expression node for an 8-bit integer constant */
181static __inline__ IRExpr *
182mkU8(UInt value)
183{
184 vassert(value < 256);
185
186 return IRExpr_Const(IRConst_U8((UChar)value));
187}
188
189/* Create an expression node for a 16-bit integer constant */
190static __inline__ IRExpr *
191mkU16(UInt value)
192{
193 vassert(value < 65536);
194
195 return IRExpr_Const(IRConst_U16((UShort)value));
196}
197
198/* Create an expression node for a 32-bit integer constant */
199static __inline__ IRExpr *
200mkU32(UInt value)
201{
202 return IRExpr_Const(IRConst_U32(value));
203}
204
205/* Create an expression node for a 64-bit integer constant */
206static __inline__ IRExpr *
207mkU64(ULong value)
208{
209 return IRExpr_Const(IRConst_U64(value));
210}
211
212/* Create an expression node for a 32-bit floating point constant
213 whose value is given by a bit pattern. */
214static __inline__ IRExpr *
215mkF32i(UInt value)
216{
217 return IRExpr_Const(IRConst_F32i(value));
218}
219
220/* Create an expression node for a 32-bit floating point constant
221 whose value is given by a bit pattern. */
222static __inline__ IRExpr *
223mkF64i(ULong value)
224{
225 return IRExpr_Const(IRConst_F64i(value));
226}
227
228/* Little helper function for my sanity. ITE = if-then-else */
229static IRExpr *
230mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
231{
232 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
233
florian99dd03e2013-01-29 03:56:06 +0000234 return IRExpr_ITE(condition, iftrue, iffalse);
sewardj2019a972011-03-07 16:04:07 +0000235}
236
237/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
florian54342272015-05-16 16:16:37 +0000238static __inline__ void
sewardj2019a972011-03-07 16:04:07 +0000239store(IRExpr *addr, IRExpr *data)
240{
241 stmt(IRStmt_Store(Iend_BE, addr, data));
242}
243
244/* Create an expression that loads a TYPE sized value from ADDR.
245 This is a big-endian machine. */
246static __inline__ IRExpr *
247load(IRType type, IRExpr *addr)
248{
249 return IRExpr_Load(Iend_BE, type, addr);
250}
251
252/* Function call */
253static void
254call_function(IRExpr *callee_address)
255{
florian8844a632012-04-13 04:04:06 +0000256 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000257
florian8844a632012-04-13 04:04:06 +0000258 dis_res->whatNext = Dis_StopHere;
259 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000260}
261
floriana64c2432011-07-16 02:11:50 +0000262/* Function call with known target. */
263static void
264call_function_and_chase(Addr64 callee_address)
265{
266 if (resteer_fn(resteer_data, callee_address)) {
267 dis_res->whatNext = Dis_ResteerU;
268 dis_res->continueAt = callee_address;
269 } else {
florian8844a632012-04-13 04:04:06 +0000270 put_IA(mkaddr_expr(callee_address));
271
floriana64c2432011-07-16 02:11:50 +0000272 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000273 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000274 }
275}
276
sewardj2019a972011-03-07 16:04:07 +0000277/* Function return sequence */
278static void
279return_from_function(IRExpr *return_address)
280{
florian8844a632012-04-13 04:04:06 +0000281 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000282
florian8844a632012-04-13 04:04:06 +0000283 dis_res->whatNext = Dis_StopHere;
284 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000285}
286
287/* A conditional branch whose target is not known at instrumentation time.
288
289 if (condition) goto computed_target;
290
291 Needs to be represented as:
292
293 if (! condition) goto next_instruction;
294 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000295*/
296static void
florianf321da72012-07-21 20:32:57 +0000297if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000298{
299 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
300
florianf321da72012-07-21 20:32:57 +0000301 condition = unop(Iop_Not1, condition);
302
florian8844a632012-04-13 04:04:06 +0000303 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
304 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000305
florian8844a632012-04-13 04:04:06 +0000306 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000307
florian8844a632012-04-13 04:04:06 +0000308 dis_res->whatNext = Dis_StopHere;
309 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000310}
311
312/* A conditional branch whose target is known at instrumentation time. */
313static void
314if_condition_goto(IRExpr *condition, Addr64 target)
315{
316 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
317
florian8844a632012-04-13 04:04:06 +0000318 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
319 S390X_GUEST_OFFSET(guest_IA)));
320
florian7346c7a2012-04-13 21:14:24 +0000321 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000322
323 dis_res->whatNext = Dis_StopHere;
324 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000325}
326
327/* An unconditional branch. Target may or may not be known at instrumentation
328 time. */
329static void
330always_goto(IRExpr *target)
331{
florian8844a632012-04-13 04:04:06 +0000332 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000333
florian8844a632012-04-13 04:04:06 +0000334 dis_res->whatNext = Dis_StopHere;
335 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000336}
337
florian8844a632012-04-13 04:04:06 +0000338
floriana64c2432011-07-16 02:11:50 +0000339/* An unconditional branch to a known target. */
340static void
341always_goto_and_chase(Addr64 target)
342{
343 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000344 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000345 dis_res->whatNext = Dis_ResteerU;
346 dis_res->continueAt = target;
347 } else {
florian8844a632012-04-13 04:04:06 +0000348 put_IA(mkaddr_expr(target));
349
350 dis_res->whatNext = Dis_StopHere;
351 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000352 }
353}
354
sewardj2019a972011-03-07 16:04:07 +0000355/* A system call */
356static void
357system_call(IRExpr *sysno)
358{
359 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000360 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000361
sewardj69007022011-04-28 20:13:45 +0000362 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000363 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
364 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000365
florian8844a632012-04-13 04:04:06 +0000366 put_IA(mkaddr_expr(guest_IA_next_instr));
367
sewardj2019a972011-03-07 16:04:07 +0000368 /* It's important that all ArchRegs carry their up-to-date value
369 at this point. So we declare an end-of-block here, which
370 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000371 dis_res->whatNext = Dis_StopHere;
372 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000373}
374
florian6820ba52012-07-26 02:01:50 +0000375/* A side exit that branches back to the current insn if CONDITION is
376 true. Does not set DisResult. */
377static void
378iterate_if(IRExpr *condition)
379{
380 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
381
382 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
383 S390X_GUEST_OFFSET(guest_IA)));
384}
385
386/* A side exit that branches back to the current insn.
387 Does not set DisResult. */
388static __inline__ void
389iterate(void)
390{
391 iterate_if(IRExpr_Const(IRConst_U1(True)));
392}
393
394/* A side exit that branches back to the insn immediately following the
395 current insn if CONDITION is true. Does not set DisResult. */
396static void
397next_insn_if(IRExpr *condition)
398{
399 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
400
401 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
402 S390X_GUEST_OFFSET(guest_IA)));
403}
404
405/* Convenience function to restart the current insn */
406static void
407restart_if(IRExpr *condition)
408{
409 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
410
sewardj05f5e012014-05-04 10:52:11 +0000411 stmt(IRStmt_Exit(condition, Ijk_InvalICache,
412 IRConst_U64(guest_IA_curr_instr),
florian6820ba52012-07-26 02:01:50 +0000413 S390X_GUEST_OFFSET(guest_IA)));
414}
415
416/* Convenience function to yield to thread scheduler */
417static void
418yield_if(IRExpr *condition)
419{
420 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
421 S390X_GUEST_OFFSET(guest_IA)));
422}
423
sewardj2019a972011-03-07 16:04:07 +0000424static __inline__ IRExpr *get_fpr_dw0(UInt);
425static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000426static __inline__ IRExpr *get_dpr_dw0(UInt);
427static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000428
429/* Read a floating point register pair and combine their contents into a
430 128-bit value */
431static IRExpr *
432get_fpr_pair(UInt archreg)
433{
434 IRExpr *high = get_fpr_dw0(archreg);
435 IRExpr *low = get_fpr_dw0(archreg + 2);
436
437 return binop(Iop_F64HLtoF128, high, low);
438}
439
440/* Write a 128-bit floating point value into a register pair. */
441static void
442put_fpr_pair(UInt archreg, IRExpr *expr)
443{
444 IRExpr *high = unop(Iop_F128HItoF64, expr);
445 IRExpr *low = unop(Iop_F128LOtoF64, expr);
446
447 put_fpr_dw0(archreg, high);
448 put_fpr_dw0(archreg + 2, low);
449}
450
floriane38f6412012-12-21 17:32:12 +0000451/* Read a floating point register pair cointaining DFP value
452 and combine their contents into a 128-bit value */
453
454static IRExpr *
455get_dpr_pair(UInt archreg)
456{
457 IRExpr *high = get_dpr_dw0(archreg);
458 IRExpr *low = get_dpr_dw0(archreg + 2);
459
460 return binop(Iop_D64HLtoD128, high, low);
461}
462
463/* Write a 128-bit decimal floating point value into a register pair. */
464static void
465put_dpr_pair(UInt archreg, IRExpr *expr)
466{
467 IRExpr *high = unop(Iop_D128HItoD64, expr);
468 IRExpr *low = unop(Iop_D128LOtoD64, expr);
469
470 put_dpr_dw0(archreg, high);
471 put_dpr_dw0(archreg + 2, low);
472}
473
floriane75dafa2012-09-01 17:54:09 +0000474/* Terminate the current IRSB with an emulation failure. */
475static void
florianafa3f042014-09-06 21:43:28 +0000476emulation_failure_with_expr(IRExpr *emfailure)
floriane75dafa2012-09-01 17:54:09 +0000477{
florianafa3f042014-09-06 21:43:28 +0000478 vassert(typeOfIRExpr(irsb->tyenv, emfailure) == Ity_I32);
479
480 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emfailure));
floriane75dafa2012-09-01 17:54:09 +0000481 dis_res->whatNext = Dis_StopHere;
482 dis_res->jk_StopHere = Ijk_EmFail;
483}
sewardj2019a972011-03-07 16:04:07 +0000484
florianafa3f042014-09-06 21:43:28 +0000485static void
486emulation_failure(VexEmNote fail_kind)
487{
488 emulation_failure_with_expr(mkU32(fail_kind));
489}
490
florian4b8efad2012-09-02 18:07:08 +0000491/* Terminate the current IRSB with an emulation warning. */
492static void
florianafa3f042014-09-06 21:43:28 +0000493emulation_warning_with_expr(IRExpr *emwarning)
494{
495 vassert(typeOfIRExpr(irsb->tyenv, emwarning) == Ity_I32);
496
497 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emwarning));
498 dis_res->whatNext = Dis_StopHere;
499 dis_res->jk_StopHere = Ijk_EmWarn;
500}
501
502static void
florian4b8efad2012-09-02 18:07:08 +0000503emulation_warning(VexEmNote warn_kind)
504{
florianafa3f042014-09-06 21:43:28 +0000505 emulation_warning_with_expr(mkU32(warn_kind));
florian4b8efad2012-09-02 18:07:08 +0000506}
507
sewardj2019a972011-03-07 16:04:07 +0000508/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000509/*--- IR Debugging aids. ---*/
510/*------------------------------------------------------------*/
511#if 0
512
513static ULong
514s390_do_print(HChar *text, ULong value)
515{
516 vex_printf("%s %llu\n", text, value);
517 return 0;
518}
519
520static void
521s390_print(HChar *text, IRExpr *value)
522{
523 IRDirty *d;
524
525 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
526 mkIRExprVec_2(mkU64((ULong)text), value));
527 stmt(IRStmt_Dirty(d));
528}
529#endif
530
531
532/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000533/*--- Build the flags thunk. ---*/
534/*------------------------------------------------------------*/
535
536/* Completely fill the flags thunk. We're always filling all fields.
537 Apparently, that is better for redundant PUT elimination. */
538static void
539s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
540{
541 UInt op_off, dep1_off, dep2_off, ndep_off;
542
florian428dfdd2012-03-27 03:09:49 +0000543 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
544 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
545 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
546 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000547
548 stmt(IRStmt_Put(op_off, op));
549 stmt(IRStmt_Put(dep1_off, dep1));
550 stmt(IRStmt_Put(dep2_off, dep2));
551 stmt(IRStmt_Put(ndep_off, ndep));
552}
553
554
555/* Create an expression for V and widen the result to 64 bit. */
556static IRExpr *
557s390_cc_widen(IRTemp v, Bool sign_extend)
558{
559 IRExpr *expr;
560
561 expr = mkexpr(v);
562
563 switch (typeOfIRTemp(irsb->tyenv, v)) {
564 case Ity_I64:
565 break;
566 case Ity_I32:
567 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
568 break;
569 case Ity_I16:
570 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
571 break;
572 case Ity_I8:
573 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
574 break;
575 default:
576 vpanic("s390_cc_widen");
577 }
578
579 return expr;
580}
581
582static void
583s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
584{
585 IRExpr *op, *dep1, *dep2, *ndep;
586
587 op = mkU64(opc);
588 dep1 = s390_cc_widen(d1, sign_extend);
589 dep2 = mkU64(0);
590 ndep = mkU64(0);
591
592 s390_cc_thunk_fill(op, dep1, dep2, ndep);
593}
594
595
596static void
597s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
598{
599 IRExpr *op, *dep1, *dep2, *ndep;
600
601 op = mkU64(opc);
602 dep1 = s390_cc_widen(d1, sign_extend);
603 dep2 = s390_cc_widen(d2, sign_extend);
604 ndep = mkU64(0);
605
606 s390_cc_thunk_fill(op, dep1, dep2, ndep);
607}
608
609
610/* memcheck believes that the NDEP field in the flags thunk is always
611 defined. But for some flag computations (e.g. add with carry) that is
612 just not true. We therefore need to convey to memcheck that the value
613 of the ndep field does matter and therefore we make the DEP2 field
614 depend on it:
615
616 DEP2 = original_DEP2 ^ NDEP
617
618 In s390_calculate_cc we exploit that (a^b)^b == a
619 I.e. we xor the DEP2 value with the NDEP value to recover the
620 original_DEP2 value. */
621static void
622s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
623{
624 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
625
626 op = mkU64(opc);
627 dep1 = s390_cc_widen(d1, sign_extend);
628 dep2 = s390_cc_widen(d2, sign_extend);
629 ndep = s390_cc_widen(nd, sign_extend);
630
631 dep2x = binop(Iop_Xor64, dep2, ndep);
632
633 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
634}
635
636
637/* Write one floating point value into the flags thunk */
638static void
639s390_cc_thunk_put1f(UInt opc, IRTemp d1)
640{
641 IRExpr *op, *dep1, *dep2, *ndep;
642
florianbafb8262013-05-31 15:41:55 +0000643 /* Make the CC_DEP1 slot appear completely defined.
644 Otherwise, assigning a 32-bit value will cause memcheck
645 to trigger an undefinedness error.
646 */
647 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
648 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
649 stmt(IRStmt_Put(dep1_off, mkU64(0)));
650 }
sewardj2019a972011-03-07 16:04:07 +0000651 op = mkU64(opc);
652 dep1 = mkexpr(d1);
653 dep2 = mkU64(0);
654 ndep = mkU64(0);
655
656 s390_cc_thunk_fill(op, dep1, dep2, ndep);
657}
658
659
660/* Write a floating point value and an integer into the flags thunk. The
661 integer value is zero-extended first. */
662static void
663s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
664{
665 IRExpr *op, *dep1, *dep2, *ndep;
666
florianbafb8262013-05-31 15:41:55 +0000667 /* Make the CC_DEP1 slot appear completely defined.
668 Otherwise, assigning a 32-bit value will cause memcheck
669 to trigger an undefinedness error.
670 */
671 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
672 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
673 stmt(IRStmt_Put(dep1_off, mkU64(0)));
674 }
sewardj2019a972011-03-07 16:04:07 +0000675 op = mkU64(opc);
676 dep1 = mkexpr(d1);
677 dep2 = s390_cc_widen(d2, False);
678 ndep = mkU64(0);
679
680 s390_cc_thunk_fill(op, dep1, dep2, ndep);
681}
682
683
684/* Write a 128-bit floating point value into the flags thunk. This is
685 done by splitting the value into two 64-bits values. */
686static void
687s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
688{
689 IRExpr *op, *hi, *lo, *ndep;
690
691 op = mkU64(opc);
692 hi = unop(Iop_F128HItoF64, mkexpr(d1));
693 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
694 ndep = mkU64(0);
695
696 s390_cc_thunk_fill(op, hi, lo, ndep);
697}
698
699
700/* Write a 128-bit floating point value and an integer into the flags thunk.
701 The integer value is zero-extended first. */
702static void
703s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
704{
705 IRExpr *op, *hi, *lo, *lox, *ndep;
706
707 op = mkU64(opc);
708 hi = unop(Iop_F128HItoF64, mkexpr(d1));
709 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
710 ndep = s390_cc_widen(nd, False);
711
712 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
713
714 s390_cc_thunk_fill(op, hi, lox, ndep);
715}
716
717
floriane38f6412012-12-21 17:32:12 +0000718/* Write a 128-bit decimal floating point value into the flags thunk.
719 This is done by splitting the value into two 64-bits values. */
720static void
721s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
722{
723 IRExpr *op, *hi, *lo, *ndep;
724
725 op = mkU64(opc);
726 hi = unop(Iop_D128HItoD64, mkexpr(d1));
727 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
728 ndep = mkU64(0);
729
730 s390_cc_thunk_fill(op, hi, lo, ndep);
731}
732
733
floriance9e3db2012-12-27 20:14:03 +0000734/* Write a 128-bit decimal floating point value and an integer into the flags
735 thunk. The integer value is zero-extended first. */
736static void
737s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
738{
739 IRExpr *op, *hi, *lo, *lox, *ndep;
740
741 op = mkU64(opc);
742 hi = unop(Iop_D128HItoD64, mkexpr(d1));
743 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
744 ndep = s390_cc_widen(nd, False);
745
746 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
747
748 s390_cc_thunk_fill(op, hi, lox, ndep);
749}
750
751
sewardj2019a972011-03-07 16:04:07 +0000752static void
753s390_cc_set(UInt val)
754{
755 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
756 mkU64(val), mkU64(0), mkU64(0));
757}
758
759/* Build IR to calculate the condition code from flags thunk.
760 Returns an expression of type Ity_I32 */
761static IRExpr *
762s390_call_calculate_cc(void)
763{
764 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
765
florian428dfdd2012-03-27 03:09:49 +0000766 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
767 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
768 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
769 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000770
771 args = mkIRExprVec_4(op, dep1, dep2, ndep);
772 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
773 "s390_calculate_cc", &s390_calculate_cc, args);
774
775 /* Exclude OP and NDEP from definedness checking. We're only
776 interested in DEP1 and DEP2. */
777 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
778
779 return call;
780}
781
782/* Build IR to calculate the internal condition code for a "compare and branch"
783 insn. Returns an expression of type Ity_I32 */
784static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000785s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000786{
florianff9613f2012-05-12 15:26:44 +0000787 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000788
florianff9613f2012-05-12 15:26:44 +0000789 switch (opc) {
790 case S390_CC_OP_SIGNED_COMPARE:
791 dep1 = s390_cc_widen(op1, True);
792 dep2 = s390_cc_widen(op2, True);
793 break;
794
795 case S390_CC_OP_UNSIGNED_COMPARE:
796 dep1 = s390_cc_widen(op1, False);
797 dep2 = s390_cc_widen(op2, False);
798 break;
799
800 default:
801 vpanic("s390_call_calculate_icc");
802 }
803
804 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000805 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000806
florianff9613f2012-05-12 15:26:44 +0000807 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000808 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000809 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000810
florianff9613f2012-05-12 15:26:44 +0000811 /* Exclude the requested condition, OP and NDEP from definedness
812 checking. We're only interested in DEP1 and DEP2. */
813 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000814
815 return call;
816}
817
818/* Build IR to calculate the condition code from flags thunk.
819 Returns an expression of type Ity_I32 */
820static IRExpr *
821s390_call_calculate_cond(UInt m)
822{
823 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
824
825 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000826 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
827 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
828 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
829 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000830
831 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
832 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
833 "s390_calculate_cond", &s390_calculate_cond, args);
834
835 /* Exclude the requested condition, OP and NDEP from definedness
836 checking. We're only interested in DEP1 and DEP2. */
837 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
838
839 return call;
840}
841
842#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
843#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
844#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
845#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
846#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
847#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
848#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
849 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
850#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
851 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000852
853
sewardj2019a972011-03-07 16:04:07 +0000854
855
856/*------------------------------------------------------------*/
857/*--- Guest register access ---*/
858/*------------------------------------------------------------*/
859
860
861/*------------------------------------------------------------*/
862/*--- ar registers ---*/
863/*------------------------------------------------------------*/
864
865/* Return the guest state offset of a ar register. */
866static UInt
867ar_offset(UInt archreg)
868{
869 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000870 S390X_GUEST_OFFSET(guest_a0),
871 S390X_GUEST_OFFSET(guest_a1),
872 S390X_GUEST_OFFSET(guest_a2),
873 S390X_GUEST_OFFSET(guest_a3),
874 S390X_GUEST_OFFSET(guest_a4),
875 S390X_GUEST_OFFSET(guest_a5),
876 S390X_GUEST_OFFSET(guest_a6),
877 S390X_GUEST_OFFSET(guest_a7),
878 S390X_GUEST_OFFSET(guest_a8),
879 S390X_GUEST_OFFSET(guest_a9),
880 S390X_GUEST_OFFSET(guest_a10),
881 S390X_GUEST_OFFSET(guest_a11),
882 S390X_GUEST_OFFSET(guest_a12),
883 S390X_GUEST_OFFSET(guest_a13),
884 S390X_GUEST_OFFSET(guest_a14),
885 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000886 };
887
888 vassert(archreg < 16);
889
890 return offset[archreg];
891}
892
893
894/* Return the guest state offset of word #0 of a ar register. */
895static __inline__ UInt
896ar_w0_offset(UInt archreg)
897{
898 return ar_offset(archreg) + 0;
899}
900
901/* Write word #0 of a ar to the guest state. */
902static __inline__ void
903put_ar_w0(UInt archreg, IRExpr *expr)
904{
905 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
906
907 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
908}
909
910/* Read word #0 of a ar register. */
911static __inline__ IRExpr *
912get_ar_w0(UInt archreg)
913{
914 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
915}
916
917
918/*------------------------------------------------------------*/
919/*--- fpr registers ---*/
920/*------------------------------------------------------------*/
921
922/* Return the guest state offset of a fpr register. */
923static UInt
924fpr_offset(UInt archreg)
925{
926 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000927 S390X_GUEST_OFFSET(guest_f0),
928 S390X_GUEST_OFFSET(guest_f1),
929 S390X_GUEST_OFFSET(guest_f2),
930 S390X_GUEST_OFFSET(guest_f3),
931 S390X_GUEST_OFFSET(guest_f4),
932 S390X_GUEST_OFFSET(guest_f5),
933 S390X_GUEST_OFFSET(guest_f6),
934 S390X_GUEST_OFFSET(guest_f7),
935 S390X_GUEST_OFFSET(guest_f8),
936 S390X_GUEST_OFFSET(guest_f9),
937 S390X_GUEST_OFFSET(guest_f10),
938 S390X_GUEST_OFFSET(guest_f11),
939 S390X_GUEST_OFFSET(guest_f12),
940 S390X_GUEST_OFFSET(guest_f13),
941 S390X_GUEST_OFFSET(guest_f14),
942 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000943 };
944
945 vassert(archreg < 16);
946
947 return offset[archreg];
948}
949
950
951/* Return the guest state offset of word #0 of a fpr register. */
952static __inline__ UInt
953fpr_w0_offset(UInt archreg)
954{
955 return fpr_offset(archreg) + 0;
956}
957
958/* Write word #0 of a fpr to the guest state. */
959static __inline__ void
960put_fpr_w0(UInt archreg, IRExpr *expr)
961{
962 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
963
964 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
965}
966
967/* Read word #0 of a fpr register. */
968static __inline__ IRExpr *
969get_fpr_w0(UInt archreg)
970{
971 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
972}
973
974/* Return the guest state offset of double word #0 of a fpr register. */
975static __inline__ UInt
976fpr_dw0_offset(UInt archreg)
977{
978 return fpr_offset(archreg) + 0;
979}
980
981/* Write double word #0 of a fpr to the guest state. */
982static __inline__ void
983put_fpr_dw0(UInt archreg, IRExpr *expr)
984{
985 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
986
987 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
988}
989
990/* Read double word #0 of a fpr register. */
991static __inline__ IRExpr *
992get_fpr_dw0(UInt archreg)
993{
994 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
995}
996
floriane38f6412012-12-21 17:32:12 +0000997/* Write word #0 of a dpr to the guest state. */
998static __inline__ void
999put_dpr_w0(UInt archreg, IRExpr *expr)
1000{
1001 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
1002
1003 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
1004}
1005
1006/* Read word #0 of a dpr register. */
1007static __inline__ IRExpr *
1008get_dpr_w0(UInt archreg)
1009{
1010 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
1011}
1012
florian12390202012-11-10 22:34:14 +00001013/* Write double word #0 of a fpr containg DFP value to the guest state. */
1014static __inline__ void
1015put_dpr_dw0(UInt archreg, IRExpr *expr)
1016{
1017 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
1018
1019 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1020}
1021
1022/* Read double word #0 of a fpr register containing DFP value. */
1023static __inline__ IRExpr *
1024get_dpr_dw0(UInt archreg)
1025{
1026 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1027}
sewardj2019a972011-03-07 16:04:07 +00001028
1029/*------------------------------------------------------------*/
1030/*--- gpr registers ---*/
1031/*------------------------------------------------------------*/
1032
1033/* Return the guest state offset of a gpr register. */
1034static UInt
1035gpr_offset(UInt archreg)
1036{
1037 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001038 S390X_GUEST_OFFSET(guest_r0),
1039 S390X_GUEST_OFFSET(guest_r1),
1040 S390X_GUEST_OFFSET(guest_r2),
1041 S390X_GUEST_OFFSET(guest_r3),
1042 S390X_GUEST_OFFSET(guest_r4),
1043 S390X_GUEST_OFFSET(guest_r5),
1044 S390X_GUEST_OFFSET(guest_r6),
1045 S390X_GUEST_OFFSET(guest_r7),
1046 S390X_GUEST_OFFSET(guest_r8),
1047 S390X_GUEST_OFFSET(guest_r9),
1048 S390X_GUEST_OFFSET(guest_r10),
1049 S390X_GUEST_OFFSET(guest_r11),
1050 S390X_GUEST_OFFSET(guest_r12),
1051 S390X_GUEST_OFFSET(guest_r13),
1052 S390X_GUEST_OFFSET(guest_r14),
1053 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001054 };
1055
1056 vassert(archreg < 16);
1057
1058 return offset[archreg];
1059}
1060
1061
1062/* Return the guest state offset of word #0 of a gpr register. */
1063static __inline__ UInt
1064gpr_w0_offset(UInt archreg)
1065{
1066 return gpr_offset(archreg) + 0;
1067}
1068
1069/* Write word #0 of a gpr to the guest state. */
1070static __inline__ void
1071put_gpr_w0(UInt archreg, IRExpr *expr)
1072{
1073 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1074
1075 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1076}
1077
1078/* Read word #0 of a gpr register. */
1079static __inline__ IRExpr *
1080get_gpr_w0(UInt archreg)
1081{
1082 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1083}
1084
1085/* Return the guest state offset of double word #0 of a gpr register. */
1086static __inline__ UInt
1087gpr_dw0_offset(UInt archreg)
1088{
1089 return gpr_offset(archreg) + 0;
1090}
1091
1092/* Write double word #0 of a gpr to the guest state. */
1093static __inline__ void
1094put_gpr_dw0(UInt archreg, IRExpr *expr)
1095{
1096 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1097
1098 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1099}
1100
1101/* Read double word #0 of a gpr register. */
1102static __inline__ IRExpr *
1103get_gpr_dw0(UInt archreg)
1104{
1105 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1106}
1107
1108/* Return the guest state offset of half word #1 of a gpr register. */
1109static __inline__ UInt
1110gpr_hw1_offset(UInt archreg)
1111{
1112 return gpr_offset(archreg) + 2;
1113}
1114
1115/* Write half word #1 of a gpr to the guest state. */
1116static __inline__ void
1117put_gpr_hw1(UInt archreg, IRExpr *expr)
1118{
1119 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1120
1121 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1122}
1123
1124/* Read half word #1 of a gpr register. */
1125static __inline__ IRExpr *
1126get_gpr_hw1(UInt archreg)
1127{
1128 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1129}
1130
1131/* Return the guest state offset of byte #6 of a gpr register. */
1132static __inline__ UInt
1133gpr_b6_offset(UInt archreg)
1134{
1135 return gpr_offset(archreg) + 6;
1136}
1137
1138/* Write byte #6 of a gpr to the guest state. */
1139static __inline__ void
1140put_gpr_b6(UInt archreg, IRExpr *expr)
1141{
1142 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1143
1144 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1145}
1146
1147/* Read byte #6 of a gpr register. */
1148static __inline__ IRExpr *
1149get_gpr_b6(UInt archreg)
1150{
1151 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1152}
1153
1154/* Return the guest state offset of byte #3 of a gpr register. */
1155static __inline__ UInt
1156gpr_b3_offset(UInt archreg)
1157{
1158 return gpr_offset(archreg) + 3;
1159}
1160
1161/* Write byte #3 of a gpr to the guest state. */
1162static __inline__ void
1163put_gpr_b3(UInt archreg, IRExpr *expr)
1164{
1165 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1166
1167 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1168}
1169
1170/* Read byte #3 of a gpr register. */
1171static __inline__ IRExpr *
1172get_gpr_b3(UInt archreg)
1173{
1174 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1175}
1176
1177/* Return the guest state offset of byte #0 of a gpr register. */
1178static __inline__ UInt
1179gpr_b0_offset(UInt archreg)
1180{
1181 return gpr_offset(archreg) + 0;
1182}
1183
1184/* Write byte #0 of a gpr to the guest state. */
1185static __inline__ void
1186put_gpr_b0(UInt archreg, IRExpr *expr)
1187{
1188 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1189
1190 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1191}
1192
1193/* Read byte #0 of a gpr register. */
1194static __inline__ IRExpr *
1195get_gpr_b0(UInt archreg)
1196{
1197 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1198}
1199
1200/* Return the guest state offset of word #1 of a gpr register. */
1201static __inline__ UInt
1202gpr_w1_offset(UInt archreg)
1203{
1204 return gpr_offset(archreg) + 4;
1205}
1206
1207/* Write word #1 of a gpr to the guest state. */
1208static __inline__ void
1209put_gpr_w1(UInt archreg, IRExpr *expr)
1210{
1211 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1212
1213 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1214}
1215
1216/* Read word #1 of a gpr register. */
1217static __inline__ IRExpr *
1218get_gpr_w1(UInt archreg)
1219{
1220 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1221}
1222
1223/* Return the guest state offset of half word #3 of a gpr register. */
1224static __inline__ UInt
1225gpr_hw3_offset(UInt archreg)
1226{
1227 return gpr_offset(archreg) + 6;
1228}
1229
1230/* Write half word #3 of a gpr to the guest state. */
1231static __inline__ void
1232put_gpr_hw3(UInt archreg, IRExpr *expr)
1233{
1234 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1235
1236 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1237}
1238
1239/* Read half word #3 of a gpr register. */
1240static __inline__ IRExpr *
1241get_gpr_hw3(UInt archreg)
1242{
1243 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1244}
1245
1246/* Return the guest state offset of byte #7 of a gpr register. */
1247static __inline__ UInt
1248gpr_b7_offset(UInt archreg)
1249{
1250 return gpr_offset(archreg) + 7;
1251}
1252
1253/* Write byte #7 of a gpr to the guest state. */
1254static __inline__ void
1255put_gpr_b7(UInt archreg, IRExpr *expr)
1256{
1257 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1258
1259 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1260}
1261
1262/* Read byte #7 of a gpr register. */
1263static __inline__ IRExpr *
1264get_gpr_b7(UInt archreg)
1265{
1266 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1267}
1268
1269/* Return the guest state offset of half word #0 of a gpr register. */
1270static __inline__ UInt
1271gpr_hw0_offset(UInt archreg)
1272{
1273 return gpr_offset(archreg) + 0;
1274}
1275
1276/* Write half word #0 of a gpr to the guest state. */
1277static __inline__ void
1278put_gpr_hw0(UInt archreg, IRExpr *expr)
1279{
1280 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1281
1282 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1283}
1284
1285/* Read half word #0 of a gpr register. */
1286static __inline__ IRExpr *
1287get_gpr_hw0(UInt archreg)
1288{
1289 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1290}
1291
1292/* Return the guest state offset of byte #4 of a gpr register. */
1293static __inline__ UInt
1294gpr_b4_offset(UInt archreg)
1295{
1296 return gpr_offset(archreg) + 4;
1297}
1298
1299/* Write byte #4 of a gpr to the guest state. */
1300static __inline__ void
1301put_gpr_b4(UInt archreg, IRExpr *expr)
1302{
1303 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1304
1305 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1306}
1307
1308/* Read byte #4 of a gpr register. */
1309static __inline__ IRExpr *
1310get_gpr_b4(UInt archreg)
1311{
1312 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1313}
1314
1315/* Return the guest state offset of byte #1 of a gpr register. */
1316static __inline__ UInt
1317gpr_b1_offset(UInt archreg)
1318{
1319 return gpr_offset(archreg) + 1;
1320}
1321
1322/* Write byte #1 of a gpr to the guest state. */
1323static __inline__ void
1324put_gpr_b1(UInt archreg, IRExpr *expr)
1325{
1326 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1327
1328 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1329}
1330
1331/* Read byte #1 of a gpr register. */
1332static __inline__ IRExpr *
1333get_gpr_b1(UInt archreg)
1334{
1335 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1336}
1337
1338/* Return the guest state offset of half word #2 of a gpr register. */
1339static __inline__ UInt
1340gpr_hw2_offset(UInt archreg)
1341{
1342 return gpr_offset(archreg) + 4;
1343}
1344
1345/* Write half word #2 of a gpr to the guest state. */
1346static __inline__ void
1347put_gpr_hw2(UInt archreg, IRExpr *expr)
1348{
1349 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1350
1351 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1352}
1353
1354/* Read half word #2 of a gpr register. */
1355static __inline__ IRExpr *
1356get_gpr_hw2(UInt archreg)
1357{
1358 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1359}
1360
1361/* Return the guest state offset of byte #5 of a gpr register. */
1362static __inline__ UInt
1363gpr_b5_offset(UInt archreg)
1364{
1365 return gpr_offset(archreg) + 5;
1366}
1367
1368/* Write byte #5 of a gpr to the guest state. */
1369static __inline__ void
1370put_gpr_b5(UInt archreg, IRExpr *expr)
1371{
1372 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1373
1374 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1375}
1376
1377/* Read byte #5 of a gpr register. */
1378static __inline__ IRExpr *
1379get_gpr_b5(UInt archreg)
1380{
1381 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1382}
1383
1384/* Return the guest state offset of byte #2 of a gpr register. */
1385static __inline__ UInt
1386gpr_b2_offset(UInt archreg)
1387{
1388 return gpr_offset(archreg) + 2;
1389}
1390
1391/* Write byte #2 of a gpr to the guest state. */
1392static __inline__ void
1393put_gpr_b2(UInt archreg, IRExpr *expr)
1394{
1395 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1396
1397 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1398}
1399
1400/* Read byte #2 of a gpr register. */
1401static __inline__ IRExpr *
1402get_gpr_b2(UInt archreg)
1403{
1404 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1405}
1406
1407/* Return the guest state offset of the counter register. */
1408static UInt
1409counter_offset(void)
1410{
floriane88b3c92011-07-05 02:48:39 +00001411 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001412}
1413
1414/* Return the guest state offset of double word #0 of the counter register. */
1415static __inline__ UInt
1416counter_dw0_offset(void)
1417{
1418 return counter_offset() + 0;
1419}
1420
1421/* Write double word #0 of the counter to the guest state. */
1422static __inline__ void
1423put_counter_dw0(IRExpr *expr)
1424{
1425 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1426
1427 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1428}
1429
1430/* Read double word #0 of the counter register. */
1431static __inline__ IRExpr *
1432get_counter_dw0(void)
1433{
1434 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1435}
1436
1437/* Return the guest state offset of word #0 of the counter register. */
1438static __inline__ UInt
1439counter_w0_offset(void)
1440{
1441 return counter_offset() + 0;
1442}
1443
1444/* Return the guest state offset of word #1 of the counter register. */
1445static __inline__ UInt
1446counter_w1_offset(void)
1447{
1448 return counter_offset() + 4;
1449}
1450
1451/* Write word #0 of the counter to the guest state. */
1452static __inline__ void
1453put_counter_w0(IRExpr *expr)
1454{
1455 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1456
1457 stmt(IRStmt_Put(counter_w0_offset(), expr));
1458}
1459
1460/* Read word #0 of the counter register. */
1461static __inline__ IRExpr *
1462get_counter_w0(void)
1463{
1464 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1465}
1466
1467/* Write word #1 of the counter to the guest state. */
1468static __inline__ void
1469put_counter_w1(IRExpr *expr)
1470{
1471 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1472
1473 stmt(IRStmt_Put(counter_w1_offset(), expr));
1474}
1475
1476/* Read word #1 of the counter register. */
1477static __inline__ IRExpr *
1478get_counter_w1(void)
1479{
1480 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1481}
1482
1483/* Return the guest state offset of the fpc register. */
1484static UInt
1485fpc_offset(void)
1486{
floriane88b3c92011-07-05 02:48:39 +00001487 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001488}
1489
1490/* Return the guest state offset of word #0 of the fpc register. */
1491static __inline__ UInt
1492fpc_w0_offset(void)
1493{
1494 return fpc_offset() + 0;
1495}
1496
1497/* Write word #0 of the fpc to the guest state. */
1498static __inline__ void
1499put_fpc_w0(IRExpr *expr)
1500{
1501 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1502
1503 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1504}
1505
1506/* Read word #0 of the fpc register. */
1507static __inline__ IRExpr *
1508get_fpc_w0(void)
1509{
1510 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1511}
1512
1513
1514/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001515/*--- Rounding modes ---*/
1516/*------------------------------------------------------------*/
1517
florian125e20d2012-10-07 15:42:37 +00001518/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001519 IRRoundingMode:
1520
1521 rounding mode | s390 | IR
1522 -------------------------
1523 to nearest | 00 | 00
1524 to zero | 01 | 11
1525 to +infinity | 10 | 10
1526 to -infinity | 11 | 01
1527
1528 So: IR = (4 - s390) & 3
1529*/
1530static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001531get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001532{
1533 IRTemp fpc_bits = newTemp(Ity_I32);
1534
1535 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1536 Prior to that bits [30:31] contained the bfp rounding mode with
1537 bit 29 being unused and having a value of 0. So we can always
1538 extract the least significant 3 bits. */
1539 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1540
1541 /* fixs390:
1542
1543
1544 if (! s390_host_has_fpext && rounding_mode > 3) {
1545 emulation warning @ runtime and
1546 set fpc to round nearest
1547 }
1548 */
1549
1550 /* For now silently adjust an unsupported rounding mode to "nearest" */
1551 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1552 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001553 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001554
1555 // rm_IR = (4 - rm_s390) & 3;
1556 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1557}
1558
1559/* Encode the s390 rounding mode as it appears in the m3 field of certain
1560 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1561 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1562 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1563 considers the default rounding mode (4.3.3). */
1564static IRTemp
1565encode_bfp_rounding_mode(UChar mode)
1566{
1567 IRExpr *rm;
1568
1569 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001570 case S390_BFP_ROUND_PER_FPC:
1571 rm = get_bfp_rounding_mode_from_fpc();
1572 break;
1573 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1574 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1575 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1576 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1577 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1578 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001579 default:
1580 vpanic("encode_bfp_rounding_mode");
1581 }
1582
1583 return mktemp(Ity_I32, rm);
1584}
1585
florianc8e4f562012-10-27 16:19:31 +00001586/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1587 IRRoundingMode:
1588
1589 rounding mode | s390 | IR
1590 ------------------------------------------------
1591 to nearest, ties to even | 000 | 000
1592 to zero | 001 | 011
1593 to +infinity | 010 | 010
1594 to -infinity | 011 | 001
1595 to nearest, ties away from 0 | 100 | 100
1596 to nearest, ties toward 0 | 101 | 111
1597 to away from 0 | 110 | 110
1598 to prepare for shorter precision | 111 | 101
1599
1600 So: IR = (s390 ^ ((s390 << 1) & 2))
1601*/
florianc8e4f562012-10-27 16:19:31 +00001602static IRExpr *
1603get_dfp_rounding_mode_from_fpc(void)
1604{
1605 IRTemp fpc_bits = newTemp(Ity_I32);
1606
1607 /* The dfp rounding mode is stored in bits [25:27].
1608 extract the bits at 25:27 and right shift 4 times. */
1609 assign(fpc_bits, binop(Iop_Shr32,
1610 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1611 mkU8(4)));
1612
1613 IRExpr *rm_s390 = mkexpr(fpc_bits);
1614 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1615
1616 return binop(Iop_Xor32, rm_s390,
1617 binop( Iop_And32,
1618 binop(Iop_Shl32, rm_s390, mkU8(1)),
1619 mkU32(2)));
1620}
1621
1622/* Encode the s390 rounding mode as it appears in the m3 field of certain
1623 instructions to VEX's IRRoundingMode. */
1624static IRTemp
1625encode_dfp_rounding_mode(UChar mode)
1626{
1627 IRExpr *rm;
1628
1629 switch (mode) {
1630 case S390_DFP_ROUND_PER_FPC_0:
1631 case S390_DFP_ROUND_PER_FPC_2:
1632 rm = get_dfp_rounding_mode_from_fpc(); break;
1633 case S390_DFP_ROUND_NEAREST_EVEN_4:
1634 case S390_DFP_ROUND_NEAREST_EVEN_8:
florian79e5a482013-06-06 19:12:46 +00001635 rm = mkU32(Irrm_NEAREST); break;
florianc8e4f562012-10-27 16:19:31 +00001636 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1637 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
florian79e5a482013-06-06 19:12:46 +00001638 rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
florianc8e4f562012-10-27 16:19:31 +00001639 case S390_DFP_ROUND_PREPARE_SHORT_3:
1640 case S390_DFP_ROUND_PREPARE_SHORT_15:
florian79e5a482013-06-06 19:12:46 +00001641 rm = mkU32(Irrm_PREPARE_SHORTER); break;
florianc8e4f562012-10-27 16:19:31 +00001642 case S390_DFP_ROUND_ZERO_5:
1643 case S390_DFP_ROUND_ZERO_9:
florian79e5a482013-06-06 19:12:46 +00001644 rm = mkU32(Irrm_ZERO ); break;
florianc8e4f562012-10-27 16:19:31 +00001645 case S390_DFP_ROUND_POSINF_6:
1646 case S390_DFP_ROUND_POSINF_10:
florian79e5a482013-06-06 19:12:46 +00001647 rm = mkU32(Irrm_PosINF); break;
florianc8e4f562012-10-27 16:19:31 +00001648 case S390_DFP_ROUND_NEGINF_7:
1649 case S390_DFP_ROUND_NEGINF_11:
florian79e5a482013-06-06 19:12:46 +00001650 rm = mkU32(Irrm_NegINF); break;
florianc8e4f562012-10-27 16:19:31 +00001651 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
florian79e5a482013-06-06 19:12:46 +00001652 rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
florianc8e4f562012-10-27 16:19:31 +00001653 case S390_DFP_ROUND_AWAY_0:
florian79e5a482013-06-06 19:12:46 +00001654 rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
florianc8e4f562012-10-27 16:19:31 +00001655 default:
1656 vpanic("encode_dfp_rounding_mode");
1657 }
1658
1659 return mktemp(Ity_I32, rm);
1660}
florian12390202012-11-10 22:34:14 +00001661
florianc8e4f562012-10-27 16:19:31 +00001662
florian2c74d242012-09-12 19:38:42 +00001663/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001664/*--- Condition code helpers ---*/
1665/*------------------------------------------------------------*/
1666
1667/* The result of a Iop_CmpFxx operation is a condition code. It is
1668 encoded using the values defined in type IRCmpFxxResult.
1669 Before we can store the condition code into the guest state (or do
1670 anything else with it for that matter) we need to convert it to
1671 the encoding that s390 uses. This is what this function does.
1672
1673 s390 VEX b6 b2 b0 cc.1 cc.0
1674 0 0x40 EQ 1 0 0 0 0
1675 1 0x01 LT 0 0 1 0 1
1676 2 0x00 GT 0 0 0 1 0
1677 3 0x45 Unordered 1 1 1 1 1
1678
1679 The following bits from the VEX encoding are interesting:
1680 b0, b2, b6 with b0 being the LSB. We observe:
1681
1682 cc.0 = b0;
1683 cc.1 = b2 | (~b0 & ~b6)
1684
1685 with cc being the s390 condition code.
1686*/
1687static IRExpr *
1688convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1689{
1690 IRTemp cc0 = newTemp(Ity_I32);
1691 IRTemp cc1 = newTemp(Ity_I32);
1692 IRTemp b0 = newTemp(Ity_I32);
1693 IRTemp b2 = newTemp(Ity_I32);
1694 IRTemp b6 = newTemp(Ity_I32);
1695
1696 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1697 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1698 mkU32(1)));
1699 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1700 mkU32(1)));
1701
1702 assign(cc0, mkexpr(b0));
1703 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1704 binop(Iop_And32,
1705 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1706 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1707 )));
1708
1709 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1710}
1711
1712
1713/* The result of a Iop_CmpDxx operation is a condition code. It is
1714 encoded using the values defined in type IRCmpDxxResult.
1715 Before we can store the condition code into the guest state (or do
1716 anything else with it for that matter) we need to convert it to
1717 the encoding that s390 uses. This is what this function does. */
1718static IRExpr *
1719convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1720{
1721 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1722 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001723 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001724}
1725
1726
1727/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001728/*--- Build IR for formats ---*/
1729/*------------------------------------------------------------*/
1730static void
florian55085f82012-11-21 00:36:55 +00001731s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001732 UChar i)
1733{
florian55085f82012-11-21 00:36:55 +00001734 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001735
sewardj7ee97522011-05-09 21:45:04 +00001736 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001737 s390_disasm(ENC2(MNM, UINT), mnm, i);
1738}
1739
1740static void
florian78d5ef72013-05-11 15:02:58 +00001741s390_format_E(const HChar *(*irgen)(void))
1742{
1743 const HChar *mnm = irgen();
1744
1745 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1746 s390_disasm(ENC1(MNM), mnm);
1747}
1748
1749static void
florian55085f82012-11-21 00:36:55 +00001750s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001751 UChar r1, UShort i2)
1752{
1753 irgen(r1, i2);
1754}
1755
1756static void
florian55085f82012-11-21 00:36:55 +00001757s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001758 UChar r1, UShort i2)
1759{
florian55085f82012-11-21 00:36:55 +00001760 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001761
sewardj7ee97522011-05-09 21:45:04 +00001762 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001763 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1764}
1765
1766static void
florian55085f82012-11-21 00:36:55 +00001767s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001768 UChar r1, UShort i2)
1769{
florian55085f82012-11-21 00:36:55 +00001770 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001771
sewardj7ee97522011-05-09 21:45:04 +00001772 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001773 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1774}
1775
1776static void
florian55085f82012-11-21 00:36:55 +00001777s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001778 UChar r1, UShort i2)
1779{
florian55085f82012-11-21 00:36:55 +00001780 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001781
sewardj7ee97522011-05-09 21:45:04 +00001782 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001783 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1784}
1785
1786static void
florian55085f82012-11-21 00:36:55 +00001787s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001788 UChar r1, UChar r3, UShort i2)
1789{
florian55085f82012-11-21 00:36:55 +00001790 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001791
sewardj7ee97522011-05-09 21:45:04 +00001792 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001793 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1794}
1795
1796static void
florian55085f82012-11-21 00:36:55 +00001797s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001798 UChar r1, UChar r3, UShort i2)
1799{
florian55085f82012-11-21 00:36:55 +00001800 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001801
sewardj7ee97522011-05-09 21:45:04 +00001802 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001803 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1804}
1805
1806static void
florian55085f82012-11-21 00:36:55 +00001807s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1808 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001809 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1810{
florian55085f82012-11-21 00:36:55 +00001811 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001812
sewardj7ee97522011-05-09 21:45:04 +00001813 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001814 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1815 i5);
1816}
1817
1818static void
florian55085f82012-11-21 00:36:55 +00001819s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1820 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001821 UChar r1, UChar r2, UShort i4, UChar m3)
1822{
florian55085f82012-11-21 00:36:55 +00001823 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001824
sewardj7ee97522011-05-09 21:45:04 +00001825 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001826 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1827 r2, m3, (Int)(Short)i4);
1828}
1829
1830static void
florian55085f82012-11-21 00:36:55 +00001831s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1832 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001833 UChar r1, UChar m3, UShort i4, UChar i2)
1834{
florian55085f82012-11-21 00:36:55 +00001835 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001836
sewardj7ee97522011-05-09 21:45:04 +00001837 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001838 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1839 r1, i2, m3, (Int)(Short)i4);
1840}
1841
1842static void
florian55085f82012-11-21 00:36:55 +00001843s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1844 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001845 UChar r1, UChar m3, UShort i4, UChar i2)
1846{
florian55085f82012-11-21 00:36:55 +00001847 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001848
sewardj7ee97522011-05-09 21:45:04 +00001849 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001850 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1851 (Int)(Char)i2, m3, (Int)(Short)i4);
1852}
1853
1854static void
florian55085f82012-11-21 00:36:55 +00001855s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001856 UChar r1, UInt i2)
1857{
1858 irgen(r1, i2);
1859}
1860
1861static void
florian55085f82012-11-21 00:36:55 +00001862s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001863 UChar r1, UInt i2)
1864{
florian55085f82012-11-21 00:36:55 +00001865 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001866
sewardj7ee97522011-05-09 21:45:04 +00001867 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001868 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1869}
1870
1871static void
florian55085f82012-11-21 00:36:55 +00001872s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001873 UChar r1, UInt i2)
1874{
florian55085f82012-11-21 00:36:55 +00001875 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001876
sewardj7ee97522011-05-09 21:45:04 +00001877 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001878 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1879}
1880
1881static void
florian55085f82012-11-21 00:36:55 +00001882s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001883 UChar r1, UInt i2)
1884{
florian55085f82012-11-21 00:36:55 +00001885 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001886
sewardj7ee97522011-05-09 21:45:04 +00001887 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001888 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1889}
1890
1891static void
florian55085f82012-11-21 00:36:55 +00001892s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001893 UChar r1, UInt i2)
1894{
florian55085f82012-11-21 00:36:55 +00001895 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001896
sewardj7ee97522011-05-09 21:45:04 +00001897 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001898 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1899}
1900
1901static void
florian55085f82012-11-21 00:36:55 +00001902s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001903 IRTemp op4addr),
1904 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1905{
florian55085f82012-11-21 00:36:55 +00001906 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001907 IRTemp op4addr = newTemp(Ity_I64);
1908
1909 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1910 mkU64(0)));
1911
1912 mnm = irgen(r1, m3, i2, op4addr);
1913
sewardj7ee97522011-05-09 21:45:04 +00001914 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001915 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1916 (Int)(Char)i2, m3, d4, 0, b4);
1917}
1918
1919static void
florian55085f82012-11-21 00:36:55 +00001920s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001921 IRTemp op4addr),
1922 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1923{
florian55085f82012-11-21 00:36:55 +00001924 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001925 IRTemp op4addr = newTemp(Ity_I64);
1926
1927 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1928 mkU64(0)));
1929
1930 mnm = irgen(r1, m3, i2, op4addr);
1931
sewardj7ee97522011-05-09 21:45:04 +00001932 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001933 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1934 i2, m3, d4, 0, b4);
1935}
1936
1937static void
florian55085f82012-11-21 00:36:55 +00001938s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001939 UChar r1, UChar r2)
1940{
1941 irgen(r1, r2);
1942}
1943
1944static void
florian55085f82012-11-21 00:36:55 +00001945s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001946 UChar r1, UChar r2)
1947{
florian55085f82012-11-21 00:36:55 +00001948 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001949
sewardj7ee97522011-05-09 21:45:04 +00001950 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001951 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1952}
1953
1954static void
florian55085f82012-11-21 00:36:55 +00001955s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001956 UChar r1, UChar r2)
1957{
florian55085f82012-11-21 00:36:55 +00001958 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001959
sewardj7ee97522011-05-09 21:45:04 +00001960 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001961 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1962}
1963
1964static void
florian55085f82012-11-21 00:36:55 +00001965s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001966 UChar r1, UChar r2)
1967{
1968 irgen(r1, r2);
1969}
1970
1971static void
florian55085f82012-11-21 00:36:55 +00001972s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001973 UChar r1, UChar r2)
1974{
florian55085f82012-11-21 00:36:55 +00001975 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001976
sewardj7ee97522011-05-09 21:45:04 +00001977 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001978 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1979}
1980
1981static void
florian55085f82012-11-21 00:36:55 +00001982s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001983 UChar r1, UChar r2)
1984{
florian55085f82012-11-21 00:36:55 +00001985 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001986
sewardj7ee97522011-05-09 21:45:04 +00001987 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001988 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1989}
1990
1991static void
florian55085f82012-11-21 00:36:55 +00001992s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001993 UChar r1, UChar r2)
1994{
florian55085f82012-11-21 00:36:55 +00001995 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001996
sewardj7ee97522011-05-09 21:45:04 +00001997 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001998 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1999}
2000
2001static void
florian55085f82012-11-21 00:36:55 +00002002s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002003 UChar r1, UChar r2)
2004{
florian55085f82012-11-21 00:36:55 +00002005 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002006
sewardj7ee97522011-05-09 21:45:04 +00002007 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002008 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
2009}
2010
2011static void
florian55085f82012-11-21 00:36:55 +00002012s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002013 UChar r1)
2014{
florian55085f82012-11-21 00:36:55 +00002015 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002016
sewardj7ee97522011-05-09 21:45:04 +00002017 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002018 s390_disasm(ENC2(MNM, GPR), mnm, r1);
2019}
2020
2021static void
florian55085f82012-11-21 00:36:55 +00002022s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002023 UChar r1)
2024{
florian55085f82012-11-21 00:36:55 +00002025 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002026
sewardj7ee97522011-05-09 21:45:04 +00002027 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002028 s390_disasm(ENC2(MNM, FPR), mnm, r1);
2029}
2030
2031static void
florian55085f82012-11-21 00:36:55 +00002032s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002033 UChar m3, UChar r1, UChar r2)
2034{
florian55085f82012-11-21 00:36:55 +00002035 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002036
2037 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002038 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002039}
2040
2041static void
florian55085f82012-11-21 00:36:55 +00002042s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002043 UChar r1, UChar r3, UChar r2)
2044{
florian55085f82012-11-21 00:36:55 +00002045 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002046
sewardj7ee97522011-05-09 21:45:04 +00002047 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002048 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2049}
2050
2051static void
florian5c539732013-02-14 14:27:12 +00002052s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2053 UChar r3, UChar r1, UChar r2)
2054{
2055 const HChar *mnm = irgen(r3, r1, r2);
2056
2057 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2058 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2059}
2060
2061static void
florian55085f82012-11-21 00:36:55 +00002062s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2063 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002064 UChar m3, UChar m4, UChar r1, UChar r2)
2065{
florian55085f82012-11-21 00:36:55 +00002066 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002067
2068 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2069 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2070}
2071
2072static void
floriane38f6412012-12-21 17:32:12 +00002073s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2074 UChar m4, UChar r1, UChar r2)
2075{
2076 const HChar *mnm = irgen(m4, r1, r2);
2077
2078 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2079 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2080}
2081
2082static void
florian55085f82012-11-21 00:36:55 +00002083s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2084 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002085 UChar m3, UChar m4, UChar r1, UChar r2)
2086{
florian55085f82012-11-21 00:36:55 +00002087 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002088
2089 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2090 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2091}
2092
2093static void
florian55085f82012-11-21 00:36:55 +00002094s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2095 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002096 UChar m3, UChar m4, UChar r1, UChar r2)
2097{
florian55085f82012-11-21 00:36:55 +00002098 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002099
2100 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2101 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2102}
2103
2104
2105static void
florian55085f82012-11-21 00:36:55 +00002106s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002107 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2108{
2109 irgen(m3, r1, r2);
2110
sewardj7ee97522011-05-09 21:45:04 +00002111 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002112 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2113}
2114
2115static void
florian55085f82012-11-21 00:36:55 +00002116s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002117 UChar r3, UChar r1, UChar r2)
2118{
florian55085f82012-11-21 00:36:55 +00002119 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002120
sewardj7ee97522011-05-09 21:45:04 +00002121 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002122 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2123}
2124
2125static void
florian5c539732013-02-14 14:27:12 +00002126s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2127 UChar r3, UChar m4, UChar r1, UChar r2)
2128{
2129 const HChar *mnm = irgen(r3, m4, r1, r2);
2130
2131 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2132 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2133}
2134
2135static void
2136s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2137 UChar r3, UChar m4, UChar r1, UChar r2)
2138{
2139 const HChar *mnm = irgen(r3, m4, r1, r2);
2140
2141 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2142 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2143}
2144
2145static void
florian55085f82012-11-21 00:36:55 +00002146s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002147 UChar r3, UChar m4, UChar r1, UChar r2)
2148{
florian55085f82012-11-21 00:36:55 +00002149 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002150
2151 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2152 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2153}
2154
2155static void
florian55085f82012-11-21 00:36:55 +00002156s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002157 UChar r3, UChar r1, UChar r2)
2158{
florian55085f82012-11-21 00:36:55 +00002159 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002160
sewardj7ee97522011-05-09 21:45:04 +00002161 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002162 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2163}
2164
2165static void
florian55085f82012-11-21 00:36:55 +00002166s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2167 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002168 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2169{
florian55085f82012-11-21 00:36:55 +00002170 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002171 IRTemp op4addr = newTemp(Ity_I64);
2172
2173 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2174 mkU64(0)));
2175
2176 mnm = irgen(r1, r2, m3, op4addr);
2177
sewardj7ee97522011-05-09 21:45:04 +00002178 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002179 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2180 r2, m3, d4, 0, b4);
2181}
2182
2183static void
florian55085f82012-11-21 00:36:55 +00002184s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002185 UChar r1, UChar b2, UShort d2)
2186{
florian55085f82012-11-21 00:36:55 +00002187 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002188 IRTemp op2addr = newTemp(Ity_I64);
2189
2190 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2191 mkU64(0)));
2192
2193 mnm = irgen(r1, op2addr);
2194
sewardj7ee97522011-05-09 21:45:04 +00002195 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002196 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2197}
2198
2199static void
florian55085f82012-11-21 00:36:55 +00002200s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002201 UChar r1, UChar r3, UChar b2, UShort d2)
2202{
florian55085f82012-11-21 00:36:55 +00002203 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002204 IRTemp op2addr = newTemp(Ity_I64);
2205
2206 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2207 mkU64(0)));
2208
2209 mnm = irgen(r1, r3, op2addr);
2210
sewardj7ee97522011-05-09 21:45:04 +00002211 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002212 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2213}
2214
2215static void
florian55085f82012-11-21 00:36:55 +00002216s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002217 UChar r1, UChar r3, UChar b2, UShort d2)
2218{
florian55085f82012-11-21 00:36:55 +00002219 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002220 IRTemp op2addr = newTemp(Ity_I64);
2221
2222 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2223 mkU64(0)));
2224
2225 mnm = irgen(r1, r3, op2addr);
2226
sewardj7ee97522011-05-09 21:45:04 +00002227 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002228 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2229}
2230
2231static void
florian55085f82012-11-21 00:36:55 +00002232s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002233 UChar r1, UChar r3, UChar b2, UShort d2)
2234{
florian55085f82012-11-21 00:36:55 +00002235 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002236 IRTemp op2addr = newTemp(Ity_I64);
2237
2238 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2239 mkU64(0)));
2240
2241 mnm = irgen(r1, r3, op2addr);
2242
sewardj7ee97522011-05-09 21:45:04 +00002243 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002244 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2245}
2246
2247static void
florian55085f82012-11-21 00:36:55 +00002248s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002249 UChar r1, UChar r3, UShort i2)
2250{
florian55085f82012-11-21 00:36:55 +00002251 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002252
sewardj7ee97522011-05-09 21:45:04 +00002253 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002254 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2255}
2256
2257static void
florian55085f82012-11-21 00:36:55 +00002258s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002259 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2260{
florian55085f82012-11-21 00:36:55 +00002261 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002262 IRTemp op2addr = newTemp(Ity_I64);
2263 IRTemp d2 = newTemp(Ity_I64);
2264
2265 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2266 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2267 mkU64(0)));
2268
2269 mnm = irgen(r1, r3, op2addr);
2270
sewardj7ee97522011-05-09 21:45:04 +00002271 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002272 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2273}
2274
2275static void
florian55085f82012-11-21 00:36:55 +00002276s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002277 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2278{
florian55085f82012-11-21 00:36:55 +00002279 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002280 IRTemp op2addr = newTemp(Ity_I64);
2281 IRTemp d2 = newTemp(Ity_I64);
2282
2283 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2284 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2285 mkU64(0)));
2286
2287 mnm = irgen(r1, r3, op2addr);
2288
sewardj7ee97522011-05-09 21:45:04 +00002289 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002290 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2291}
2292
2293static void
florian55085f82012-11-21 00:36:55 +00002294s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002295 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2296{
florian55085f82012-11-21 00:36:55 +00002297 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002298 IRTemp op2addr = newTemp(Ity_I64);
2299 IRTemp d2 = newTemp(Ity_I64);
2300
2301 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2302 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2303 mkU64(0)));
2304
2305 mnm = irgen(r1, r3, op2addr);
2306
sewardj7ee97522011-05-09 21:45:04 +00002307 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002308 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2309}
2310
2311static void
florian55085f82012-11-21 00:36:55 +00002312s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002313 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2314 Int xmnm_kind)
2315{
2316 IRTemp op2addr = newTemp(Ity_I64);
2317 IRTemp d2 = newTemp(Ity_I64);
2318
florian6820ba52012-07-26 02:01:50 +00002319 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2320
sewardjd7bde722011-04-05 13:19:33 +00002321 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2322 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2323 mkU64(0)));
2324
2325 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002326
2327 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002328
sewardj7ee97522011-05-09 21:45:04 +00002329 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002330 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2331}
2332
2333static void
florian55085f82012-11-21 00:36:55 +00002334s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002335 IRTemp op2addr),
2336 UChar r1, UChar x2, UChar b2, UShort d2)
2337{
2338 IRTemp op2addr = newTemp(Ity_I64);
2339
2340 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2341 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2342 mkU64(0)));
2343
2344 irgen(r1, x2, b2, d2, op2addr);
2345}
2346
2347static void
florian55085f82012-11-21 00:36:55 +00002348s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002349 UChar r1, UChar x2, UChar b2, UShort d2)
2350{
florian55085f82012-11-21 00:36:55 +00002351 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002352 IRTemp op2addr = newTemp(Ity_I64);
2353
2354 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2355 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2356 mkU64(0)));
2357
2358 mnm = irgen(r1, op2addr);
2359
sewardj7ee97522011-05-09 21:45:04 +00002360 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002361 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2362}
2363
2364static void
florian55085f82012-11-21 00:36:55 +00002365s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002366 UChar r1, UChar x2, UChar b2, UShort d2)
2367{
florian55085f82012-11-21 00:36:55 +00002368 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002369 IRTemp op2addr = newTemp(Ity_I64);
2370
2371 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2372 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2373 mkU64(0)));
2374
2375 mnm = irgen(r1, op2addr);
2376
sewardj7ee97522011-05-09 21:45:04 +00002377 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002378 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2379}
2380
2381static void
florian55085f82012-11-21 00:36:55 +00002382s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002383 UChar r1, UChar x2, UChar b2, UShort d2)
2384{
florian55085f82012-11-21 00:36:55 +00002385 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002386 IRTemp op2addr = newTemp(Ity_I64);
2387
2388 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2389 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2390 mkU64(0)));
2391
2392 mnm = irgen(r1, op2addr);
2393
sewardj7ee97522011-05-09 21:45:04 +00002394 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002395 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2396}
2397
2398static void
florian55085f82012-11-21 00:36:55 +00002399s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002400 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2401{
florian55085f82012-11-21 00:36:55 +00002402 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002403 IRTemp op2addr = newTemp(Ity_I64);
2404
2405 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2406 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2407 mkU64(0)));
2408
2409 mnm = irgen(r3, op2addr, r1);
2410
sewardj7ee97522011-05-09 21:45:04 +00002411 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002412 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2413}
2414
2415static void
florian55085f82012-11-21 00:36:55 +00002416s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002417 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2418{
florian55085f82012-11-21 00:36:55 +00002419 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002420 IRTemp op2addr = newTemp(Ity_I64);
2421 IRTemp d2 = newTemp(Ity_I64);
2422
2423 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2424 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2425 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2426 mkU64(0)));
2427
2428 mnm = irgen(r1, op2addr);
2429
sewardj7ee97522011-05-09 21:45:04 +00002430 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002431 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2432}
2433
2434static void
florian55085f82012-11-21 00:36:55 +00002435s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002436 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2437{
florian55085f82012-11-21 00:36:55 +00002438 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002439 IRTemp op2addr = newTemp(Ity_I64);
2440 IRTemp d2 = newTemp(Ity_I64);
2441
2442 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2443 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2444 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2445 mkU64(0)));
2446
2447 mnm = irgen(r1, op2addr);
2448
sewardj7ee97522011-05-09 21:45:04 +00002449 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002450 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2451}
2452
2453static void
florian55085f82012-11-21 00:36:55 +00002454s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002455 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2456{
florian55085f82012-11-21 00:36:55 +00002457 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002458 IRTemp op2addr = newTemp(Ity_I64);
2459 IRTemp d2 = newTemp(Ity_I64);
2460
2461 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2462 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2463 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2464 mkU64(0)));
2465
2466 mnm = irgen();
2467
sewardj7ee97522011-05-09 21:45:04 +00002468 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002469 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2470}
2471
2472static void
florian55085f82012-11-21 00:36:55 +00002473s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002474 UChar b2, UShort d2)
2475{
florian55085f82012-11-21 00:36:55 +00002476 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002477 IRTemp op2addr = newTemp(Ity_I64);
2478
2479 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2480 mkU64(0)));
2481
2482 mnm = irgen(op2addr);
2483
sewardj7ee97522011-05-09 21:45:04 +00002484 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002485 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2486}
2487
2488static void
florian55085f82012-11-21 00:36:55 +00002489s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002490 UChar i2, UChar b1, UShort d1)
2491{
florian55085f82012-11-21 00:36:55 +00002492 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002493 IRTemp op1addr = newTemp(Ity_I64);
2494
2495 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2496 mkU64(0)));
2497
2498 mnm = irgen(i2, op1addr);
2499
sewardj7ee97522011-05-09 21:45:04 +00002500 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002501 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2502}
2503
2504static void
florian55085f82012-11-21 00:36:55 +00002505s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002506 UChar i2, UChar b1, UShort dl1, UChar dh1)
2507{
florian55085f82012-11-21 00:36:55 +00002508 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002509 IRTemp op1addr = newTemp(Ity_I64);
2510 IRTemp d1 = newTemp(Ity_I64);
2511
2512 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2513 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2514 mkU64(0)));
2515
2516 mnm = irgen(i2, op1addr);
2517
sewardj7ee97522011-05-09 21:45:04 +00002518 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002519 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2520}
2521
2522static void
florian55085f82012-11-21 00:36:55 +00002523s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002524 UChar i2, UChar b1, UShort dl1, UChar dh1)
2525{
florian55085f82012-11-21 00:36:55 +00002526 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002527 IRTemp op1addr = newTemp(Ity_I64);
2528 IRTemp d1 = newTemp(Ity_I64);
2529
2530 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2531 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2532 mkU64(0)));
2533
2534 mnm = irgen(i2, op1addr);
2535
sewardj7ee97522011-05-09 21:45:04 +00002536 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002537 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2538}
2539
2540static void
florian55085f82012-11-21 00:36:55 +00002541s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002542 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2543{
florian55085f82012-11-21 00:36:55 +00002544 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002545 IRTemp op1addr = newTemp(Ity_I64);
2546 IRTemp op2addr = newTemp(Ity_I64);
2547
2548 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2549 mkU64(0)));
2550 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2551 mkU64(0)));
2552
2553 mnm = irgen(l, op1addr, op2addr);
2554
sewardj7ee97522011-05-09 21:45:04 +00002555 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002556 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2557}
2558
2559static void
florian55085f82012-11-21 00:36:55 +00002560s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002561 UChar b1, UShort d1, UShort i2)
2562{
florian55085f82012-11-21 00:36:55 +00002563 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002564 IRTemp op1addr = newTemp(Ity_I64);
2565
2566 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2567 mkU64(0)));
2568
2569 mnm = irgen(i2, op1addr);
2570
sewardj7ee97522011-05-09 21:45:04 +00002571 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002572 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2573}
2574
2575static void
florian55085f82012-11-21 00:36:55 +00002576s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002577 UChar b1, UShort d1, UShort i2)
2578{
florian55085f82012-11-21 00:36:55 +00002579 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002580 IRTemp op1addr = newTemp(Ity_I64);
2581
2582 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2583 mkU64(0)));
2584
2585 mnm = irgen(i2, op1addr);
2586
sewardj7ee97522011-05-09 21:45:04 +00002587 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002588 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2589}
2590
2591
2592
2593/*------------------------------------------------------------*/
2594/*--- Build IR for opcodes ---*/
2595/*------------------------------------------------------------*/
2596
florian55085f82012-11-21 00:36:55 +00002597static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002598s390_irgen_AR(UChar r1, UChar r2)
2599{
2600 IRTemp op1 = newTemp(Ity_I32);
2601 IRTemp op2 = newTemp(Ity_I32);
2602 IRTemp result = newTemp(Ity_I32);
2603
2604 assign(op1, get_gpr_w1(r1));
2605 assign(op2, get_gpr_w1(r2));
2606 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2607 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2608 put_gpr_w1(r1, mkexpr(result));
2609
2610 return "ar";
2611}
2612
florian55085f82012-11-21 00:36:55 +00002613static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002614s390_irgen_AGR(UChar r1, UChar r2)
2615{
2616 IRTemp op1 = newTemp(Ity_I64);
2617 IRTemp op2 = newTemp(Ity_I64);
2618 IRTemp result = newTemp(Ity_I64);
2619
2620 assign(op1, get_gpr_dw0(r1));
2621 assign(op2, get_gpr_dw0(r2));
2622 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2623 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2624 put_gpr_dw0(r1, mkexpr(result));
2625
2626 return "agr";
2627}
2628
florian55085f82012-11-21 00:36:55 +00002629static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002630s390_irgen_AGFR(UChar r1, UChar r2)
2631{
2632 IRTemp op1 = newTemp(Ity_I64);
2633 IRTemp op2 = newTemp(Ity_I64);
2634 IRTemp result = newTemp(Ity_I64);
2635
2636 assign(op1, get_gpr_dw0(r1));
2637 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2638 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2639 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2640 put_gpr_dw0(r1, mkexpr(result));
2641
2642 return "agfr";
2643}
2644
florian55085f82012-11-21 00:36:55 +00002645static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002646s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2647{
2648 IRTemp op2 = newTemp(Ity_I32);
2649 IRTemp op3 = newTemp(Ity_I32);
2650 IRTemp result = newTemp(Ity_I32);
2651
2652 assign(op2, get_gpr_w1(r2));
2653 assign(op3, get_gpr_w1(r3));
2654 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2655 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2656 put_gpr_w1(r1, mkexpr(result));
2657
2658 return "ark";
2659}
2660
florian55085f82012-11-21 00:36:55 +00002661static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002662s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2663{
2664 IRTemp op2 = newTemp(Ity_I64);
2665 IRTemp op3 = newTemp(Ity_I64);
2666 IRTemp result = newTemp(Ity_I64);
2667
2668 assign(op2, get_gpr_dw0(r2));
2669 assign(op3, get_gpr_dw0(r3));
2670 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2671 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2672 put_gpr_dw0(r1, mkexpr(result));
2673
2674 return "agrk";
2675}
2676
florian55085f82012-11-21 00:36:55 +00002677static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002678s390_irgen_A(UChar r1, IRTemp op2addr)
2679{
2680 IRTemp op1 = newTemp(Ity_I32);
2681 IRTemp op2 = newTemp(Ity_I32);
2682 IRTemp result = newTemp(Ity_I32);
2683
2684 assign(op1, get_gpr_w1(r1));
2685 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2686 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2687 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2688 put_gpr_w1(r1, mkexpr(result));
2689
2690 return "a";
2691}
2692
florian55085f82012-11-21 00:36:55 +00002693static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002694s390_irgen_AY(UChar r1, IRTemp op2addr)
2695{
2696 IRTemp op1 = newTemp(Ity_I32);
2697 IRTemp op2 = newTemp(Ity_I32);
2698 IRTemp result = newTemp(Ity_I32);
2699
2700 assign(op1, get_gpr_w1(r1));
2701 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2702 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2703 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2704 put_gpr_w1(r1, mkexpr(result));
2705
2706 return "ay";
2707}
2708
florian55085f82012-11-21 00:36:55 +00002709static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002710s390_irgen_AG(UChar r1, IRTemp op2addr)
2711{
2712 IRTemp op1 = newTemp(Ity_I64);
2713 IRTemp op2 = newTemp(Ity_I64);
2714 IRTemp result = newTemp(Ity_I64);
2715
2716 assign(op1, get_gpr_dw0(r1));
2717 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2718 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2719 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2720 put_gpr_dw0(r1, mkexpr(result));
2721
2722 return "ag";
2723}
2724
florian55085f82012-11-21 00:36:55 +00002725static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002726s390_irgen_AGF(UChar r1, IRTemp op2addr)
2727{
2728 IRTemp op1 = newTemp(Ity_I64);
2729 IRTemp op2 = newTemp(Ity_I64);
2730 IRTemp result = newTemp(Ity_I64);
2731
2732 assign(op1, get_gpr_dw0(r1));
2733 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2734 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2735 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2736 put_gpr_dw0(r1, mkexpr(result));
2737
2738 return "agf";
2739}
2740
florian55085f82012-11-21 00:36:55 +00002741static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002742s390_irgen_AFI(UChar r1, UInt i2)
2743{
2744 IRTemp op1 = newTemp(Ity_I32);
2745 Int op2;
2746 IRTemp result = newTemp(Ity_I32);
2747
2748 assign(op1, get_gpr_w1(r1));
2749 op2 = (Int)i2;
2750 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2751 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2752 mkU32((UInt)op2)));
2753 put_gpr_w1(r1, mkexpr(result));
2754
2755 return "afi";
2756}
2757
florian55085f82012-11-21 00:36:55 +00002758static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002759s390_irgen_AGFI(UChar r1, UInt i2)
2760{
2761 IRTemp op1 = newTemp(Ity_I64);
2762 Long op2;
2763 IRTemp result = newTemp(Ity_I64);
2764
2765 assign(op1, get_gpr_dw0(r1));
2766 op2 = (Long)(Int)i2;
2767 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2768 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2769 mkU64((ULong)op2)));
2770 put_gpr_dw0(r1, mkexpr(result));
2771
2772 return "agfi";
2773}
2774
florian55085f82012-11-21 00:36:55 +00002775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002776s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2777{
2778 Int op2;
2779 IRTemp op3 = newTemp(Ity_I32);
2780 IRTemp result = newTemp(Ity_I32);
2781
2782 op2 = (Int)(Short)i2;
2783 assign(op3, get_gpr_w1(r3));
2784 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2785 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2786 op2)), op3);
2787 put_gpr_w1(r1, mkexpr(result));
2788
2789 return "ahik";
2790}
2791
florian55085f82012-11-21 00:36:55 +00002792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002793s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2794{
2795 Long op2;
2796 IRTemp op3 = newTemp(Ity_I64);
2797 IRTemp result = newTemp(Ity_I64);
2798
2799 op2 = (Long)(Short)i2;
2800 assign(op3, get_gpr_dw0(r3));
2801 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2802 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2803 op2)), op3);
2804 put_gpr_dw0(r1, mkexpr(result));
2805
2806 return "aghik";
2807}
2808
florian55085f82012-11-21 00:36:55 +00002809static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002810s390_irgen_ASI(UChar i2, IRTemp op1addr)
2811{
2812 IRTemp op1 = newTemp(Ity_I32);
2813 Int op2;
2814 IRTemp result = newTemp(Ity_I32);
2815
2816 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2817 op2 = (Int)(Char)i2;
2818 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2819 store(mkexpr(op1addr), mkexpr(result));
2820 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2821 mkU32((UInt)op2)));
2822
2823 return "asi";
2824}
2825
florian55085f82012-11-21 00:36:55 +00002826static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002827s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2828{
2829 IRTemp op1 = newTemp(Ity_I64);
2830 Long op2;
2831 IRTemp result = newTemp(Ity_I64);
2832
2833 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2834 op2 = (Long)(Char)i2;
2835 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2836 store(mkexpr(op1addr), mkexpr(result));
2837 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2838 mkU64((ULong)op2)));
2839
2840 return "agsi";
2841}
2842
florian55085f82012-11-21 00:36:55 +00002843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002844s390_irgen_AH(UChar r1, IRTemp op2addr)
2845{
2846 IRTemp op1 = newTemp(Ity_I32);
2847 IRTemp op2 = newTemp(Ity_I32);
2848 IRTemp result = newTemp(Ity_I32);
2849
2850 assign(op1, get_gpr_w1(r1));
2851 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2852 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2853 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2854 put_gpr_w1(r1, mkexpr(result));
2855
2856 return "ah";
2857}
2858
florian55085f82012-11-21 00:36:55 +00002859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002860s390_irgen_AHY(UChar r1, IRTemp op2addr)
2861{
2862 IRTemp op1 = newTemp(Ity_I32);
2863 IRTemp op2 = newTemp(Ity_I32);
2864 IRTemp result = newTemp(Ity_I32);
2865
2866 assign(op1, get_gpr_w1(r1));
2867 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2868 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2869 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2870 put_gpr_w1(r1, mkexpr(result));
2871
2872 return "ahy";
2873}
2874
florian55085f82012-11-21 00:36:55 +00002875static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002876s390_irgen_AHI(UChar r1, UShort i2)
2877{
2878 IRTemp op1 = newTemp(Ity_I32);
2879 Int op2;
2880 IRTemp result = newTemp(Ity_I32);
2881
2882 assign(op1, get_gpr_w1(r1));
2883 op2 = (Int)(Short)i2;
2884 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2885 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2886 mkU32((UInt)op2)));
2887 put_gpr_w1(r1, mkexpr(result));
2888
2889 return "ahi";
2890}
2891
florian55085f82012-11-21 00:36:55 +00002892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002893s390_irgen_AGHI(UChar r1, UShort i2)
2894{
2895 IRTemp op1 = newTemp(Ity_I64);
2896 Long op2;
2897 IRTemp result = newTemp(Ity_I64);
2898
2899 assign(op1, get_gpr_dw0(r1));
2900 op2 = (Long)(Short)i2;
2901 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2902 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2903 mkU64((ULong)op2)));
2904 put_gpr_dw0(r1, mkexpr(result));
2905
2906 return "aghi";
2907}
2908
florian55085f82012-11-21 00:36:55 +00002909static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002910s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2911{
2912 IRTemp op2 = newTemp(Ity_I32);
2913 IRTemp op3 = newTemp(Ity_I32);
2914 IRTemp result = newTemp(Ity_I32);
2915
2916 assign(op2, get_gpr_w0(r2));
2917 assign(op3, get_gpr_w0(r3));
2918 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2919 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2920 put_gpr_w0(r1, mkexpr(result));
2921
2922 return "ahhhr";
2923}
2924
florian55085f82012-11-21 00:36:55 +00002925static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002926s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2927{
2928 IRTemp op2 = newTemp(Ity_I32);
2929 IRTemp op3 = newTemp(Ity_I32);
2930 IRTemp result = newTemp(Ity_I32);
2931
2932 assign(op2, get_gpr_w0(r2));
2933 assign(op3, get_gpr_w1(r3));
2934 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2935 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2936 put_gpr_w0(r1, mkexpr(result));
2937
2938 return "ahhlr";
2939}
2940
florian55085f82012-11-21 00:36:55 +00002941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002942s390_irgen_AIH(UChar r1, UInt i2)
2943{
2944 IRTemp op1 = newTemp(Ity_I32);
2945 Int op2;
2946 IRTemp result = newTemp(Ity_I32);
2947
2948 assign(op1, get_gpr_w0(r1));
2949 op2 = (Int)i2;
2950 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2951 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2952 mkU32((UInt)op2)));
2953 put_gpr_w0(r1, mkexpr(result));
2954
2955 return "aih";
2956}
2957
florian55085f82012-11-21 00:36:55 +00002958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002959s390_irgen_ALR(UChar r1, UChar r2)
2960{
2961 IRTemp op1 = newTemp(Ity_I32);
2962 IRTemp op2 = newTemp(Ity_I32);
2963 IRTemp result = newTemp(Ity_I32);
2964
2965 assign(op1, get_gpr_w1(r1));
2966 assign(op2, get_gpr_w1(r2));
2967 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2968 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2969 put_gpr_w1(r1, mkexpr(result));
2970
2971 return "alr";
2972}
2973
florian55085f82012-11-21 00:36:55 +00002974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002975s390_irgen_ALGR(UChar r1, UChar r2)
2976{
2977 IRTemp op1 = newTemp(Ity_I64);
2978 IRTemp op2 = newTemp(Ity_I64);
2979 IRTemp result = newTemp(Ity_I64);
2980
2981 assign(op1, get_gpr_dw0(r1));
2982 assign(op2, get_gpr_dw0(r2));
2983 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2984 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2985 put_gpr_dw0(r1, mkexpr(result));
2986
2987 return "algr";
2988}
2989
florian55085f82012-11-21 00:36:55 +00002990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002991s390_irgen_ALGFR(UChar r1, UChar r2)
2992{
2993 IRTemp op1 = newTemp(Ity_I64);
2994 IRTemp op2 = newTemp(Ity_I64);
2995 IRTemp result = newTemp(Ity_I64);
2996
2997 assign(op1, get_gpr_dw0(r1));
2998 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2999 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3000 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3001 put_gpr_dw0(r1, mkexpr(result));
3002
3003 return "algfr";
3004}
3005
florian55085f82012-11-21 00:36:55 +00003006static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003007s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
3008{
3009 IRTemp op2 = newTemp(Ity_I32);
3010 IRTemp op3 = newTemp(Ity_I32);
3011 IRTemp result = newTemp(Ity_I32);
3012
3013 assign(op2, get_gpr_w1(r2));
3014 assign(op3, get_gpr_w1(r3));
3015 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3016 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3017 put_gpr_w1(r1, mkexpr(result));
3018
3019 return "alrk";
3020}
3021
florian55085f82012-11-21 00:36:55 +00003022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003023s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
3024{
3025 IRTemp op2 = newTemp(Ity_I64);
3026 IRTemp op3 = newTemp(Ity_I64);
3027 IRTemp result = newTemp(Ity_I64);
3028
3029 assign(op2, get_gpr_dw0(r2));
3030 assign(op3, get_gpr_dw0(r3));
3031 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
3032 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
3033 put_gpr_dw0(r1, mkexpr(result));
3034
3035 return "algrk";
3036}
3037
florian55085f82012-11-21 00:36:55 +00003038static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003039s390_irgen_AL(UChar r1, IRTemp op2addr)
3040{
3041 IRTemp op1 = newTemp(Ity_I32);
3042 IRTemp op2 = newTemp(Ity_I32);
3043 IRTemp result = newTemp(Ity_I32);
3044
3045 assign(op1, get_gpr_w1(r1));
3046 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3047 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3048 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3049 put_gpr_w1(r1, mkexpr(result));
3050
3051 return "al";
3052}
3053
florian55085f82012-11-21 00:36:55 +00003054static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003055s390_irgen_ALY(UChar r1, IRTemp op2addr)
3056{
3057 IRTemp op1 = newTemp(Ity_I32);
3058 IRTemp op2 = newTemp(Ity_I32);
3059 IRTemp result = newTemp(Ity_I32);
3060
3061 assign(op1, get_gpr_w1(r1));
3062 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3063 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3064 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3065 put_gpr_w1(r1, mkexpr(result));
3066
3067 return "aly";
3068}
3069
florian55085f82012-11-21 00:36:55 +00003070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003071s390_irgen_ALG(UChar r1, IRTemp op2addr)
3072{
3073 IRTemp op1 = newTemp(Ity_I64);
3074 IRTemp op2 = newTemp(Ity_I64);
3075 IRTemp result = newTemp(Ity_I64);
3076
3077 assign(op1, get_gpr_dw0(r1));
3078 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3079 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3080 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3081 put_gpr_dw0(r1, mkexpr(result));
3082
3083 return "alg";
3084}
3085
florian55085f82012-11-21 00:36:55 +00003086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003087s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3088{
3089 IRTemp op1 = newTemp(Ity_I64);
3090 IRTemp op2 = newTemp(Ity_I64);
3091 IRTemp result = newTemp(Ity_I64);
3092
3093 assign(op1, get_gpr_dw0(r1));
3094 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3095 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3096 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3097 put_gpr_dw0(r1, mkexpr(result));
3098
3099 return "algf";
3100}
3101
florian55085f82012-11-21 00:36:55 +00003102static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003103s390_irgen_ALFI(UChar r1, UInt i2)
3104{
3105 IRTemp op1 = newTemp(Ity_I32);
3106 UInt op2;
3107 IRTemp result = newTemp(Ity_I32);
3108
3109 assign(op1, get_gpr_w1(r1));
3110 op2 = i2;
3111 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3112 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3113 mkU32(op2)));
3114 put_gpr_w1(r1, mkexpr(result));
3115
3116 return "alfi";
3117}
3118
florian55085f82012-11-21 00:36:55 +00003119static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003120s390_irgen_ALGFI(UChar r1, UInt i2)
3121{
3122 IRTemp op1 = newTemp(Ity_I64);
3123 ULong op2;
3124 IRTemp result = newTemp(Ity_I64);
3125
3126 assign(op1, get_gpr_dw0(r1));
3127 op2 = (ULong)i2;
3128 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3129 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3130 mkU64(op2)));
3131 put_gpr_dw0(r1, mkexpr(result));
3132
3133 return "algfi";
3134}
3135
florian55085f82012-11-21 00:36:55 +00003136static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003137s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3138{
3139 IRTemp op2 = newTemp(Ity_I32);
3140 IRTemp op3 = newTemp(Ity_I32);
3141 IRTemp result = newTemp(Ity_I32);
3142
3143 assign(op2, get_gpr_w0(r2));
3144 assign(op3, get_gpr_w0(r3));
3145 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3146 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3147 put_gpr_w0(r1, mkexpr(result));
3148
3149 return "alhhhr";
3150}
3151
florian55085f82012-11-21 00:36:55 +00003152static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003153s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3154{
3155 IRTemp op2 = newTemp(Ity_I32);
3156 IRTemp op3 = newTemp(Ity_I32);
3157 IRTemp result = newTemp(Ity_I32);
3158
3159 assign(op2, get_gpr_w0(r2));
3160 assign(op3, get_gpr_w1(r3));
3161 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3162 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3163 put_gpr_w0(r1, mkexpr(result));
3164
3165 return "alhhlr";
3166}
3167
florian55085f82012-11-21 00:36:55 +00003168static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003169s390_irgen_ALCR(UChar r1, UChar r2)
3170{
3171 IRTemp op1 = newTemp(Ity_I32);
3172 IRTemp op2 = newTemp(Ity_I32);
3173 IRTemp result = newTemp(Ity_I32);
3174 IRTemp carry_in = newTemp(Ity_I32);
3175
3176 assign(op1, get_gpr_w1(r1));
3177 assign(op2, get_gpr_w1(r2));
3178 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3179 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3180 mkexpr(carry_in)));
3181 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3182 put_gpr_w1(r1, mkexpr(result));
3183
3184 return "alcr";
3185}
3186
florian55085f82012-11-21 00:36:55 +00003187static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003188s390_irgen_ALCGR(UChar r1, UChar r2)
3189{
3190 IRTemp op1 = newTemp(Ity_I64);
3191 IRTemp op2 = newTemp(Ity_I64);
3192 IRTemp result = newTemp(Ity_I64);
3193 IRTemp carry_in = newTemp(Ity_I64);
3194
3195 assign(op1, get_gpr_dw0(r1));
3196 assign(op2, get_gpr_dw0(r2));
3197 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3198 mkU8(1))));
3199 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3200 mkexpr(carry_in)));
3201 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3202 put_gpr_dw0(r1, mkexpr(result));
3203
3204 return "alcgr";
3205}
3206
florian55085f82012-11-21 00:36:55 +00003207static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003208s390_irgen_ALC(UChar r1, IRTemp op2addr)
3209{
3210 IRTemp op1 = newTemp(Ity_I32);
3211 IRTemp op2 = newTemp(Ity_I32);
3212 IRTemp result = newTemp(Ity_I32);
3213 IRTemp carry_in = newTemp(Ity_I32);
3214
3215 assign(op1, get_gpr_w1(r1));
3216 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3217 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3218 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3219 mkexpr(carry_in)));
3220 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3221 put_gpr_w1(r1, mkexpr(result));
3222
3223 return "alc";
3224}
3225
florian55085f82012-11-21 00:36:55 +00003226static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003227s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3228{
3229 IRTemp op1 = newTemp(Ity_I64);
3230 IRTemp op2 = newTemp(Ity_I64);
3231 IRTemp result = newTemp(Ity_I64);
3232 IRTemp carry_in = newTemp(Ity_I64);
3233
3234 assign(op1, get_gpr_dw0(r1));
3235 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3236 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3237 mkU8(1))));
3238 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3239 mkexpr(carry_in)));
3240 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3241 put_gpr_dw0(r1, mkexpr(result));
3242
3243 return "alcg";
3244}
3245
florian55085f82012-11-21 00:36:55 +00003246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003247s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3248{
3249 IRTemp op1 = newTemp(Ity_I32);
3250 UInt op2;
3251 IRTemp result = newTemp(Ity_I32);
3252
3253 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3254 op2 = (UInt)(Int)(Char)i2;
3255 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3256 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3257 mkU32(op2)));
3258 store(mkexpr(op1addr), mkexpr(result));
3259
3260 return "alsi";
3261}
3262
florian55085f82012-11-21 00:36:55 +00003263static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003264s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3265{
3266 IRTemp op1 = newTemp(Ity_I64);
3267 ULong op2;
3268 IRTemp result = newTemp(Ity_I64);
3269
3270 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3271 op2 = (ULong)(Long)(Char)i2;
3272 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3273 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3274 mkU64(op2)));
3275 store(mkexpr(op1addr), mkexpr(result));
3276
3277 return "algsi";
3278}
3279
florian55085f82012-11-21 00:36:55 +00003280static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003281s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3282{
3283 UInt op2;
3284 IRTemp op3 = newTemp(Ity_I32);
3285 IRTemp result = newTemp(Ity_I32);
3286
3287 op2 = (UInt)(Int)(Short)i2;
3288 assign(op3, get_gpr_w1(r3));
3289 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3290 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3291 op3);
3292 put_gpr_w1(r1, mkexpr(result));
3293
3294 return "alhsik";
3295}
3296
florian55085f82012-11-21 00:36:55 +00003297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003298s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3299{
3300 ULong op2;
3301 IRTemp op3 = newTemp(Ity_I64);
3302 IRTemp result = newTemp(Ity_I64);
3303
3304 op2 = (ULong)(Long)(Short)i2;
3305 assign(op3, get_gpr_dw0(r3));
3306 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3307 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3308 op3);
3309 put_gpr_dw0(r1, mkexpr(result));
3310
3311 return "alghsik";
3312}
3313
florian55085f82012-11-21 00:36:55 +00003314static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003315s390_irgen_ALSIH(UChar r1, UInt i2)
3316{
3317 IRTemp op1 = newTemp(Ity_I32);
3318 UInt op2;
3319 IRTemp result = newTemp(Ity_I32);
3320
3321 assign(op1, get_gpr_w0(r1));
3322 op2 = i2;
3323 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3324 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3325 mkU32(op2)));
3326 put_gpr_w0(r1, mkexpr(result));
3327
3328 return "alsih";
3329}
3330
florian55085f82012-11-21 00:36:55 +00003331static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003332s390_irgen_ALSIHN(UChar r1, UInt i2)
3333{
3334 IRTemp op1 = newTemp(Ity_I32);
3335 UInt op2;
3336 IRTemp result = newTemp(Ity_I32);
3337
3338 assign(op1, get_gpr_w0(r1));
3339 op2 = i2;
3340 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3341 put_gpr_w0(r1, mkexpr(result));
3342
3343 return "alsihn";
3344}
3345
florian55085f82012-11-21 00:36:55 +00003346static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003347s390_irgen_NR(UChar r1, UChar r2)
3348{
3349 IRTemp op1 = newTemp(Ity_I32);
3350 IRTemp op2 = newTemp(Ity_I32);
3351 IRTemp result = newTemp(Ity_I32);
3352
3353 assign(op1, get_gpr_w1(r1));
3354 assign(op2, get_gpr_w1(r2));
3355 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3356 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3357 put_gpr_w1(r1, mkexpr(result));
3358
3359 return "nr";
3360}
3361
florian55085f82012-11-21 00:36:55 +00003362static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003363s390_irgen_NGR(UChar r1, UChar r2)
3364{
3365 IRTemp op1 = newTemp(Ity_I64);
3366 IRTemp op2 = newTemp(Ity_I64);
3367 IRTemp result = newTemp(Ity_I64);
3368
3369 assign(op1, get_gpr_dw0(r1));
3370 assign(op2, get_gpr_dw0(r2));
3371 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3372 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3373 put_gpr_dw0(r1, mkexpr(result));
3374
3375 return "ngr";
3376}
3377
florian55085f82012-11-21 00:36:55 +00003378static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003379s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3380{
3381 IRTemp op2 = newTemp(Ity_I32);
3382 IRTemp op3 = newTemp(Ity_I32);
3383 IRTemp result = newTemp(Ity_I32);
3384
3385 assign(op2, get_gpr_w1(r2));
3386 assign(op3, get_gpr_w1(r3));
3387 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3388 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3389 put_gpr_w1(r1, mkexpr(result));
3390
3391 return "nrk";
3392}
3393
florian55085f82012-11-21 00:36:55 +00003394static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003395s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3396{
3397 IRTemp op2 = newTemp(Ity_I64);
3398 IRTemp op3 = newTemp(Ity_I64);
3399 IRTemp result = newTemp(Ity_I64);
3400
3401 assign(op2, get_gpr_dw0(r2));
3402 assign(op3, get_gpr_dw0(r3));
3403 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3404 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3405 put_gpr_dw0(r1, mkexpr(result));
3406
3407 return "ngrk";
3408}
3409
florian55085f82012-11-21 00:36:55 +00003410static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003411s390_irgen_N(UChar r1, IRTemp op2addr)
3412{
3413 IRTemp op1 = newTemp(Ity_I32);
3414 IRTemp op2 = newTemp(Ity_I32);
3415 IRTemp result = newTemp(Ity_I32);
3416
3417 assign(op1, get_gpr_w1(r1));
3418 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3419 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3420 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3421 put_gpr_w1(r1, mkexpr(result));
3422
3423 return "n";
3424}
3425
florian55085f82012-11-21 00:36:55 +00003426static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003427s390_irgen_NY(UChar r1, IRTemp op2addr)
3428{
3429 IRTemp op1 = newTemp(Ity_I32);
3430 IRTemp op2 = newTemp(Ity_I32);
3431 IRTemp result = newTemp(Ity_I32);
3432
3433 assign(op1, get_gpr_w1(r1));
3434 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3435 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3436 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3437 put_gpr_w1(r1, mkexpr(result));
3438
3439 return "ny";
3440}
3441
florian55085f82012-11-21 00:36:55 +00003442static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003443s390_irgen_NG(UChar r1, IRTemp op2addr)
3444{
3445 IRTemp op1 = newTemp(Ity_I64);
3446 IRTemp op2 = newTemp(Ity_I64);
3447 IRTemp result = newTemp(Ity_I64);
3448
3449 assign(op1, get_gpr_dw0(r1));
3450 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3451 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3452 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3453 put_gpr_dw0(r1, mkexpr(result));
3454
3455 return "ng";
3456}
3457
florian55085f82012-11-21 00:36:55 +00003458static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003459s390_irgen_NI(UChar i2, IRTemp op1addr)
3460{
3461 IRTemp op1 = newTemp(Ity_I8);
3462 UChar op2;
3463 IRTemp result = newTemp(Ity_I8);
3464
3465 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3466 op2 = i2;
3467 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3468 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3469 store(mkexpr(op1addr), mkexpr(result));
3470
3471 return "ni";
3472}
3473
florian55085f82012-11-21 00:36:55 +00003474static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003475s390_irgen_NIY(UChar i2, IRTemp op1addr)
3476{
3477 IRTemp op1 = newTemp(Ity_I8);
3478 UChar op2;
3479 IRTemp result = newTemp(Ity_I8);
3480
3481 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3482 op2 = i2;
3483 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3484 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3485 store(mkexpr(op1addr), mkexpr(result));
3486
3487 return "niy";
3488}
3489
florian55085f82012-11-21 00:36:55 +00003490static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003491s390_irgen_NIHF(UChar r1, UInt i2)
3492{
3493 IRTemp op1 = newTemp(Ity_I32);
3494 UInt op2;
3495 IRTemp result = newTemp(Ity_I32);
3496
3497 assign(op1, get_gpr_w0(r1));
3498 op2 = i2;
3499 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3500 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3501 put_gpr_w0(r1, mkexpr(result));
3502
3503 return "nihf";
3504}
3505
florian55085f82012-11-21 00:36:55 +00003506static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003507s390_irgen_NIHH(UChar r1, UShort i2)
3508{
3509 IRTemp op1 = newTemp(Ity_I16);
3510 UShort op2;
3511 IRTemp result = newTemp(Ity_I16);
3512
3513 assign(op1, get_gpr_hw0(r1));
3514 op2 = i2;
3515 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3516 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3517 put_gpr_hw0(r1, mkexpr(result));
3518
3519 return "nihh";
3520}
3521
florian55085f82012-11-21 00:36:55 +00003522static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003523s390_irgen_NIHL(UChar r1, UShort i2)
3524{
3525 IRTemp op1 = newTemp(Ity_I16);
3526 UShort op2;
3527 IRTemp result = newTemp(Ity_I16);
3528
3529 assign(op1, get_gpr_hw1(r1));
3530 op2 = i2;
3531 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3532 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3533 put_gpr_hw1(r1, mkexpr(result));
3534
3535 return "nihl";
3536}
3537
florian55085f82012-11-21 00:36:55 +00003538static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003539s390_irgen_NILF(UChar r1, UInt i2)
3540{
3541 IRTemp op1 = newTemp(Ity_I32);
3542 UInt op2;
3543 IRTemp result = newTemp(Ity_I32);
3544
3545 assign(op1, get_gpr_w1(r1));
3546 op2 = i2;
3547 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3548 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3549 put_gpr_w1(r1, mkexpr(result));
3550
3551 return "nilf";
3552}
3553
florian55085f82012-11-21 00:36:55 +00003554static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003555s390_irgen_NILH(UChar r1, UShort i2)
3556{
3557 IRTemp op1 = newTemp(Ity_I16);
3558 UShort op2;
3559 IRTemp result = newTemp(Ity_I16);
3560
3561 assign(op1, get_gpr_hw2(r1));
3562 op2 = i2;
3563 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3564 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3565 put_gpr_hw2(r1, mkexpr(result));
3566
3567 return "nilh";
3568}
3569
florian55085f82012-11-21 00:36:55 +00003570static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003571s390_irgen_NILL(UChar r1, UShort i2)
3572{
3573 IRTemp op1 = newTemp(Ity_I16);
3574 UShort op2;
3575 IRTemp result = newTemp(Ity_I16);
3576
3577 assign(op1, get_gpr_hw3(r1));
3578 op2 = i2;
3579 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3580 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3581 put_gpr_hw3(r1, mkexpr(result));
3582
3583 return "nill";
3584}
3585
florian55085f82012-11-21 00:36:55 +00003586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003587s390_irgen_BASR(UChar r1, UChar r2)
3588{
3589 IRTemp target = newTemp(Ity_I64);
3590
3591 if (r2 == 0) {
3592 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3593 } else {
3594 if (r1 != r2) {
3595 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3596 call_function(get_gpr_dw0(r2));
3597 } else {
3598 assign(target, get_gpr_dw0(r2));
3599 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3600 call_function(mkexpr(target));
3601 }
3602 }
3603
3604 return "basr";
3605}
3606
florian55085f82012-11-21 00:36:55 +00003607static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003608s390_irgen_BAS(UChar r1, IRTemp op2addr)
3609{
3610 IRTemp target = newTemp(Ity_I64);
3611
3612 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3613 assign(target, mkexpr(op2addr));
3614 call_function(mkexpr(target));
3615
3616 return "bas";
3617}
3618
florian55085f82012-11-21 00:36:55 +00003619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003620s390_irgen_BCR(UChar r1, UChar r2)
3621{
3622 IRTemp cond = newTemp(Ity_I32);
3623
sewardja52e37e2011-04-28 18:48:06 +00003624 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3625 stmt(IRStmt_MBE(Imbe_Fence));
3626 }
3627
sewardj2019a972011-03-07 16:04:07 +00003628 if ((r2 == 0) || (r1 == 0)) {
3629 } else {
3630 if (r1 == 15) {
3631 return_from_function(get_gpr_dw0(r2));
3632 } else {
3633 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003634 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3635 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003636 }
3637 }
sewardj7ee97522011-05-09 21:45:04 +00003638 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003639 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3640
3641 return "bcr";
3642}
3643
florian55085f82012-11-21 00:36:55 +00003644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003645s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3646{
3647 IRTemp cond = newTemp(Ity_I32);
3648
3649 if (r1 == 0) {
3650 } else {
3651 if (r1 == 15) {
3652 always_goto(mkexpr(op2addr));
3653 } else {
3654 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003655 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3656 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003657 }
3658 }
sewardj7ee97522011-05-09 21:45:04 +00003659 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003660 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3661
3662 return "bc";
3663}
3664
florian55085f82012-11-21 00:36:55 +00003665static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003666s390_irgen_BCTR(UChar r1, UChar r2)
3667{
3668 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3669 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003670 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3671 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003672 }
3673
3674 return "bctr";
3675}
3676
florian55085f82012-11-21 00:36:55 +00003677static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003678s390_irgen_BCTGR(UChar r1, UChar r2)
3679{
3680 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3681 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003682 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3683 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003684 }
3685
3686 return "bctgr";
3687}
3688
florian55085f82012-11-21 00:36:55 +00003689static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003690s390_irgen_BCT(UChar r1, IRTemp op2addr)
3691{
3692 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003693 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3694 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003695
3696 return "bct";
3697}
3698
florian55085f82012-11-21 00:36:55 +00003699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003700s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3701{
3702 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003703 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3704 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003705
3706 return "bctg";
3707}
3708
florian55085f82012-11-21 00:36:55 +00003709static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003710s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3711{
3712 IRTemp value = newTemp(Ity_I32);
3713
3714 assign(value, get_gpr_w1(r3 | 1));
3715 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003716 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3717 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003718
3719 return "bxh";
3720}
3721
florian55085f82012-11-21 00:36:55 +00003722static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003723s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3724{
3725 IRTemp value = newTemp(Ity_I64);
3726
3727 assign(value, get_gpr_dw0(r3 | 1));
3728 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003729 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3730 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003731
3732 return "bxhg";
3733}
3734
florian55085f82012-11-21 00:36:55 +00003735static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003736s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3737{
3738 IRTemp value = newTemp(Ity_I32);
3739
3740 assign(value, get_gpr_w1(r3 | 1));
3741 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003742 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3743 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003744
3745 return "bxle";
3746}
3747
florian55085f82012-11-21 00:36:55 +00003748static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003749s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3750{
3751 IRTemp value = newTemp(Ity_I64);
3752
3753 assign(value, get_gpr_dw0(r3 | 1));
3754 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003755 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3756 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003757
3758 return "bxleg";
3759}
3760
florian55085f82012-11-21 00:36:55 +00003761static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003762s390_irgen_BRAS(UChar r1, UShort i2)
3763{
3764 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003765 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003766
3767 return "bras";
3768}
3769
florian55085f82012-11-21 00:36:55 +00003770static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003771s390_irgen_BRASL(UChar r1, UInt i2)
3772{
3773 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003774 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003775
3776 return "brasl";
3777}
3778
florian55085f82012-11-21 00:36:55 +00003779static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003780s390_irgen_BRC(UChar r1, UShort i2)
3781{
3782 IRTemp cond = newTemp(Ity_I32);
3783
3784 if (r1 == 0) {
3785 } else {
3786 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003787 always_goto_and_chase(
3788 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003789 } else {
3790 assign(cond, s390_call_calculate_cond(r1));
3791 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3792 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3793
3794 }
3795 }
sewardj7ee97522011-05-09 21:45:04 +00003796 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003797 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3798
3799 return "brc";
3800}
3801
florian55085f82012-11-21 00:36:55 +00003802static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003803s390_irgen_BRCL(UChar r1, UInt i2)
3804{
3805 IRTemp cond = newTemp(Ity_I32);
3806
3807 if (r1 == 0) {
3808 } else {
3809 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003810 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003811 } else {
3812 assign(cond, s390_call_calculate_cond(r1));
3813 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3814 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3815 }
3816 }
sewardj7ee97522011-05-09 21:45:04 +00003817 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003818 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3819
3820 return "brcl";
3821}
3822
florian55085f82012-11-21 00:36:55 +00003823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003824s390_irgen_BRCT(UChar r1, UShort i2)
3825{
3826 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3827 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3828 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3829
3830 return "brct";
3831}
3832
florian55085f82012-11-21 00:36:55 +00003833static const HChar *
Elliott Hughesa0664b92017-04-18 17:46:52 -07003834s390_irgen_BRCTH(UChar r1, UInt i2)
3835{
3836 put_gpr_w0(r1, binop(Iop_Sub32, get_gpr_w0(r1), mkU32(1)));
3837 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w0(r1), mkU32(0)),
3838 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3839
3840 return "brcth";
3841}
3842
3843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003844s390_irgen_BRCTG(UChar r1, UShort i2)
3845{
3846 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3847 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3848 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3849
3850 return "brctg";
3851}
3852
florian55085f82012-11-21 00:36:55 +00003853static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003854s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3855{
3856 IRTemp value = newTemp(Ity_I32);
3857
3858 assign(value, get_gpr_w1(r3 | 1));
3859 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3860 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3861 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3862
3863 return "brxh";
3864}
3865
florian55085f82012-11-21 00:36:55 +00003866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003867s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3868{
3869 IRTemp value = newTemp(Ity_I64);
3870
3871 assign(value, get_gpr_dw0(r3 | 1));
3872 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3873 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3874 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3875
3876 return "brxhg";
3877}
3878
florian55085f82012-11-21 00:36:55 +00003879static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003880s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3881{
3882 IRTemp value = newTemp(Ity_I32);
3883
3884 assign(value, get_gpr_w1(r3 | 1));
3885 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3886 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3887 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3888
3889 return "brxle";
3890}
3891
florian55085f82012-11-21 00:36:55 +00003892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003893s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3894{
3895 IRTemp value = newTemp(Ity_I64);
3896
3897 assign(value, get_gpr_dw0(r3 | 1));
3898 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3899 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3900 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3901
3902 return "brxlg";
3903}
3904
florian55085f82012-11-21 00:36:55 +00003905static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003906s390_irgen_CR(UChar r1, UChar r2)
3907{
3908 IRTemp op1 = newTemp(Ity_I32);
3909 IRTemp op2 = newTemp(Ity_I32);
3910
3911 assign(op1, get_gpr_w1(r1));
3912 assign(op2, get_gpr_w1(r2));
3913 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3914
3915 return "cr";
3916}
3917
florian55085f82012-11-21 00:36:55 +00003918static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003919s390_irgen_CGR(UChar r1, UChar r2)
3920{
3921 IRTemp op1 = newTemp(Ity_I64);
3922 IRTemp op2 = newTemp(Ity_I64);
3923
3924 assign(op1, get_gpr_dw0(r1));
3925 assign(op2, get_gpr_dw0(r2));
3926 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3927
3928 return "cgr";
3929}
3930
florian55085f82012-11-21 00:36:55 +00003931static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003932s390_irgen_CGFR(UChar r1, UChar r2)
3933{
3934 IRTemp op1 = newTemp(Ity_I64);
3935 IRTemp op2 = newTemp(Ity_I64);
3936
3937 assign(op1, get_gpr_dw0(r1));
3938 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3939 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3940
3941 return "cgfr";
3942}
3943
florian55085f82012-11-21 00:36:55 +00003944static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003945s390_irgen_C(UChar r1, IRTemp op2addr)
3946{
3947 IRTemp op1 = newTemp(Ity_I32);
3948 IRTemp op2 = newTemp(Ity_I32);
3949
3950 assign(op1, get_gpr_w1(r1));
3951 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3952 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3953
3954 return "c";
3955}
3956
florian55085f82012-11-21 00:36:55 +00003957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003958s390_irgen_CY(UChar r1, IRTemp op2addr)
3959{
3960 IRTemp op1 = newTemp(Ity_I32);
3961 IRTemp op2 = newTemp(Ity_I32);
3962
3963 assign(op1, get_gpr_w1(r1));
3964 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3965 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3966
3967 return "cy";
3968}
3969
florian55085f82012-11-21 00:36:55 +00003970static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003971s390_irgen_CG(UChar r1, IRTemp op2addr)
3972{
3973 IRTemp op1 = newTemp(Ity_I64);
3974 IRTemp op2 = newTemp(Ity_I64);
3975
3976 assign(op1, get_gpr_dw0(r1));
3977 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3978 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3979
3980 return "cg";
3981}
3982
florian55085f82012-11-21 00:36:55 +00003983static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003984s390_irgen_CGF(UChar r1, IRTemp op2addr)
3985{
3986 IRTemp op1 = newTemp(Ity_I64);
3987 IRTemp op2 = newTemp(Ity_I64);
3988
3989 assign(op1, get_gpr_dw0(r1));
3990 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3991 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3992
3993 return "cgf";
3994}
3995
florian55085f82012-11-21 00:36:55 +00003996static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003997s390_irgen_CFI(UChar r1, UInt i2)
3998{
3999 IRTemp op1 = newTemp(Ity_I32);
4000 Int op2;
4001
4002 assign(op1, get_gpr_w1(r1));
4003 op2 = (Int)i2;
4004 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4005 mkU32((UInt)op2)));
4006
4007 return "cfi";
4008}
4009
florian55085f82012-11-21 00:36:55 +00004010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004011s390_irgen_CGFI(UChar r1, UInt i2)
4012{
4013 IRTemp op1 = newTemp(Ity_I64);
4014 Long op2;
4015
4016 assign(op1, get_gpr_dw0(r1));
4017 op2 = (Long)(Int)i2;
4018 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4019 mkU64((ULong)op2)));
4020
4021 return "cgfi";
4022}
4023
florian55085f82012-11-21 00:36:55 +00004024static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004025s390_irgen_CRL(UChar r1, UInt i2)
4026{
4027 IRTemp op1 = newTemp(Ity_I32);
4028 IRTemp op2 = newTemp(Ity_I32);
4029
4030 assign(op1, get_gpr_w1(r1));
4031 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4032 i2 << 1))));
4033 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4034
4035 return "crl";
4036}
4037
florian55085f82012-11-21 00:36:55 +00004038static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004039s390_irgen_CGRL(UChar r1, UInt i2)
4040{
4041 IRTemp op1 = newTemp(Ity_I64);
4042 IRTemp op2 = newTemp(Ity_I64);
4043
4044 assign(op1, get_gpr_dw0(r1));
4045 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4046 i2 << 1))));
4047 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4048
4049 return "cgrl";
4050}
4051
florian55085f82012-11-21 00:36:55 +00004052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004053s390_irgen_CGFRL(UChar r1, UInt i2)
4054{
4055 IRTemp op1 = newTemp(Ity_I64);
4056 IRTemp op2 = newTemp(Ity_I64);
4057
4058 assign(op1, get_gpr_dw0(r1));
4059 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4060 ((ULong)(Long)(Int)i2 << 1)))));
4061 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4062
4063 return "cgfrl";
4064}
4065
florian55085f82012-11-21 00:36:55 +00004066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004067s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4068{
4069 IRTemp op1 = newTemp(Ity_I32);
4070 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004071 IRTemp cond = newTemp(Ity_I32);
4072
4073 if (m3 == 0) {
4074 } else {
4075 if (m3 == 14) {
4076 always_goto(mkexpr(op4addr));
4077 } else {
4078 assign(op1, get_gpr_w1(r1));
4079 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004080 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4081 op1, op2));
florianf321da72012-07-21 20:32:57 +00004082 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4083 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004084 }
4085 }
4086
4087 return "crb";
4088}
4089
florian55085f82012-11-21 00:36:55 +00004090static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004091s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4092{
4093 IRTemp op1 = newTemp(Ity_I64);
4094 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004095 IRTemp cond = newTemp(Ity_I32);
4096
4097 if (m3 == 0) {
4098 } else {
4099 if (m3 == 14) {
4100 always_goto(mkexpr(op4addr));
4101 } else {
4102 assign(op1, get_gpr_dw0(r1));
4103 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004104 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4105 op1, op2));
florianf321da72012-07-21 20:32:57 +00004106 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4107 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004108 }
4109 }
4110
4111 return "cgrb";
4112}
4113
florian55085f82012-11-21 00:36:55 +00004114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004115s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4116{
4117 IRTemp op1 = newTemp(Ity_I32);
4118 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004119 IRTemp cond = newTemp(Ity_I32);
4120
4121 if (m3 == 0) {
4122 } else {
4123 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004124 always_goto_and_chase(
4125 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004126 } else {
4127 assign(op1, get_gpr_w1(r1));
4128 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004129 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4130 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004131 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4132 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4133
4134 }
4135 }
4136
4137 return "crj";
4138}
4139
florian55085f82012-11-21 00:36:55 +00004140static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004141s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4142{
4143 IRTemp op1 = newTemp(Ity_I64);
4144 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004145 IRTemp cond = newTemp(Ity_I32);
4146
4147 if (m3 == 0) {
4148 } else {
4149 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004150 always_goto_and_chase(
4151 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004152 } else {
4153 assign(op1, get_gpr_dw0(r1));
4154 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004155 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4156 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004157 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4158 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4159
4160 }
4161 }
4162
4163 return "cgrj";
4164}
4165
florian55085f82012-11-21 00:36:55 +00004166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004167s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4168{
4169 IRTemp op1 = newTemp(Ity_I32);
4170 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004171 IRTemp cond = newTemp(Ity_I32);
4172
4173 if (m3 == 0) {
4174 } else {
4175 if (m3 == 14) {
4176 always_goto(mkexpr(op4addr));
4177 } else {
4178 assign(op1, get_gpr_w1(r1));
4179 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004180 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4181 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004182 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4183 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004184 }
4185 }
4186
4187 return "cib";
4188}
4189
florian55085f82012-11-21 00:36:55 +00004190static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004191s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4192{
4193 IRTemp op1 = newTemp(Ity_I64);
4194 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004195 IRTemp cond = newTemp(Ity_I32);
4196
4197 if (m3 == 0) {
4198 } else {
4199 if (m3 == 14) {
4200 always_goto(mkexpr(op4addr));
4201 } else {
4202 assign(op1, get_gpr_dw0(r1));
4203 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004204 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4205 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004206 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4207 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004208 }
4209 }
4210
4211 return "cgib";
4212}
4213
florian55085f82012-11-21 00:36:55 +00004214static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004215s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4216{
4217 IRTemp op1 = newTemp(Ity_I32);
4218 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004219 IRTemp cond = newTemp(Ity_I32);
4220
4221 if (m3 == 0) {
4222 } else {
4223 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004224 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004225 } else {
4226 assign(op1, get_gpr_w1(r1));
4227 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004228 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4229 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004230 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4231 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4232
4233 }
4234 }
4235
4236 return "cij";
4237}
4238
florian55085f82012-11-21 00:36:55 +00004239static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004240s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4241{
4242 IRTemp op1 = newTemp(Ity_I64);
4243 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004244 IRTemp cond = newTemp(Ity_I32);
4245
4246 if (m3 == 0) {
4247 } else {
4248 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004249 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004250 } else {
4251 assign(op1, get_gpr_dw0(r1));
4252 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004253 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4254 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004255 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4256 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4257
4258 }
4259 }
4260
4261 return "cgij";
4262}
4263
florian55085f82012-11-21 00:36:55 +00004264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004265s390_irgen_CH(UChar r1, IRTemp op2addr)
4266{
4267 IRTemp op1 = newTemp(Ity_I32);
4268 IRTemp op2 = newTemp(Ity_I32);
4269
4270 assign(op1, get_gpr_w1(r1));
4271 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4272 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4273
4274 return "ch";
4275}
4276
florian55085f82012-11-21 00:36:55 +00004277static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004278s390_irgen_CHY(UChar r1, IRTemp op2addr)
4279{
4280 IRTemp op1 = newTemp(Ity_I32);
4281 IRTemp op2 = newTemp(Ity_I32);
4282
4283 assign(op1, get_gpr_w1(r1));
4284 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4285 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4286
4287 return "chy";
4288}
4289
florian55085f82012-11-21 00:36:55 +00004290static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004291s390_irgen_CGH(UChar r1, IRTemp op2addr)
4292{
4293 IRTemp op1 = newTemp(Ity_I64);
4294 IRTemp op2 = newTemp(Ity_I64);
4295
4296 assign(op1, get_gpr_dw0(r1));
4297 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4298 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4299
4300 return "cgh";
4301}
4302
florian55085f82012-11-21 00:36:55 +00004303static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004304s390_irgen_CHI(UChar r1, UShort i2)
4305{
4306 IRTemp op1 = newTemp(Ity_I32);
4307 Int op2;
4308
4309 assign(op1, get_gpr_w1(r1));
4310 op2 = (Int)(Short)i2;
4311 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4312 mkU32((UInt)op2)));
4313
4314 return "chi";
4315}
4316
florian55085f82012-11-21 00:36:55 +00004317static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004318s390_irgen_CGHI(UChar r1, UShort i2)
4319{
4320 IRTemp op1 = newTemp(Ity_I64);
4321 Long op2;
4322
4323 assign(op1, get_gpr_dw0(r1));
4324 op2 = (Long)(Short)i2;
4325 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4326 mkU64((ULong)op2)));
4327
4328 return "cghi";
4329}
4330
florian55085f82012-11-21 00:36:55 +00004331static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004332s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4333{
4334 IRTemp op1 = newTemp(Ity_I16);
4335 Short op2;
4336
4337 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4338 op2 = (Short)i2;
4339 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4340 mkU16((UShort)op2)));
4341
4342 return "chhsi";
4343}
4344
florian55085f82012-11-21 00:36:55 +00004345static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004346s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4347{
4348 IRTemp op1 = newTemp(Ity_I32);
4349 Int op2;
4350
4351 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4352 op2 = (Int)(Short)i2;
4353 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4354 mkU32((UInt)op2)));
4355
4356 return "chsi";
4357}
4358
florian55085f82012-11-21 00:36:55 +00004359static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004360s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4361{
4362 IRTemp op1 = newTemp(Ity_I64);
4363 Long op2;
4364
4365 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4366 op2 = (Long)(Short)i2;
4367 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4368 mkU64((ULong)op2)));
4369
4370 return "cghsi";
4371}
4372
florian55085f82012-11-21 00:36:55 +00004373static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004374s390_irgen_CHRL(UChar r1, UInt i2)
4375{
4376 IRTemp op1 = newTemp(Ity_I32);
4377 IRTemp op2 = newTemp(Ity_I32);
4378
4379 assign(op1, get_gpr_w1(r1));
4380 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4381 ((ULong)(Long)(Int)i2 << 1)))));
4382 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4383
4384 return "chrl";
4385}
4386
florian55085f82012-11-21 00:36:55 +00004387static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004388s390_irgen_CGHRL(UChar r1, UInt i2)
4389{
4390 IRTemp op1 = newTemp(Ity_I64);
4391 IRTemp op2 = newTemp(Ity_I64);
4392
4393 assign(op1, get_gpr_dw0(r1));
4394 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4395 ((ULong)(Long)(Int)i2 << 1)))));
4396 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4397
4398 return "cghrl";
4399}
4400
florian55085f82012-11-21 00:36:55 +00004401static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004402s390_irgen_CHHR(UChar r1, UChar r2)
4403{
4404 IRTemp op1 = newTemp(Ity_I32);
4405 IRTemp op2 = newTemp(Ity_I32);
4406
4407 assign(op1, get_gpr_w0(r1));
4408 assign(op2, get_gpr_w0(r2));
4409 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4410
4411 return "chhr";
4412}
4413
florian55085f82012-11-21 00:36:55 +00004414static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004415s390_irgen_CHLR(UChar r1, UChar r2)
4416{
4417 IRTemp op1 = newTemp(Ity_I32);
4418 IRTemp op2 = newTemp(Ity_I32);
4419
4420 assign(op1, get_gpr_w0(r1));
4421 assign(op2, get_gpr_w1(r2));
4422 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4423
4424 return "chlr";
4425}
4426
florian55085f82012-11-21 00:36:55 +00004427static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004428s390_irgen_CHF(UChar r1, IRTemp op2addr)
4429{
4430 IRTemp op1 = newTemp(Ity_I32);
4431 IRTemp op2 = newTemp(Ity_I32);
4432
4433 assign(op1, get_gpr_w0(r1));
4434 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4435 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4436
4437 return "chf";
4438}
4439
florian55085f82012-11-21 00:36:55 +00004440static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004441s390_irgen_CIH(UChar r1, UInt i2)
4442{
4443 IRTemp op1 = newTemp(Ity_I32);
4444 Int op2;
4445
4446 assign(op1, get_gpr_w0(r1));
4447 op2 = (Int)i2;
4448 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4449 mkU32((UInt)op2)));
4450
4451 return "cih";
4452}
4453
florian55085f82012-11-21 00:36:55 +00004454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004455s390_irgen_CLR(UChar r1, UChar r2)
4456{
4457 IRTemp op1 = newTemp(Ity_I32);
4458 IRTemp op2 = newTemp(Ity_I32);
4459
4460 assign(op1, get_gpr_w1(r1));
4461 assign(op2, get_gpr_w1(r2));
4462 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4463
4464 return "clr";
4465}
4466
florian55085f82012-11-21 00:36:55 +00004467static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004468s390_irgen_CLGR(UChar r1, UChar r2)
4469{
4470 IRTemp op1 = newTemp(Ity_I64);
4471 IRTemp op2 = newTemp(Ity_I64);
4472
4473 assign(op1, get_gpr_dw0(r1));
4474 assign(op2, get_gpr_dw0(r2));
4475 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4476
4477 return "clgr";
4478}
4479
florian55085f82012-11-21 00:36:55 +00004480static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004481s390_irgen_CLGFR(UChar r1, UChar r2)
4482{
4483 IRTemp op1 = newTemp(Ity_I64);
4484 IRTemp op2 = newTemp(Ity_I64);
4485
4486 assign(op1, get_gpr_dw0(r1));
4487 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4488 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4489
4490 return "clgfr";
4491}
4492
florian55085f82012-11-21 00:36:55 +00004493static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004494s390_irgen_CL(UChar r1, IRTemp op2addr)
4495{
4496 IRTemp op1 = newTemp(Ity_I32);
4497 IRTemp op2 = newTemp(Ity_I32);
4498
4499 assign(op1, get_gpr_w1(r1));
4500 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4501 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4502
4503 return "cl";
4504}
4505
florian55085f82012-11-21 00:36:55 +00004506static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004507s390_irgen_CLY(UChar r1, IRTemp op2addr)
4508{
4509 IRTemp op1 = newTemp(Ity_I32);
4510 IRTemp op2 = newTemp(Ity_I32);
4511
4512 assign(op1, get_gpr_w1(r1));
4513 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4514 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4515
4516 return "cly";
4517}
4518
florian55085f82012-11-21 00:36:55 +00004519static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004520s390_irgen_CLG(UChar r1, IRTemp op2addr)
4521{
4522 IRTemp op1 = newTemp(Ity_I64);
4523 IRTemp op2 = newTemp(Ity_I64);
4524
4525 assign(op1, get_gpr_dw0(r1));
4526 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4527 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4528
4529 return "clg";
4530}
4531
florian55085f82012-11-21 00:36:55 +00004532static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004533s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4534{
4535 IRTemp op1 = newTemp(Ity_I64);
4536 IRTemp op2 = newTemp(Ity_I64);
4537
4538 assign(op1, get_gpr_dw0(r1));
4539 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4540 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4541
4542 return "clgf";
4543}
4544
florian55085f82012-11-21 00:36:55 +00004545static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004546s390_irgen_CLFI(UChar r1, UInt i2)
4547{
4548 IRTemp op1 = newTemp(Ity_I32);
4549 UInt op2;
4550
4551 assign(op1, get_gpr_w1(r1));
4552 op2 = i2;
4553 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4554 mkU32(op2)));
4555
4556 return "clfi";
4557}
4558
florian55085f82012-11-21 00:36:55 +00004559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004560s390_irgen_CLGFI(UChar r1, UInt i2)
4561{
4562 IRTemp op1 = newTemp(Ity_I64);
4563 ULong op2;
4564
4565 assign(op1, get_gpr_dw0(r1));
4566 op2 = (ULong)i2;
4567 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4568 mkU64(op2)));
4569
4570 return "clgfi";
4571}
4572
florian55085f82012-11-21 00:36:55 +00004573static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004574s390_irgen_CLI(UChar i2, IRTemp op1addr)
4575{
4576 IRTemp op1 = newTemp(Ity_I8);
4577 UChar op2;
4578
4579 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4580 op2 = i2;
4581 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4582 mkU8(op2)));
4583
4584 return "cli";
4585}
4586
florian55085f82012-11-21 00:36:55 +00004587static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004588s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4589{
4590 IRTemp op1 = newTemp(Ity_I8);
4591 UChar op2;
4592
4593 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4594 op2 = i2;
4595 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4596 mkU8(op2)));
4597
4598 return "cliy";
4599}
4600
florian55085f82012-11-21 00:36:55 +00004601static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004602s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4603{
4604 IRTemp op1 = newTemp(Ity_I32);
4605 UInt op2;
4606
4607 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4608 op2 = (UInt)i2;
4609 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4610 mkU32(op2)));
4611
4612 return "clfhsi";
4613}
4614
florian55085f82012-11-21 00:36:55 +00004615static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004616s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4617{
4618 IRTemp op1 = newTemp(Ity_I64);
4619 ULong op2;
4620
4621 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4622 op2 = (ULong)i2;
4623 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4624 mkU64(op2)));
4625
4626 return "clghsi";
4627}
4628
florian55085f82012-11-21 00:36:55 +00004629static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004630s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4631{
4632 IRTemp op1 = newTemp(Ity_I16);
4633 UShort op2;
4634
4635 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4636 op2 = i2;
4637 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4638 mkU16(op2)));
4639
4640 return "clhhsi";
4641}
4642
florian55085f82012-11-21 00:36:55 +00004643static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004644s390_irgen_CLRL(UChar r1, UInt i2)
4645{
4646 IRTemp op1 = newTemp(Ity_I32);
4647 IRTemp op2 = newTemp(Ity_I32);
4648
4649 assign(op1, get_gpr_w1(r1));
4650 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4651 i2 << 1))));
4652 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4653
4654 return "clrl";
4655}
4656
florian55085f82012-11-21 00:36:55 +00004657static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004658s390_irgen_CLGRL(UChar r1, UInt i2)
4659{
4660 IRTemp op1 = newTemp(Ity_I64);
4661 IRTemp op2 = newTemp(Ity_I64);
4662
4663 assign(op1, get_gpr_dw0(r1));
4664 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4665 i2 << 1))));
4666 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4667
4668 return "clgrl";
4669}
4670
florian55085f82012-11-21 00:36:55 +00004671static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004672s390_irgen_CLGFRL(UChar r1, UInt i2)
4673{
4674 IRTemp op1 = newTemp(Ity_I64);
4675 IRTemp op2 = newTemp(Ity_I64);
4676
4677 assign(op1, get_gpr_dw0(r1));
4678 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4679 ((ULong)(Long)(Int)i2 << 1)))));
4680 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4681
4682 return "clgfrl";
4683}
4684
florian55085f82012-11-21 00:36:55 +00004685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004686s390_irgen_CLHRL(UChar r1, UInt i2)
4687{
4688 IRTemp op1 = newTemp(Ity_I32);
4689 IRTemp op2 = newTemp(Ity_I32);
4690
4691 assign(op1, get_gpr_w1(r1));
4692 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4693 ((ULong)(Long)(Int)i2 << 1)))));
4694 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4695
4696 return "clhrl";
4697}
4698
florian55085f82012-11-21 00:36:55 +00004699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004700s390_irgen_CLGHRL(UChar r1, UInt i2)
4701{
4702 IRTemp op1 = newTemp(Ity_I64);
4703 IRTemp op2 = newTemp(Ity_I64);
4704
4705 assign(op1, get_gpr_dw0(r1));
4706 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4707 ((ULong)(Long)(Int)i2 << 1)))));
4708 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4709
4710 return "clghrl";
4711}
4712
florian55085f82012-11-21 00:36:55 +00004713static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004714s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4715{
4716 IRTemp op1 = newTemp(Ity_I32);
4717 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004718 IRTemp cond = newTemp(Ity_I32);
4719
4720 if (m3 == 0) {
4721 } else {
4722 if (m3 == 14) {
4723 always_goto(mkexpr(op4addr));
4724 } else {
4725 assign(op1, get_gpr_w1(r1));
4726 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004727 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4728 op1, op2));
florianf321da72012-07-21 20:32:57 +00004729 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4730 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004731 }
4732 }
4733
4734 return "clrb";
4735}
4736
florian55085f82012-11-21 00:36:55 +00004737static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004738s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4739{
4740 IRTemp op1 = newTemp(Ity_I64);
4741 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004742 IRTemp cond = newTemp(Ity_I32);
4743
4744 if (m3 == 0) {
4745 } else {
4746 if (m3 == 14) {
4747 always_goto(mkexpr(op4addr));
4748 } else {
4749 assign(op1, get_gpr_dw0(r1));
4750 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004751 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4752 op1, op2));
florianf321da72012-07-21 20:32:57 +00004753 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4754 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004755 }
4756 }
4757
4758 return "clgrb";
4759}
4760
florian55085f82012-11-21 00:36:55 +00004761static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004762s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4763{
4764 IRTemp op1 = newTemp(Ity_I32);
4765 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004766 IRTemp cond = newTemp(Ity_I32);
4767
4768 if (m3 == 0) {
4769 } else {
4770 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004771 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004772 } else {
4773 assign(op1, get_gpr_w1(r1));
4774 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004775 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4776 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004777 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4778 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4779
4780 }
4781 }
4782
4783 return "clrj";
4784}
4785
florian55085f82012-11-21 00:36:55 +00004786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004787s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4788{
4789 IRTemp op1 = newTemp(Ity_I64);
4790 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004791 IRTemp cond = newTemp(Ity_I32);
4792
4793 if (m3 == 0) {
4794 } else {
4795 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004796 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004797 } else {
4798 assign(op1, get_gpr_dw0(r1));
4799 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004800 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4801 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004802 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4803 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4804
4805 }
4806 }
4807
4808 return "clgrj";
4809}
4810
florian55085f82012-11-21 00:36:55 +00004811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004812s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4813{
4814 IRTemp op1 = newTemp(Ity_I32);
4815 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004816 IRTemp cond = newTemp(Ity_I32);
4817
4818 if (m3 == 0) {
4819 } else {
4820 if (m3 == 14) {
4821 always_goto(mkexpr(op4addr));
4822 } else {
4823 assign(op1, get_gpr_w1(r1));
4824 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004825 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4826 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004827 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4828 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004829 }
4830 }
4831
4832 return "clib";
4833}
4834
florian55085f82012-11-21 00:36:55 +00004835static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004836s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4837{
4838 IRTemp op1 = newTemp(Ity_I64);
4839 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004840 IRTemp cond = newTemp(Ity_I32);
4841
4842 if (m3 == 0) {
4843 } else {
4844 if (m3 == 14) {
4845 always_goto(mkexpr(op4addr));
4846 } else {
4847 assign(op1, get_gpr_dw0(r1));
4848 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004849 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4850 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004851 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4852 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004853 }
4854 }
4855
4856 return "clgib";
4857}
4858
florian55085f82012-11-21 00:36:55 +00004859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004860s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4861{
4862 IRTemp op1 = newTemp(Ity_I32);
4863 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004864 IRTemp cond = newTemp(Ity_I32);
4865
4866 if (m3 == 0) {
4867 } else {
4868 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004869 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004870 } else {
4871 assign(op1, get_gpr_w1(r1));
4872 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004873 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4874 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004875 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4876 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4877
4878 }
4879 }
4880
4881 return "clij";
4882}
4883
florian55085f82012-11-21 00:36:55 +00004884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004885s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4886{
4887 IRTemp op1 = newTemp(Ity_I64);
4888 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004889 IRTemp cond = newTemp(Ity_I32);
4890
4891 if (m3 == 0) {
4892 } else {
4893 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004894 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004895 } else {
4896 assign(op1, get_gpr_dw0(r1));
4897 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004898 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4899 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004900 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4901 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4902
4903 }
4904 }
4905
4906 return "clgij";
4907}
4908
florian55085f82012-11-21 00:36:55 +00004909static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004910s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4911{
4912 IRTemp op1 = newTemp(Ity_I32);
4913 IRTemp op2 = newTemp(Ity_I32);
4914 IRTemp b0 = newTemp(Ity_I32);
4915 IRTemp b1 = newTemp(Ity_I32);
4916 IRTemp b2 = newTemp(Ity_I32);
4917 IRTemp b3 = newTemp(Ity_I32);
4918 IRTemp c0 = newTemp(Ity_I32);
4919 IRTemp c1 = newTemp(Ity_I32);
4920 IRTemp c2 = newTemp(Ity_I32);
4921 IRTemp c3 = newTemp(Ity_I32);
4922 UChar n;
4923
4924 n = 0;
4925 if ((r3 & 8) != 0) {
4926 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4927 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4928 n = n + 1;
4929 } else {
4930 assign(b0, mkU32(0));
4931 assign(c0, mkU32(0));
4932 }
4933 if ((r3 & 4) != 0) {
4934 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4935 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4936 mkU64(n)))));
4937 n = n + 1;
4938 } else {
4939 assign(b1, mkU32(0));
4940 assign(c1, mkU32(0));
4941 }
4942 if ((r3 & 2) != 0) {
4943 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4944 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4945 mkU64(n)))));
4946 n = n + 1;
4947 } else {
4948 assign(b2, mkU32(0));
4949 assign(c2, mkU32(0));
4950 }
4951 if ((r3 & 1) != 0) {
4952 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4953 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4954 mkU64(n)))));
4955 n = n + 1;
4956 } else {
4957 assign(b3, mkU32(0));
4958 assign(c3, mkU32(0));
4959 }
4960 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4961 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4962 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4963 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4964 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4965 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4966 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4967
4968 return "clm";
4969}
4970
florian55085f82012-11-21 00:36:55 +00004971static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004972s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4973{
4974 IRTemp op1 = newTemp(Ity_I32);
4975 IRTemp op2 = newTemp(Ity_I32);
4976 IRTemp b0 = newTemp(Ity_I32);
4977 IRTemp b1 = newTemp(Ity_I32);
4978 IRTemp b2 = newTemp(Ity_I32);
4979 IRTemp b3 = newTemp(Ity_I32);
4980 IRTemp c0 = newTemp(Ity_I32);
4981 IRTemp c1 = newTemp(Ity_I32);
4982 IRTemp c2 = newTemp(Ity_I32);
4983 IRTemp c3 = newTemp(Ity_I32);
4984 UChar n;
4985
4986 n = 0;
4987 if ((r3 & 8) != 0) {
4988 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4989 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4990 n = n + 1;
4991 } else {
4992 assign(b0, mkU32(0));
4993 assign(c0, mkU32(0));
4994 }
4995 if ((r3 & 4) != 0) {
4996 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4997 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4998 mkU64(n)))));
4999 n = n + 1;
5000 } else {
5001 assign(b1, mkU32(0));
5002 assign(c1, mkU32(0));
5003 }
5004 if ((r3 & 2) != 0) {
5005 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
5006 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5007 mkU64(n)))));
5008 n = n + 1;
5009 } else {
5010 assign(b2, mkU32(0));
5011 assign(c2, mkU32(0));
5012 }
5013 if ((r3 & 1) != 0) {
5014 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
5015 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5016 mkU64(n)))));
5017 n = n + 1;
5018 } else {
5019 assign(b3, mkU32(0));
5020 assign(c3, mkU32(0));
5021 }
5022 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5023 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5024 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5025 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5026 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5027 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5028 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5029
5030 return "clmy";
5031}
5032
florian55085f82012-11-21 00:36:55 +00005033static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005034s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5035{
5036 IRTemp op1 = newTemp(Ity_I32);
5037 IRTemp op2 = newTemp(Ity_I32);
5038 IRTemp b0 = newTemp(Ity_I32);
5039 IRTemp b1 = newTemp(Ity_I32);
5040 IRTemp b2 = newTemp(Ity_I32);
5041 IRTemp b3 = newTemp(Ity_I32);
5042 IRTemp c0 = newTemp(Ity_I32);
5043 IRTemp c1 = newTemp(Ity_I32);
5044 IRTemp c2 = newTemp(Ity_I32);
5045 IRTemp c3 = newTemp(Ity_I32);
5046 UChar n;
5047
5048 n = 0;
5049 if ((r3 & 8) != 0) {
5050 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5051 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5052 n = n + 1;
5053 } else {
5054 assign(b0, mkU32(0));
5055 assign(c0, mkU32(0));
5056 }
5057 if ((r3 & 4) != 0) {
5058 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5059 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5060 mkU64(n)))));
5061 n = n + 1;
5062 } else {
5063 assign(b1, mkU32(0));
5064 assign(c1, mkU32(0));
5065 }
5066 if ((r3 & 2) != 0) {
5067 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5068 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5069 mkU64(n)))));
5070 n = n + 1;
5071 } else {
5072 assign(b2, mkU32(0));
5073 assign(c2, mkU32(0));
5074 }
5075 if ((r3 & 1) != 0) {
5076 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5077 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5078 mkU64(n)))));
5079 n = n + 1;
5080 } else {
5081 assign(b3, mkU32(0));
5082 assign(c3, mkU32(0));
5083 }
5084 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5085 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5086 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5087 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5088 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5089 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5090 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5091
5092 return "clmh";
5093}
5094
florian55085f82012-11-21 00:36:55 +00005095static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005096s390_irgen_CLHHR(UChar r1, UChar r2)
5097{
5098 IRTemp op1 = newTemp(Ity_I32);
5099 IRTemp op2 = newTemp(Ity_I32);
5100
5101 assign(op1, get_gpr_w0(r1));
5102 assign(op2, get_gpr_w0(r2));
5103 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5104
5105 return "clhhr";
5106}
5107
florian55085f82012-11-21 00:36:55 +00005108static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005109s390_irgen_CLHLR(UChar r1, UChar r2)
5110{
5111 IRTemp op1 = newTemp(Ity_I32);
5112 IRTemp op2 = newTemp(Ity_I32);
5113
5114 assign(op1, get_gpr_w0(r1));
5115 assign(op2, get_gpr_w1(r2));
5116 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5117
5118 return "clhlr";
5119}
5120
florian55085f82012-11-21 00:36:55 +00005121static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005122s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5123{
5124 IRTemp op1 = newTemp(Ity_I32);
5125 IRTemp op2 = newTemp(Ity_I32);
5126
5127 assign(op1, get_gpr_w0(r1));
5128 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5129 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5130
5131 return "clhf";
5132}
5133
florian55085f82012-11-21 00:36:55 +00005134static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005135s390_irgen_CLIH(UChar r1, UInt i2)
5136{
5137 IRTemp op1 = newTemp(Ity_I32);
5138 UInt op2;
5139
5140 assign(op1, get_gpr_w0(r1));
5141 op2 = i2;
5142 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5143 mkU32(op2)));
5144
5145 return "clih";
5146}
5147
florian55085f82012-11-21 00:36:55 +00005148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005149s390_irgen_CPYA(UChar r1, UChar r2)
5150{
5151 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005152 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005153 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5154
5155 return "cpya";
5156}
5157
florian55085f82012-11-21 00:36:55 +00005158static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005159s390_irgen_XR(UChar r1, UChar r2)
5160{
5161 IRTemp op1 = newTemp(Ity_I32);
5162 IRTemp op2 = newTemp(Ity_I32);
5163 IRTemp result = newTemp(Ity_I32);
5164
5165 if (r1 == r2) {
5166 assign(result, mkU32(0));
5167 } else {
5168 assign(op1, get_gpr_w1(r1));
5169 assign(op2, get_gpr_w1(r2));
5170 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5171 }
5172 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5173 put_gpr_w1(r1, mkexpr(result));
5174
5175 return "xr";
5176}
5177
florian55085f82012-11-21 00:36:55 +00005178static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005179s390_irgen_XGR(UChar r1, UChar r2)
5180{
5181 IRTemp op1 = newTemp(Ity_I64);
5182 IRTemp op2 = newTemp(Ity_I64);
5183 IRTemp result = newTemp(Ity_I64);
5184
5185 if (r1 == r2) {
5186 assign(result, mkU64(0));
5187 } else {
5188 assign(op1, get_gpr_dw0(r1));
5189 assign(op2, get_gpr_dw0(r2));
5190 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5191 }
5192 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5193 put_gpr_dw0(r1, mkexpr(result));
5194
5195 return "xgr";
5196}
5197
florian55085f82012-11-21 00:36:55 +00005198static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005199s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5200{
5201 IRTemp op2 = newTemp(Ity_I32);
5202 IRTemp op3 = newTemp(Ity_I32);
5203 IRTemp result = newTemp(Ity_I32);
5204
5205 assign(op2, get_gpr_w1(r2));
5206 assign(op3, get_gpr_w1(r3));
5207 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5208 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5209 put_gpr_w1(r1, mkexpr(result));
5210
5211 return "xrk";
5212}
5213
florian55085f82012-11-21 00:36:55 +00005214static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005215s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5216{
5217 IRTemp op2 = newTemp(Ity_I64);
5218 IRTemp op3 = newTemp(Ity_I64);
5219 IRTemp result = newTemp(Ity_I64);
5220
5221 assign(op2, get_gpr_dw0(r2));
5222 assign(op3, get_gpr_dw0(r3));
5223 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5224 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5225 put_gpr_dw0(r1, mkexpr(result));
5226
5227 return "xgrk";
5228}
5229
florian55085f82012-11-21 00:36:55 +00005230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005231s390_irgen_X(UChar r1, IRTemp op2addr)
5232{
5233 IRTemp op1 = newTemp(Ity_I32);
5234 IRTemp op2 = newTemp(Ity_I32);
5235 IRTemp result = newTemp(Ity_I32);
5236
5237 assign(op1, get_gpr_w1(r1));
5238 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5239 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5240 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5241 put_gpr_w1(r1, mkexpr(result));
5242
5243 return "x";
5244}
5245
florian55085f82012-11-21 00:36:55 +00005246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005247s390_irgen_XY(UChar r1, IRTemp op2addr)
5248{
5249 IRTemp op1 = newTemp(Ity_I32);
5250 IRTemp op2 = newTemp(Ity_I32);
5251 IRTemp result = newTemp(Ity_I32);
5252
5253 assign(op1, get_gpr_w1(r1));
5254 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5255 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5256 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5257 put_gpr_w1(r1, mkexpr(result));
5258
5259 return "xy";
5260}
5261
florian55085f82012-11-21 00:36:55 +00005262static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005263s390_irgen_XG(UChar r1, IRTemp op2addr)
5264{
5265 IRTemp op1 = newTemp(Ity_I64);
5266 IRTemp op2 = newTemp(Ity_I64);
5267 IRTemp result = newTemp(Ity_I64);
5268
5269 assign(op1, get_gpr_dw0(r1));
5270 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5271 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5272 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5273 put_gpr_dw0(r1, mkexpr(result));
5274
5275 return "xg";
5276}
5277
florian55085f82012-11-21 00:36:55 +00005278static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005279s390_irgen_XI(UChar i2, IRTemp op1addr)
5280{
5281 IRTemp op1 = newTemp(Ity_I8);
5282 UChar op2;
5283 IRTemp result = newTemp(Ity_I8);
5284
5285 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5286 op2 = i2;
5287 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5288 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5289 store(mkexpr(op1addr), mkexpr(result));
5290
5291 return "xi";
5292}
5293
florian55085f82012-11-21 00:36:55 +00005294static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005295s390_irgen_XIY(UChar i2, IRTemp op1addr)
5296{
5297 IRTemp op1 = newTemp(Ity_I8);
5298 UChar op2;
5299 IRTemp result = newTemp(Ity_I8);
5300
5301 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5302 op2 = i2;
5303 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5304 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5305 store(mkexpr(op1addr), mkexpr(result));
5306
5307 return "xiy";
5308}
5309
florian55085f82012-11-21 00:36:55 +00005310static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005311s390_irgen_XIHF(UChar r1, UInt i2)
5312{
5313 IRTemp op1 = newTemp(Ity_I32);
5314 UInt op2;
5315 IRTemp result = newTemp(Ity_I32);
5316
5317 assign(op1, get_gpr_w0(r1));
5318 op2 = i2;
5319 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5320 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5321 put_gpr_w0(r1, mkexpr(result));
5322
5323 return "xihf";
5324}
5325
florian55085f82012-11-21 00:36:55 +00005326static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005327s390_irgen_XILF(UChar r1, UInt i2)
5328{
5329 IRTemp op1 = newTemp(Ity_I32);
5330 UInt op2;
5331 IRTemp result = newTemp(Ity_I32);
5332
5333 assign(op1, get_gpr_w1(r1));
5334 op2 = i2;
5335 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5336 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5337 put_gpr_w1(r1, mkexpr(result));
5338
5339 return "xilf";
5340}
5341
florian55085f82012-11-21 00:36:55 +00005342static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005343s390_irgen_EAR(UChar r1, UChar r2)
5344{
5345 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005346 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005347 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5348
5349 return "ear";
5350}
5351
florian55085f82012-11-21 00:36:55 +00005352static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005353s390_irgen_IC(UChar r1, IRTemp op2addr)
5354{
5355 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5356
5357 return "ic";
5358}
5359
florian55085f82012-11-21 00:36:55 +00005360static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005361s390_irgen_ICY(UChar r1, IRTemp op2addr)
5362{
5363 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5364
5365 return "icy";
5366}
5367
florian55085f82012-11-21 00:36:55 +00005368static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005369s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5370{
5371 UChar n;
5372 IRTemp result = newTemp(Ity_I32);
5373 UInt mask;
5374
5375 n = 0;
5376 mask = (UInt)r3;
5377 if ((mask & 8) != 0) {
5378 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5379 n = n + 1;
5380 }
5381 if ((mask & 4) != 0) {
5382 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5383
5384 n = n + 1;
5385 }
5386 if ((mask & 2) != 0) {
5387 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5388
5389 n = n + 1;
5390 }
5391 if ((mask & 1) != 0) {
5392 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5393
5394 n = n + 1;
5395 }
5396 assign(result, get_gpr_w1(r1));
5397 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5398 mkU32(mask)));
5399
5400 return "icm";
5401}
5402
florian55085f82012-11-21 00:36:55 +00005403static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005404s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5405{
5406 UChar n;
5407 IRTemp result = newTemp(Ity_I32);
5408 UInt mask;
5409
5410 n = 0;
5411 mask = (UInt)r3;
5412 if ((mask & 8) != 0) {
5413 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5414 n = n + 1;
5415 }
5416 if ((mask & 4) != 0) {
5417 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5418
5419 n = n + 1;
5420 }
5421 if ((mask & 2) != 0) {
5422 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5423
5424 n = n + 1;
5425 }
5426 if ((mask & 1) != 0) {
5427 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5428
5429 n = n + 1;
5430 }
5431 assign(result, get_gpr_w1(r1));
5432 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5433 mkU32(mask)));
5434
5435 return "icmy";
5436}
5437
florian55085f82012-11-21 00:36:55 +00005438static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005439s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5440{
5441 UChar n;
5442 IRTemp result = newTemp(Ity_I32);
5443 UInt mask;
5444
5445 n = 0;
5446 mask = (UInt)r3;
5447 if ((mask & 8) != 0) {
5448 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5449 n = n + 1;
5450 }
5451 if ((mask & 4) != 0) {
5452 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5453
5454 n = n + 1;
5455 }
5456 if ((mask & 2) != 0) {
5457 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5458
5459 n = n + 1;
5460 }
5461 if ((mask & 1) != 0) {
5462 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5463
5464 n = n + 1;
5465 }
5466 assign(result, get_gpr_w0(r1));
5467 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5468 mkU32(mask)));
5469
5470 return "icmh";
5471}
5472
florian55085f82012-11-21 00:36:55 +00005473static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005474s390_irgen_IIHF(UChar r1, UInt i2)
5475{
5476 put_gpr_w0(r1, mkU32(i2));
5477
5478 return "iihf";
5479}
5480
florian55085f82012-11-21 00:36:55 +00005481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005482s390_irgen_IIHH(UChar r1, UShort i2)
5483{
5484 put_gpr_hw0(r1, mkU16(i2));
5485
5486 return "iihh";
5487}
5488
florian55085f82012-11-21 00:36:55 +00005489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005490s390_irgen_IIHL(UChar r1, UShort i2)
5491{
5492 put_gpr_hw1(r1, mkU16(i2));
5493
5494 return "iihl";
5495}
5496
florian55085f82012-11-21 00:36:55 +00005497static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005498s390_irgen_IILF(UChar r1, UInt i2)
5499{
5500 put_gpr_w1(r1, mkU32(i2));
5501
5502 return "iilf";
5503}
5504
florian55085f82012-11-21 00:36:55 +00005505static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005506s390_irgen_IILH(UChar r1, UShort i2)
5507{
5508 put_gpr_hw2(r1, mkU16(i2));
5509
5510 return "iilh";
5511}
5512
florian55085f82012-11-21 00:36:55 +00005513static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005514s390_irgen_IILL(UChar r1, UShort i2)
5515{
5516 put_gpr_hw3(r1, mkU16(i2));
5517
5518 return "iill";
5519}
5520
florian55085f82012-11-21 00:36:55 +00005521static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005522s390_irgen_LR(UChar r1, UChar r2)
5523{
5524 put_gpr_w1(r1, get_gpr_w1(r2));
5525
5526 return "lr";
5527}
5528
florian55085f82012-11-21 00:36:55 +00005529static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005530s390_irgen_LGR(UChar r1, UChar r2)
5531{
5532 put_gpr_dw0(r1, get_gpr_dw0(r2));
5533
5534 return "lgr";
5535}
5536
florian55085f82012-11-21 00:36:55 +00005537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005538s390_irgen_LGFR(UChar r1, UChar r2)
5539{
5540 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5541
5542 return "lgfr";
5543}
5544
florian55085f82012-11-21 00:36:55 +00005545static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005546s390_irgen_L(UChar r1, IRTemp op2addr)
5547{
5548 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5549
5550 return "l";
5551}
5552
florian55085f82012-11-21 00:36:55 +00005553static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005554s390_irgen_LY(UChar r1, IRTemp op2addr)
5555{
5556 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5557
5558 return "ly";
5559}
5560
florian55085f82012-11-21 00:36:55 +00005561static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005562s390_irgen_LG(UChar r1, IRTemp op2addr)
5563{
5564 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5565
5566 return "lg";
5567}
5568
florian55085f82012-11-21 00:36:55 +00005569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005570s390_irgen_LGF(UChar r1, IRTemp op2addr)
5571{
5572 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5573
5574 return "lgf";
5575}
5576
florian55085f82012-11-21 00:36:55 +00005577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005578s390_irgen_LGFI(UChar r1, UInt i2)
5579{
5580 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5581
5582 return "lgfi";
5583}
5584
florian55085f82012-11-21 00:36:55 +00005585static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005586s390_irgen_LRL(UChar r1, UInt i2)
5587{
5588 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5589 i2 << 1))));
5590
5591 return "lrl";
5592}
5593
florian55085f82012-11-21 00:36:55 +00005594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005595s390_irgen_LGRL(UChar r1, UInt i2)
5596{
5597 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5598 i2 << 1))));
5599
5600 return "lgrl";
5601}
5602
florian55085f82012-11-21 00:36:55 +00005603static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005604s390_irgen_LGFRL(UChar r1, UInt i2)
5605{
5606 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5607 ((ULong)(Long)(Int)i2 << 1)))));
5608
5609 return "lgfrl";
5610}
5611
florian55085f82012-11-21 00:36:55 +00005612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005613s390_irgen_LA(UChar r1, IRTemp op2addr)
5614{
5615 put_gpr_dw0(r1, mkexpr(op2addr));
5616
5617 return "la";
5618}
5619
florian55085f82012-11-21 00:36:55 +00005620static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005621s390_irgen_LAY(UChar r1, IRTemp op2addr)
5622{
5623 put_gpr_dw0(r1, mkexpr(op2addr));
5624
5625 return "lay";
5626}
5627
florian55085f82012-11-21 00:36:55 +00005628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005629s390_irgen_LAE(UChar r1, IRTemp op2addr)
5630{
5631 put_gpr_dw0(r1, mkexpr(op2addr));
5632
5633 return "lae";
5634}
5635
florian55085f82012-11-21 00:36:55 +00005636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005637s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5638{
5639 put_gpr_dw0(r1, mkexpr(op2addr));
5640
5641 return "laey";
5642}
5643
florian55085f82012-11-21 00:36:55 +00005644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005645s390_irgen_LARL(UChar r1, UInt i2)
5646{
5647 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5648
5649 return "larl";
5650}
5651
floriana265ee72012-12-02 20:58:17 +00005652/* The IR representation of LAA and friends is an approximation of what
5653 happens natively. Essentially a loop containing a compare-and-swap is
5654 constructed which will iterate until the CAS succeeds. As a consequence,
5655 instrumenters may see more memory accesses than happen natively. See also
5656 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005657static void
5658s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005659{
floriana265ee72012-12-02 20:58:17 +00005660 IRCAS *cas;
5661 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005662 IRTemp op2 = newTemp(Ity_I32);
5663 IRTemp op3 = newTemp(Ity_I32);
5664 IRTemp result = newTemp(Ity_I32);
5665
5666 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5667 assign(op3, get_gpr_w1(r3));
5668 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005669
5670 /* Place the addition of second operand and third operand at the
5671 second-operand location everytime */
5672 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5673 Iend_BE, mkexpr(op2addr),
5674 NULL, mkexpr(op2), /* expected value */
5675 NULL, mkexpr(result) /* new value */);
5676 stmt(IRStmt_CAS(cas));
5677
florianffc94012012-12-02 21:31:15 +00005678 /* Set CC according to 32-bit addition */
5679 if (is_signed) {
5680 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5681 } else {
5682 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5683 }
floriana265ee72012-12-02 20:58:17 +00005684
5685 /* If old_mem contains the expected value, then the CAS succeeded.
5686 Otherwise, it did not */
5687 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5688 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005689}
5690
5691static void
5692s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5693{
5694 IRCAS *cas;
5695 IRTemp old_mem = newTemp(Ity_I64);
5696 IRTemp op2 = newTemp(Ity_I64);
5697 IRTemp op3 = newTemp(Ity_I64);
5698 IRTemp result = newTemp(Ity_I64);
5699
5700 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5701 assign(op3, get_gpr_dw0(r3));
5702 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5703
5704 /* Place the addition of second operand and third operand at the
5705 second-operand location everytime */
5706 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5707 Iend_BE, mkexpr(op2addr),
5708 NULL, mkexpr(op2), /* expected value */
5709 NULL, mkexpr(result) /* new value */);
5710 stmt(IRStmt_CAS(cas));
5711
5712 /* Set CC according to 64-bit addition */
5713 if (is_signed) {
5714 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5715 } else {
5716 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5717 }
5718
5719 /* If old_mem contains the expected value, then the CAS succeeded.
5720 Otherwise, it did not */
5721 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5722 put_gpr_dw0(r1, mkexpr(old_mem));
5723}
5724
5725static void
5726s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5727{
5728 IRCAS *cas;
5729 IRTemp old_mem = newTemp(Ity_I32);
5730 IRTemp op2 = newTemp(Ity_I32);
5731 IRTemp op3 = newTemp(Ity_I32);
5732 IRTemp result = newTemp(Ity_I32);
5733
5734 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5735 assign(op3, get_gpr_w1(r3));
5736 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5737
5738 /* Place the addition of second operand and third operand at the
5739 second-operand location everytime */
5740 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5741 Iend_BE, mkexpr(op2addr),
5742 NULL, mkexpr(op2), /* expected value */
5743 NULL, mkexpr(result) /* new value */);
5744 stmt(IRStmt_CAS(cas));
5745
5746 /* Set CC according to bitwise operation */
5747 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5748
5749 /* If old_mem contains the expected value, then the CAS succeeded.
5750 Otherwise, it did not */
5751 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5752 put_gpr_w1(r1, mkexpr(old_mem));
5753}
5754
5755static void
5756s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5757{
5758 IRCAS *cas;
5759 IRTemp old_mem = newTemp(Ity_I64);
5760 IRTemp op2 = newTemp(Ity_I64);
5761 IRTemp op3 = newTemp(Ity_I64);
5762 IRTemp result = newTemp(Ity_I64);
5763
5764 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5765 assign(op3, get_gpr_dw0(r3));
5766 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5767
5768 /* Place the addition of second operand and third operand at the
5769 second-operand location everytime */
5770 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5771 Iend_BE, mkexpr(op2addr),
5772 NULL, mkexpr(op2), /* expected value */
5773 NULL, mkexpr(result) /* new value */);
5774 stmt(IRStmt_CAS(cas));
5775
5776 /* Set CC according to bitwise operation */
5777 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5778
5779 /* If old_mem contains the expected value, then the CAS succeeded.
5780 Otherwise, it did not */
5781 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5782 put_gpr_dw0(r1, mkexpr(old_mem));
5783}
5784
5785static const HChar *
5786s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5787{
5788 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005789
5790 return "laa";
5791}
5792
florian55085f82012-11-21 00:36:55 +00005793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005794s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5795{
florianffc94012012-12-02 21:31:15 +00005796 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005797
5798 return "laag";
5799}
5800
florian55085f82012-11-21 00:36:55 +00005801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005802s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5803{
florianffc94012012-12-02 21:31:15 +00005804 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005805
5806 return "laal";
5807}
5808
florian55085f82012-11-21 00:36:55 +00005809static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005810s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5811{
florianffc94012012-12-02 21:31:15 +00005812 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005813
5814 return "laalg";
5815}
5816
florian55085f82012-11-21 00:36:55 +00005817static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005818s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5819{
florianffc94012012-12-02 21:31:15 +00005820 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005821
5822 return "lan";
5823}
5824
florian55085f82012-11-21 00:36:55 +00005825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005826s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5827{
florianffc94012012-12-02 21:31:15 +00005828 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005829
5830 return "lang";
5831}
5832
florian55085f82012-11-21 00:36:55 +00005833static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005834s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5835{
florianffc94012012-12-02 21:31:15 +00005836 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005837
5838 return "lax";
5839}
5840
florian55085f82012-11-21 00:36:55 +00005841static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005842s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5843{
florianffc94012012-12-02 21:31:15 +00005844 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005845
5846 return "laxg";
5847}
5848
florian55085f82012-11-21 00:36:55 +00005849static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005850s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5851{
florianffc94012012-12-02 21:31:15 +00005852 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005853
5854 return "lao";
5855}
5856
florian55085f82012-11-21 00:36:55 +00005857static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005858s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5859{
florianffc94012012-12-02 21:31:15 +00005860 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005861
5862 return "laog";
5863}
5864
florian55085f82012-11-21 00:36:55 +00005865static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005866s390_irgen_LTR(UChar r1, UChar r2)
5867{
5868 IRTemp op2 = newTemp(Ity_I32);
5869
5870 assign(op2, get_gpr_w1(r2));
5871 put_gpr_w1(r1, mkexpr(op2));
5872 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5873
5874 return "ltr";
5875}
5876
florian55085f82012-11-21 00:36:55 +00005877static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005878s390_irgen_LTGR(UChar r1, UChar r2)
5879{
5880 IRTemp op2 = newTemp(Ity_I64);
5881
5882 assign(op2, get_gpr_dw0(r2));
5883 put_gpr_dw0(r1, mkexpr(op2));
5884 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5885
5886 return "ltgr";
5887}
5888
florian55085f82012-11-21 00:36:55 +00005889static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005890s390_irgen_LTGFR(UChar r1, UChar r2)
5891{
5892 IRTemp op2 = newTemp(Ity_I64);
5893
5894 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5895 put_gpr_dw0(r1, mkexpr(op2));
5896 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5897
5898 return "ltgfr";
5899}
5900
florian55085f82012-11-21 00:36:55 +00005901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005902s390_irgen_LT(UChar r1, IRTemp op2addr)
5903{
5904 IRTemp op2 = newTemp(Ity_I32);
5905
5906 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5907 put_gpr_w1(r1, mkexpr(op2));
5908 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5909
5910 return "lt";
5911}
5912
florian55085f82012-11-21 00:36:55 +00005913static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005914s390_irgen_LTG(UChar r1, IRTemp op2addr)
5915{
5916 IRTemp op2 = newTemp(Ity_I64);
5917
5918 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5919 put_gpr_dw0(r1, mkexpr(op2));
5920 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5921
5922 return "ltg";
5923}
5924
florian55085f82012-11-21 00:36:55 +00005925static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005926s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5927{
5928 IRTemp op2 = newTemp(Ity_I64);
5929
5930 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5931 put_gpr_dw0(r1, mkexpr(op2));
5932 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5933
5934 return "ltgf";
5935}
5936
florian55085f82012-11-21 00:36:55 +00005937static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005938s390_irgen_LBR(UChar r1, UChar r2)
5939{
5940 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5941
5942 return "lbr";
5943}
5944
florian55085f82012-11-21 00:36:55 +00005945static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005946s390_irgen_LGBR(UChar r1, UChar r2)
5947{
5948 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5949
5950 return "lgbr";
5951}
5952
florian55085f82012-11-21 00:36:55 +00005953static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005954s390_irgen_LB(UChar r1, IRTemp op2addr)
5955{
5956 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5957
5958 return "lb";
5959}
5960
florian55085f82012-11-21 00:36:55 +00005961static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005962s390_irgen_LGB(UChar r1, IRTemp op2addr)
5963{
5964 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5965
5966 return "lgb";
5967}
5968
florian55085f82012-11-21 00:36:55 +00005969static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005970s390_irgen_LBH(UChar r1, IRTemp op2addr)
5971{
5972 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5973
5974 return "lbh";
5975}
5976
florian55085f82012-11-21 00:36:55 +00005977static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005978s390_irgen_LCR(UChar r1, UChar r2)
5979{
5980 Int op1;
5981 IRTemp op2 = newTemp(Ity_I32);
5982 IRTemp result = newTemp(Ity_I32);
5983
5984 op1 = 0;
5985 assign(op2, get_gpr_w1(r2));
5986 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5987 put_gpr_w1(r1, mkexpr(result));
5988 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5989 op1)), op2);
5990
5991 return "lcr";
5992}
5993
florian55085f82012-11-21 00:36:55 +00005994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005995s390_irgen_LCGR(UChar r1, UChar r2)
5996{
5997 Long op1;
5998 IRTemp op2 = newTemp(Ity_I64);
5999 IRTemp result = newTemp(Ity_I64);
6000
6001 op1 = 0ULL;
6002 assign(op2, get_gpr_dw0(r2));
6003 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6004 put_gpr_dw0(r1, mkexpr(result));
6005 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6006 op1)), op2);
6007
6008 return "lcgr";
6009}
6010
florian55085f82012-11-21 00:36:55 +00006011static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006012s390_irgen_LCGFR(UChar r1, UChar r2)
6013{
6014 Long op1;
6015 IRTemp op2 = newTemp(Ity_I64);
6016 IRTemp result = newTemp(Ity_I64);
6017
6018 op1 = 0ULL;
6019 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6020 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6021 put_gpr_dw0(r1, mkexpr(result));
6022 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6023 op1)), op2);
6024
6025 return "lcgfr";
6026}
6027
florian55085f82012-11-21 00:36:55 +00006028static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006029s390_irgen_LHR(UChar r1, UChar r2)
6030{
6031 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
6032
6033 return "lhr";
6034}
6035
florian55085f82012-11-21 00:36:55 +00006036static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006037s390_irgen_LGHR(UChar r1, UChar r2)
6038{
6039 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6040
6041 return "lghr";
6042}
6043
florian55085f82012-11-21 00:36:55 +00006044static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006045s390_irgen_LH(UChar r1, IRTemp op2addr)
6046{
6047 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6048
6049 return "lh";
6050}
6051
florian55085f82012-11-21 00:36:55 +00006052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006053s390_irgen_LHY(UChar r1, IRTemp op2addr)
6054{
6055 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6056
6057 return "lhy";
6058}
6059
florian55085f82012-11-21 00:36:55 +00006060static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006061s390_irgen_LGH(UChar r1, IRTemp op2addr)
6062{
6063 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6064
6065 return "lgh";
6066}
6067
florian55085f82012-11-21 00:36:55 +00006068static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006069s390_irgen_LHI(UChar r1, UShort i2)
6070{
6071 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6072
6073 return "lhi";
6074}
6075
florian55085f82012-11-21 00:36:55 +00006076static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006077s390_irgen_LGHI(UChar r1, UShort i2)
6078{
6079 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6080
6081 return "lghi";
6082}
6083
florian55085f82012-11-21 00:36:55 +00006084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006085s390_irgen_LHRL(UChar r1, UInt i2)
6086{
6087 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6088 ((ULong)(Long)(Int)i2 << 1)))));
6089
6090 return "lhrl";
6091}
6092
florian55085f82012-11-21 00:36:55 +00006093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006094s390_irgen_LGHRL(UChar r1, UInt i2)
6095{
6096 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6097 ((ULong)(Long)(Int)i2 << 1)))));
6098
6099 return "lghrl";
6100}
6101
florian55085f82012-11-21 00:36:55 +00006102static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006103s390_irgen_LHH(UChar r1, IRTemp op2addr)
6104{
6105 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6106
6107 return "lhh";
6108}
6109
florian55085f82012-11-21 00:36:55 +00006110static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006111s390_irgen_LFH(UChar r1, IRTemp op2addr)
6112{
6113 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6114
6115 return "lfh";
6116}
6117
florian55085f82012-11-21 00:36:55 +00006118static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006119s390_irgen_LLGFR(UChar r1, UChar r2)
6120{
6121 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6122
6123 return "llgfr";
6124}
6125
florian55085f82012-11-21 00:36:55 +00006126static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006127s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6128{
6129 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6130
6131 return "llgf";
6132}
6133
florian55085f82012-11-21 00:36:55 +00006134static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006135s390_irgen_LLGFRL(UChar r1, UInt i2)
6136{
6137 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6138 ((ULong)(Long)(Int)i2 << 1)))));
6139
6140 return "llgfrl";
6141}
6142
florian55085f82012-11-21 00:36:55 +00006143static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006144s390_irgen_LLCR(UChar r1, UChar r2)
6145{
6146 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6147
6148 return "llcr";
6149}
6150
florian55085f82012-11-21 00:36:55 +00006151static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006152s390_irgen_LLGCR(UChar r1, UChar r2)
6153{
6154 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6155
6156 return "llgcr";
6157}
6158
florian55085f82012-11-21 00:36:55 +00006159static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006160s390_irgen_LLC(UChar r1, IRTemp op2addr)
6161{
6162 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6163
6164 return "llc";
6165}
6166
florian55085f82012-11-21 00:36:55 +00006167static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006168s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6169{
6170 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6171
6172 return "llgc";
6173}
6174
florian55085f82012-11-21 00:36:55 +00006175static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006176s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6177{
6178 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6179
6180 return "llch";
6181}
6182
florian55085f82012-11-21 00:36:55 +00006183static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006184s390_irgen_LLHR(UChar r1, UChar r2)
6185{
6186 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6187
6188 return "llhr";
6189}
6190
florian55085f82012-11-21 00:36:55 +00006191static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006192s390_irgen_LLGHR(UChar r1, UChar r2)
6193{
6194 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6195
6196 return "llghr";
6197}
6198
florian55085f82012-11-21 00:36:55 +00006199static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006200s390_irgen_LLH(UChar r1, IRTemp op2addr)
6201{
6202 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6203
6204 return "llh";
6205}
6206
florian55085f82012-11-21 00:36:55 +00006207static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006208s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6209{
6210 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6211
6212 return "llgh";
6213}
6214
florian55085f82012-11-21 00:36:55 +00006215static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006216s390_irgen_LLHRL(UChar r1, UInt i2)
6217{
6218 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6219 ((ULong)(Long)(Int)i2 << 1)))));
6220
6221 return "llhrl";
6222}
6223
florian55085f82012-11-21 00:36:55 +00006224static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006225s390_irgen_LLGHRL(UChar r1, UInt i2)
6226{
6227 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6228 ((ULong)(Long)(Int)i2 << 1)))));
6229
6230 return "llghrl";
6231}
6232
florian55085f82012-11-21 00:36:55 +00006233static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006234s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6235{
6236 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6237
6238 return "llhh";
6239}
6240
florian55085f82012-11-21 00:36:55 +00006241static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006242s390_irgen_LLIHF(UChar r1, UInt i2)
6243{
6244 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6245
6246 return "llihf";
6247}
6248
florian55085f82012-11-21 00:36:55 +00006249static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006250s390_irgen_LLIHH(UChar r1, UShort i2)
6251{
6252 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6253
6254 return "llihh";
6255}
6256
florian55085f82012-11-21 00:36:55 +00006257static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006258s390_irgen_LLIHL(UChar r1, UShort i2)
6259{
6260 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6261
6262 return "llihl";
6263}
6264
florian55085f82012-11-21 00:36:55 +00006265static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006266s390_irgen_LLILF(UChar r1, UInt i2)
6267{
6268 put_gpr_dw0(r1, mkU64(i2));
6269
6270 return "llilf";
6271}
6272
florian55085f82012-11-21 00:36:55 +00006273static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006274s390_irgen_LLILH(UChar r1, UShort i2)
6275{
6276 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6277
6278 return "llilh";
6279}
6280
florian55085f82012-11-21 00:36:55 +00006281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006282s390_irgen_LLILL(UChar r1, UShort i2)
6283{
6284 put_gpr_dw0(r1, mkU64(i2));
6285
6286 return "llill";
6287}
6288
florian55085f82012-11-21 00:36:55 +00006289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006290s390_irgen_LLGTR(UChar r1, UChar r2)
6291{
6292 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6293 mkU32(2147483647))));
6294
6295 return "llgtr";
6296}
6297
florian55085f82012-11-21 00:36:55 +00006298static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006299s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6300{
6301 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6302 mkexpr(op2addr)), mkU32(2147483647))));
6303
6304 return "llgt";
6305}
6306
florian55085f82012-11-21 00:36:55 +00006307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006308s390_irgen_LNR(UChar r1, UChar r2)
6309{
6310 IRTemp op2 = newTemp(Ity_I32);
6311 IRTemp result = newTemp(Ity_I32);
6312
6313 assign(op2, get_gpr_w1(r2));
6314 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6315 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6316 put_gpr_w1(r1, mkexpr(result));
6317 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6318
6319 return "lnr";
6320}
6321
florian55085f82012-11-21 00:36:55 +00006322static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006323s390_irgen_LNGR(UChar r1, UChar r2)
6324{
6325 IRTemp op2 = newTemp(Ity_I64);
6326 IRTemp result = newTemp(Ity_I64);
6327
6328 assign(op2, get_gpr_dw0(r2));
6329 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6330 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6331 put_gpr_dw0(r1, mkexpr(result));
6332 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6333
6334 return "lngr";
6335}
6336
florian55085f82012-11-21 00:36:55 +00006337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006338s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6339{
6340 IRTemp op2 = newTemp(Ity_I64);
6341 IRTemp result = newTemp(Ity_I64);
6342
6343 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6344 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6345 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6346 put_gpr_dw0(r1, mkexpr(result));
6347 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6348
6349 return "lngfr";
6350}
6351
florian55085f82012-11-21 00:36:55 +00006352static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006353s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6354{
florian6820ba52012-07-26 02:01:50 +00006355 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006356 put_gpr_w1(r1, get_gpr_w1(r2));
6357
6358 return "locr";
6359}
6360
florian55085f82012-11-21 00:36:55 +00006361static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006362s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6363{
florian6820ba52012-07-26 02:01:50 +00006364 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006365 put_gpr_dw0(r1, get_gpr_dw0(r2));
6366
6367 return "locgr";
6368}
6369
florian55085f82012-11-21 00:36:55 +00006370static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006371s390_irgen_LOC(UChar r1, IRTemp op2addr)
6372{
6373 /* condition is checked in format handler */
6374 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6375
6376 return "loc";
6377}
6378
florian55085f82012-11-21 00:36:55 +00006379static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006380s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6381{
6382 /* condition is checked in format handler */
6383 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6384
6385 return "locg";
6386}
6387
florian55085f82012-11-21 00:36:55 +00006388static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006389s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6390{
6391 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6392 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6393 ));
6394
6395 return "lpq";
6396}
6397
florian55085f82012-11-21 00:36:55 +00006398static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006399s390_irgen_LPR(UChar r1, UChar r2)
6400{
6401 IRTemp op2 = newTemp(Ity_I32);
6402 IRTemp result = newTemp(Ity_I32);
6403
6404 assign(op2, get_gpr_w1(r2));
6405 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6406 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6407 put_gpr_w1(r1, mkexpr(result));
6408 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6409
6410 return "lpr";
6411}
6412
florian55085f82012-11-21 00:36:55 +00006413static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006414s390_irgen_LPGR(UChar r1, UChar r2)
6415{
6416 IRTemp op2 = newTemp(Ity_I64);
6417 IRTemp result = newTemp(Ity_I64);
6418
6419 assign(op2, get_gpr_dw0(r2));
6420 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6421 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6422 put_gpr_dw0(r1, mkexpr(result));
6423 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6424
6425 return "lpgr";
6426}
6427
florian55085f82012-11-21 00:36:55 +00006428static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006429s390_irgen_LPGFR(UChar r1, UChar r2)
6430{
6431 IRTemp op2 = newTemp(Ity_I64);
6432 IRTemp result = newTemp(Ity_I64);
6433
6434 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6435 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6436 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6437 put_gpr_dw0(r1, mkexpr(result));
6438 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6439
6440 return "lpgfr";
6441}
6442
florian55085f82012-11-21 00:36:55 +00006443static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006444s390_irgen_LRVR(UChar r1, UChar r2)
6445{
6446 IRTemp b0 = newTemp(Ity_I8);
6447 IRTemp b1 = newTemp(Ity_I8);
6448 IRTemp b2 = newTemp(Ity_I8);
6449 IRTemp b3 = newTemp(Ity_I8);
6450
6451 assign(b3, get_gpr_b7(r2));
6452 assign(b2, get_gpr_b6(r2));
6453 assign(b1, get_gpr_b5(r2));
6454 assign(b0, get_gpr_b4(r2));
6455 put_gpr_b4(r1, mkexpr(b3));
6456 put_gpr_b5(r1, mkexpr(b2));
6457 put_gpr_b6(r1, mkexpr(b1));
6458 put_gpr_b7(r1, mkexpr(b0));
6459
6460 return "lrvr";
6461}
6462
florian55085f82012-11-21 00:36:55 +00006463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006464s390_irgen_LRVGR(UChar r1, UChar r2)
6465{
6466 IRTemp b0 = newTemp(Ity_I8);
6467 IRTemp b1 = newTemp(Ity_I8);
6468 IRTemp b2 = newTemp(Ity_I8);
6469 IRTemp b3 = newTemp(Ity_I8);
6470 IRTemp b4 = newTemp(Ity_I8);
6471 IRTemp b5 = newTemp(Ity_I8);
6472 IRTemp b6 = newTemp(Ity_I8);
6473 IRTemp b7 = newTemp(Ity_I8);
6474
6475 assign(b7, get_gpr_b7(r2));
6476 assign(b6, get_gpr_b6(r2));
6477 assign(b5, get_gpr_b5(r2));
6478 assign(b4, get_gpr_b4(r2));
6479 assign(b3, get_gpr_b3(r2));
6480 assign(b2, get_gpr_b2(r2));
6481 assign(b1, get_gpr_b1(r2));
6482 assign(b0, get_gpr_b0(r2));
6483 put_gpr_b0(r1, mkexpr(b7));
6484 put_gpr_b1(r1, mkexpr(b6));
6485 put_gpr_b2(r1, mkexpr(b5));
6486 put_gpr_b3(r1, mkexpr(b4));
6487 put_gpr_b4(r1, mkexpr(b3));
6488 put_gpr_b5(r1, mkexpr(b2));
6489 put_gpr_b6(r1, mkexpr(b1));
6490 put_gpr_b7(r1, mkexpr(b0));
6491
6492 return "lrvgr";
6493}
6494
florian55085f82012-11-21 00:36:55 +00006495static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006496s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6497{
6498 IRTemp op2 = newTemp(Ity_I16);
6499
6500 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6501 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6502 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6503
6504 return "lrvh";
6505}
6506
florian55085f82012-11-21 00:36:55 +00006507static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006508s390_irgen_LRV(UChar r1, IRTemp op2addr)
6509{
6510 IRTemp op2 = newTemp(Ity_I32);
6511
6512 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6513 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6514 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6515 mkU8(8)), mkU32(255))));
6516 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6517 mkU8(16)), mkU32(255))));
6518 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6519 mkU8(24)), mkU32(255))));
6520
6521 return "lrv";
6522}
6523
florian55085f82012-11-21 00:36:55 +00006524static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006525s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6526{
6527 IRTemp op2 = newTemp(Ity_I64);
6528
6529 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6530 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6531 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6532 mkU8(8)), mkU64(255))));
6533 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6534 mkU8(16)), mkU64(255))));
6535 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6536 mkU8(24)), mkU64(255))));
6537 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6538 mkU8(32)), mkU64(255))));
6539 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6540 mkU8(40)), mkU64(255))));
6541 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6542 mkU8(48)), mkU64(255))));
6543 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6544 mkU8(56)), mkU64(255))));
6545
6546 return "lrvg";
6547}
6548
florian55085f82012-11-21 00:36:55 +00006549static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006550s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6551{
6552 store(mkexpr(op1addr), mkU16(i2));
6553
6554 return "mvhhi";
6555}
6556
florian55085f82012-11-21 00:36:55 +00006557static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006558s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6559{
6560 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6561
6562 return "mvhi";
6563}
6564
florian55085f82012-11-21 00:36:55 +00006565static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006566s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6567{
6568 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6569
6570 return "mvghi";
6571}
6572
florian55085f82012-11-21 00:36:55 +00006573static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006574s390_irgen_MVI(UChar i2, IRTemp op1addr)
6575{
6576 store(mkexpr(op1addr), mkU8(i2));
6577
6578 return "mvi";
6579}
6580
florian55085f82012-11-21 00:36:55 +00006581static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006582s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6583{
6584 store(mkexpr(op1addr), mkU8(i2));
6585
6586 return "mviy";
6587}
6588
florian55085f82012-11-21 00:36:55 +00006589static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006590s390_irgen_MR(UChar r1, UChar r2)
6591{
6592 IRTemp op1 = newTemp(Ity_I32);
6593 IRTemp op2 = newTemp(Ity_I32);
6594 IRTemp result = newTemp(Ity_I64);
6595
6596 assign(op1, get_gpr_w1(r1 + 1));
6597 assign(op2, get_gpr_w1(r2));
6598 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6599 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6600 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6601
6602 return "mr";
6603}
6604
florian55085f82012-11-21 00:36:55 +00006605static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006606s390_irgen_M(UChar r1, IRTemp op2addr)
6607{
6608 IRTemp op1 = newTemp(Ity_I32);
6609 IRTemp op2 = newTemp(Ity_I32);
6610 IRTemp result = newTemp(Ity_I64);
6611
6612 assign(op1, get_gpr_w1(r1 + 1));
6613 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6614 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6615 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6616 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6617
6618 return "m";
6619}
6620
florian55085f82012-11-21 00:36:55 +00006621static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006622s390_irgen_MFY(UChar r1, IRTemp op2addr)
6623{
6624 IRTemp op1 = newTemp(Ity_I32);
6625 IRTemp op2 = newTemp(Ity_I32);
6626 IRTemp result = newTemp(Ity_I64);
6627
6628 assign(op1, get_gpr_w1(r1 + 1));
6629 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6630 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6631 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6632 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6633
6634 return "mfy";
6635}
6636
florian55085f82012-11-21 00:36:55 +00006637static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006638s390_irgen_MH(UChar r1, IRTemp op2addr)
6639{
6640 IRTemp op1 = newTemp(Ity_I32);
6641 IRTemp op2 = newTemp(Ity_I16);
6642 IRTemp result = newTemp(Ity_I64);
6643
6644 assign(op1, get_gpr_w1(r1));
6645 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6646 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6647 ));
6648 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6649
6650 return "mh";
6651}
6652
florian55085f82012-11-21 00:36:55 +00006653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006654s390_irgen_MHY(UChar r1, IRTemp op2addr)
6655{
6656 IRTemp op1 = newTemp(Ity_I32);
6657 IRTemp op2 = newTemp(Ity_I16);
6658 IRTemp result = newTemp(Ity_I64);
6659
6660 assign(op1, get_gpr_w1(r1));
6661 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6662 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6663 ));
6664 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6665
6666 return "mhy";
6667}
6668
florian55085f82012-11-21 00:36:55 +00006669static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006670s390_irgen_MHI(UChar r1, UShort i2)
6671{
6672 IRTemp op1 = newTemp(Ity_I32);
6673 Short op2;
6674 IRTemp result = newTemp(Ity_I64);
6675
6676 assign(op1, get_gpr_w1(r1));
6677 op2 = (Short)i2;
6678 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6679 mkU16((UShort)op2))));
6680 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6681
6682 return "mhi";
6683}
6684
florian55085f82012-11-21 00:36:55 +00006685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006686s390_irgen_MGHI(UChar r1, UShort i2)
6687{
6688 IRTemp op1 = newTemp(Ity_I64);
6689 Short op2;
6690 IRTemp result = newTemp(Ity_I128);
6691
6692 assign(op1, get_gpr_dw0(r1));
6693 op2 = (Short)i2;
6694 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6695 mkU16((UShort)op2))));
6696 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6697
6698 return "mghi";
6699}
6700
florian55085f82012-11-21 00:36:55 +00006701static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006702s390_irgen_MLR(UChar r1, UChar r2)
6703{
6704 IRTemp op1 = newTemp(Ity_I32);
6705 IRTemp op2 = newTemp(Ity_I32);
6706 IRTemp result = newTemp(Ity_I64);
6707
6708 assign(op1, get_gpr_w1(r1 + 1));
6709 assign(op2, get_gpr_w1(r2));
6710 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6711 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6712 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6713
6714 return "mlr";
6715}
6716
florian55085f82012-11-21 00:36:55 +00006717static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006718s390_irgen_MLGR(UChar r1, UChar r2)
6719{
6720 IRTemp op1 = newTemp(Ity_I64);
6721 IRTemp op2 = newTemp(Ity_I64);
6722 IRTemp result = newTemp(Ity_I128);
6723
6724 assign(op1, get_gpr_dw0(r1 + 1));
6725 assign(op2, get_gpr_dw0(r2));
6726 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6727 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6728 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6729
6730 return "mlgr";
6731}
6732
florian55085f82012-11-21 00:36:55 +00006733static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006734s390_irgen_ML(UChar r1, IRTemp op2addr)
6735{
6736 IRTemp op1 = newTemp(Ity_I32);
6737 IRTemp op2 = newTemp(Ity_I32);
6738 IRTemp result = newTemp(Ity_I64);
6739
6740 assign(op1, get_gpr_w1(r1 + 1));
6741 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6742 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6743 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6744 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6745
6746 return "ml";
6747}
6748
florian55085f82012-11-21 00:36:55 +00006749static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006750s390_irgen_MLG(UChar r1, IRTemp op2addr)
6751{
6752 IRTemp op1 = newTemp(Ity_I64);
6753 IRTemp op2 = newTemp(Ity_I64);
6754 IRTemp result = newTemp(Ity_I128);
6755
6756 assign(op1, get_gpr_dw0(r1 + 1));
6757 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6758 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6759 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6760 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6761
6762 return "mlg";
6763}
6764
florian55085f82012-11-21 00:36:55 +00006765static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006766s390_irgen_MSR(UChar r1, UChar r2)
6767{
6768 IRTemp op1 = newTemp(Ity_I32);
6769 IRTemp op2 = newTemp(Ity_I32);
6770 IRTemp result = newTemp(Ity_I64);
6771
6772 assign(op1, get_gpr_w1(r1));
6773 assign(op2, get_gpr_w1(r2));
6774 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6775 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6776
6777 return "msr";
6778}
6779
florian55085f82012-11-21 00:36:55 +00006780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006781s390_irgen_MSGR(UChar r1, UChar r2)
6782{
6783 IRTemp op1 = newTemp(Ity_I64);
6784 IRTemp op2 = newTemp(Ity_I64);
6785 IRTemp result = newTemp(Ity_I128);
6786
6787 assign(op1, get_gpr_dw0(r1));
6788 assign(op2, get_gpr_dw0(r2));
6789 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6790 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6791
6792 return "msgr";
6793}
6794
florian55085f82012-11-21 00:36:55 +00006795static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006796s390_irgen_MSGFR(UChar r1, UChar r2)
6797{
6798 IRTemp op1 = newTemp(Ity_I64);
6799 IRTemp op2 = newTemp(Ity_I32);
6800 IRTemp result = newTemp(Ity_I128);
6801
6802 assign(op1, get_gpr_dw0(r1));
6803 assign(op2, get_gpr_w1(r2));
6804 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6805 ));
6806 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6807
6808 return "msgfr";
6809}
6810
florian55085f82012-11-21 00:36:55 +00006811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006812s390_irgen_MS(UChar r1, IRTemp op2addr)
6813{
6814 IRTemp op1 = newTemp(Ity_I32);
6815 IRTemp op2 = newTemp(Ity_I32);
6816 IRTemp result = newTemp(Ity_I64);
6817
6818 assign(op1, get_gpr_w1(r1));
6819 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6820 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6821 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6822
6823 return "ms";
6824}
6825
florian55085f82012-11-21 00:36:55 +00006826static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006827s390_irgen_MSY(UChar r1, IRTemp op2addr)
6828{
6829 IRTemp op1 = newTemp(Ity_I32);
6830 IRTemp op2 = newTemp(Ity_I32);
6831 IRTemp result = newTemp(Ity_I64);
6832
6833 assign(op1, get_gpr_w1(r1));
6834 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6835 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6836 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6837
6838 return "msy";
6839}
6840
florian55085f82012-11-21 00:36:55 +00006841static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006842s390_irgen_MSG(UChar r1, IRTemp op2addr)
6843{
6844 IRTemp op1 = newTemp(Ity_I64);
6845 IRTemp op2 = newTemp(Ity_I64);
6846 IRTemp result = newTemp(Ity_I128);
6847
6848 assign(op1, get_gpr_dw0(r1));
6849 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6850 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6851 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6852
6853 return "msg";
6854}
6855
florian55085f82012-11-21 00:36:55 +00006856static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006857s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6858{
6859 IRTemp op1 = newTemp(Ity_I64);
6860 IRTemp op2 = newTemp(Ity_I32);
6861 IRTemp result = newTemp(Ity_I128);
6862
6863 assign(op1, get_gpr_dw0(r1));
6864 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6865 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6866 ));
6867 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6868
6869 return "msgf";
6870}
6871
florian55085f82012-11-21 00:36:55 +00006872static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006873s390_irgen_MSFI(UChar r1, UInt i2)
6874{
6875 IRTemp op1 = newTemp(Ity_I32);
6876 Int op2;
6877 IRTemp result = newTemp(Ity_I64);
6878
6879 assign(op1, get_gpr_w1(r1));
6880 op2 = (Int)i2;
6881 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6882 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6883
6884 return "msfi";
6885}
6886
florian55085f82012-11-21 00:36:55 +00006887static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006888s390_irgen_MSGFI(UChar r1, UInt i2)
6889{
6890 IRTemp op1 = newTemp(Ity_I64);
6891 Int op2;
6892 IRTemp result = newTemp(Ity_I128);
6893
6894 assign(op1, get_gpr_dw0(r1));
6895 op2 = (Int)i2;
6896 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6897 op2))));
6898 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6899
6900 return "msgfi";
6901}
6902
florian55085f82012-11-21 00:36:55 +00006903static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006904s390_irgen_OR(UChar r1, UChar r2)
6905{
6906 IRTemp op1 = newTemp(Ity_I32);
6907 IRTemp op2 = newTemp(Ity_I32);
6908 IRTemp result = newTemp(Ity_I32);
6909
6910 assign(op1, get_gpr_w1(r1));
6911 assign(op2, get_gpr_w1(r2));
6912 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6913 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6914 put_gpr_w1(r1, mkexpr(result));
6915
6916 return "or";
6917}
6918
florian55085f82012-11-21 00:36:55 +00006919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006920s390_irgen_OGR(UChar r1, UChar r2)
6921{
6922 IRTemp op1 = newTemp(Ity_I64);
6923 IRTemp op2 = newTemp(Ity_I64);
6924 IRTemp result = newTemp(Ity_I64);
6925
6926 assign(op1, get_gpr_dw0(r1));
6927 assign(op2, get_gpr_dw0(r2));
6928 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6929 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6930 put_gpr_dw0(r1, mkexpr(result));
6931
6932 return "ogr";
6933}
6934
florian55085f82012-11-21 00:36:55 +00006935static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006936s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6937{
6938 IRTemp op2 = newTemp(Ity_I32);
6939 IRTemp op3 = newTemp(Ity_I32);
6940 IRTemp result = newTemp(Ity_I32);
6941
6942 assign(op2, get_gpr_w1(r2));
6943 assign(op3, get_gpr_w1(r3));
6944 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6945 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6946 put_gpr_w1(r1, mkexpr(result));
6947
6948 return "ork";
6949}
6950
florian55085f82012-11-21 00:36:55 +00006951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006952s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6953{
6954 IRTemp op2 = newTemp(Ity_I64);
6955 IRTemp op3 = newTemp(Ity_I64);
6956 IRTemp result = newTemp(Ity_I64);
6957
6958 assign(op2, get_gpr_dw0(r2));
6959 assign(op3, get_gpr_dw0(r3));
6960 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6961 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6962 put_gpr_dw0(r1, mkexpr(result));
6963
6964 return "ogrk";
6965}
6966
florian55085f82012-11-21 00:36:55 +00006967static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006968s390_irgen_O(UChar r1, IRTemp op2addr)
6969{
6970 IRTemp op1 = newTemp(Ity_I32);
6971 IRTemp op2 = newTemp(Ity_I32);
6972 IRTemp result = newTemp(Ity_I32);
6973
6974 assign(op1, get_gpr_w1(r1));
6975 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6976 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6977 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6978 put_gpr_w1(r1, mkexpr(result));
6979
6980 return "o";
6981}
6982
florian55085f82012-11-21 00:36:55 +00006983static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006984s390_irgen_OY(UChar r1, IRTemp op2addr)
6985{
6986 IRTemp op1 = newTemp(Ity_I32);
6987 IRTemp op2 = newTemp(Ity_I32);
6988 IRTemp result = newTemp(Ity_I32);
6989
6990 assign(op1, get_gpr_w1(r1));
6991 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6992 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6993 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6994 put_gpr_w1(r1, mkexpr(result));
6995
6996 return "oy";
6997}
6998
florian55085f82012-11-21 00:36:55 +00006999static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007000s390_irgen_OG(UChar r1, IRTemp op2addr)
7001{
7002 IRTemp op1 = newTemp(Ity_I64);
7003 IRTemp op2 = newTemp(Ity_I64);
7004 IRTemp result = newTemp(Ity_I64);
7005
7006 assign(op1, get_gpr_dw0(r1));
7007 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7008 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
7009 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7010 put_gpr_dw0(r1, mkexpr(result));
7011
7012 return "og";
7013}
7014
florian55085f82012-11-21 00:36:55 +00007015static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007016s390_irgen_OI(UChar i2, IRTemp op1addr)
7017{
7018 IRTemp op1 = newTemp(Ity_I8);
7019 UChar op2;
7020 IRTemp result = newTemp(Ity_I8);
7021
7022 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7023 op2 = i2;
7024 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7025 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7026 store(mkexpr(op1addr), mkexpr(result));
7027
7028 return "oi";
7029}
7030
florian55085f82012-11-21 00:36:55 +00007031static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007032s390_irgen_OIY(UChar i2, IRTemp op1addr)
7033{
7034 IRTemp op1 = newTemp(Ity_I8);
7035 UChar op2;
7036 IRTemp result = newTemp(Ity_I8);
7037
7038 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7039 op2 = i2;
7040 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7041 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7042 store(mkexpr(op1addr), mkexpr(result));
7043
7044 return "oiy";
7045}
7046
florian55085f82012-11-21 00:36:55 +00007047static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007048s390_irgen_OIHF(UChar r1, UInt i2)
7049{
7050 IRTemp op1 = newTemp(Ity_I32);
7051 UInt op2;
7052 IRTemp result = newTemp(Ity_I32);
7053
7054 assign(op1, get_gpr_w0(r1));
7055 op2 = i2;
7056 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7057 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7058 put_gpr_w0(r1, mkexpr(result));
7059
7060 return "oihf";
7061}
7062
florian55085f82012-11-21 00:36:55 +00007063static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007064s390_irgen_OIHH(UChar r1, UShort i2)
7065{
7066 IRTemp op1 = newTemp(Ity_I16);
7067 UShort op2;
7068 IRTemp result = newTemp(Ity_I16);
7069
7070 assign(op1, get_gpr_hw0(r1));
7071 op2 = i2;
7072 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7073 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7074 put_gpr_hw0(r1, mkexpr(result));
7075
7076 return "oihh";
7077}
7078
florian55085f82012-11-21 00:36:55 +00007079static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007080s390_irgen_OIHL(UChar r1, UShort i2)
7081{
7082 IRTemp op1 = newTemp(Ity_I16);
7083 UShort op2;
7084 IRTemp result = newTemp(Ity_I16);
7085
7086 assign(op1, get_gpr_hw1(r1));
7087 op2 = i2;
7088 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7089 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7090 put_gpr_hw1(r1, mkexpr(result));
7091
7092 return "oihl";
7093}
7094
florian55085f82012-11-21 00:36:55 +00007095static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007096s390_irgen_OILF(UChar r1, UInt i2)
7097{
7098 IRTemp op1 = newTemp(Ity_I32);
7099 UInt op2;
7100 IRTemp result = newTemp(Ity_I32);
7101
7102 assign(op1, get_gpr_w1(r1));
7103 op2 = i2;
7104 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7105 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7106 put_gpr_w1(r1, mkexpr(result));
7107
7108 return "oilf";
7109}
7110
florian55085f82012-11-21 00:36:55 +00007111static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007112s390_irgen_OILH(UChar r1, UShort i2)
7113{
7114 IRTemp op1 = newTemp(Ity_I16);
7115 UShort op2;
7116 IRTemp result = newTemp(Ity_I16);
7117
7118 assign(op1, get_gpr_hw2(r1));
7119 op2 = i2;
7120 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7121 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7122 put_gpr_hw2(r1, mkexpr(result));
7123
7124 return "oilh";
7125}
7126
florian55085f82012-11-21 00:36:55 +00007127static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007128s390_irgen_OILL(UChar r1, UShort i2)
7129{
7130 IRTemp op1 = newTemp(Ity_I16);
7131 UShort op2;
7132 IRTemp result = newTemp(Ity_I16);
7133
7134 assign(op1, get_gpr_hw3(r1));
7135 op2 = i2;
7136 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7137 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7138 put_gpr_hw3(r1, mkexpr(result));
7139
7140 return "oill";
7141}
7142
florian55085f82012-11-21 00:36:55 +00007143static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007144s390_irgen_PFD(void)
7145{
7146
7147 return "pfd";
7148}
7149
florian55085f82012-11-21 00:36:55 +00007150static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007151s390_irgen_PFDRL(void)
7152{
7153
7154 return "pfdrl";
7155}
7156
florian78d5ef72013-05-11 15:02:58 +00007157static IRExpr *
7158get_rounding_mode_from_gr0(void)
7159{
7160 IRTemp rm_bits = newTemp(Ity_I32);
7161 IRExpr *s390rm;
7162 IRExpr *irrm;
7163
florian78d5ef72013-05-11 15:02:58 +00007164 /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7165 when PFPO insn is called. So, extract the bits at [60:63] */
7166 assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7167 s390rm = mkexpr(rm_bits);
7168 irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7169 mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7170 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7171 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7172 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7173 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7174 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7175 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7176 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7177 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7178 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7179 mkexpr(encode_dfp_rounding_mode(
7180 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7181 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7182 mkexpr(encode_dfp_rounding_mode(
7183 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7184 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7185 mkexpr(encode_dfp_rounding_mode(
7186 S390_DFP_ROUND_AWAY_0)),
7187 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7188 mkexpr(encode_dfp_rounding_mode(
7189 S390_DFP_ROUND_PREPARE_SHORT_15)),
7190 /* if rounding mode is 0 or invalid (2-7)
7191 set S390_DFP_ROUND_PER_FPC_0 */
7192 mkexpr(encode_dfp_rounding_mode(
7193 S390_DFP_ROUND_PER_FPC_0)))))))))));
7194
7195 return irrm;
7196}
7197
7198static IRExpr *
7199s390_call_pfpo_helper(IRExpr *gr0)
7200{
7201 IRExpr **args, *call;
7202
7203 args = mkIRExprVec_1(gr0);
7204 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7205 "s390_do_pfpo", &s390_do_pfpo, args);
7206 /* Nothing is excluded from definedness checking. */
7207 call->Iex.CCall.cee->mcx_mask = 0;
7208
7209 return call;
7210}
7211
7212static const HChar *
7213s390_irgen_PFPO(void)
7214{
7215 IRTemp gr0 = newTemp(Ity_I32); /* word 1 [32:63] of GR 0 */
7216 IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7217 IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */
7218 IRTemp ef = newTemp(Ity_I32); /* Emulation Failure */
florian7ab421d2013-06-17 21:03:56 +00007219 IRTemp src1 = newTemp(Ity_F32);
7220 IRTemp dst1 = newTemp(Ity_D32);
7221 IRTemp src2 = newTemp(Ity_F32);
7222 IRTemp dst2 = newTemp(Ity_D64);
7223 IRTemp src3 = newTemp(Ity_F32);
florian78d5ef72013-05-11 15:02:58 +00007224 IRTemp dst3 = newTemp(Ity_D128);
florian7ab421d2013-06-17 21:03:56 +00007225 IRTemp src4 = newTemp(Ity_F64);
7226 IRTemp dst4 = newTemp(Ity_D32);
7227 IRTemp src5 = newTemp(Ity_F64);
7228 IRTemp dst5 = newTemp(Ity_D64);
7229 IRTemp src6 = newTemp(Ity_F64);
7230 IRTemp dst6 = newTemp(Ity_D128);
7231 IRTemp src7 = newTemp(Ity_F128);
7232 IRTemp dst7 = newTemp(Ity_D32);
7233 IRTemp src8 = newTemp(Ity_F128);
7234 IRTemp dst8 = newTemp(Ity_D64);
7235 IRTemp src9 = newTemp(Ity_F128);
7236 IRTemp dst9 = newTemp(Ity_D128);
7237 IRTemp src10 = newTemp(Ity_D32);
7238 IRTemp dst10 = newTemp(Ity_F32);
7239 IRTemp src11 = newTemp(Ity_D32);
7240 IRTemp dst11 = newTemp(Ity_F64);
7241 IRTemp src12 = newTemp(Ity_D32);
7242 IRTemp dst12 = newTemp(Ity_F128);
7243 IRTemp src13 = newTemp(Ity_D64);
7244 IRTemp dst13 = newTemp(Ity_F32);
7245 IRTemp src14 = newTemp(Ity_D64);
7246 IRTemp dst14 = newTemp(Ity_F64);
7247 IRTemp src15 = newTemp(Ity_D64);
7248 IRTemp dst15 = newTemp(Ity_F128);
7249 IRTemp src16 = newTemp(Ity_D128);
7250 IRTemp dst16 = newTemp(Ity_F32);
7251 IRTemp src17 = newTemp(Ity_D128);
7252 IRTemp dst17 = newTemp(Ity_F64);
7253 IRTemp src18 = newTemp(Ity_D128);
7254 IRTemp dst18 = newTemp(Ity_F128);
florian78d5ef72013-05-11 15:02:58 +00007255 IRExpr *irrm;
7256
florianad00ea92014-12-05 18:55:39 +00007257 if (! s390_host_has_pfpo) {
7258 emulation_failure(EmFail_S390X_pfpo);
7259 goto done;
7260 }
florian78d5ef72013-05-11 15:02:58 +00007261
7262 assign(gr0, get_gpr_w1(0));
7263 /* get function code */
7264 assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7265 mkU32(0x7fffff)));
7266 /* get validity test bit */
7267 assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7268 mkU32(0x1)));
7269 irrm = get_rounding_mode_from_gr0();
7270
7271 /* test_bit is 1 */
florian7ab421d2013-06-17 21:03:56 +00007272 assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
florian78d5ef72013-05-11 15:02:58 +00007273 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7274
7275 /* Return code set in GR1 is usually 0. Non-zero value is set only
7276 when exceptions are raised. See Programming Notes point 5 in the
7277 instrcution description of pfpo in POP. Since valgrind does not
7278 model exception, it might be safe to just set 0 to GR 1. */
7279 put_gpr_w1(1, mkU32(0x0));
7280 next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7281
7282 /* Check validity of function code in GR 0 */
7283 assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
florianafa3f042014-09-06 21:43:28 +00007284 emulation_failure_with_expr(mkexpr(ef));
florian78d5ef72013-05-11 15:02:58 +00007285
7286 stmt(
7287 IRStmt_Exit(
7288 binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7289 Ijk_EmFail,
7290 IRConst_U64(guest_IA_next_instr),
7291 S390X_GUEST_OFFSET(guest_IA)
7292 )
7293 );
7294
florian7ab421d2013-06-17 21:03:56 +00007295 /* F32 -> D32 */
florian78d5ef72013-05-11 15:02:58 +00007296 /* get source from FPR 4,6 - already set in src1 */
florian7ab421d2013-06-17 21:03:56 +00007297 assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
7298 put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007299 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007300 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
7301 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
florian78d5ef72013-05-11 15:02:58 +00007302
florian7ab421d2013-06-17 21:03:56 +00007303 /* F32 -> D64 */
7304 assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
7305 assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
7306 put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007307 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007308 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
7309 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007310
florian7ab421d2013-06-17 21:03:56 +00007311 /* F32 -> D128 */
7312 assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
7313 assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
florian78d5ef72013-05-11 15:02:58 +00007314 put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7315 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007316 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
7317 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
7318
7319 /* F64 -> D32 */
7320 assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7321 assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
7322 put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7323 put_gpr_w1(1, mkU32(0x0));
7324 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
7325 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
7326
7327 /* F64 -> D64 */
7328 assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7329 assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
7330 put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7331 put_gpr_w1(1, mkU32(0x0));
7332 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
7333 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7334
7335 /* F64 -> D128 */
7336 assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7337 assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
7338 put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7339 put_gpr_w1(1, mkU32(0x0));
7340 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
florian78d5ef72013-05-11 15:02:58 +00007341 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7342
florian7ab421d2013-06-17 21:03:56 +00007343 /* F128 -> D32 */
7344 assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
7345 assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
7346 put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007347 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007348 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
7349 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
7350
7351 /* F128 -> D64 */
7352 assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
7353 assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
7354 put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
7355 put_gpr_w1(1, mkU32(0x0));
7356 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
7357 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007358
7359 /* F128 -> D128 */
florian7ab421d2013-06-17 21:03:56 +00007360 assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
7361 assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
7362 put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007363 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007364 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
florian78d5ef72013-05-11 15:02:58 +00007365 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7366
florian7ab421d2013-06-17 21:03:56 +00007367 /* D32 -> F32 */
7368 assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
7369 assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
7370 put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007371 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007372 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
7373 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
7374
7375 /* D32 -> F64 */
7376 assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
7377 assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
7378 put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
7379 put_gpr_w1(1, mkU32(0x0));
7380 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
7381 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
7382
7383 /* D32 -> F128 */
7384 assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
7385 assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
7386 put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
7387 put_gpr_w1(1, mkU32(0x0));
7388 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
7389 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
7390
7391 /* D64 -> F32 */
7392 assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7393 assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
7394 put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
7395 put_gpr_w1(1, mkU32(0x0));
7396 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
7397 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
7398
7399 /* D64 -> F64 */
7400 assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7401 assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
7402 put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
7403 put_gpr_w1(1, mkU32(0x0));
7404 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
7405 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7406
7407 /* D64 -> F128 */
7408 assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7409 assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
7410 put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
7411 put_gpr_w1(1, mkU32(0x0));
7412 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
7413 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
7414
7415 /* D128 -> F32 */
7416 assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
7417 assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
7418 put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
7419 put_gpr_w1(1, mkU32(0x0));
7420 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
7421 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
7422
7423 /* D128 -> F64 */
7424 assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
7425 assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
7426 put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
7427 put_gpr_w1(1, mkU32(0x0));
7428 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
7429 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7430
7431 /* D128 -> F128 */
7432 assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
7433 assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
7434 put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
7435 put_gpr_w1(1, mkU32(0x0));
7436 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
florian78d5ef72013-05-11 15:02:58 +00007437 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7438
florianad00ea92014-12-05 18:55:39 +00007439 done:
florian78d5ef72013-05-11 15:02:58 +00007440 return "pfpo";
7441}
7442
florian55085f82012-11-21 00:36:55 +00007443static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007444s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7445{
7446 IRTemp amount = newTemp(Ity_I64);
7447 IRTemp op = newTemp(Ity_I32);
7448
7449 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7450 assign(op, get_gpr_w1(r3));
7451 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7452 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7453 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7454
7455 return "rll";
7456}
7457
florian55085f82012-11-21 00:36:55 +00007458static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007459s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7460{
7461 IRTemp amount = newTemp(Ity_I64);
7462 IRTemp op = newTemp(Ity_I64);
7463
7464 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7465 assign(op, get_gpr_dw0(r3));
7466 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7467 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7468 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7469
7470 return "rllg";
7471}
7472
florian55085f82012-11-21 00:36:55 +00007473static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007474s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7475{
7476 UChar from;
7477 UChar to;
7478 UChar rot;
7479 UChar t_bit;
7480 ULong mask;
7481 ULong maskc;
7482 IRTemp result = newTemp(Ity_I64);
7483 IRTemp op2 = newTemp(Ity_I64);
7484
7485 from = i3 & 63;
7486 to = i4 & 63;
7487 rot = i5 & 63;
7488 t_bit = i3 & 128;
7489 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7490 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7491 mkU8(64 - rot))));
7492 if (from <= to) {
7493 mask = ~0ULL;
7494 mask = (mask >> from) & (mask << (63 - to));
7495 maskc = ~mask;
7496 } else {
7497 maskc = ~0ULL;
7498 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7499 mask = ~maskc;
7500 }
7501 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7502 ), mkU64(mask)));
7503 if (t_bit == 0) {
7504 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7505 mkU64(maskc)), mkexpr(result)));
7506 }
7507 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7508
7509 return "rnsbg";
7510}
7511
florian55085f82012-11-21 00:36:55 +00007512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007513s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7514{
7515 UChar from;
7516 UChar to;
7517 UChar rot;
7518 UChar t_bit;
7519 ULong mask;
7520 ULong maskc;
7521 IRTemp result = newTemp(Ity_I64);
7522 IRTemp op2 = newTemp(Ity_I64);
7523
7524 from = i3 & 63;
7525 to = i4 & 63;
7526 rot = i5 & 63;
7527 t_bit = i3 & 128;
7528 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7529 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7530 mkU8(64 - rot))));
7531 if (from <= to) {
7532 mask = ~0ULL;
7533 mask = (mask >> from) & (mask << (63 - to));
7534 maskc = ~mask;
7535 } else {
7536 maskc = ~0ULL;
7537 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7538 mask = ~maskc;
7539 }
7540 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7541 ), mkU64(mask)));
7542 if (t_bit == 0) {
7543 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7544 mkU64(maskc)), mkexpr(result)));
7545 }
7546 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7547
7548 return "rxsbg";
7549}
7550
florian55085f82012-11-21 00:36:55 +00007551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007552s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7553{
7554 UChar from;
7555 UChar to;
7556 UChar rot;
7557 UChar t_bit;
7558 ULong mask;
7559 ULong maskc;
7560 IRTemp result = newTemp(Ity_I64);
7561 IRTemp op2 = newTemp(Ity_I64);
7562
7563 from = i3 & 63;
7564 to = i4 & 63;
7565 rot = i5 & 63;
7566 t_bit = i3 & 128;
7567 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7568 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7569 mkU8(64 - rot))));
7570 if (from <= to) {
7571 mask = ~0ULL;
7572 mask = (mask >> from) & (mask << (63 - to));
7573 maskc = ~mask;
7574 } else {
7575 maskc = ~0ULL;
7576 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7577 mask = ~maskc;
7578 }
7579 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7580 ), mkU64(mask)));
7581 if (t_bit == 0) {
7582 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7583 mkU64(maskc)), mkexpr(result)));
7584 }
7585 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7586
7587 return "rosbg";
7588}
7589
florian55085f82012-11-21 00:36:55 +00007590static const HChar *
Elliott Hughesa0664b92017-04-18 17:46:52 -07007591s390_irgen_RISBGx(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
7592 Bool set_cc)
sewardj2019a972011-03-07 16:04:07 +00007593{
7594 UChar from;
7595 UChar to;
7596 UChar rot;
7597 UChar z_bit;
7598 ULong mask;
7599 ULong maskc;
7600 IRTemp op2 = newTemp(Ity_I64);
7601 IRTemp result = newTemp(Ity_I64);
7602
7603 from = i3 & 63;
7604 to = i4 & 63;
7605 rot = i5 & 63;
7606 z_bit = i4 & 128;
7607 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7608 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7609 mkU8(64 - rot))));
7610 if (from <= to) {
7611 mask = ~0ULL;
7612 mask = (mask >> from) & (mask << (63 - to));
7613 maskc = ~mask;
7614 } else {
7615 maskc = ~0ULL;
7616 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7617 mask = ~maskc;
7618 }
7619 if (z_bit == 0) {
7620 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7621 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7622 } else {
7623 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7624 }
7625 assign(result, get_gpr_dw0(r1));
Elliott Hughesa0664b92017-04-18 17:46:52 -07007626 if (set_cc) {
7627 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7628 return "risbg";
7629 }
sewardj2019a972011-03-07 16:04:07 +00007630
Elliott Hughesa0664b92017-04-18 17:46:52 -07007631 return "risbgn";
7632}
7633
7634static const HChar *
7635s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7636{
7637 return s390_irgen_RISBGx(r1, r2, i3, i4, i5, True);
7638}
7639
7640static const HChar *
7641s390_irgen_RISBGN(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7642{
7643 return s390_irgen_RISBGx(r1, r2, i3, i4, i5, False);
7644}
7645
7646static IRExpr *
7647s390_irgen_RISBxG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
7648 Bool high)
7649{
7650 UChar from;
7651 UChar to;
7652 UChar rot;
7653 UChar z_bit;
7654 UInt mask;
7655 UInt maskc;
7656 IRTemp op2 = newTemp(Ity_I32);
7657
7658 from = i3 & 31;
7659 to = i4 & 31;
7660 rot = i5 & 63;
7661 z_bit = i4 & 128;
7662 if (rot == 0) {
7663 assign(op2, high ? get_gpr_w0(r2) : get_gpr_w1(r2));
7664 } else if (rot == 32) {
7665 assign(op2, high ? get_gpr_w1(r2) : get_gpr_w0(r2));
7666 } else {
7667 assign(op2,
7668 unop(high ? Iop_64HIto32 : Iop_64to32,
7669 binop(Iop_Or64,
7670 binop(Iop_Shl64, get_gpr_dw0(r2), mkU8(rot)),
7671 binop(Iop_Shr64, get_gpr_dw0(r2), mkU8(64 - rot)))));
7672 }
7673 if (from <= to) {
7674 mask = ~0U;
7675 mask = (mask >> from) & (mask << (31 - to));
7676 maskc = ~mask;
7677 } else {
7678 maskc = ~0U;
7679 maskc = (maskc >> (to + 1)) & (maskc << (32 - from));
7680 mask = ~maskc;
7681 }
7682 if (z_bit) {
7683 return binop(Iop_And32, mkexpr(op2), mkU32(mask));
7684 }
7685 return binop(Iop_Or32,
7686 binop(Iop_And32, high ? get_gpr_w0(r1) : get_gpr_w1(r1),
7687 mkU32(maskc)),
7688 binop(Iop_And32, mkexpr(op2), mkU32(mask)));
7689}
7690
7691static const HChar *
7692s390_irgen_RISBHG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7693{
7694 put_gpr_w0(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, True));
7695 return "risbhg";
7696}
7697
7698static const HChar *
7699s390_irgen_RISBLG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7700{
7701 put_gpr_w1(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, False));
7702 return "risblg";
sewardj2019a972011-03-07 16:04:07 +00007703}
7704
florian55085f82012-11-21 00:36:55 +00007705static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007706s390_irgen_SAR(UChar r1, UChar r2)
7707{
7708 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007709 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007710 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7711
7712 return "sar";
7713}
7714
florian55085f82012-11-21 00:36:55 +00007715static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007716s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7717{
7718 IRTemp p1 = newTemp(Ity_I64);
7719 IRTemp p2 = newTemp(Ity_I64);
7720 IRTemp op = newTemp(Ity_I64);
7721 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007722 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007723 IRTemp shift_amount = newTemp(Ity_I64);
7724
7725 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7726 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7727 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7728 ));
7729 sign_mask = 1ULL << 63;
7730 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7731 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007732 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7733 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007734 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7735 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7736 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7737
7738 return "slda";
7739}
7740
florian55085f82012-11-21 00:36:55 +00007741static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007742s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7743{
7744 IRTemp p1 = newTemp(Ity_I64);
7745 IRTemp p2 = newTemp(Ity_I64);
7746 IRTemp result = newTemp(Ity_I64);
7747
7748 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7749 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7750 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7751 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7752 mkexpr(op2addr), mkU64(63)))));
7753 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7754 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7755
7756 return "sldl";
7757}
7758
florian55085f82012-11-21 00:36:55 +00007759static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007760s390_irgen_SLA(UChar r1, IRTemp op2addr)
7761{
7762 IRTemp uop = newTemp(Ity_I32);
7763 IRTemp result = newTemp(Ity_I32);
7764 UInt sign_mask;
7765 IRTemp shift_amount = newTemp(Ity_I64);
7766 IRTemp op = newTemp(Ity_I32);
7767
7768 assign(op, get_gpr_w1(r1));
7769 assign(uop, get_gpr_w1(r1));
7770 sign_mask = 2147483648U;
7771 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7772 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7773 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7774 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7775 put_gpr_w1(r1, mkexpr(result));
7776 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7777
7778 return "sla";
7779}
7780
florian55085f82012-11-21 00:36:55 +00007781static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007782s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7783{
7784 IRTemp uop = newTemp(Ity_I32);
7785 IRTemp result = newTemp(Ity_I32);
7786 UInt sign_mask;
7787 IRTemp shift_amount = newTemp(Ity_I64);
7788 IRTemp op = newTemp(Ity_I32);
7789
7790 assign(op, get_gpr_w1(r3));
7791 assign(uop, get_gpr_w1(r3));
7792 sign_mask = 2147483648U;
7793 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7794 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7795 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7796 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7797 put_gpr_w1(r1, mkexpr(result));
7798 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7799
7800 return "slak";
7801}
7802
florian55085f82012-11-21 00:36:55 +00007803static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007804s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7805{
7806 IRTemp uop = newTemp(Ity_I64);
7807 IRTemp result = newTemp(Ity_I64);
7808 ULong sign_mask;
7809 IRTemp shift_amount = newTemp(Ity_I64);
7810 IRTemp op = newTemp(Ity_I64);
7811
7812 assign(op, get_gpr_dw0(r3));
7813 assign(uop, get_gpr_dw0(r3));
7814 sign_mask = 9223372036854775808ULL;
7815 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7816 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7817 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7818 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7819 put_gpr_dw0(r1, mkexpr(result));
7820 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7821
7822 return "slag";
7823}
7824
florian55085f82012-11-21 00:36:55 +00007825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007826s390_irgen_SLL(UChar r1, IRTemp op2addr)
7827{
7828 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7829 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7830
7831 return "sll";
7832}
7833
florian55085f82012-11-21 00:36:55 +00007834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007835s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7836{
7837 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7838 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7839
7840 return "sllk";
7841}
7842
florian55085f82012-11-21 00:36:55 +00007843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007844s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7845{
7846 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7847 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7848
7849 return "sllg";
7850}
7851
florian55085f82012-11-21 00:36:55 +00007852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007853s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7854{
7855 IRTemp p1 = newTemp(Ity_I64);
7856 IRTemp p2 = newTemp(Ity_I64);
7857 IRTemp result = newTemp(Ity_I64);
7858
7859 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7860 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7861 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7862 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7863 mkexpr(op2addr), mkU64(63)))));
7864 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7865 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7866 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7867
7868 return "srda";
7869}
7870
florian55085f82012-11-21 00:36:55 +00007871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007872s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7873{
7874 IRTemp p1 = newTemp(Ity_I64);
7875 IRTemp p2 = newTemp(Ity_I64);
7876 IRTemp result = newTemp(Ity_I64);
7877
7878 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7879 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7880 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7881 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7882 mkexpr(op2addr), mkU64(63)))));
7883 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7884 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7885
7886 return "srdl";
7887}
7888
florian55085f82012-11-21 00:36:55 +00007889static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007890s390_irgen_SRA(UChar r1, IRTemp op2addr)
7891{
7892 IRTemp result = newTemp(Ity_I32);
7893 IRTemp op = newTemp(Ity_I32);
7894
7895 assign(op, get_gpr_w1(r1));
7896 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7897 mkexpr(op2addr), mkU64(63)))));
7898 put_gpr_w1(r1, mkexpr(result));
7899 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7900
7901 return "sra";
7902}
7903
florian55085f82012-11-21 00:36:55 +00007904static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007905s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7906{
7907 IRTemp result = newTemp(Ity_I32);
7908 IRTemp op = newTemp(Ity_I32);
7909
7910 assign(op, get_gpr_w1(r3));
7911 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7912 mkexpr(op2addr), mkU64(63)))));
7913 put_gpr_w1(r1, mkexpr(result));
7914 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7915
7916 return "srak";
7917}
7918
florian55085f82012-11-21 00:36:55 +00007919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007920s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7921{
7922 IRTemp result = newTemp(Ity_I64);
7923 IRTemp op = newTemp(Ity_I64);
7924
7925 assign(op, get_gpr_dw0(r3));
7926 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7927 mkexpr(op2addr), mkU64(63)))));
7928 put_gpr_dw0(r1, mkexpr(result));
7929 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7930
7931 return "srag";
7932}
7933
florian55085f82012-11-21 00:36:55 +00007934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007935s390_irgen_SRL(UChar r1, IRTemp op2addr)
7936{
7937 IRTemp op = newTemp(Ity_I32);
7938
7939 assign(op, get_gpr_w1(r1));
7940 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7941 mkexpr(op2addr), mkU64(63)))));
7942
7943 return "srl";
7944}
7945
florian55085f82012-11-21 00:36:55 +00007946static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007947s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7948{
7949 IRTemp op = newTemp(Ity_I32);
7950
7951 assign(op, get_gpr_w1(r3));
7952 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7953 mkexpr(op2addr), mkU64(63)))));
7954
7955 return "srlk";
7956}
7957
florian55085f82012-11-21 00:36:55 +00007958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007959s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7960{
7961 IRTemp op = newTemp(Ity_I64);
7962
7963 assign(op, get_gpr_dw0(r3));
7964 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7965 mkexpr(op2addr), mkU64(63)))));
7966
7967 return "srlg";
7968}
7969
florian55085f82012-11-21 00:36:55 +00007970static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007971s390_irgen_ST(UChar r1, IRTemp op2addr)
7972{
7973 store(mkexpr(op2addr), get_gpr_w1(r1));
7974
7975 return "st";
7976}
7977
florian55085f82012-11-21 00:36:55 +00007978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007979s390_irgen_STY(UChar r1, IRTemp op2addr)
7980{
7981 store(mkexpr(op2addr), get_gpr_w1(r1));
7982
7983 return "sty";
7984}
7985
florian55085f82012-11-21 00:36:55 +00007986static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007987s390_irgen_STG(UChar r1, IRTemp op2addr)
7988{
7989 store(mkexpr(op2addr), get_gpr_dw0(r1));
7990
7991 return "stg";
7992}
7993
florian55085f82012-11-21 00:36:55 +00007994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007995s390_irgen_STRL(UChar r1, UInt i2)
7996{
7997 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7998 get_gpr_w1(r1));
7999
8000 return "strl";
8001}
8002
florian55085f82012-11-21 00:36:55 +00008003static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008004s390_irgen_STGRL(UChar r1, UInt i2)
8005{
8006 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8007 get_gpr_dw0(r1));
8008
8009 return "stgrl";
8010}
8011
florian55085f82012-11-21 00:36:55 +00008012static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008013s390_irgen_STC(UChar r1, IRTemp op2addr)
8014{
8015 store(mkexpr(op2addr), get_gpr_b7(r1));
8016
8017 return "stc";
8018}
8019
florian55085f82012-11-21 00:36:55 +00008020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008021s390_irgen_STCY(UChar r1, IRTemp op2addr)
8022{
8023 store(mkexpr(op2addr), get_gpr_b7(r1));
8024
8025 return "stcy";
8026}
8027
florian55085f82012-11-21 00:36:55 +00008028static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008029s390_irgen_STCH(UChar r1, IRTemp op2addr)
8030{
8031 store(mkexpr(op2addr), get_gpr_b3(r1));
8032
8033 return "stch";
8034}
8035
florian55085f82012-11-21 00:36:55 +00008036static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008037s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
8038{
8039 UChar mask;
8040 UChar n;
8041
8042 mask = (UChar)r3;
8043 n = 0;
8044 if ((mask & 8) != 0) {
8045 store(mkexpr(op2addr), get_gpr_b4(r1));
8046 n = n + 1;
8047 }
8048 if ((mask & 4) != 0) {
8049 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
8050 n = n + 1;
8051 }
8052 if ((mask & 2) != 0) {
8053 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
8054 n = n + 1;
8055 }
8056 if ((mask & 1) != 0) {
8057 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
8058 }
8059
8060 return "stcm";
8061}
8062
florian55085f82012-11-21 00:36:55 +00008063static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008064s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
8065{
8066 UChar mask;
8067 UChar n;
8068
8069 mask = (UChar)r3;
8070 n = 0;
8071 if ((mask & 8) != 0) {
8072 store(mkexpr(op2addr), get_gpr_b4(r1));
8073 n = n + 1;
8074 }
8075 if ((mask & 4) != 0) {
8076 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
8077 n = n + 1;
8078 }
8079 if ((mask & 2) != 0) {
8080 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
8081 n = n + 1;
8082 }
8083 if ((mask & 1) != 0) {
8084 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
8085 }
8086
8087 return "stcmy";
8088}
8089
florian55085f82012-11-21 00:36:55 +00008090static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008091s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
8092{
8093 UChar mask;
8094 UChar n;
8095
8096 mask = (UChar)r3;
8097 n = 0;
8098 if ((mask & 8) != 0) {
8099 store(mkexpr(op2addr), get_gpr_b0(r1));
8100 n = n + 1;
8101 }
8102 if ((mask & 4) != 0) {
8103 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
8104 n = n + 1;
8105 }
8106 if ((mask & 2) != 0) {
8107 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
8108 n = n + 1;
8109 }
8110 if ((mask & 1) != 0) {
8111 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
8112 }
8113
8114 return "stcmh";
8115}
8116
florian55085f82012-11-21 00:36:55 +00008117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008118s390_irgen_STH(UChar r1, IRTemp op2addr)
8119{
8120 store(mkexpr(op2addr), get_gpr_hw3(r1));
8121
8122 return "sth";
8123}
8124
florian55085f82012-11-21 00:36:55 +00008125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008126s390_irgen_STHY(UChar r1, IRTemp op2addr)
8127{
8128 store(mkexpr(op2addr), get_gpr_hw3(r1));
8129
8130 return "sthy";
8131}
8132
florian55085f82012-11-21 00:36:55 +00008133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008134s390_irgen_STHRL(UChar r1, UInt i2)
8135{
8136 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8137 get_gpr_hw3(r1));
8138
8139 return "sthrl";
8140}
8141
florian55085f82012-11-21 00:36:55 +00008142static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008143s390_irgen_STHH(UChar r1, IRTemp op2addr)
8144{
8145 store(mkexpr(op2addr), get_gpr_hw1(r1));
8146
8147 return "sthh";
8148}
8149
florian55085f82012-11-21 00:36:55 +00008150static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008151s390_irgen_STFH(UChar r1, IRTemp op2addr)
8152{
8153 store(mkexpr(op2addr), get_gpr_w0(r1));
8154
8155 return "stfh";
8156}
8157
florian55085f82012-11-21 00:36:55 +00008158static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008159s390_irgen_STOC(UChar r1, IRTemp op2addr)
8160{
8161 /* condition is checked in format handler */
8162 store(mkexpr(op2addr), get_gpr_w1(r1));
8163
8164 return "stoc";
8165}
8166
florian55085f82012-11-21 00:36:55 +00008167static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008168s390_irgen_STOCG(UChar r1, IRTemp op2addr)
8169{
8170 /* condition is checked in format handler */
8171 store(mkexpr(op2addr), get_gpr_dw0(r1));
8172
8173 return "stocg";
8174}
8175
florian55085f82012-11-21 00:36:55 +00008176static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008177s390_irgen_STPQ(UChar r1, IRTemp op2addr)
8178{
8179 store(mkexpr(op2addr), get_gpr_dw0(r1));
8180 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
8181
8182 return "stpq";
8183}
8184
florian55085f82012-11-21 00:36:55 +00008185static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008186s390_irgen_STRVH(UChar r1, IRTemp op2addr)
8187{
8188 store(mkexpr(op2addr), get_gpr_b7(r1));
8189 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8190
8191 return "strvh";
8192}
8193
florian55085f82012-11-21 00:36:55 +00008194static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008195s390_irgen_STRV(UChar r1, IRTemp op2addr)
8196{
8197 store(mkexpr(op2addr), get_gpr_b7(r1));
8198 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8199 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8200 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8201
8202 return "strv";
8203}
8204
florian55085f82012-11-21 00:36:55 +00008205static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008206s390_irgen_STRVG(UChar r1, IRTemp op2addr)
8207{
8208 store(mkexpr(op2addr), get_gpr_b7(r1));
8209 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8210 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8211 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8212 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
8213 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
8214 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
8215 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
8216
8217 return "strvg";
8218}
8219
florian55085f82012-11-21 00:36:55 +00008220static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008221s390_irgen_SR(UChar r1, UChar r2)
8222{
8223 IRTemp op1 = newTemp(Ity_I32);
8224 IRTemp op2 = newTemp(Ity_I32);
8225 IRTemp result = newTemp(Ity_I32);
8226
8227 assign(op1, get_gpr_w1(r1));
8228 assign(op2, get_gpr_w1(r2));
8229 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8230 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8231 put_gpr_w1(r1, mkexpr(result));
8232
8233 return "sr";
8234}
8235
florian55085f82012-11-21 00:36:55 +00008236static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008237s390_irgen_SGR(UChar r1, UChar r2)
8238{
8239 IRTemp op1 = newTemp(Ity_I64);
8240 IRTemp op2 = newTemp(Ity_I64);
8241 IRTemp result = newTemp(Ity_I64);
8242
8243 assign(op1, get_gpr_dw0(r1));
8244 assign(op2, get_gpr_dw0(r2));
8245 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8246 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8247 put_gpr_dw0(r1, mkexpr(result));
8248
8249 return "sgr";
8250}
8251
florian55085f82012-11-21 00:36:55 +00008252static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008253s390_irgen_SGFR(UChar r1, UChar r2)
8254{
8255 IRTemp op1 = newTemp(Ity_I64);
8256 IRTemp op2 = newTemp(Ity_I64);
8257 IRTemp result = newTemp(Ity_I64);
8258
8259 assign(op1, get_gpr_dw0(r1));
8260 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8261 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8262 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8263 put_gpr_dw0(r1, mkexpr(result));
8264
8265 return "sgfr";
8266}
8267
florian55085f82012-11-21 00:36:55 +00008268static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008269s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8270{
8271 IRTemp op2 = newTemp(Ity_I32);
8272 IRTemp op3 = newTemp(Ity_I32);
8273 IRTemp result = newTemp(Ity_I32);
8274
8275 assign(op2, get_gpr_w1(r2));
8276 assign(op3, get_gpr_w1(r3));
8277 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8278 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8279 put_gpr_w1(r1, mkexpr(result));
8280
8281 return "srk";
8282}
8283
florian55085f82012-11-21 00:36:55 +00008284static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008285s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8286{
8287 IRTemp op2 = newTemp(Ity_I64);
8288 IRTemp op3 = newTemp(Ity_I64);
8289 IRTemp result = newTemp(Ity_I64);
8290
8291 assign(op2, get_gpr_dw0(r2));
8292 assign(op3, get_gpr_dw0(r3));
8293 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8294 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8295 put_gpr_dw0(r1, mkexpr(result));
8296
8297 return "sgrk";
8298}
8299
florian55085f82012-11-21 00:36:55 +00008300static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008301s390_irgen_S(UChar r1, IRTemp op2addr)
8302{
8303 IRTemp op1 = newTemp(Ity_I32);
8304 IRTemp op2 = newTemp(Ity_I32);
8305 IRTemp result = newTemp(Ity_I32);
8306
8307 assign(op1, get_gpr_w1(r1));
8308 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8309 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8310 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8311 put_gpr_w1(r1, mkexpr(result));
8312
8313 return "s";
8314}
8315
florian55085f82012-11-21 00:36:55 +00008316static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008317s390_irgen_SY(UChar r1, IRTemp op2addr)
8318{
8319 IRTemp op1 = newTemp(Ity_I32);
8320 IRTemp op2 = newTemp(Ity_I32);
8321 IRTemp result = newTemp(Ity_I32);
8322
8323 assign(op1, get_gpr_w1(r1));
8324 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8325 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8326 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8327 put_gpr_w1(r1, mkexpr(result));
8328
8329 return "sy";
8330}
8331
florian55085f82012-11-21 00:36:55 +00008332static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008333s390_irgen_SG(UChar r1, IRTemp op2addr)
8334{
8335 IRTemp op1 = newTemp(Ity_I64);
8336 IRTemp op2 = newTemp(Ity_I64);
8337 IRTemp result = newTemp(Ity_I64);
8338
8339 assign(op1, get_gpr_dw0(r1));
8340 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8341 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8342 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8343 put_gpr_dw0(r1, mkexpr(result));
8344
8345 return "sg";
8346}
8347
florian55085f82012-11-21 00:36:55 +00008348static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008349s390_irgen_SGF(UChar r1, IRTemp op2addr)
8350{
8351 IRTemp op1 = newTemp(Ity_I64);
8352 IRTemp op2 = newTemp(Ity_I64);
8353 IRTemp result = newTemp(Ity_I64);
8354
8355 assign(op1, get_gpr_dw0(r1));
8356 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8357 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8358 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8359 put_gpr_dw0(r1, mkexpr(result));
8360
8361 return "sgf";
8362}
8363
florian55085f82012-11-21 00:36:55 +00008364static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008365s390_irgen_SH(UChar r1, IRTemp op2addr)
8366{
8367 IRTemp op1 = newTemp(Ity_I32);
8368 IRTemp op2 = newTemp(Ity_I32);
8369 IRTemp result = newTemp(Ity_I32);
8370
8371 assign(op1, get_gpr_w1(r1));
8372 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8373 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8374 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8375 put_gpr_w1(r1, mkexpr(result));
8376
8377 return "sh";
8378}
8379
florian55085f82012-11-21 00:36:55 +00008380static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008381s390_irgen_SHY(UChar r1, IRTemp op2addr)
8382{
8383 IRTemp op1 = newTemp(Ity_I32);
8384 IRTemp op2 = newTemp(Ity_I32);
8385 IRTemp result = newTemp(Ity_I32);
8386
8387 assign(op1, get_gpr_w1(r1));
8388 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8389 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8390 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8391 put_gpr_w1(r1, mkexpr(result));
8392
8393 return "shy";
8394}
8395
florian55085f82012-11-21 00:36:55 +00008396static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008397s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8398{
8399 IRTemp op2 = newTemp(Ity_I32);
8400 IRTemp op3 = newTemp(Ity_I32);
8401 IRTemp result = newTemp(Ity_I32);
8402
8403 assign(op2, get_gpr_w0(r1));
8404 assign(op3, get_gpr_w0(r2));
8405 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8406 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8407 put_gpr_w0(r1, mkexpr(result));
8408
8409 return "shhhr";
8410}
8411
florian55085f82012-11-21 00:36:55 +00008412static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008413s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8414{
8415 IRTemp op2 = newTemp(Ity_I32);
8416 IRTemp op3 = newTemp(Ity_I32);
8417 IRTemp result = newTemp(Ity_I32);
8418
8419 assign(op2, get_gpr_w0(r1));
8420 assign(op3, get_gpr_w1(r2));
8421 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8422 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8423 put_gpr_w0(r1, mkexpr(result));
8424
8425 return "shhlr";
8426}
8427
florian55085f82012-11-21 00:36:55 +00008428static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008429s390_irgen_SLR(UChar r1, UChar r2)
8430{
8431 IRTemp op1 = newTemp(Ity_I32);
8432 IRTemp op2 = newTemp(Ity_I32);
8433 IRTemp result = newTemp(Ity_I32);
8434
8435 assign(op1, get_gpr_w1(r1));
8436 assign(op2, get_gpr_w1(r2));
8437 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8438 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8439 put_gpr_w1(r1, mkexpr(result));
8440
8441 return "slr";
8442}
8443
florian55085f82012-11-21 00:36:55 +00008444static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008445s390_irgen_SLGR(UChar r1, UChar r2)
8446{
8447 IRTemp op1 = newTemp(Ity_I64);
8448 IRTemp op2 = newTemp(Ity_I64);
8449 IRTemp result = newTemp(Ity_I64);
8450
8451 assign(op1, get_gpr_dw0(r1));
8452 assign(op2, get_gpr_dw0(r2));
8453 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8454 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8455 put_gpr_dw0(r1, mkexpr(result));
8456
8457 return "slgr";
8458}
8459
florian55085f82012-11-21 00:36:55 +00008460static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008461s390_irgen_SLGFR(UChar r1, UChar r2)
8462{
8463 IRTemp op1 = newTemp(Ity_I64);
8464 IRTemp op2 = newTemp(Ity_I64);
8465 IRTemp result = newTemp(Ity_I64);
8466
8467 assign(op1, get_gpr_dw0(r1));
8468 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8469 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8470 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8471 put_gpr_dw0(r1, mkexpr(result));
8472
8473 return "slgfr";
8474}
8475
florian55085f82012-11-21 00:36:55 +00008476static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008477s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8478{
8479 IRTemp op2 = newTemp(Ity_I32);
8480 IRTemp op3 = newTemp(Ity_I32);
8481 IRTemp result = newTemp(Ity_I32);
8482
8483 assign(op2, get_gpr_w1(r2));
8484 assign(op3, get_gpr_w1(r3));
8485 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8486 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8487 put_gpr_w1(r1, mkexpr(result));
8488
8489 return "slrk";
8490}
8491
florian55085f82012-11-21 00:36:55 +00008492static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008493s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8494{
8495 IRTemp op2 = newTemp(Ity_I64);
8496 IRTemp op3 = newTemp(Ity_I64);
8497 IRTemp result = newTemp(Ity_I64);
8498
8499 assign(op2, get_gpr_dw0(r2));
8500 assign(op3, get_gpr_dw0(r3));
8501 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8502 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8503 put_gpr_dw0(r1, mkexpr(result));
8504
8505 return "slgrk";
8506}
8507
florian55085f82012-11-21 00:36:55 +00008508static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008509s390_irgen_SL(UChar r1, IRTemp op2addr)
8510{
8511 IRTemp op1 = newTemp(Ity_I32);
8512 IRTemp op2 = newTemp(Ity_I32);
8513 IRTemp result = newTemp(Ity_I32);
8514
8515 assign(op1, get_gpr_w1(r1));
8516 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8517 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8518 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8519 put_gpr_w1(r1, mkexpr(result));
8520
8521 return "sl";
8522}
8523
florian55085f82012-11-21 00:36:55 +00008524static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008525s390_irgen_SLY(UChar r1, IRTemp op2addr)
8526{
8527 IRTemp op1 = newTemp(Ity_I32);
8528 IRTemp op2 = newTemp(Ity_I32);
8529 IRTemp result = newTemp(Ity_I32);
8530
8531 assign(op1, get_gpr_w1(r1));
8532 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8533 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8534 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8535 put_gpr_w1(r1, mkexpr(result));
8536
8537 return "sly";
8538}
8539
florian55085f82012-11-21 00:36:55 +00008540static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008541s390_irgen_SLG(UChar r1, IRTemp op2addr)
8542{
8543 IRTemp op1 = newTemp(Ity_I64);
8544 IRTemp op2 = newTemp(Ity_I64);
8545 IRTemp result = newTemp(Ity_I64);
8546
8547 assign(op1, get_gpr_dw0(r1));
8548 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8549 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8550 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8551 put_gpr_dw0(r1, mkexpr(result));
8552
8553 return "slg";
8554}
8555
florian55085f82012-11-21 00:36:55 +00008556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008557s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8558{
8559 IRTemp op1 = newTemp(Ity_I64);
8560 IRTemp op2 = newTemp(Ity_I64);
8561 IRTemp result = newTemp(Ity_I64);
8562
8563 assign(op1, get_gpr_dw0(r1));
8564 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8565 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8566 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8567 put_gpr_dw0(r1, mkexpr(result));
8568
8569 return "slgf";
8570}
8571
florian55085f82012-11-21 00:36:55 +00008572static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008573s390_irgen_SLFI(UChar r1, UInt i2)
8574{
8575 IRTemp op1 = newTemp(Ity_I32);
8576 UInt op2;
8577 IRTemp result = newTemp(Ity_I32);
8578
8579 assign(op1, get_gpr_w1(r1));
8580 op2 = i2;
8581 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8582 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8583 mkU32(op2)));
8584 put_gpr_w1(r1, mkexpr(result));
8585
8586 return "slfi";
8587}
8588
florian55085f82012-11-21 00:36:55 +00008589static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008590s390_irgen_SLGFI(UChar r1, UInt i2)
8591{
8592 IRTemp op1 = newTemp(Ity_I64);
8593 ULong op2;
8594 IRTemp result = newTemp(Ity_I64);
8595
8596 assign(op1, get_gpr_dw0(r1));
8597 op2 = (ULong)i2;
8598 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8599 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8600 mkU64(op2)));
8601 put_gpr_dw0(r1, mkexpr(result));
8602
8603 return "slgfi";
8604}
8605
florian55085f82012-11-21 00:36:55 +00008606static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008607s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8608{
8609 IRTemp op2 = newTemp(Ity_I32);
8610 IRTemp op3 = newTemp(Ity_I32);
8611 IRTemp result = newTemp(Ity_I32);
8612
8613 assign(op2, get_gpr_w0(r1));
8614 assign(op3, get_gpr_w0(r2));
8615 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8616 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8617 put_gpr_w0(r1, mkexpr(result));
8618
8619 return "slhhhr";
8620}
8621
florian55085f82012-11-21 00:36:55 +00008622static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008623s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8624{
8625 IRTemp op2 = newTemp(Ity_I32);
8626 IRTemp op3 = newTemp(Ity_I32);
8627 IRTemp result = newTemp(Ity_I32);
8628
8629 assign(op2, get_gpr_w0(r1));
8630 assign(op3, get_gpr_w1(r2));
8631 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8632 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8633 put_gpr_w0(r1, mkexpr(result));
8634
8635 return "slhhlr";
8636}
8637
florian55085f82012-11-21 00:36:55 +00008638static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008639s390_irgen_SLBR(UChar r1, UChar r2)
8640{
8641 IRTemp op1 = newTemp(Ity_I32);
8642 IRTemp op2 = newTemp(Ity_I32);
8643 IRTemp result = newTemp(Ity_I32);
8644 IRTemp borrow_in = newTemp(Ity_I32);
8645
8646 assign(op1, get_gpr_w1(r1));
8647 assign(op2, get_gpr_w1(r2));
8648 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8649 s390_call_calculate_cc(), mkU8(1))));
8650 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8651 mkexpr(borrow_in)));
8652 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8653 put_gpr_w1(r1, mkexpr(result));
8654
8655 return "slbr";
8656}
8657
florian55085f82012-11-21 00:36:55 +00008658static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008659s390_irgen_SLBGR(UChar r1, UChar r2)
8660{
8661 IRTemp op1 = newTemp(Ity_I64);
8662 IRTemp op2 = newTemp(Ity_I64);
8663 IRTemp result = newTemp(Ity_I64);
8664 IRTemp borrow_in = newTemp(Ity_I64);
8665
8666 assign(op1, get_gpr_dw0(r1));
8667 assign(op2, get_gpr_dw0(r2));
8668 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8669 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8670 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8671 mkexpr(borrow_in)));
8672 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8673 put_gpr_dw0(r1, mkexpr(result));
8674
8675 return "slbgr";
8676}
8677
florian55085f82012-11-21 00:36:55 +00008678static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008679s390_irgen_SLB(UChar r1, IRTemp op2addr)
8680{
8681 IRTemp op1 = newTemp(Ity_I32);
8682 IRTemp op2 = newTemp(Ity_I32);
8683 IRTemp result = newTemp(Ity_I32);
8684 IRTemp borrow_in = newTemp(Ity_I32);
8685
8686 assign(op1, get_gpr_w1(r1));
8687 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8688 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8689 s390_call_calculate_cc(), mkU8(1))));
8690 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8691 mkexpr(borrow_in)));
8692 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8693 put_gpr_w1(r1, mkexpr(result));
8694
8695 return "slb";
8696}
8697
florian55085f82012-11-21 00:36:55 +00008698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008699s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8700{
8701 IRTemp op1 = newTemp(Ity_I64);
8702 IRTemp op2 = newTemp(Ity_I64);
8703 IRTemp result = newTemp(Ity_I64);
8704 IRTemp borrow_in = newTemp(Ity_I64);
8705
8706 assign(op1, get_gpr_dw0(r1));
8707 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8708 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8709 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8710 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8711 mkexpr(borrow_in)));
8712 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8713 put_gpr_dw0(r1, mkexpr(result));
8714
8715 return "slbg";
8716}
8717
florian55085f82012-11-21 00:36:55 +00008718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008719s390_irgen_SVC(UChar i)
8720{
8721 IRTemp sysno = newTemp(Ity_I64);
8722
8723 if (i != 0) {
8724 assign(sysno, mkU64(i));
8725 } else {
8726 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8727 }
8728 system_call(mkexpr(sysno));
8729
8730 return "svc";
8731}
8732
florian55085f82012-11-21 00:36:55 +00008733static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008734s390_irgen_TM(UChar i2, IRTemp op1addr)
8735{
8736 UChar mask;
8737 IRTemp value = newTemp(Ity_I8);
8738
8739 mask = i2;
8740 assign(value, load(Ity_I8, mkexpr(op1addr)));
8741 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8742 mkU8(mask)));
8743
8744 return "tm";
8745}
8746
florian55085f82012-11-21 00:36:55 +00008747static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008748s390_irgen_TMY(UChar i2, IRTemp op1addr)
8749{
8750 UChar mask;
8751 IRTemp value = newTemp(Ity_I8);
8752
8753 mask = i2;
8754 assign(value, load(Ity_I8, mkexpr(op1addr)));
8755 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8756 mkU8(mask)));
8757
8758 return "tmy";
8759}
8760
florian55085f82012-11-21 00:36:55 +00008761static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008762s390_irgen_TMHH(UChar r1, UShort i2)
8763{
8764 UShort mask;
8765 IRTemp value = newTemp(Ity_I16);
8766
8767 mask = i2;
8768 assign(value, get_gpr_hw0(r1));
8769 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8770 mkU16(mask)));
8771
8772 return "tmhh";
8773}
8774
florian55085f82012-11-21 00:36:55 +00008775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008776s390_irgen_TMHL(UChar r1, UShort i2)
8777{
8778 UShort mask;
8779 IRTemp value = newTemp(Ity_I16);
8780
8781 mask = i2;
8782 assign(value, get_gpr_hw1(r1));
8783 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8784 mkU16(mask)));
8785
8786 return "tmhl";
8787}
8788
florian55085f82012-11-21 00:36:55 +00008789static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008790s390_irgen_TMLH(UChar r1, UShort i2)
8791{
8792 UShort mask;
8793 IRTemp value = newTemp(Ity_I16);
8794
8795 mask = i2;
8796 assign(value, get_gpr_hw2(r1));
8797 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8798 mkU16(mask)));
8799
8800 return "tmlh";
8801}
8802
florian55085f82012-11-21 00:36:55 +00008803static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008804s390_irgen_TMLL(UChar r1, UShort i2)
8805{
8806 UShort mask;
8807 IRTemp value = newTemp(Ity_I16);
8808
8809 mask = i2;
8810 assign(value, get_gpr_hw3(r1));
8811 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8812 mkU16(mask)));
8813
8814 return "tmll";
8815}
8816
florian55085f82012-11-21 00:36:55 +00008817static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008818s390_irgen_EFPC(UChar r1)
8819{
8820 put_gpr_w1(r1, get_fpc_w0());
8821
8822 return "efpc";
8823}
8824
florian55085f82012-11-21 00:36:55 +00008825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008826s390_irgen_LER(UChar r1, UChar r2)
8827{
8828 put_fpr_w0(r1, get_fpr_w0(r2));
8829
8830 return "ler";
8831}
8832
florian55085f82012-11-21 00:36:55 +00008833static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008834s390_irgen_LDR(UChar r1, UChar r2)
8835{
8836 put_fpr_dw0(r1, get_fpr_dw0(r2));
8837
8838 return "ldr";
8839}
8840
florian55085f82012-11-21 00:36:55 +00008841static const HChar *
Elliott Hughesa0664b92017-04-18 17:46:52 -07008842s390_irgen_LDER(UChar r1, UChar r2)
8843{
8844 put_fpr_dw0(r1, mkF64i(0x0));
8845 put_fpr_w0(r1, get_fpr_w0(r2));
8846
8847 return "lder";
8848}
8849
8850static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008851s390_irgen_LXR(UChar r1, UChar r2)
8852{
8853 put_fpr_dw0(r1, get_fpr_dw0(r2));
8854 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8855
8856 return "lxr";
8857}
8858
florian55085f82012-11-21 00:36:55 +00008859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008860s390_irgen_LE(UChar r1, IRTemp op2addr)
8861{
8862 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8863
8864 return "le";
8865}
8866
florian55085f82012-11-21 00:36:55 +00008867static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008868s390_irgen_LD(UChar r1, IRTemp op2addr)
8869{
8870 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8871
8872 return "ld";
8873}
8874
florian55085f82012-11-21 00:36:55 +00008875static const HChar *
Elliott Hughesa0664b92017-04-18 17:46:52 -07008876s390_irgen_LDE(UChar r1, IRTemp op2addr)
8877{
8878 put_fpr_dw0(r1, mkF64i(0x0));
8879 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8880
8881 return "lde";
8882}
8883
8884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008885s390_irgen_LEY(UChar r1, IRTemp op2addr)
8886{
8887 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8888
8889 return "ley";
8890}
8891
florian55085f82012-11-21 00:36:55 +00008892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008893s390_irgen_LDY(UChar r1, IRTemp op2addr)
8894{
8895 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8896
8897 return "ldy";
8898}
8899
florian55085f82012-11-21 00:36:55 +00008900static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008901s390_irgen_LFPC(IRTemp op2addr)
8902{
8903 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8904
8905 return "lfpc";
8906}
8907
florian55085f82012-11-21 00:36:55 +00008908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008909s390_irgen_LZER(UChar r1)
8910{
8911 put_fpr_w0(r1, mkF32i(0x0));
8912
8913 return "lzer";
8914}
8915
florian55085f82012-11-21 00:36:55 +00008916static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008917s390_irgen_LZDR(UChar r1)
8918{
8919 put_fpr_dw0(r1, mkF64i(0x0));
8920
8921 return "lzdr";
8922}
8923
florian55085f82012-11-21 00:36:55 +00008924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008925s390_irgen_LZXR(UChar r1)
8926{
8927 put_fpr_dw0(r1, mkF64i(0x0));
8928 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8929
8930 return "lzxr";
8931}
8932
florian55085f82012-11-21 00:36:55 +00008933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008934s390_irgen_SRNM(IRTemp op2addr)
8935{
florianf0fa1be2012-09-18 20:24:38 +00008936 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008937
florianf0fa1be2012-09-18 20:24:38 +00008938 input_mask = 3;
8939 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008940
florianf0fa1be2012-09-18 20:24:38 +00008941 put_fpc_w0(binop(Iop_Or32,
8942 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8943 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8944 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008945 return "srnm";
8946}
8947
florian55085f82012-11-21 00:36:55 +00008948static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008949s390_irgen_SRNMB(IRTemp op2addr)
8950{
8951 UInt input_mask, fpc_mask;
8952
8953 input_mask = 7;
8954 fpc_mask = 7;
8955
8956 put_fpc_w0(binop(Iop_Or32,
8957 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8958 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8959 mkU32(input_mask))));
8960 return "srnmb";
8961}
8962
florian81a4bfe2012-09-20 01:25:28 +00008963static void
florianf0fa1be2012-09-18 20:24:38 +00008964s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8965{
8966 if (b2 == 0) { /* This is the typical case */
8967 if (d2 > 3) {
8968 if (s390_host_has_fpext && d2 == 7) {
8969 /* ok */
8970 } else {
8971 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008972 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008973 }
8974 }
8975 }
8976
8977 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8978}
8979
florian82cdba62013-03-12 01:31:24 +00008980/* Wrapper to validate the parameter as in SRNMB is not required, as all
8981 the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8982static const HChar *
8983s390_irgen_SRNMT(IRTemp op2addr)
8984{
8985 UInt input_mask, fpc_mask;
8986
8987 input_mask = 7;
8988 fpc_mask = 0x70;
8989
8990 /* fpc[25:27] <- op2addr[61:63]
8991 fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8992 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8993 binop(Iop_Shl32, binop(Iop_And32,
8994 unop(Iop_64to32, mkexpr(op2addr)),
8995 mkU32(input_mask)), mkU8(4))));
8996 return "srnmt";
8997}
8998
florianf0fa1be2012-09-18 20:24:38 +00008999
florian55085f82012-11-21 00:36:55 +00009000static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009001s390_irgen_SFPC(UChar r1)
9002{
9003 put_fpc_w0(get_gpr_w1(r1));
9004
9005 return "sfpc";
9006}
9007
florian55085f82012-11-21 00:36:55 +00009008static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009009s390_irgen_STE(UChar r1, IRTemp op2addr)
9010{
9011 store(mkexpr(op2addr), get_fpr_w0(r1));
9012
9013 return "ste";
9014}
9015
florian55085f82012-11-21 00:36:55 +00009016static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009017s390_irgen_STD(UChar r1, IRTemp op2addr)
9018{
9019 store(mkexpr(op2addr), get_fpr_dw0(r1));
9020
9021 return "std";
9022}
9023
florian55085f82012-11-21 00:36:55 +00009024static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009025s390_irgen_STEY(UChar r1, IRTemp op2addr)
9026{
9027 store(mkexpr(op2addr), get_fpr_w0(r1));
9028
9029 return "stey";
9030}
9031
florian55085f82012-11-21 00:36:55 +00009032static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009033s390_irgen_STDY(UChar r1, IRTemp op2addr)
9034{
9035 store(mkexpr(op2addr), get_fpr_dw0(r1));
9036
9037 return "stdy";
9038}
9039
florian55085f82012-11-21 00:36:55 +00009040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009041s390_irgen_STFPC(IRTemp op2addr)
9042{
9043 store(mkexpr(op2addr), get_fpc_w0());
9044
9045 return "stfpc";
9046}
9047
florian55085f82012-11-21 00:36:55 +00009048static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009049s390_irgen_AEBR(UChar r1, UChar r2)
9050{
9051 IRTemp op1 = newTemp(Ity_F32);
9052 IRTemp op2 = newTemp(Ity_F32);
9053 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009054 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009055
9056 assign(op1, get_fpr_w0(r1));
9057 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009058 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009059 mkexpr(op2)));
9060 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9061 put_fpr_w0(r1, mkexpr(result));
9062
9063 return "aebr";
9064}
9065
florian55085f82012-11-21 00:36:55 +00009066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009067s390_irgen_ADBR(UChar r1, UChar r2)
9068{
9069 IRTemp op1 = newTemp(Ity_F64);
9070 IRTemp op2 = newTemp(Ity_F64);
9071 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009072 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009073
9074 assign(op1, get_fpr_dw0(r1));
9075 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009076 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009077 mkexpr(op2)));
9078 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9079 put_fpr_dw0(r1, mkexpr(result));
9080
9081 return "adbr";
9082}
9083
florian55085f82012-11-21 00:36:55 +00009084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009085s390_irgen_AEB(UChar r1, IRTemp op2addr)
9086{
9087 IRTemp op1 = newTemp(Ity_F32);
9088 IRTemp op2 = newTemp(Ity_F32);
9089 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009090 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009091
9092 assign(op1, get_fpr_w0(r1));
9093 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009094 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009095 mkexpr(op2)));
9096 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9097 put_fpr_w0(r1, mkexpr(result));
9098
9099 return "aeb";
9100}
9101
florian55085f82012-11-21 00:36:55 +00009102static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009103s390_irgen_ADB(UChar r1, IRTemp op2addr)
9104{
9105 IRTemp op1 = newTemp(Ity_F64);
9106 IRTemp op2 = newTemp(Ity_F64);
9107 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009108 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009109
9110 assign(op1, get_fpr_dw0(r1));
9111 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009112 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009113 mkexpr(op2)));
9114 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9115 put_fpr_dw0(r1, mkexpr(result));
9116
9117 return "adb";
9118}
9119
florian55085f82012-11-21 00:36:55 +00009120static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009121s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
9122 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009123{
florian125e20d2012-10-07 15:42:37 +00009124 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009125 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009126 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009127 }
sewardj2019a972011-03-07 16:04:07 +00009128 IRTemp op2 = newTemp(Ity_I32);
9129
9130 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009131 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009132 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009133
9134 return "cefbr";
9135}
9136
florian55085f82012-11-21 00:36:55 +00009137static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009138s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
9139 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009140{
9141 IRTemp op2 = newTemp(Ity_I32);
9142
9143 assign(op2, get_gpr_w1(r2));
9144 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
9145
9146 return "cdfbr";
9147}
9148
florian55085f82012-11-21 00:36:55 +00009149static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009150s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
9151 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009152{
florian125e20d2012-10-07 15:42:37 +00009153 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009154 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009155 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009156 }
sewardj2019a972011-03-07 16:04:07 +00009157 IRTemp op2 = newTemp(Ity_I64);
9158
9159 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009160 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009161 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009162
9163 return "cegbr";
9164}
9165
florian55085f82012-11-21 00:36:55 +00009166static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009167s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
9168 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009169{
florian125e20d2012-10-07 15:42:37 +00009170 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009171 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009172 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009173 }
sewardj2019a972011-03-07 16:04:07 +00009174 IRTemp op2 = newTemp(Ity_I64);
9175
9176 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009177 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009178 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009179
9180 return "cdgbr";
9181}
9182
florian55085f82012-11-21 00:36:55 +00009183static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009184s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
9185 UChar r1, UChar r2)
9186{
floriane75dafa2012-09-01 17:54:09 +00009187 if (! s390_host_has_fpext) {
9188 emulation_failure(EmFail_S390X_fpext);
9189 } else {
9190 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009191
floriane75dafa2012-09-01 17:54:09 +00009192 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009193 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009194 mkexpr(op2)));
9195 }
florian1c8f7ff2012-09-01 00:12:11 +00009196 return "celfbr";
9197}
9198
florian55085f82012-11-21 00:36:55 +00009199static const HChar *
floriand2129202012-09-01 20:01:39 +00009200s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
9201 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00009202{
floriane75dafa2012-09-01 17:54:09 +00009203 if (! s390_host_has_fpext) {
9204 emulation_failure(EmFail_S390X_fpext);
9205 } else {
9206 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009207
floriane75dafa2012-09-01 17:54:09 +00009208 assign(op2, get_gpr_w1(r2));
9209 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
9210 }
florian1c8f7ff2012-09-01 00:12:11 +00009211 return "cdlfbr";
9212}
9213
florian55085f82012-11-21 00:36:55 +00009214static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009215s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
9216 UChar r1, UChar r2)
9217{
floriane75dafa2012-09-01 17:54:09 +00009218 if (! s390_host_has_fpext) {
9219 emulation_failure(EmFail_S390X_fpext);
9220 } else {
9221 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009222
floriane75dafa2012-09-01 17:54:09 +00009223 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009224 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009225 mkexpr(op2)));
9226 }
florian1c8f7ff2012-09-01 00:12:11 +00009227 return "celgbr";
9228}
9229
florian55085f82012-11-21 00:36:55 +00009230static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009231s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
9232 UChar r1, UChar r2)
9233{
floriane75dafa2012-09-01 17:54:09 +00009234 if (! s390_host_has_fpext) {
9235 emulation_failure(EmFail_S390X_fpext);
9236 } else {
9237 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009238
floriane75dafa2012-09-01 17:54:09 +00009239 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009240 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
9241 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009242 mkexpr(op2)));
9243 }
florian1c8f7ff2012-09-01 00:12:11 +00009244 return "cdlgbr";
9245}
9246
florian55085f82012-11-21 00:36:55 +00009247static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009248s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9249 UChar r1, UChar r2)
9250{
floriane75dafa2012-09-01 17:54:09 +00009251 if (! s390_host_has_fpext) {
9252 emulation_failure(EmFail_S390X_fpext);
9253 } else {
9254 IRTemp op = newTemp(Ity_F32);
9255 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009256 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009257
floriane75dafa2012-09-01 17:54:09 +00009258 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009259 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +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_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009263 }
florian1c8f7ff2012-09-01 00:12:11 +00009264 return "clfebr";
9265}
9266
florian55085f82012-11-21 00:36:55 +00009267static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009268s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9269 UChar r1, UChar r2)
9270{
floriane75dafa2012-09-01 17:54:09 +00009271 if (! s390_host_has_fpext) {
9272 emulation_failure(EmFail_S390X_fpext);
9273 } else {
9274 IRTemp op = newTemp(Ity_F64);
9275 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009276 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009277
floriane75dafa2012-09-01 17:54:09 +00009278 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009279 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009280 mkexpr(op)));
9281 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009282 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009283 }
florian1c8f7ff2012-09-01 00:12:11 +00009284 return "clfdbr";
9285}
9286
florian55085f82012-11-21 00:36:55 +00009287static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009288s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9289 UChar r1, UChar r2)
9290{
floriane75dafa2012-09-01 17:54:09 +00009291 if (! s390_host_has_fpext) {
9292 emulation_failure(EmFail_S390X_fpext);
9293 } else {
9294 IRTemp op = newTemp(Ity_F32);
9295 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009296 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009297
floriane75dafa2012-09-01 17:54:09 +00009298 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009299 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009300 mkexpr(op)));
9301 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009302 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009303 }
florian1c8f7ff2012-09-01 00:12:11 +00009304 return "clgebr";
9305}
9306
florian55085f82012-11-21 00:36:55 +00009307static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009308s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9309 UChar r1, UChar r2)
9310{
floriane75dafa2012-09-01 17:54:09 +00009311 if (! s390_host_has_fpext) {
9312 emulation_failure(EmFail_S390X_fpext);
9313 } else {
9314 IRTemp op = newTemp(Ity_F64);
9315 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009316 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009317
floriane75dafa2012-09-01 17:54:09 +00009318 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009319 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009320 mkexpr(op)));
9321 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009322 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009323 }
florian1c8f7ff2012-09-01 00:12:11 +00009324 return "clgdbr";
9325}
9326
florian55085f82012-11-21 00:36:55 +00009327static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009328s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9329 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009330{
9331 IRTemp op = newTemp(Ity_F32);
9332 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009333 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009334
9335 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009336 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009337 mkexpr(op)));
9338 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009339 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009340
9341 return "cfebr";
9342}
9343
florian55085f82012-11-21 00:36:55 +00009344static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009345s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9346 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009347{
9348 IRTemp op = newTemp(Ity_F64);
9349 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009350 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009351
9352 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009353 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009354 mkexpr(op)));
9355 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009356 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009357
9358 return "cfdbr";
9359}
9360
florian55085f82012-11-21 00:36:55 +00009361static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009362s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9363 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009364{
9365 IRTemp op = newTemp(Ity_F32);
9366 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009367 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009368
9369 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009370 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009371 mkexpr(op)));
9372 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009373 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009374
9375 return "cgebr";
9376}
9377
florian55085f82012-11-21 00:36:55 +00009378static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009379s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9380 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009381{
9382 IRTemp op = newTemp(Ity_F64);
9383 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009384 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009385
9386 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009387 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009388 mkexpr(op)));
9389 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009390 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009391
9392 return "cgdbr";
9393}
9394
florian55085f82012-11-21 00:36:55 +00009395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009396s390_irgen_DEBR(UChar r1, UChar r2)
9397{
9398 IRTemp op1 = newTemp(Ity_F32);
9399 IRTemp op2 = newTemp(Ity_F32);
9400 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009401 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009402
9403 assign(op1, get_fpr_w0(r1));
9404 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009405 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009406 mkexpr(op2)));
9407 put_fpr_w0(r1, mkexpr(result));
9408
9409 return "debr";
9410}
9411
florian55085f82012-11-21 00:36:55 +00009412static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009413s390_irgen_DDBR(UChar r1, UChar r2)
9414{
9415 IRTemp op1 = newTemp(Ity_F64);
9416 IRTemp op2 = newTemp(Ity_F64);
9417 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009418 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009419
9420 assign(op1, get_fpr_dw0(r1));
9421 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009422 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009423 mkexpr(op2)));
9424 put_fpr_dw0(r1, mkexpr(result));
9425
9426 return "ddbr";
9427}
9428
florian55085f82012-11-21 00:36:55 +00009429static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009430s390_irgen_DEB(UChar r1, IRTemp op2addr)
9431{
9432 IRTemp op1 = newTemp(Ity_F32);
9433 IRTemp op2 = newTemp(Ity_F32);
9434 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009435 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009436
9437 assign(op1, get_fpr_w0(r1));
9438 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009439 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009440 mkexpr(op2)));
9441 put_fpr_w0(r1, mkexpr(result));
9442
9443 return "deb";
9444}
9445
florian55085f82012-11-21 00:36:55 +00009446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009447s390_irgen_DDB(UChar r1, IRTemp op2addr)
9448{
9449 IRTemp op1 = newTemp(Ity_F64);
9450 IRTemp op2 = newTemp(Ity_F64);
9451 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009452 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009453
9454 assign(op1, get_fpr_dw0(r1));
9455 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009456 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009457 mkexpr(op2)));
9458 put_fpr_dw0(r1, mkexpr(result));
9459
9460 return "ddb";
9461}
9462
florian55085f82012-11-21 00:36:55 +00009463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009464s390_irgen_LTEBR(UChar r1, UChar r2)
9465{
9466 IRTemp result = newTemp(Ity_F32);
9467
9468 assign(result, get_fpr_w0(r2));
9469 put_fpr_w0(r1, mkexpr(result));
9470 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9471
9472 return "ltebr";
9473}
9474
florian55085f82012-11-21 00:36:55 +00009475static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009476s390_irgen_LTDBR(UChar r1, UChar r2)
9477{
9478 IRTemp result = newTemp(Ity_F64);
9479
9480 assign(result, get_fpr_dw0(r2));
9481 put_fpr_dw0(r1, mkexpr(result));
9482 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9483
9484 return "ltdbr";
9485}
9486
florian55085f82012-11-21 00:36:55 +00009487static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009488s390_irgen_LCEBR(UChar r1, UChar r2)
9489{
9490 IRTemp result = newTemp(Ity_F32);
9491
9492 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9493 put_fpr_w0(r1, mkexpr(result));
9494 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9495
9496 return "lcebr";
9497}
9498
florian55085f82012-11-21 00:36:55 +00009499static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009500s390_irgen_LCDBR(UChar r1, UChar r2)
9501{
9502 IRTemp result = newTemp(Ity_F64);
9503
9504 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9505 put_fpr_dw0(r1, mkexpr(result));
9506 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9507
9508 return "lcdbr";
9509}
9510
florian55085f82012-11-21 00:36:55 +00009511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009512s390_irgen_LDEBR(UChar r1, UChar r2)
9513{
9514 IRTemp op = newTemp(Ity_F32);
9515
9516 assign(op, get_fpr_w0(r2));
9517 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9518
9519 return "ldebr";
9520}
9521
florian55085f82012-11-21 00:36:55 +00009522static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009523s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9524{
9525 IRTemp op = newTemp(Ity_F32);
9526
9527 assign(op, load(Ity_F32, mkexpr(op2addr)));
9528 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9529
9530 return "ldeb";
9531}
9532
florian55085f82012-11-21 00:36:55 +00009533static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009534s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9535 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009536{
florian125e20d2012-10-07 15:42:37 +00009537 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009538 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009539 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009540 }
sewardj2019a972011-03-07 16:04:07 +00009541 IRTemp op = newTemp(Ity_F64);
9542
9543 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009544 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009545 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009546
9547 return "ledbr";
9548}
9549
florian55085f82012-11-21 00:36:55 +00009550static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009551s390_irgen_MEEBR(UChar r1, UChar r2)
9552{
9553 IRTemp op1 = newTemp(Ity_F32);
9554 IRTemp op2 = newTemp(Ity_F32);
9555 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009556 IRRoundingMode rounding_mode =
9557 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009558
9559 assign(op1, get_fpr_w0(r1));
9560 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009561 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009562 mkexpr(op2)));
9563 put_fpr_w0(r1, mkexpr(result));
9564
9565 return "meebr";
9566}
9567
florian55085f82012-11-21 00:36:55 +00009568static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009569s390_irgen_MDBR(UChar r1, UChar r2)
9570{
9571 IRTemp op1 = newTemp(Ity_F64);
9572 IRTemp op2 = newTemp(Ity_F64);
9573 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009574 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009575
9576 assign(op1, get_fpr_dw0(r1));
9577 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009578 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009579 mkexpr(op2)));
9580 put_fpr_dw0(r1, mkexpr(result));
9581
9582 return "mdbr";
9583}
9584
florian55085f82012-11-21 00:36:55 +00009585static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009586s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9587{
9588 IRTemp op1 = newTemp(Ity_F32);
9589 IRTemp op2 = newTemp(Ity_F32);
9590 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009591 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009592
9593 assign(op1, get_fpr_w0(r1));
9594 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009595 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009596 mkexpr(op2)));
9597 put_fpr_w0(r1, mkexpr(result));
9598
9599 return "meeb";
9600}
9601
florian55085f82012-11-21 00:36:55 +00009602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009603s390_irgen_MDB(UChar r1, IRTemp op2addr)
9604{
9605 IRTemp op1 = newTemp(Ity_F64);
9606 IRTemp op2 = newTemp(Ity_F64);
9607 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009608 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009609
9610 assign(op1, get_fpr_dw0(r1));
9611 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009612 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009613 mkexpr(op2)));
9614 put_fpr_dw0(r1, mkexpr(result));
9615
9616 return "mdb";
9617}
9618
florian55085f82012-11-21 00:36:55 +00009619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009620s390_irgen_SEBR(UChar r1, UChar r2)
9621{
9622 IRTemp op1 = newTemp(Ity_F32);
9623 IRTemp op2 = newTemp(Ity_F32);
9624 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009625 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009626
9627 assign(op1, get_fpr_w0(r1));
9628 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009629 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009630 mkexpr(op2)));
9631 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9632 put_fpr_w0(r1, mkexpr(result));
9633
9634 return "sebr";
9635}
9636
florian55085f82012-11-21 00:36:55 +00009637static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009638s390_irgen_SDBR(UChar r1, UChar r2)
9639{
9640 IRTemp op1 = newTemp(Ity_F64);
9641 IRTemp op2 = newTemp(Ity_F64);
9642 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009643 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009644
9645 assign(op1, get_fpr_dw0(r1));
9646 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009647 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009648 mkexpr(op2)));
9649 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9650 put_fpr_dw0(r1, mkexpr(result));
9651
9652 return "sdbr";
9653}
9654
florian55085f82012-11-21 00:36:55 +00009655static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009656s390_irgen_SEB(UChar r1, IRTemp op2addr)
9657{
9658 IRTemp op1 = newTemp(Ity_F32);
9659 IRTemp op2 = newTemp(Ity_F32);
9660 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009661 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009662
9663 assign(op1, get_fpr_w0(r1));
9664 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009665 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009666 mkexpr(op2)));
9667 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9668 put_fpr_w0(r1, mkexpr(result));
9669
9670 return "seb";
9671}
9672
florian55085f82012-11-21 00:36:55 +00009673static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009674s390_irgen_SDB(UChar r1, IRTemp op2addr)
9675{
9676 IRTemp op1 = newTemp(Ity_F64);
9677 IRTemp op2 = newTemp(Ity_F64);
9678 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009679 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009680
9681 assign(op1, get_fpr_dw0(r1));
9682 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009683 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009684 mkexpr(op2)));
9685 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9686 put_fpr_dw0(r1, mkexpr(result));
9687
9688 return "sdb";
9689}
9690
florian55085f82012-11-21 00:36:55 +00009691static const HChar *
florian12390202012-11-10 22:34:14 +00009692s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9693{
florianfb596602014-12-06 16:34:48 +00009694 if (! s390_host_has_dfp) {
9695 emulation_failure(EmFail_S390X_DFP_insn);
9696 } else {
9697 IRTemp op1 = newTemp(Ity_D64);
9698 IRTemp op2 = newTemp(Ity_D64);
9699 IRTemp result = newTemp(Ity_D64);
9700 IRTemp rounding_mode;
florian12390202012-11-10 22:34:14 +00009701
florianfb596602014-12-06 16:34:48 +00009702 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9703 emulation_warning(EmWarn_S390X_fpext_rounding);
9704 m4 = S390_DFP_ROUND_PER_FPC_0;
9705 }
florian1bb7f6f2013-02-11 00:03:27 +00009706
florianfb596602014-12-06 16:34:48 +00009707 rounding_mode = encode_dfp_rounding_mode(m4);
9708 assign(op1, get_dpr_dw0(r2));
9709 assign(op2, get_dpr_dw0(r3));
9710 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9711 mkexpr(op2)));
9712 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9713 put_dpr_dw0(r1, mkexpr(result));
florian1bb7f6f2013-02-11 00:03:27 +00009714 }
florian12390202012-11-10 22:34:14 +00009715 return (m4 == 0) ? "adtr" : "adtra";
9716}
9717
florian55085f82012-11-21 00:36:55 +00009718static const HChar *
floriane38f6412012-12-21 17:32:12 +00009719s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9720{
florianfb596602014-12-06 16:34:48 +00009721 if (! s390_host_has_dfp) {
9722 emulation_failure(EmFail_S390X_DFP_insn);
9723 } else {
9724 IRTemp op1 = newTemp(Ity_D128);
9725 IRTemp op2 = newTemp(Ity_D128);
9726 IRTemp result = newTemp(Ity_D128);
9727 IRTemp rounding_mode;
floriane38f6412012-12-21 17:32:12 +00009728
florianfb596602014-12-06 16:34:48 +00009729 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9730 emulation_warning(EmWarn_S390X_fpext_rounding);
9731 m4 = S390_DFP_ROUND_PER_FPC_0;
9732 }
florian1bb7f6f2013-02-11 00:03:27 +00009733
florianfb596602014-12-06 16:34:48 +00009734 rounding_mode = encode_dfp_rounding_mode(m4);
9735 assign(op1, get_dpr_pair(r2));
9736 assign(op2, get_dpr_pair(r3));
9737 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9738 mkexpr(op2)));
9739 put_dpr_pair(r1, mkexpr(result));
9740
9741 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
florian1bb7f6f2013-02-11 00:03:27 +00009742 }
floriane38f6412012-12-21 17:32:12 +00009743 return (m4 == 0) ? "axtr" : "axtra";
9744}
9745
9746static const HChar *
9747s390_irgen_CDTR(UChar r1, UChar r2)
9748{
9749 IRTemp op1 = newTemp(Ity_D64);
9750 IRTemp op2 = newTemp(Ity_D64);
9751 IRTemp cc_vex = newTemp(Ity_I32);
9752 IRTemp cc_s390 = newTemp(Ity_I32);
9753
9754 assign(op1, get_dpr_dw0(r1));
9755 assign(op2, get_dpr_dw0(r2));
9756 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9757
florian2d3d87f2012-12-21 21:05:17 +00009758 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009759 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9760
9761 return "cdtr";
9762}
9763
9764static const HChar *
9765s390_irgen_CXTR(UChar r1, UChar r2)
9766{
9767 IRTemp op1 = newTemp(Ity_D128);
9768 IRTemp op2 = newTemp(Ity_D128);
9769 IRTemp cc_vex = newTemp(Ity_I32);
9770 IRTemp cc_s390 = newTemp(Ity_I32);
9771
9772 assign(op1, get_dpr_pair(r1));
9773 assign(op2, get_dpr_pair(r2));
9774 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9775
florian2d3d87f2012-12-21 21:05:17 +00009776 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009777 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9778
9779 return "cxtr";
9780}
9781
9782static const HChar *
florian5f034622013-01-13 02:29:05 +00009783s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9784 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9785{
florianfb596602014-12-06 16:34:48 +00009786 if (! s390_host_has_dfp) {
9787 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009788 } else {
florianfb596602014-12-06 16:34:48 +00009789 if (! s390_host_has_fpext) {
9790 emulation_failure(EmFail_S390X_fpext);
9791 } else {
9792 IRTemp op2 = newTemp(Ity_I32);
florian5f034622013-01-13 02:29:05 +00009793
florianfb596602014-12-06 16:34:48 +00009794 assign(op2, get_gpr_w1(r2));
9795 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9796 }
florian5f034622013-01-13 02:29:05 +00009797 }
9798 return "cdftr";
9799}
9800
9801static const HChar *
9802s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9803 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9804{
florianfb596602014-12-06 16:34:48 +00009805 if (! s390_host_has_dfp) {
9806 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009807 } else {
florianfb596602014-12-06 16:34:48 +00009808 if (! s390_host_has_fpext) {
9809 emulation_failure(EmFail_S390X_fpext);
9810 } else {
9811 IRTemp op2 = newTemp(Ity_I32);
florian5f034622013-01-13 02:29:05 +00009812
florianfb596602014-12-06 16:34:48 +00009813 assign(op2, get_gpr_w1(r2));
9814 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9815 }
florian5f034622013-01-13 02:29:05 +00009816 }
9817 return "cxftr";
9818}
9819
9820static const HChar *
floriana887acd2013-02-08 23:32:54 +00009821s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9822 UChar r1, UChar r2)
9823{
florianfb596602014-12-06 16:34:48 +00009824 if (! s390_host_has_dfp) {
9825 emulation_failure(EmFail_S390X_DFP_insn);
9826 } else {
9827 IRTemp op2 = newTemp(Ity_I64);
floriana887acd2013-02-08 23:32:54 +00009828
florianfb596602014-12-06 16:34:48 +00009829 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9830 emulation_warning(EmWarn_S390X_fpext_rounding);
9831 m3 = S390_DFP_ROUND_PER_FPC_0;
9832 }
9833
9834 assign(op2, get_gpr_dw0(r2));
9835 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9836 mkexpr(op2)));
floriana887acd2013-02-08 23:32:54 +00009837 }
floriana887acd2013-02-08 23:32:54 +00009838 return (m3 == 0) ? "cdgtr" : "cdgtra";
9839}
9840
9841static const HChar *
9842s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9843 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9844{
florianfb596602014-12-06 16:34:48 +00009845 if (! s390_host_has_dfp) {
9846 emulation_failure(EmFail_S390X_DFP_insn);
9847 } else {
9848 IRTemp op2 = newTemp(Ity_I64);
floriana887acd2013-02-08 23:32:54 +00009849
florianfb596602014-12-06 16:34:48 +00009850 /* No emulation warning here about an non-zero m3 on hosts without
9851 floating point extension facility. No rounding is performed */
floriana887acd2013-02-08 23:32:54 +00009852
florianfb596602014-12-06 16:34:48 +00009853 assign(op2, get_gpr_dw0(r2));
9854 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9855 }
floriana887acd2013-02-08 23:32:54 +00009856 return "cxgtr";
9857}
9858
9859static const HChar *
florian5f034622013-01-13 02:29:05 +00009860s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9861 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9862{
florianfb596602014-12-06 16:34:48 +00009863 if (! s390_host_has_dfp) {
9864 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009865 } else {
florianfb596602014-12-06 16:34:48 +00009866 if (! s390_host_has_fpext) {
9867 emulation_failure(EmFail_S390X_fpext);
9868 } else {
9869 IRTemp op2 = newTemp(Ity_I32);
florian5f034622013-01-13 02:29:05 +00009870
florianfb596602014-12-06 16:34:48 +00009871 assign(op2, get_gpr_w1(r2));
9872 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9873 }
florian5f034622013-01-13 02:29:05 +00009874 }
9875 return "cdlftr";
9876}
9877
9878static const HChar *
9879s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9880 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9881{
florianfb596602014-12-06 16:34:48 +00009882 if (! s390_host_has_dfp) {
9883 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009884 } else {
florianfb596602014-12-06 16:34:48 +00009885 if (! s390_host_has_fpext) {
9886 emulation_failure(EmFail_S390X_fpext);
9887 } else {
9888 IRTemp op2 = newTemp(Ity_I32);
florian5f034622013-01-13 02:29:05 +00009889
florianfb596602014-12-06 16:34:48 +00009890 assign(op2, get_gpr_w1(r2));
9891 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9892 }
florian5f034622013-01-13 02:29:05 +00009893 }
9894 return "cxlftr";
9895}
9896
9897static const HChar *
9898s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9899 UChar r1, UChar r2)
9900{
florianfb596602014-12-06 16:34:48 +00009901 if (! s390_host_has_dfp) {
9902 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009903 } else {
florianfb596602014-12-06 16:34:48 +00009904 if (! s390_host_has_fpext) {
9905 emulation_failure(EmFail_S390X_fpext);
9906 } else {
9907 IRTemp op2 = newTemp(Ity_I64);
florian5f034622013-01-13 02:29:05 +00009908
florianfb596602014-12-06 16:34:48 +00009909 assign(op2, get_gpr_dw0(r2));
9910 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9911 mkexpr(encode_dfp_rounding_mode(m3)),
9912 mkexpr(op2)));
9913 }
florian5f034622013-01-13 02:29:05 +00009914 }
9915 return "cdlgtr";
9916}
9917
9918static const HChar *
9919s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9920 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9921{
florianfb596602014-12-06 16:34:48 +00009922 if (! s390_host_has_dfp) {
9923 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009924 } else {
florianfb596602014-12-06 16:34:48 +00009925 if (! s390_host_has_fpext) {
9926 emulation_failure(EmFail_S390X_fpext);
9927 } else {
9928 IRTemp op2 = newTemp(Ity_I64);
florian5f034622013-01-13 02:29:05 +00009929
florianfb596602014-12-06 16:34:48 +00009930 assign(op2, get_gpr_dw0(r2));
9931 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9932 }
florian5f034622013-01-13 02:29:05 +00009933 }
9934 return "cxlgtr";
9935}
9936
9937static const HChar *
9938s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9939 UChar r1, UChar r2)
9940{
florianfb596602014-12-06 16:34:48 +00009941 if (! s390_host_has_dfp) {
9942 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009943 } else {
florianfb596602014-12-06 16:34:48 +00009944 if (! s390_host_has_fpext) {
9945 emulation_failure(EmFail_S390X_fpext);
9946 } else {
9947 IRTemp op = newTemp(Ity_D64);
9948 IRTemp result = newTemp(Ity_I32);
9949 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
florian5f034622013-01-13 02:29:05 +00009950
florianfb596602014-12-06 16:34:48 +00009951 assign(op, get_dpr_dw0(r2));
9952 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9953 mkexpr(op)));
9954 put_gpr_w1(r1, mkexpr(result));
9955 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9956 }
florian5f034622013-01-13 02:29:05 +00009957 }
9958 return "cfdtr";
9959}
9960
9961static const HChar *
9962s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9963 UChar r1, UChar r2)
9964{
florianfb596602014-12-06 16:34:48 +00009965 if (! s390_host_has_dfp) {
9966 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009967 } else {
florianfb596602014-12-06 16:34:48 +00009968 if (! s390_host_has_fpext) {
9969 emulation_failure(EmFail_S390X_fpext);
9970 } else {
9971 IRTemp op = newTemp(Ity_D128);
9972 IRTemp result = newTemp(Ity_I32);
9973 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
florian5f034622013-01-13 02:29:05 +00009974
florianfb596602014-12-06 16:34:48 +00009975 assign(op, get_dpr_pair(r2));
9976 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9977 mkexpr(op)));
9978 put_gpr_w1(r1, mkexpr(result));
9979 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op,
9980 rounding_mode);
9981 }
florian5f034622013-01-13 02:29:05 +00009982 }
9983 return "cfxtr";
9984}
9985
9986static const HChar *
floriana887acd2013-02-08 23:32:54 +00009987s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9988 UChar r1, UChar r2)
9989{
florianfb596602014-12-06 16:34:48 +00009990 if (! s390_host_has_dfp) {
9991 emulation_failure(EmFail_S390X_DFP_insn);
9992 } else {
9993 IRTemp op = newTemp(Ity_D64);
9994 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
floriana887acd2013-02-08 23:32:54 +00009995
florianfb596602014-12-06 16:34:48 +00009996 /* If fpext is not installed and m3 is in 1:7,
9997 rounding mode performed is unpredictable */
9998 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9999 emulation_warning(EmWarn_S390X_fpext_rounding);
10000 m3 = S390_DFP_ROUND_PER_FPC_0;
10001 }
floriana887acd2013-02-08 23:32:54 +000010002
florianfb596602014-12-06 16:34:48 +000010003 assign(op, get_dpr_dw0(r2));
10004 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
10005 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
floriana887acd2013-02-08 23:32:54 +000010006 }
floriana887acd2013-02-08 23:32:54 +000010007 return "cgdtr";
10008}
10009
10010static const HChar *
10011s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
10012 UChar r1, UChar r2)
10013{
florianfb596602014-12-06 16:34:48 +000010014 if (! s390_host_has_dfp) {
10015 emulation_failure(EmFail_S390X_DFP_insn);
10016 } else {
10017 IRTemp op = newTemp(Ity_D128);
10018 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
floriana887acd2013-02-08 23:32:54 +000010019
florianfb596602014-12-06 16:34:48 +000010020 /* If fpext is not installed and m3 is in 1:7,
10021 rounding mode performed is unpredictable */
10022 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10023 emulation_warning(EmWarn_S390X_fpext_rounding);
10024 m3 = S390_DFP_ROUND_PER_FPC_0;
10025 }
10026 assign(op, get_dpr_pair(r2));
10027 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
10028 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
floriana887acd2013-02-08 23:32:54 +000010029 }
floriana887acd2013-02-08 23:32:54 +000010030 return "cgxtr";
10031}
10032
10033static const HChar *
florian20c6bca2012-12-26 17:47:19 +000010034s390_irgen_CEDTR(UChar r1, UChar r2)
10035{
florianfb596602014-12-06 16:34:48 +000010036 if (! s390_host_has_dfp) {
10037 emulation_failure(EmFail_S390X_DFP_insn);
10038 } else {
10039 IRTemp op1 = newTemp(Ity_D64);
10040 IRTemp op2 = newTemp(Ity_D64);
10041 IRTemp cc_vex = newTemp(Ity_I32);
10042 IRTemp cc_s390 = newTemp(Ity_I32);
florian20c6bca2012-12-26 17:47:19 +000010043
florianfb596602014-12-06 16:34:48 +000010044 assign(op1, get_dpr_dw0(r1));
10045 assign(op2, get_dpr_dw0(r2));
10046 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
florian20c6bca2012-12-26 17:47:19 +000010047
florianfb596602014-12-06 16:34:48 +000010048 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
10049 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10050 }
florian20c6bca2012-12-26 17:47:19 +000010051 return "cedtr";
10052}
10053
10054static const HChar *
10055s390_irgen_CEXTR(UChar r1, UChar r2)
10056{
florianfb596602014-12-06 16:34:48 +000010057 if (! s390_host_has_dfp) {
10058 emulation_failure(EmFail_S390X_DFP_insn);
10059 } else {
10060 IRTemp op1 = newTemp(Ity_D128);
10061 IRTemp op2 = newTemp(Ity_D128);
10062 IRTemp cc_vex = newTemp(Ity_I32);
10063 IRTemp cc_s390 = newTemp(Ity_I32);
florian20c6bca2012-12-26 17:47:19 +000010064
florianfb596602014-12-06 16:34:48 +000010065 assign(op1, get_dpr_pair(r1));
10066 assign(op2, get_dpr_pair(r2));
10067 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
florian20c6bca2012-12-26 17:47:19 +000010068
florianfb596602014-12-06 16:34:48 +000010069 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
10070 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10071 }
florian20c6bca2012-12-26 17:47:19 +000010072 return "cextr";
10073}
10074
10075static const HChar *
florian5f034622013-01-13 02:29:05 +000010076s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
10077 UChar r1, UChar r2)
10078{
florianfb596602014-12-06 16:34:48 +000010079 if (! s390_host_has_dfp) {
10080 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +000010081 } else {
florianfb596602014-12-06 16:34:48 +000010082 if (! s390_host_has_fpext) {
10083 emulation_failure(EmFail_S390X_fpext);
10084 } else {
10085 IRTemp op = newTemp(Ity_D64);
10086 IRTemp result = newTemp(Ity_I32);
10087 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
florian5f034622013-01-13 02:29:05 +000010088
florianfb596602014-12-06 16:34:48 +000010089 assign(op, get_dpr_dw0(r2));
10090 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
10091 mkexpr(op)));
10092 put_gpr_w1(r1, mkexpr(result));
10093 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
10094 }
florian5f034622013-01-13 02:29:05 +000010095 }
10096 return "clfdtr";
10097}
10098
10099static const HChar *
10100s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
10101 UChar r1, UChar r2)
10102{
florianfb596602014-12-06 16:34:48 +000010103 if (! s390_host_has_dfp) {
10104 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +000010105 } else {
florianfb596602014-12-06 16:34:48 +000010106 if (! s390_host_has_fpext) {
10107 emulation_failure(EmFail_S390X_fpext);
10108 } else {
10109 IRTemp op = newTemp(Ity_D128);
10110 IRTemp result = newTemp(Ity_I32);
10111 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
florian5f034622013-01-13 02:29:05 +000010112
florianfb596602014-12-06 16:34:48 +000010113 assign(op, get_dpr_pair(r2));
10114 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
10115 mkexpr(op)));
10116 put_gpr_w1(r1, mkexpr(result));
10117 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op,
10118 rounding_mode);
10119 }
florian5f034622013-01-13 02:29:05 +000010120 }
10121 return "clfxtr";
10122}
10123
10124static const HChar *
10125s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
10126 UChar r1, UChar r2)
10127{
florianfb596602014-12-06 16:34:48 +000010128 if (! s390_host_has_dfp) {
10129 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +000010130 } else {
florianfb596602014-12-06 16:34:48 +000010131 if (! s390_host_has_fpext) {
10132 emulation_failure(EmFail_S390X_fpext);
10133 } else {
10134 IRTemp op = newTemp(Ity_D64);
10135 IRTemp result = newTemp(Ity_I64);
10136 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
florian5f034622013-01-13 02:29:05 +000010137
florianfb596602014-12-06 16:34:48 +000010138 assign(op, get_dpr_dw0(r2));
10139 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
10140 mkexpr(op)));
10141 put_gpr_dw0(r1, mkexpr(result));
10142 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
10143 }
florian5f034622013-01-13 02:29:05 +000010144 }
10145 return "clgdtr";
10146}
10147
10148static const HChar *
10149s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
10150 UChar r1, UChar r2)
10151{
florianfb596602014-12-06 16:34:48 +000010152 if (! s390_host_has_dfp) {
10153 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +000010154 } else {
florianfb596602014-12-06 16:34:48 +000010155 if (! s390_host_has_fpext) {
10156 emulation_failure(EmFail_S390X_fpext);
10157 } else {
10158 IRTemp op = newTemp(Ity_D128);
10159 IRTemp result = newTemp(Ity_I64);
10160 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
florian5f034622013-01-13 02:29:05 +000010161
florianfb596602014-12-06 16:34:48 +000010162 assign(op, get_dpr_pair(r2));
10163 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
10164 mkexpr(op)));
10165 put_gpr_dw0(r1, mkexpr(result));
10166 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
10167 rounding_mode);
10168 }
florian5f034622013-01-13 02:29:05 +000010169 }
10170 return "clgxtr";
10171}
10172
10173static const HChar *
florian12390202012-11-10 22:34:14 +000010174s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10175{
florianfb596602014-12-06 16:34:48 +000010176 if (! s390_host_has_dfp) {
10177 emulation_failure(EmFail_S390X_DFP_insn);
10178 } else {
10179 IRTemp op1 = newTemp(Ity_D64);
10180 IRTemp op2 = newTemp(Ity_D64);
10181 IRTemp result = newTemp(Ity_D64);
10182 IRTemp rounding_mode;
florian12390202012-11-10 22:34:14 +000010183
florianfb596602014-12-06 16:34:48 +000010184 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10185 emulation_warning(EmWarn_S390X_fpext_rounding);
10186 m4 = S390_DFP_ROUND_PER_FPC_0;
10187 }
florian1bb7f6f2013-02-11 00:03:27 +000010188
florianfb596602014-12-06 16:34:48 +000010189 rounding_mode = encode_dfp_rounding_mode(m4);
10190 assign(op1, get_dpr_dw0(r2));
10191 assign(op2, get_dpr_dw0(r3));
10192 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
10193 mkexpr(op2)));
10194 put_dpr_dw0(r1, mkexpr(result));
florian1bb7f6f2013-02-11 00:03:27 +000010195 }
florian12390202012-11-10 22:34:14 +000010196 return (m4 == 0) ? "ddtr" : "ddtra";
10197}
10198
florian55085f82012-11-21 00:36:55 +000010199static const HChar *
floriane38f6412012-12-21 17:32:12 +000010200s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10201{
florianfb596602014-12-06 16:34:48 +000010202 if (! s390_host_has_dfp) {
10203 emulation_failure(EmFail_S390X_DFP_insn);
10204 } else {
10205 IRTemp op1 = newTemp(Ity_D128);
10206 IRTemp op2 = newTemp(Ity_D128);
10207 IRTemp result = newTemp(Ity_D128);
10208 IRTemp rounding_mode;
floriane38f6412012-12-21 17:32:12 +000010209
florianfb596602014-12-06 16:34:48 +000010210 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10211 emulation_warning(EmWarn_S390X_fpext_rounding);
10212 m4 = S390_DFP_ROUND_PER_FPC_0;
10213 }
florian1bb7f6f2013-02-11 00:03:27 +000010214
florianfb596602014-12-06 16:34:48 +000010215 rounding_mode = encode_dfp_rounding_mode(m4);
10216 assign(op1, get_dpr_pair(r2));
10217 assign(op2, get_dpr_pair(r3));
10218 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
10219 mkexpr(op2)));
10220 put_dpr_pair(r1, mkexpr(result));
florian1bb7f6f2013-02-11 00:03:27 +000010221 }
floriane38f6412012-12-21 17:32:12 +000010222 return (m4 == 0) ? "dxtr" : "dxtra";
10223}
10224
10225static const HChar *
florian5c539732013-02-14 14:27:12 +000010226s390_irgen_EEDTR(UChar r1, UChar r2)
10227{
florianfb596602014-12-06 16:34:48 +000010228 if (! s390_host_has_dfp) {
10229 emulation_failure(EmFail_S390X_DFP_insn);
10230 } else {
10231 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
10232 }
florian5c539732013-02-14 14:27:12 +000010233 return "eedtr";
10234}
10235
10236static const HChar *
10237s390_irgen_EEXTR(UChar r1, UChar r2)
10238{
florianfb596602014-12-06 16:34:48 +000010239 if (! s390_host_has_dfp) {
10240 emulation_failure(EmFail_S390X_DFP_insn);
10241 } else {
10242 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
10243 }
florian5c539732013-02-14 14:27:12 +000010244 return "eextr";
10245}
10246
10247static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010248s390_irgen_ESDTR(UChar r1, UChar r2)
10249{
florianfb596602014-12-06 16:34:48 +000010250 if (! s390_host_has_dfp) {
10251 emulation_failure(EmFail_S390X_DFP_insn);
10252 } else {
10253 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
10254 }
floriance9e3db2012-12-27 20:14:03 +000010255 return "esdtr";
10256}
10257
10258static const HChar *
10259s390_irgen_ESXTR(UChar r1, UChar r2)
10260{
florianfb596602014-12-06 16:34:48 +000010261 if (! s390_host_has_dfp) {
10262 emulation_failure(EmFail_S390X_DFP_insn);
10263 } else {
10264 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
10265 }
floriance9e3db2012-12-27 20:14:03 +000010266 return "esxtr";
10267}
10268
10269static const HChar *
florian5c539732013-02-14 14:27:12 +000010270s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
10271{
florianfb596602014-12-06 16:34:48 +000010272 if (! s390_host_has_dfp) {
10273 emulation_failure(EmFail_S390X_DFP_insn);
10274 } else {
10275 IRTemp op1 = newTemp(Ity_I64);
10276 IRTemp op2 = newTemp(Ity_D64);
10277 IRTemp result = newTemp(Ity_D64);
florian5c539732013-02-14 14:27:12 +000010278
florianfb596602014-12-06 16:34:48 +000010279 assign(op1, get_gpr_dw0(r2));
10280 assign(op2, get_dpr_dw0(r3));
10281 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
10282 put_dpr_dw0(r1, mkexpr(result));
10283 }
florian5c539732013-02-14 14:27:12 +000010284 return "iedtr";
10285}
10286
10287static const HChar *
10288s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
10289{
florianfb596602014-12-06 16:34:48 +000010290 if (! s390_host_has_dfp) {
10291 emulation_failure(EmFail_S390X_DFP_insn);
10292 } else {
10293 IRTemp op1 = newTemp(Ity_I64);
10294 IRTemp op2 = newTemp(Ity_D128);
10295 IRTemp result = newTemp(Ity_D128);
florian5c539732013-02-14 14:27:12 +000010296
florianfb596602014-12-06 16:34:48 +000010297 assign(op1, get_gpr_dw0(r2));
10298 assign(op2, get_dpr_pair(r3));
10299 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10300 put_dpr_pair(r1, mkexpr(result));
10301 }
florian5c539732013-02-14 14:27:12 +000010302 return "iextr";
10303}
10304
10305static const HChar *
floriane38f6412012-12-21 17:32:12 +000010306s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10307{
florianfb596602014-12-06 16:34:48 +000010308 if (! s390_host_has_dfp) {
10309 emulation_failure(EmFail_S390X_DFP_insn);
10310 } else {
10311 IRTemp op = newTemp(Ity_D32);
floriane38f6412012-12-21 17:32:12 +000010312
florianfb596602014-12-06 16:34:48 +000010313 assign(op, get_dpr_w0(r2));
10314 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10315 }
floriane38f6412012-12-21 17:32:12 +000010316 return "ldetr";
10317}
10318
10319static const HChar *
10320s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10321{
10322 IRTemp op = newTemp(Ity_D64);
10323
10324 assign(op, get_dpr_dw0(r2));
10325 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10326
10327 return "lxdtr";
10328}
10329
10330static const HChar *
10331s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10332 UChar r1, UChar r2)
10333{
florianfb596602014-12-06 16:34:48 +000010334 if (! s390_host_has_dfp) {
10335 emulation_failure(EmFail_S390X_DFP_insn);
10336 } else {
10337 /* If fpext is not installed and m3 is in 1:7,
10338 rounding mode performed is unpredictable */
10339 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10340 emulation_warning(EmWarn_S390X_fpext_rounding);
10341 m3 = S390_DFP_ROUND_PER_FPC_0;
10342 }
10343 IRTemp result = newTemp(Ity_D64);
florian1bb7f6f2013-02-11 00:03:27 +000010344
florianfb596602014-12-06 16:34:48 +000010345 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10346 get_dpr_pair(r2)));
10347 put_dpr_dw0(r1, mkexpr(result));
floriane38f6412012-12-21 17:32:12 +000010348 }
floriane38f6412012-12-21 17:32:12 +000010349 return "ldxtr";
10350}
10351
10352static const HChar *
10353s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10354 UChar r1, UChar r2)
10355{
florianfb596602014-12-06 16:34:48 +000010356 if (! s390_host_has_dfp) {
10357 emulation_failure(EmFail_S390X_DFP_insn);
10358 } else {
10359 /* If fpext is not installed and m3 is in 1:7,
10360 rounding mode performed is unpredictable */
10361 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10362 emulation_warning(EmWarn_S390X_fpext_rounding);
10363 m3 = S390_DFP_ROUND_PER_FPC_0;
10364 }
10365 IRTemp op = newTemp(Ity_D64);
florian1bb7f6f2013-02-11 00:03:27 +000010366
florianfb596602014-12-06 16:34:48 +000010367 assign(op, get_dpr_dw0(r2));
10368 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10369 mkexpr(op)));
floriane38f6412012-12-21 17:32:12 +000010370 }
floriane38f6412012-12-21 17:32:12 +000010371 return "ledtr";
10372}
10373
10374static const HChar *
10375s390_irgen_LTDTR(UChar r1, UChar r2)
10376{
10377 IRTemp result = newTemp(Ity_D64);
10378
10379 assign(result, get_dpr_dw0(r2));
10380 put_dpr_dw0(r1, mkexpr(result));
10381 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10382
10383 return "ltdtr";
10384}
10385
10386static const HChar *
10387s390_irgen_LTXTR(UChar r1, UChar r2)
10388{
10389 IRTemp result = newTemp(Ity_D128);
10390
10391 assign(result, get_dpr_pair(r2));
10392 put_dpr_pair(r1, mkexpr(result));
10393 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10394
10395 return "ltxtr";
10396}
10397
10398static const HChar *
florian12390202012-11-10 22:34:14 +000010399s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10400{
florianfb596602014-12-06 16:34:48 +000010401 if (! s390_host_has_dfp) {
10402 emulation_failure(EmFail_S390X_DFP_insn);
10403 } else {
10404 IRTemp op1 = newTemp(Ity_D64);
10405 IRTemp op2 = newTemp(Ity_D64);
10406 IRTemp result = newTemp(Ity_D64);
10407 IRTemp rounding_mode;
florian12390202012-11-10 22:34:14 +000010408
florianfb596602014-12-06 16:34:48 +000010409 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10410 emulation_warning(EmWarn_S390X_fpext_rounding);
10411 m4 = S390_DFP_ROUND_PER_FPC_0;
10412 }
florian1bb7f6f2013-02-11 00:03:27 +000010413
florianfb596602014-12-06 16:34:48 +000010414 rounding_mode = encode_dfp_rounding_mode(m4);
10415 assign(op1, get_dpr_dw0(r2));
10416 assign(op2, get_dpr_dw0(r3));
10417 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10418 mkexpr(op2)));
10419 put_dpr_dw0(r1, mkexpr(result));
florian1bb7f6f2013-02-11 00:03:27 +000010420 }
florian12390202012-11-10 22:34:14 +000010421 return (m4 == 0) ? "mdtr" : "mdtra";
10422}
10423
florian55085f82012-11-21 00:36:55 +000010424static const HChar *
floriane38f6412012-12-21 17:32:12 +000010425s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10426{
florianfb596602014-12-06 16:34:48 +000010427 if (! s390_host_has_dfp) {
10428 emulation_failure(EmFail_S390X_DFP_insn);
10429 } else {
10430 IRTemp op1 = newTemp(Ity_D128);
10431 IRTemp op2 = newTemp(Ity_D128);
10432 IRTemp result = newTemp(Ity_D128);
10433 IRTemp rounding_mode;
floriane38f6412012-12-21 17:32:12 +000010434
florianfb596602014-12-06 16:34:48 +000010435 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10436 emulation_warning(EmWarn_S390X_fpext_rounding);
10437 m4 = S390_DFP_ROUND_PER_FPC_0;
10438 }
florian1bb7f6f2013-02-11 00:03:27 +000010439
florianfb596602014-12-06 16:34:48 +000010440 rounding_mode = encode_dfp_rounding_mode(m4);
10441 assign(op1, get_dpr_pair(r2));
10442 assign(op2, get_dpr_pair(r3));
10443 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10444 mkexpr(op2)));
10445 put_dpr_pair(r1, mkexpr(result));
florian1bb7f6f2013-02-11 00:03:27 +000010446 }
floriane38f6412012-12-21 17:32:12 +000010447 return (m4 == 0) ? "mxtr" : "mxtra";
10448}
10449
10450static const HChar *
florian5c539732013-02-14 14:27:12 +000010451s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10452{
florianfb596602014-12-06 16:34:48 +000010453 if (! s390_host_has_dfp) {
10454 emulation_failure(EmFail_S390X_DFP_insn);
10455 } else {
10456 IRTemp op1 = newTemp(Ity_D64);
10457 IRTemp op2 = newTemp(Ity_D64);
10458 IRTemp result = newTemp(Ity_D64);
10459 IRTemp rounding_mode;
florian5c539732013-02-14 14:27:12 +000010460
florianfb596602014-12-06 16:34:48 +000010461 /* If fpext is not installed and m4 is in 1:7,
10462 rounding mode performed is unpredictable */
10463 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10464 emulation_warning(EmWarn_S390X_fpext_rounding);
10465 m4 = S390_DFP_ROUND_PER_FPC_0;
10466 }
10467
10468 rounding_mode = encode_dfp_rounding_mode(m4);
10469 assign(op1, get_dpr_dw0(r2));
10470 assign(op2, get_dpr_dw0(r3));
10471 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10472 mkexpr(op2)));
10473 put_dpr_dw0(r1, mkexpr(result));
florian5c539732013-02-14 14:27:12 +000010474 }
florian5c539732013-02-14 14:27:12 +000010475 return "qadtr";
10476}
10477
10478static const HChar *
10479s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10480{
florianfb596602014-12-06 16:34:48 +000010481 if (! s390_host_has_dfp) {
10482 emulation_failure(EmFail_S390X_DFP_insn);
10483 } else {
10484 IRTemp op1 = newTemp(Ity_D128);
10485 IRTemp op2 = newTemp(Ity_D128);
10486 IRTemp result = newTemp(Ity_D128);
10487 IRTemp rounding_mode;
florian5c539732013-02-14 14:27:12 +000010488
florianfb596602014-12-06 16:34:48 +000010489 /* If fpext is not installed and m4 is in 1:7,
10490 rounding mode performed is unpredictable */
10491 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10492 emulation_warning(EmWarn_S390X_fpext_rounding);
10493 m4 = S390_DFP_ROUND_PER_FPC_0;
10494 }
10495
10496 rounding_mode = encode_dfp_rounding_mode(m4);
10497 assign(op1, get_dpr_pair(r2));
10498 assign(op2, get_dpr_pair(r3));
10499 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10500 mkexpr(op2)));
10501 put_dpr_pair(r1, mkexpr(result));
florian5c539732013-02-14 14:27:12 +000010502 }
florian5c539732013-02-14 14:27:12 +000010503 return "qaxtr";
10504}
10505
10506static const HChar *
10507s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10508{
florianfb596602014-12-06 16:34:48 +000010509 if (! s390_host_has_dfp) {
10510 emulation_failure(EmFail_S390X_DFP_insn);
10511 } else {
10512 IRTemp op1 = newTemp(Ity_I8);
10513 IRTemp op2 = newTemp(Ity_D64);
10514 IRTemp result = newTemp(Ity_D64);
10515 IRTemp rounding_mode;
florian5c539732013-02-14 14:27:12 +000010516
florianfb596602014-12-06 16:34:48 +000010517 /* If fpext is not installed and m4 is in 1:7,
10518 rounding mode performed is unpredictable */
10519 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10520 emulation_warning(EmWarn_S390X_fpext_rounding);
10521 m4 = S390_DFP_ROUND_PER_FPC_0;
10522 }
10523
10524 rounding_mode = encode_dfp_rounding_mode(m4);
10525 assign(op1, get_gpr_b7(r2));
10526 assign(op2, get_dpr_dw0(r3));
10527 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10528 mkexpr(op1), mkexpr(op2)));
10529 put_dpr_dw0(r1, mkexpr(result));
florian5c539732013-02-14 14:27:12 +000010530 }
florian5c539732013-02-14 14:27:12 +000010531 return "rrdtr";
10532}
10533
10534static const HChar *
10535s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10536{
florianfb596602014-12-06 16:34:48 +000010537 if (! s390_host_has_dfp) {
10538 emulation_failure(EmFail_S390X_DFP_insn);
10539 } else {
10540 IRTemp op1 = newTemp(Ity_I8);
10541 IRTemp op2 = newTemp(Ity_D128);
10542 IRTemp result = newTemp(Ity_D128);
10543 IRTemp rounding_mode;
florian5c539732013-02-14 14:27:12 +000010544
florianfb596602014-12-06 16:34:48 +000010545 /* If fpext is not installed and m4 is in 1:7,
10546 rounding mode performed is unpredictable */
10547 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10548 emulation_warning(EmWarn_S390X_fpext_rounding);
10549 m4 = S390_DFP_ROUND_PER_FPC_0;
10550 }
10551
10552 rounding_mode = encode_dfp_rounding_mode(m4);
10553 assign(op1, get_gpr_b7(r2));
10554 assign(op2, get_dpr_pair(r3));
10555 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10556 mkexpr(op1), mkexpr(op2)));
10557 put_dpr_pair(r1, mkexpr(result));
florian5c539732013-02-14 14:27:12 +000010558 }
florian5c539732013-02-14 14:27:12 +000010559 return "rrxtr";
10560}
10561
10562static const HChar *
florian12390202012-11-10 22:34:14 +000010563s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10564{
florianfb596602014-12-06 16:34:48 +000010565 if (! s390_host_has_dfp) {
10566 emulation_failure(EmFail_S390X_DFP_insn);
10567 } else {
10568 IRTemp op1 = newTemp(Ity_D64);
10569 IRTemp op2 = newTemp(Ity_D64);
10570 IRTemp result = newTemp(Ity_D64);
10571 IRTemp rounding_mode;
florian12390202012-11-10 22:34:14 +000010572
florianfb596602014-12-06 16:34:48 +000010573 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10574 emulation_warning(EmWarn_S390X_fpext_rounding);
10575 m4 = S390_DFP_ROUND_PER_FPC_0;
10576 }
florian1bb7f6f2013-02-11 00:03:27 +000010577
florianfb596602014-12-06 16:34:48 +000010578 rounding_mode = encode_dfp_rounding_mode(m4);
10579 assign(op1, get_dpr_dw0(r2));
10580 assign(op2, get_dpr_dw0(r3));
10581 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10582 mkexpr(op2)));
10583 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10584 put_dpr_dw0(r1, mkexpr(result));
florian1bb7f6f2013-02-11 00:03:27 +000010585 }
florian12390202012-11-10 22:34:14 +000010586 return (m4 == 0) ? "sdtr" : "sdtra";
10587}
10588
floriane38f6412012-12-21 17:32:12 +000010589static const HChar *
10590s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10591{
florianfb596602014-12-06 16:34:48 +000010592 if (! s390_host_has_dfp) {
10593 emulation_failure(EmFail_S390X_DFP_insn);
10594 } else {
10595 IRTemp op1 = newTemp(Ity_D128);
10596 IRTemp op2 = newTemp(Ity_D128);
10597 IRTemp result = newTemp(Ity_D128);
10598 IRTemp rounding_mode;
floriane38f6412012-12-21 17:32:12 +000010599
florianfb596602014-12-06 16:34:48 +000010600 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10601 emulation_warning(EmWarn_S390X_fpext_rounding);
10602 m4 = S390_DFP_ROUND_PER_FPC_0;
10603 }
florian1bb7f6f2013-02-11 00:03:27 +000010604
florianfb596602014-12-06 16:34:48 +000010605 rounding_mode = encode_dfp_rounding_mode(m4);
10606 assign(op1, get_dpr_pair(r2));
10607 assign(op2, get_dpr_pair(r3));
10608 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10609 mkexpr(op2)));
10610 put_dpr_pair(r1, mkexpr(result));
10611
10612 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
florian1bb7f6f2013-02-11 00:03:27 +000010613 }
floriane38f6412012-12-21 17:32:12 +000010614 return (m4 == 0) ? "sxtr" : "sxtra";
10615}
sewardj2019a972011-03-07 16:04:07 +000010616
florian55085f82012-11-21 00:36:55 +000010617static const HChar *
florian1b901d42013-01-01 22:19:24 +000010618s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10619{
florianfb596602014-12-06 16:34:48 +000010620 if (! s390_host_has_dfp) {
10621 emulation_failure(EmFail_S390X_DFP_insn);
10622 } else {
10623 IRTemp op = newTemp(Ity_D64);
florian1b901d42013-01-01 22:19:24 +000010624
florianfb596602014-12-06 16:34:48 +000010625 assign(op, get_dpr_dw0(r3));
10626 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op),
10627 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10628 mkU64(63)))));
10629 }
florian1b901d42013-01-01 22:19:24 +000010630 return "sldt";
10631}
10632
10633static const HChar *
10634s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10635{
florianfb596602014-12-06 16:34:48 +000010636 if (! s390_host_has_dfp) {
10637 emulation_failure(EmFail_S390X_DFP_insn);
10638 } else {
10639 IRTemp op = newTemp(Ity_D128);
florian1b901d42013-01-01 22:19:24 +000010640
florianfb596602014-12-06 16:34:48 +000010641 assign(op, get_dpr_pair(r3));
10642 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op),
10643 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10644 mkU64(63)))));
10645 }
florian1b901d42013-01-01 22:19:24 +000010646 return "slxt";
10647}
10648
10649static const HChar *
10650s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10651{
florianfb596602014-12-06 16:34:48 +000010652 if (! s390_host_has_dfp) {
10653 emulation_failure(EmFail_S390X_DFP_insn);
10654 } else {
10655 IRTemp op = newTemp(Ity_D64);
florian1b901d42013-01-01 22:19:24 +000010656
florianfb596602014-12-06 16:34:48 +000010657 assign(op, get_dpr_dw0(r3));
10658 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op),
10659 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10660 mkU64(63)))));
10661 }
florian1b901d42013-01-01 22:19:24 +000010662 return "srdt";
10663}
10664
10665static const HChar *
10666s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10667{
florianfb596602014-12-06 16:34:48 +000010668 if (! s390_host_has_dfp) {
10669 emulation_failure(EmFail_S390X_DFP_insn);
10670 } else {
10671 IRTemp op = newTemp(Ity_D128);
florian1b901d42013-01-01 22:19:24 +000010672
florianfb596602014-12-06 16:34:48 +000010673 assign(op, get_dpr_pair(r3));
10674 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op),
10675 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10676 mkU64(63)))));
10677 }
florian1b901d42013-01-01 22:19:24 +000010678 return "srxt";
10679}
10680
10681static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010682s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10683{
florianfb596602014-12-06 16:34:48 +000010684 if (! s390_host_has_dfp) {
10685 emulation_failure(EmFail_S390X_DFP_insn);
10686 } else {
10687 IRTemp value = newTemp(Ity_D32);
floriance9e3db2012-12-27 20:14:03 +000010688
florianfb596602014-12-06 16:34:48 +000010689 assign(value, get_dpr_w0(r1));
floriance9e3db2012-12-27 20:14:03 +000010690
florianfb596602014-12-06 16:34:48 +000010691 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10692 }
floriance9e3db2012-12-27 20:14:03 +000010693 return "tdcet";
10694}
10695
10696static const HChar *
10697s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10698{
florianfb596602014-12-06 16:34:48 +000010699 if (! s390_host_has_dfp) {
10700 emulation_failure(EmFail_S390X_DFP_insn);
10701 } else {
10702 IRTemp value = newTemp(Ity_D64);
floriance9e3db2012-12-27 20:14:03 +000010703
florianfb596602014-12-06 16:34:48 +000010704 assign(value, get_dpr_dw0(r1));
floriance9e3db2012-12-27 20:14:03 +000010705
florianfb596602014-12-06 16:34:48 +000010706 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10707 }
floriance9e3db2012-12-27 20:14:03 +000010708 return "tdcdt";
10709}
10710
10711static const HChar *
10712s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10713{
florianfb596602014-12-06 16:34:48 +000010714 if (! s390_host_has_dfp) {
10715 emulation_failure(EmFail_S390X_DFP_insn);
10716 } else {
10717 IRTemp value = newTemp(Ity_D128);
floriance9e3db2012-12-27 20:14:03 +000010718
florianfb596602014-12-06 16:34:48 +000010719 assign(value, get_dpr_pair(r1));
floriance9e3db2012-12-27 20:14:03 +000010720
florianfb596602014-12-06 16:34:48 +000010721 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10722 }
floriance9e3db2012-12-27 20:14:03 +000010723 return "tdcxt";
10724}
10725
10726static const HChar *
10727s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10728{
florianfb596602014-12-06 16:34:48 +000010729 if (! s390_host_has_dfp) {
10730 emulation_failure(EmFail_S390X_DFP_insn);
10731 } else {
10732 IRTemp value = newTemp(Ity_D32);
floriance9e3db2012-12-27 20:14:03 +000010733
florianfb596602014-12-06 16:34:48 +000010734 assign(value, get_dpr_w0(r1));
floriance9e3db2012-12-27 20:14:03 +000010735
florianfb596602014-12-06 16:34:48 +000010736 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10737 }
floriance9e3db2012-12-27 20:14:03 +000010738 return "tdget";
10739}
10740
10741static const HChar *
10742s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10743{
florianfb596602014-12-06 16:34:48 +000010744 if (! s390_host_has_dfp) {
10745 emulation_failure(EmFail_S390X_DFP_insn);
10746 } else {
10747 IRTemp value = newTemp(Ity_D64);
floriance9e3db2012-12-27 20:14:03 +000010748
florianfb596602014-12-06 16:34:48 +000010749 assign(value, get_dpr_dw0(r1));
floriance9e3db2012-12-27 20:14:03 +000010750
florianfb596602014-12-06 16:34:48 +000010751 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10752 }
floriance9e3db2012-12-27 20:14:03 +000010753 return "tdgdt";
10754}
10755
10756static const HChar *
10757s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10758{
florianfb596602014-12-06 16:34:48 +000010759 if (! s390_host_has_dfp) {
10760 emulation_failure(EmFail_S390X_DFP_insn);
10761 } else {
10762 IRTemp value = newTemp(Ity_D128);
floriance9e3db2012-12-27 20:14:03 +000010763
florianfb596602014-12-06 16:34:48 +000010764 assign(value, get_dpr_pair(r1));
floriance9e3db2012-12-27 20:14:03 +000010765
florianfb596602014-12-06 16:34:48 +000010766 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10767 }
floriance9e3db2012-12-27 20:14:03 +000010768 return "tdgxt";
10769}
10770
10771static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010772s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10773{
florian79e839e2012-05-05 02:20:30 +000010774 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010775
florian79e839e2012-05-05 02:20:30 +000010776 assign(len, mkU64(length));
10777 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010778
10779 return "clc";
10780}
10781
florian55085f82012-11-21 00:36:55 +000010782static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010783s390_irgen_CLCL(UChar r1, UChar r2)
10784{
10785 IRTemp addr1 = newTemp(Ity_I64);
10786 IRTemp addr2 = newTemp(Ity_I64);
10787 IRTemp addr1_load = newTemp(Ity_I64);
10788 IRTemp addr2_load = newTemp(Ity_I64);
10789 IRTemp len1 = newTemp(Ity_I32);
10790 IRTemp len2 = newTemp(Ity_I32);
10791 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10792 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10793 IRTemp single1 = newTemp(Ity_I8);
10794 IRTemp single2 = newTemp(Ity_I8);
10795 IRTemp pad = newTemp(Ity_I8);
10796
10797 assign(addr1, get_gpr_dw0(r1));
10798 assign(r1p1, get_gpr_w1(r1 + 1));
10799 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10800 assign(addr2, get_gpr_dw0(r2));
10801 assign(r2p1, get_gpr_w1(r2 + 1));
10802 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10803 assign(pad, get_gpr_b4(r2 + 1));
10804
10805 /* len1 == 0 and len2 == 0? Exit */
10806 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010807 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10808 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010809
10810 /* Because mkite evaluates both the then-clause and the else-clause
10811 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10812 may be NULL and loading from there would segfault. So we provide a
10813 valid dummy address in that case. Loading from there does no harm and
10814 the value will be discarded at runtime. */
10815 assign(addr1_load,
10816 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10817 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10818 assign(single1,
10819 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10820 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10821
10822 assign(addr2_load,
10823 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10824 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10825 assign(single2,
10826 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10827 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10828
10829 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10830 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010831 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010832
10833 /* Update len1 and addr1, unless len1 == 0. */
10834 put_gpr_dw0(r1,
10835 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10836 mkexpr(addr1),
10837 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10838
10839 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10840 put_gpr_w1(r1 + 1,
10841 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10842 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10843 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10844
10845 /* Update len2 and addr2, unless len2 == 0. */
10846 put_gpr_dw0(r2,
10847 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10848 mkexpr(addr2),
10849 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10850
10851 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10852 put_gpr_w1(r2 + 1,
10853 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10854 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10855 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10856
florian6820ba52012-07-26 02:01:50 +000010857 iterate();
florianb0c9a132011-09-08 15:37:39 +000010858
10859 return "clcl";
10860}
10861
florian55085f82012-11-21 00:36:55 +000010862static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010863s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10864{
10865 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10866
10867 addr1 = newTemp(Ity_I64);
10868 addr3 = newTemp(Ity_I64);
10869 addr1_load = newTemp(Ity_I64);
10870 addr3_load = newTemp(Ity_I64);
10871 len1 = newTemp(Ity_I64);
10872 len3 = newTemp(Ity_I64);
10873 single1 = newTemp(Ity_I8);
10874 single3 = newTemp(Ity_I8);
10875
10876 assign(addr1, get_gpr_dw0(r1));
10877 assign(len1, get_gpr_dw0(r1 + 1));
10878 assign(addr3, get_gpr_dw0(r3));
10879 assign(len3, get_gpr_dw0(r3 + 1));
10880
10881 /* len1 == 0 and len3 == 0? Exit */
10882 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010883 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10884 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010885
10886 /* A mux requires both ways to be possible. This is a way to prevent clcle
10887 from reading from addr1 if it should read from the pad. Since the pad
10888 has no address, just read from the instruction, we discard that anyway */
10889 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010890 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10891 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010892
10893 /* same for addr3 */
10894 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010895 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10896 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010897
10898 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010899 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10900 unop(Iop_64to8, mkexpr(pad2)),
10901 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010902
10903 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010904 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10905 unop(Iop_64to8, mkexpr(pad2)),
10906 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010907
10908 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10909 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010910 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010911
10912 /* If a length in 0 we must not change this length and the address */
10913 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010914 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10915 mkexpr(addr1),
10916 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010917
10918 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010919 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10920 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010921
10922 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010923 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10924 mkexpr(addr3),
10925 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010926
10927 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010928 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10929 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010930
florian6820ba52012-07-26 02:01:50 +000010931 iterate();
sewardj2019a972011-03-07 16:04:07 +000010932
10933 return "clcle";
10934}
floriana64c2432011-07-16 02:11:50 +000010935
florianb0bf6602012-05-05 00:01:16 +000010936
sewardj2019a972011-03-07 16:04:07 +000010937static void
10938s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10939{
florianb0bf6602012-05-05 00:01:16 +000010940 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10941}
sewardj2019a972011-03-07 16:04:07 +000010942
sewardj2019a972011-03-07 16:04:07 +000010943
florianb0bf6602012-05-05 00:01:16 +000010944static void
10945s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10946{
10947 s390_irgen_xonc(Iop_And8, length, start1, start2);
10948}
sewardj2019a972011-03-07 16:04:07 +000010949
sewardj2019a972011-03-07 16:04:07 +000010950
florianb0bf6602012-05-05 00:01:16 +000010951static void
10952s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10953{
10954 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010955}
10956
10957
10958static void
10959s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10960{
10961 IRTemp current1 = newTemp(Ity_I8);
10962 IRTemp current2 = newTemp(Ity_I8);
10963 IRTemp counter = newTemp(Ity_I64);
10964
10965 assign(counter, get_counter_dw0());
10966 put_counter_dw0(mkU64(0));
10967
10968 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10969 mkexpr(counter))));
10970 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10971 mkexpr(counter))));
10972 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10973 False);
10974
10975 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010976 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010977
10978 /* Check for end of field */
10979 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010980 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010981 put_counter_dw0(mkU64(0));
10982}
10983
10984static void
10985s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10986{
10987 IRTemp counter = newTemp(Ity_I64);
10988
10989 assign(counter, get_counter_dw0());
10990
10991 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10992 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10993
10994 /* Check for end of field */
10995 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010996 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010997 put_counter_dw0(mkU64(0));
10998}
10999
florianf87d4fb2012-05-05 02:55:24 +000011000static void
Elliott Hughesa0664b92017-04-18 17:46:52 -070011001s390_irgen_MVCIN_EX(IRTemp length, IRTemp start1, IRTemp start2)
11002{
11003 IRTemp counter = newTemp(Ity_I64);
11004
11005 assign(counter, get_counter_dw0());
11006
11007 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
11008 load(Ity_I8, binop(Iop_Sub64, mkexpr(start2), mkexpr(counter))));
11009
11010 /* Check for end of field */
11011 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11012 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
11013 put_counter_dw0(mkU64(0));
11014}
11015
11016static void
florianf87d4fb2012-05-05 02:55:24 +000011017s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
11018{
11019 IRTemp op = newTemp(Ity_I8);
11020 IRTemp op1 = newTemp(Ity_I8);
11021 IRTemp result = newTemp(Ity_I64);
11022 IRTemp counter = newTemp(Ity_I64);
11023
11024 assign(counter, get_counter_dw0());
11025
11026 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
11027
11028 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
11029
11030 assign(op1, load(Ity_I8, mkexpr(result)));
11031 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
11032
11033 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011034 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000011035 put_counter_dw0(mkU64(0));
11036}
sewardj2019a972011-03-07 16:04:07 +000011037
11038
11039static void
11040s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000011041 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000011042 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000011043{
11044 struct SS {
11045 unsigned int op : 8;
11046 unsigned int l : 8;
11047 unsigned int b1 : 4;
11048 unsigned int d1 : 12;
11049 unsigned int b2 : 4;
11050 unsigned int d2 : 12;
11051 };
11052 union {
11053 struct SS dec;
11054 unsigned long bytes;
11055 } ss;
11056 IRTemp cond;
11057 IRDirty *d;
11058 IRTemp torun;
11059
11060 IRTemp start1 = newTemp(Ity_I64);
11061 IRTemp start2 = newTemp(Ity_I64);
11062 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
11063 cond = newTemp(Ity_I1);
11064 torun = newTemp(Ity_I64);
11065
11066 assign(torun, load(Ity_I64, mkexpr(addr2)));
11067 /* Start with a check that the saved code is still correct */
11068 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
11069 /* If not, save the new value */
11070 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
11071 mkIRExprVec_1(mkexpr(torun)));
11072 d->guard = mkexpr(cond);
11073 stmt(IRStmt_Dirty(d));
11074
11075 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000011076 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian428dfdd2012-03-27 03:09:49 +000011077 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000011078 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000011079 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000011080
11081 ss.bytes = last_execute_target;
11082 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
11083 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
11084 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
11085 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
11086 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
11087 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
11088 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000011089
sewardj2019a972011-03-07 16:04:07 +000011090 last_execute_target = 0;
11091}
11092
florian55085f82012-11-21 00:36:55 +000011093static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011094s390_irgen_EX(UChar r1, IRTemp addr2)
11095{
11096 switch(last_execute_target & 0xff00000000000000ULL) {
11097 case 0:
11098 {
11099 /* no code information yet */
11100 IRDirty *d;
11101
11102 /* so safe the code... */
11103 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
11104 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
11105 stmt(IRStmt_Dirty(d));
11106 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000011107 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian428dfdd2012-03-27 03:09:49 +000011108 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000011109 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000011110 restart_if(IRExpr_Const(IRConst_U1(True)));
11111
sewardj2019a972011-03-07 16:04:07 +000011112 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000011113 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000011114 dis_res->whatNext = Dis_StopHere;
sewardj05f5e012014-05-04 10:52:11 +000011115 dis_res->jk_StopHere = Ijk_InvalICache;
sewardj2019a972011-03-07 16:04:07 +000011116 break;
11117 }
11118
11119 case 0xd200000000000000ULL:
11120 /* special case MVC */
11121 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000011122 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000011123
11124 case 0xd500000000000000ULL:
11125 /* special case CLC */
11126 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000011127 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000011128
11129 case 0xd700000000000000ULL:
11130 /* special case XC */
11131 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000011132 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000011133
florianb0bf6602012-05-05 00:01:16 +000011134 case 0xd600000000000000ULL:
11135 /* special case OC */
11136 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000011137 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000011138
11139 case 0xd400000000000000ULL:
11140 /* special case NC */
11141 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000011142 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000011143
florianf87d4fb2012-05-05 02:55:24 +000011144 case 0xdc00000000000000ULL:
11145 /* special case TR */
11146 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000011147 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000011148
Elliott Hughesa0664b92017-04-18 17:46:52 -070011149 case 0xe800000000000000ULL:
11150 /* special case MVCIN */
11151 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVCIN_EX, 64);
11152 return "ex@mvcin";
11153
sewardj2019a972011-03-07 16:04:07 +000011154 default:
11155 {
11156 /* everything else will get a self checking prefix that also checks the
11157 register content */
11158 IRDirty *d;
11159 UChar *bytes;
11160 IRTemp cond;
11161 IRTemp orperand;
11162 IRTemp torun;
11163
11164 cond = newTemp(Ity_I1);
11165 orperand = newTemp(Ity_I64);
11166 torun = newTemp(Ity_I64);
11167
11168 if (r1 == 0)
11169 assign(orperand, mkU64(0));
11170 else
11171 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
11172 /* This code is going to be translated */
11173 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
11174 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
11175
11176 /* Start with a check that saved code is still correct */
11177 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
11178 mkU64(last_execute_target)));
11179 /* If not, save the new value */
11180 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
11181 mkIRExprVec_1(mkexpr(torun)));
11182 d->guard = mkexpr(cond);
11183 stmt(IRStmt_Dirty(d));
11184
11185 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000011186 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART), mkU64(guest_IA_curr_instr)));
11187 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000011188 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000011189
11190 /* Now comes the actual translation */
11191 bytes = (UChar *) &last_execute_target;
11192 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
11193 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000011194 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000011195 vex_printf(" which was executed by\n");
11196 /* dont make useless translations in the next execute */
11197 last_execute_target = 0;
11198 }
11199 }
11200 return "ex";
11201}
11202
florian55085f82012-11-21 00:36:55 +000011203static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011204s390_irgen_EXRL(UChar r1, UInt offset)
11205{
11206 IRTemp addr = newTemp(Ity_I64);
11207 /* we might save one round trip because we know the target */
11208 if (!last_execute_target)
11209 last_execute_target = *(ULong *)(HWord)
11210 (guest_IA_curr_instr + offset * 2UL);
11211 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
11212 s390_irgen_EX(r1, addr);
11213 return "exrl";
11214}
11215
florian55085f82012-11-21 00:36:55 +000011216static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011217s390_irgen_IPM(UChar r1)
11218{
11219 // As long as we dont support SPM, lets just assume 0 as program mask
11220 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
11221 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
11222
11223 return "ipm";
11224}
11225
11226
florian55085f82012-11-21 00:36:55 +000011227static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011228s390_irgen_SRST(UChar r1, UChar r2)
11229{
11230 IRTemp address = newTemp(Ity_I64);
11231 IRTemp next = newTemp(Ity_I64);
11232 IRTemp delim = newTemp(Ity_I8);
11233 IRTemp counter = newTemp(Ity_I64);
11234 IRTemp byte = newTemp(Ity_I8);
11235
11236 assign(address, get_gpr_dw0(r2));
11237 assign(next, get_gpr_dw0(r1));
11238
11239 assign(counter, get_counter_dw0());
11240 put_counter_dw0(mkU64(0));
11241
11242 // start = next? CC=2 and out r1 and r2 unchanged
11243 s390_cc_set(2);
11244 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011245 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000011246
11247 assign(byte, load(Ity_I8, mkexpr(address)));
11248 assign(delim, get_gpr_b7(0));
11249
11250 // byte = delim? CC=1, R1=address
11251 s390_cc_set(1);
11252 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000011253 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011254
11255 // else: all equal, no end yet, loop
11256 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11257 put_gpr_dw0(r1, mkexpr(next));
11258 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011259
florian6820ba52012-07-26 02:01:50 +000011260 iterate();
sewardj2019a972011-03-07 16:04:07 +000011261
11262 return "srst";
11263}
11264
florian55085f82012-11-21 00:36:55 +000011265static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011266s390_irgen_CLST(UChar r1, UChar r2)
11267{
11268 IRTemp address1 = newTemp(Ity_I64);
11269 IRTemp address2 = newTemp(Ity_I64);
11270 IRTemp end = newTemp(Ity_I8);
11271 IRTemp counter = newTemp(Ity_I64);
11272 IRTemp byte1 = newTemp(Ity_I8);
11273 IRTemp byte2 = newTemp(Ity_I8);
11274
11275 assign(address1, get_gpr_dw0(r1));
11276 assign(address2, get_gpr_dw0(r2));
11277 assign(end, get_gpr_b7(0));
11278 assign(counter, get_counter_dw0());
11279 put_counter_dw0(mkU64(0));
11280 assign(byte1, load(Ity_I8, mkexpr(address1)));
11281 assign(byte2, load(Ity_I8, mkexpr(address2)));
11282
11283 // end in both? all equal, reset r1 and r2 to start values
11284 s390_cc_set(0);
11285 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
11286 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011287 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
11288 binop(Iop_Or8,
11289 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
11290 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000011291
11292 put_gpr_dw0(r1, mkexpr(address1));
11293 put_gpr_dw0(r2, mkexpr(address2));
11294
11295 // End found in string1
11296 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011297 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000011298
11299 // End found in string2
11300 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011301 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000011302
11303 // string1 < string2
11304 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011305 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
11306 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000011307
11308 // string2 < string1
11309 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011310 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
11311 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000011312
11313 // else: all equal, no end yet, loop
11314 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11315 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
11316 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011317
florian6820ba52012-07-26 02:01:50 +000011318 iterate();
sewardj2019a972011-03-07 16:04:07 +000011319
11320 return "clst";
11321}
11322
11323static void
11324s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11325{
11326 UChar reg;
11327 IRTemp addr = newTemp(Ity_I64);
11328
11329 assign(addr, mkexpr(op2addr));
11330 reg = r1;
11331 do {
11332 IRTemp old = addr;
11333
11334 reg %= 16;
11335 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
11336 addr = newTemp(Ity_I64);
11337 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11338 reg++;
11339 } while (reg != (r3 + 1));
11340}
11341
florian55085f82012-11-21 00:36:55 +000011342static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011343s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
11344{
11345 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11346
11347 return "lm";
11348}
11349
florian55085f82012-11-21 00:36:55 +000011350static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011351s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11352{
11353 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11354
11355 return "lmy";
11356}
11357
florian55085f82012-11-21 00:36:55 +000011358static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011359s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11360{
11361 UChar reg;
11362 IRTemp addr = newTemp(Ity_I64);
11363
11364 assign(addr, mkexpr(op2addr));
11365 reg = r1;
11366 do {
11367 IRTemp old = addr;
11368
11369 reg %= 16;
11370 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11371 addr = newTemp(Ity_I64);
11372 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11373 reg++;
11374 } while (reg != (r3 + 1));
11375
11376 return "lmh";
11377}
11378
florian55085f82012-11-21 00:36:55 +000011379static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011380s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11381{
11382 UChar reg;
11383 IRTemp addr = newTemp(Ity_I64);
11384
11385 assign(addr, mkexpr(op2addr));
11386 reg = r1;
11387 do {
11388 IRTemp old = addr;
11389
11390 reg %= 16;
11391 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11392 addr = newTemp(Ity_I64);
11393 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11394 reg++;
11395 } while (reg != (r3 + 1));
11396
11397 return "lmg";
11398}
11399
11400static void
11401s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11402{
11403 UChar reg;
11404 IRTemp addr = newTemp(Ity_I64);
11405
11406 assign(addr, mkexpr(op2addr));
11407 reg = r1;
11408 do {
11409 IRTemp old = addr;
11410
11411 reg %= 16;
11412 store(mkexpr(addr), get_gpr_w1(reg));
11413 addr = newTemp(Ity_I64);
11414 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11415 reg++;
11416 } while( reg != (r3 + 1));
11417}
11418
florian55085f82012-11-21 00:36:55 +000011419static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011420s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11421{
11422 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11423
11424 return "stm";
11425}
11426
florian55085f82012-11-21 00:36:55 +000011427static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011428s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11429{
11430 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11431
11432 return "stmy";
11433}
11434
florian55085f82012-11-21 00:36:55 +000011435static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011436s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11437{
11438 UChar reg;
11439 IRTemp addr = newTemp(Ity_I64);
11440
11441 assign(addr, mkexpr(op2addr));
11442 reg = r1;
11443 do {
11444 IRTemp old = addr;
11445
11446 reg %= 16;
11447 store(mkexpr(addr), get_gpr_w0(reg));
11448 addr = newTemp(Ity_I64);
11449 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11450 reg++;
11451 } while( reg != (r3 + 1));
11452
11453 return "stmh";
11454}
11455
florian55085f82012-11-21 00:36:55 +000011456static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011457s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11458{
11459 UChar reg;
11460 IRTemp addr = newTemp(Ity_I64);
11461
11462 assign(addr, mkexpr(op2addr));
11463 reg = r1;
11464 do {
11465 IRTemp old = addr;
11466
11467 reg %= 16;
11468 store(mkexpr(addr), get_gpr_dw0(reg));
11469 addr = newTemp(Ity_I64);
11470 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11471 reg++;
11472 } while( reg != (r3 + 1));
11473
11474 return "stmg";
11475}
11476
11477static void
florianb0bf6602012-05-05 00:01:16 +000011478s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000011479{
11480 IRTemp old1 = newTemp(Ity_I8);
11481 IRTemp old2 = newTemp(Ity_I8);
11482 IRTemp new1 = newTemp(Ity_I8);
11483 IRTemp counter = newTemp(Ity_I32);
11484 IRTemp addr1 = newTemp(Ity_I64);
11485
11486 assign(counter, get_counter_w0());
11487
11488 assign(addr1, binop(Iop_Add64, mkexpr(start1),
11489 unop(Iop_32Uto64, mkexpr(counter))));
11490
11491 assign(old1, load(Ity_I8, mkexpr(addr1)));
11492 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11493 unop(Iop_32Uto64,mkexpr(counter)))));
11494 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11495
11496 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000011497 if (op == Iop_Xor8) {
11498 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000011499 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11500 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000011501 } else
11502 store(mkexpr(addr1), mkexpr(new1));
11503 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11504 get_counter_w1()));
11505
11506 /* Check for end of field */
11507 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011508 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000011509 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11510 False);
11511 put_counter_dw0(mkU64(0));
11512}
11513
florian55085f82012-11-21 00:36:55 +000011514static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011515s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11516{
florianb0bf6602012-05-05 00:01:16 +000011517 IRTemp len = newTemp(Ity_I32);
11518
11519 assign(len, mkU32(length));
11520 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011521
11522 return "xc";
11523}
11524
sewardjb63967e2011-03-24 08:50:04 +000011525static void
11526s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11527{
11528 IRTemp counter = newTemp(Ity_I32);
11529 IRTemp start = newTemp(Ity_I64);
11530 IRTemp addr = newTemp(Ity_I64);
11531
11532 assign(start,
11533 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11534
11535 if (length < 8) {
11536 UInt i;
11537
11538 for (i = 0; i <= length; ++i) {
11539 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11540 }
11541 } else {
11542 assign(counter, get_counter_w0());
11543
11544 assign(addr, binop(Iop_Add64, mkexpr(start),
11545 unop(Iop_32Uto64, mkexpr(counter))));
11546
11547 store(mkexpr(addr), mkU8(0));
11548
11549 /* Check for end of field */
11550 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011551 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000011552
11553 /* Reset counter */
11554 put_counter_dw0(mkU64(0));
11555 }
11556
11557 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11558
sewardj7ee97522011-05-09 21:45:04 +000011559 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000011560 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11561}
11562
florian55085f82012-11-21 00:36:55 +000011563static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011564s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11565{
florianb0bf6602012-05-05 00:01:16 +000011566 IRTemp len = newTemp(Ity_I32);
11567
11568 assign(len, mkU32(length));
11569 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011570
11571 return "nc";
11572}
11573
florian55085f82012-11-21 00:36:55 +000011574static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011575s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11576{
florianb0bf6602012-05-05 00:01:16 +000011577 IRTemp len = newTemp(Ity_I32);
11578
11579 assign(len, mkU32(length));
11580 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011581
11582 return "oc";
11583}
11584
11585
florian55085f82012-11-21 00:36:55 +000011586static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011587s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11588{
florian79e839e2012-05-05 02:20:30 +000011589 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000011590
florian79e839e2012-05-05 02:20:30 +000011591 assign(len, mkU64(length));
11592 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011593
11594 return "mvc";
11595}
11596
florian55085f82012-11-21 00:36:55 +000011597static const HChar *
Elliott Hughesa0664b92017-04-18 17:46:52 -070011598s390_irgen_MVCIN(UChar length, IRTemp start1, IRTemp start2)
11599{
11600 IRTemp len = newTemp(Ity_I64);
11601
11602 assign(len, mkU64(length));
11603 s390_irgen_MVCIN_EX(len, start1, start2);
11604
11605 return "mvcin";
11606}
11607
11608static const HChar *
florianb0c9a132011-09-08 15:37:39 +000011609s390_irgen_MVCL(UChar r1, UChar r2)
11610{
11611 IRTemp addr1 = newTemp(Ity_I64);
11612 IRTemp addr2 = newTemp(Ity_I64);
11613 IRTemp addr2_load = newTemp(Ity_I64);
11614 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
11615 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
11616 IRTemp len1 = newTemp(Ity_I32);
11617 IRTemp len2 = newTemp(Ity_I32);
11618 IRTemp pad = newTemp(Ity_I8);
11619 IRTemp single = newTemp(Ity_I8);
11620
11621 assign(addr1, get_gpr_dw0(r1));
11622 assign(r1p1, get_gpr_w1(r1 + 1));
11623 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11624 assign(addr2, get_gpr_dw0(r2));
11625 assign(r2p1, get_gpr_w1(r2 + 1));
11626 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11627 assign(pad, get_gpr_b4(r2 + 1));
11628
11629 /* len1 == 0 ? */
11630 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011631 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000011632
11633 /* Check for destructive overlap:
11634 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11635 s390_cc_set(3);
11636 IRTemp cond1 = newTemp(Ity_I32);
11637 assign(cond1, unop(Iop_1Uto32,
11638 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11639 IRTemp cond2 = newTemp(Ity_I32);
11640 assign(cond2, unop(Iop_1Uto32,
11641 binop(Iop_CmpLT64U, mkexpr(addr1),
11642 binop(Iop_Add64, mkexpr(addr2),
11643 unop(Iop_32Uto64, mkexpr(len1))))));
11644 IRTemp cond3 = newTemp(Ity_I32);
11645 assign(cond3, unop(Iop_1Uto32,
11646 binop(Iop_CmpLT64U,
11647 mkexpr(addr1),
11648 binop(Iop_Add64, mkexpr(addr2),
11649 unop(Iop_32Uto64, mkexpr(len2))))));
11650
florian6820ba52012-07-26 02:01:50 +000011651 next_insn_if(binop(Iop_CmpEQ32,
11652 binop(Iop_And32,
11653 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11654 mkexpr(cond3)),
11655 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011656
11657 /* See s390_irgen_CLCL for explanation why we cannot load directly
11658 and need two steps. */
11659 assign(addr2_load,
11660 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11661 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11662 assign(single,
11663 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11664 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11665
11666 store(mkexpr(addr1), mkexpr(single));
11667
11668 /* Update addr1 and len1 */
11669 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11670 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11671
11672 /* Update addr2 and len2 */
11673 put_gpr_dw0(r2,
11674 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11675 mkexpr(addr2),
11676 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11677
11678 /* When updating len2 we must not modify bits (r2+1)[0:39] */
11679 put_gpr_w1(r2 + 1,
11680 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11681 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11682 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11683
11684 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011685 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011686
11687 return "mvcl";
11688}
11689
11690
florian55085f82012-11-21 00:36:55 +000011691static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011692s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11693{
11694 IRTemp addr1, addr3, addr3_load, len1, len3, single;
11695
11696 addr1 = newTemp(Ity_I64);
11697 addr3 = newTemp(Ity_I64);
11698 addr3_load = newTemp(Ity_I64);
11699 len1 = newTemp(Ity_I64);
11700 len3 = newTemp(Ity_I64);
11701 single = newTemp(Ity_I8);
11702
11703 assign(addr1, get_gpr_dw0(r1));
11704 assign(len1, get_gpr_dw0(r1 + 1));
11705 assign(addr3, get_gpr_dw0(r3));
11706 assign(len3, get_gpr_dw0(r3 + 1));
11707
11708 // len1 == 0 ?
11709 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011710 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000011711
11712 /* This is a hack to prevent mvcle from reading from addr3 if it
11713 should read from the pad. Since the pad has no address, just
11714 read from the instruction, we discard that anyway */
11715 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000011716 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11717 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000011718
11719 assign(single,
florian6ad49522011-09-09 02:38:55 +000011720 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11721 unop(Iop_64to8, mkexpr(pad2)),
11722 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000011723 store(mkexpr(addr1), mkexpr(single));
11724
11725 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11726
11727 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11728
11729 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000011730 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11731 mkexpr(addr3),
11732 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011733
11734 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000011735 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11736 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011737
sewardj2019a972011-03-07 16:04:07 +000011738 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011739 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000011740
11741 return "mvcle";
11742}
11743
florian55085f82012-11-21 00:36:55 +000011744static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011745s390_irgen_MVST(UChar r1, UChar r2)
11746{
11747 IRTemp addr1 = newTemp(Ity_I64);
11748 IRTemp addr2 = newTemp(Ity_I64);
11749 IRTemp end = newTemp(Ity_I8);
11750 IRTemp byte = newTemp(Ity_I8);
11751 IRTemp counter = newTemp(Ity_I64);
11752
11753 assign(addr1, get_gpr_dw0(r1));
11754 assign(addr2, get_gpr_dw0(r2));
11755 assign(counter, get_counter_dw0());
11756 assign(end, get_gpr_b7(0));
11757 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11758 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11759
11760 // We use unlimited as cpu-determined number
11761 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011762 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011763
11764 // and always set cc=1 at the end + update r1
11765 s390_cc_set(1);
11766 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11767 put_counter_dw0(mkU64(0));
11768
11769 return "mvst";
11770}
11771
11772static void
11773s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11774{
11775 IRTemp op1 = newTemp(Ity_I64);
11776 IRTemp result = newTemp(Ity_I64);
11777
11778 assign(op1, binop(Iop_32HLto64,
11779 get_gpr_w1(r1), // high 32 bits
11780 get_gpr_w1(r1 + 1))); // low 32 bits
11781 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11782 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11783 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11784}
11785
11786static void
11787s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11788{
11789 IRTemp op1 = newTemp(Ity_I128);
11790 IRTemp result = newTemp(Ity_I128);
11791
11792 assign(op1, binop(Iop_64HLto128,
11793 get_gpr_dw0(r1), // high 64 bits
11794 get_gpr_dw0(r1 + 1))); // low 64 bits
11795 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11796 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11797 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11798}
11799
11800static void
11801s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11802{
11803 IRTemp op1 = newTemp(Ity_I64);
11804 IRTemp result = newTemp(Ity_I128);
11805
11806 assign(op1, get_gpr_dw0(r1 + 1));
11807 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11808 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11809 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11810}
11811
florian55085f82012-11-21 00:36:55 +000011812static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011813s390_irgen_DR(UChar r1, UChar r2)
11814{
11815 IRTemp op2 = newTemp(Ity_I32);
11816
11817 assign(op2, get_gpr_w1(r2));
11818
11819 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11820
11821 return "dr";
11822}
11823
florian55085f82012-11-21 00:36:55 +000011824static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011825s390_irgen_D(UChar r1, IRTemp op2addr)
11826{
11827 IRTemp op2 = newTemp(Ity_I32);
11828
11829 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11830
11831 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11832
11833 return "d";
11834}
11835
florian55085f82012-11-21 00:36:55 +000011836static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011837s390_irgen_DLR(UChar r1, UChar r2)
11838{
11839 IRTemp op2 = newTemp(Ity_I32);
11840
11841 assign(op2, get_gpr_w1(r2));
11842
11843 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11844
florian7cd1cde2012-08-16 23:57:43 +000011845 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011846}
11847
florian55085f82012-11-21 00:36:55 +000011848static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011849s390_irgen_DL(UChar r1, IRTemp op2addr)
11850{
11851 IRTemp op2 = newTemp(Ity_I32);
11852
11853 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11854
11855 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11856
11857 return "dl";
11858}
11859
florian55085f82012-11-21 00:36:55 +000011860static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011861s390_irgen_DLG(UChar r1, IRTemp op2addr)
11862{
11863 IRTemp op2 = newTemp(Ity_I64);
11864
11865 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11866
11867 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11868
11869 return "dlg";
11870}
11871
florian55085f82012-11-21 00:36:55 +000011872static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011873s390_irgen_DLGR(UChar r1, UChar r2)
11874{
11875 IRTemp op2 = newTemp(Ity_I64);
11876
11877 assign(op2, get_gpr_dw0(r2));
11878
11879 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11880
11881 return "dlgr";
11882}
11883
florian55085f82012-11-21 00:36:55 +000011884static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011885s390_irgen_DSGR(UChar r1, UChar r2)
11886{
11887 IRTemp op2 = newTemp(Ity_I64);
11888
11889 assign(op2, get_gpr_dw0(r2));
11890
11891 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11892
11893 return "dsgr";
11894}
11895
florian55085f82012-11-21 00:36:55 +000011896static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011897s390_irgen_DSG(UChar r1, IRTemp op2addr)
11898{
11899 IRTemp op2 = newTemp(Ity_I64);
11900
11901 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11902
11903 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11904
11905 return "dsg";
11906}
11907
florian55085f82012-11-21 00:36:55 +000011908static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011909s390_irgen_DSGFR(UChar r1, UChar r2)
11910{
11911 IRTemp op2 = newTemp(Ity_I64);
11912
11913 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11914
11915 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11916
11917 return "dsgfr";
11918}
11919
florian55085f82012-11-21 00:36:55 +000011920static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011921s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11922{
11923 IRTemp op2 = newTemp(Ity_I64);
11924
11925 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11926
11927 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11928
11929 return "dsgf";
11930}
11931
11932static void
11933s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11934{
11935 UChar reg;
11936 IRTemp addr = newTemp(Ity_I64);
11937
11938 assign(addr, mkexpr(op2addr));
11939 reg = r1;
11940 do {
11941 IRTemp old = addr;
11942
11943 reg %= 16;
11944 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11945 addr = newTemp(Ity_I64);
11946 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11947 reg++;
11948 } while (reg != (r3 + 1));
11949}
11950
florian55085f82012-11-21 00:36:55 +000011951static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011952s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11953{
11954 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11955
11956 return "lam";
11957}
11958
florian55085f82012-11-21 00:36:55 +000011959static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011960s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11961{
11962 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11963
11964 return "lamy";
11965}
11966
11967static void
11968s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11969{
11970 UChar reg;
11971 IRTemp addr = newTemp(Ity_I64);
11972
11973 assign(addr, mkexpr(op2addr));
11974 reg = r1;
11975 do {
11976 IRTemp old = addr;
11977
11978 reg %= 16;
11979 store(mkexpr(addr), get_ar_w0(reg));
11980 addr = newTemp(Ity_I64);
11981 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11982 reg++;
11983 } while (reg != (r3 + 1));
11984}
11985
florian55085f82012-11-21 00:36:55 +000011986static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011987s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11988{
11989 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11990
11991 return "stam";
11992}
11993
florian55085f82012-11-21 00:36:55 +000011994static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011995s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11996{
11997 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11998
11999 return "stamy";
12000}
12001
12002
12003/* Implementation for 32-bit compare-and-swap */
12004static void
12005s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
12006{
12007 IRCAS *cas;
12008 IRTemp op1 = newTemp(Ity_I32);
12009 IRTemp old_mem = newTemp(Ity_I32);
12010 IRTemp op3 = newTemp(Ity_I32);
12011 IRTemp result = newTemp(Ity_I32);
12012 IRTemp nequal = newTemp(Ity_I1);
12013
12014 assign(op1, get_gpr_w1(r1));
12015 assign(op3, get_gpr_w1(r3));
12016
12017 /* The first and second operands are compared. If they are equal,
12018 the third operand is stored at the second- operand location. */
12019 cas = mkIRCAS(IRTemp_INVALID, old_mem,
12020 Iend_BE, mkexpr(op2addr),
12021 NULL, mkexpr(op1), /* expected value */
12022 NULL, mkexpr(op3) /* new value */);
12023 stmt(IRStmt_CAS(cas));
12024
12025 /* Set CC. Operands compared equal -> 0, else 1. */
12026 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
12027 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12028
12029 /* If operands were equal (cc == 0) just store the old value op1 in r1.
12030 Otherwise, store the old_value from memory in r1 and yield. */
12031 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12032 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000012033 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000012034}
12035
florian55085f82012-11-21 00:36:55 +000012036static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012037s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
12038{
12039 s390_irgen_cas_32(r1, r3, op2addr);
12040
12041 return "cs";
12042}
12043
florian55085f82012-11-21 00:36:55 +000012044static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012045s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
12046{
12047 s390_irgen_cas_32(r1, r3, op2addr);
12048
12049 return "csy";
12050}
12051
florian55085f82012-11-21 00:36:55 +000012052static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012053s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
12054{
12055 IRCAS *cas;
12056 IRTemp op1 = newTemp(Ity_I64);
12057 IRTemp old_mem = newTemp(Ity_I64);
12058 IRTemp op3 = newTemp(Ity_I64);
12059 IRTemp result = newTemp(Ity_I64);
12060 IRTemp nequal = newTemp(Ity_I1);
12061
12062 assign(op1, get_gpr_dw0(r1));
12063 assign(op3, get_gpr_dw0(r3));
12064
12065 /* The first and second operands are compared. If they are equal,
12066 the third operand is stored at the second- operand location. */
12067 cas = mkIRCAS(IRTemp_INVALID, old_mem,
12068 Iend_BE, mkexpr(op2addr),
12069 NULL, mkexpr(op1), /* expected value */
12070 NULL, mkexpr(op3) /* new value */);
12071 stmt(IRStmt_CAS(cas));
12072
12073 /* Set CC. Operands compared equal -> 0, else 1. */
12074 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
12075 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12076
12077 /* If operands were equal (cc == 0) just store the old value op1 in r1.
12078 Otherwise, store the old_value from memory in r1 and yield. */
12079 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12080 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000012081 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000012082
12083 return "csg";
12084}
12085
florian448cbba2012-06-06 02:26:01 +000012086/* Implementation for 32-bit compare-double-and-swap */
12087static void
12088s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
12089{
12090 IRCAS *cas;
12091 IRTemp op1_high = newTemp(Ity_I32);
12092 IRTemp op1_low = newTemp(Ity_I32);
12093 IRTemp old_mem_high = newTemp(Ity_I32);
12094 IRTemp old_mem_low = newTemp(Ity_I32);
12095 IRTemp op3_high = newTemp(Ity_I32);
12096 IRTemp op3_low = newTemp(Ity_I32);
12097 IRTemp result = newTemp(Ity_I32);
12098 IRTemp nequal = newTemp(Ity_I1);
12099
12100 assign(op1_high, get_gpr_w1(r1));
12101 assign(op1_low, get_gpr_w1(r1+1));
12102 assign(op3_high, get_gpr_w1(r3));
12103 assign(op3_low, get_gpr_w1(r3+1));
12104
12105 /* The first and second operands are compared. If they are equal,
12106 the third operand is stored at the second-operand location. */
12107 cas = mkIRCAS(old_mem_high, old_mem_low,
12108 Iend_BE, mkexpr(op2addr),
12109 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
12110 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
12111 stmt(IRStmt_CAS(cas));
12112
12113 /* Set CC. Operands compared equal -> 0, else 1. */
12114 assign(result, unop(Iop_1Uto32,
12115 binop(Iop_CmpNE32,
12116 binop(Iop_Or32,
12117 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
12118 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
12119 mkU32(0))));
12120
12121 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12122
12123 /* If operands were equal (cc == 0) just store the old value op1 in r1.
12124 Otherwise, store the old_value from memory in r1 and yield. */
12125 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12126 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
12127 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000012128 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000012129}
12130
florian55085f82012-11-21 00:36:55 +000012131static const HChar *
florian448cbba2012-06-06 02:26:01 +000012132s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
12133{
12134 s390_irgen_cdas_32(r1, r3, op2addr);
12135
12136 return "cds";
12137}
12138
florian55085f82012-11-21 00:36:55 +000012139static const HChar *
florian448cbba2012-06-06 02:26:01 +000012140s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
12141{
12142 s390_irgen_cdas_32(r1, r3, op2addr);
12143
12144 return "cdsy";
12145}
12146
florian55085f82012-11-21 00:36:55 +000012147static const HChar *
florian448cbba2012-06-06 02:26:01 +000012148s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
12149{
12150 IRCAS *cas;
12151 IRTemp op1_high = newTemp(Ity_I64);
12152 IRTemp op1_low = newTemp(Ity_I64);
12153 IRTemp old_mem_high = newTemp(Ity_I64);
12154 IRTemp old_mem_low = newTemp(Ity_I64);
12155 IRTemp op3_high = newTemp(Ity_I64);
12156 IRTemp op3_low = newTemp(Ity_I64);
12157 IRTemp result = newTemp(Ity_I64);
12158 IRTemp nequal = newTemp(Ity_I1);
12159
12160 assign(op1_high, get_gpr_dw0(r1));
12161 assign(op1_low, get_gpr_dw0(r1+1));
12162 assign(op3_high, get_gpr_dw0(r3));
12163 assign(op3_low, get_gpr_dw0(r3+1));
12164
12165 /* The first and second operands are compared. If they are equal,
12166 the third operand is stored at the second-operand location. */
12167 cas = mkIRCAS(old_mem_high, old_mem_low,
12168 Iend_BE, mkexpr(op2addr),
12169 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
12170 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
12171 stmt(IRStmt_CAS(cas));
12172
12173 /* Set CC. Operands compared equal -> 0, else 1. */
12174 assign(result, unop(Iop_1Uto64,
12175 binop(Iop_CmpNE64,
12176 binop(Iop_Or64,
12177 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
12178 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
12179 mkU64(0))));
12180
12181 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12182
12183 /* If operands were equal (cc == 0) just store the old value op1 in r1.
12184 Otherwise, store the old_value from memory in r1 and yield. */
12185 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12186 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
12187 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000012188 yield_if(mkexpr(nequal));
12189
florian448cbba2012-06-06 02:26:01 +000012190 return "cdsg";
12191}
12192
sewardj2019a972011-03-07 16:04:07 +000012193
12194/* Binary floating point */
12195
florian55085f82012-11-21 00:36:55 +000012196static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012197s390_irgen_AXBR(UChar r1, UChar r2)
12198{
12199 IRTemp op1 = newTemp(Ity_F128);
12200 IRTemp op2 = newTemp(Ity_F128);
12201 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012202 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012203
12204 assign(op1, get_fpr_pair(r1));
12205 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012206 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012207 mkexpr(op2)));
12208 put_fpr_pair(r1, mkexpr(result));
12209
12210 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12211
12212 return "axbr";
12213}
12214
florian55085f82012-11-21 00:36:55 +000012215static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012216s390_irgen_CEBR(UChar r1, UChar r2)
12217{
12218 IRTemp op1 = newTemp(Ity_F32);
12219 IRTemp op2 = newTemp(Ity_F32);
12220 IRTemp cc_vex = newTemp(Ity_I32);
12221 IRTemp cc_s390 = newTemp(Ity_I32);
12222
12223 assign(op1, get_fpr_w0(r1));
12224 assign(op2, get_fpr_w0(r2));
12225 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12226
florian2d3d87f2012-12-21 21:05:17 +000012227 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012228 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12229
12230 return "cebr";
12231}
12232
florian55085f82012-11-21 00:36:55 +000012233static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012234s390_irgen_CDBR(UChar r1, UChar r2)
12235{
12236 IRTemp op1 = newTemp(Ity_F64);
12237 IRTemp op2 = newTemp(Ity_F64);
12238 IRTemp cc_vex = newTemp(Ity_I32);
12239 IRTemp cc_s390 = newTemp(Ity_I32);
12240
12241 assign(op1, get_fpr_dw0(r1));
12242 assign(op2, get_fpr_dw0(r2));
12243 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12244
florian2d3d87f2012-12-21 21:05:17 +000012245 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012246 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12247
12248 return "cdbr";
12249}
12250
florian55085f82012-11-21 00:36:55 +000012251static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012252s390_irgen_CXBR(UChar r1, UChar r2)
12253{
12254 IRTemp op1 = newTemp(Ity_F128);
12255 IRTemp op2 = newTemp(Ity_F128);
12256 IRTemp cc_vex = newTemp(Ity_I32);
12257 IRTemp cc_s390 = newTemp(Ity_I32);
12258
12259 assign(op1, get_fpr_pair(r1));
12260 assign(op2, get_fpr_pair(r2));
12261 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
12262
florian2d3d87f2012-12-21 21:05:17 +000012263 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012264 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12265
12266 return "cxbr";
12267}
12268
florian55085f82012-11-21 00:36:55 +000012269static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012270s390_irgen_CEB(UChar r1, IRTemp op2addr)
12271{
12272 IRTemp op1 = newTemp(Ity_F32);
12273 IRTemp op2 = newTemp(Ity_F32);
12274 IRTemp cc_vex = newTemp(Ity_I32);
12275 IRTemp cc_s390 = newTemp(Ity_I32);
12276
12277 assign(op1, get_fpr_w0(r1));
12278 assign(op2, load(Ity_F32, mkexpr(op2addr)));
12279 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12280
florian2d3d87f2012-12-21 21:05:17 +000012281 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012282 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12283
12284 return "ceb";
12285}
12286
florian55085f82012-11-21 00:36:55 +000012287static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012288s390_irgen_CDB(UChar r1, IRTemp op2addr)
12289{
12290 IRTemp op1 = newTemp(Ity_F64);
12291 IRTemp op2 = newTemp(Ity_F64);
12292 IRTemp cc_vex = newTemp(Ity_I32);
12293 IRTemp cc_s390 = newTemp(Ity_I32);
12294
12295 assign(op1, get_fpr_dw0(r1));
12296 assign(op2, load(Ity_F64, mkexpr(op2addr)));
12297 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12298
florian2d3d87f2012-12-21 21:05:17 +000012299 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012300 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12301
12302 return "cdb";
12303}
12304
florian55085f82012-11-21 00:36:55 +000012305static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012306s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
12307 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012308{
12309 IRTemp op2 = newTemp(Ity_I32);
12310
12311 assign(op2, get_gpr_w1(r2));
12312 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
12313
12314 return "cxfbr";
12315}
12316
florian55085f82012-11-21 00:36:55 +000012317static const HChar *
floriand2129202012-09-01 20:01:39 +000012318s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
12319 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012320{
floriane75dafa2012-09-01 17:54:09 +000012321 if (! s390_host_has_fpext) {
12322 emulation_failure(EmFail_S390X_fpext);
12323 } else {
12324 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000012325
floriane75dafa2012-09-01 17:54:09 +000012326 assign(op2, get_gpr_w1(r2));
12327 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
12328 }
florian1c8f7ff2012-09-01 00:12:11 +000012329 return "cxlfbr";
12330}
12331
12332
florian55085f82012-11-21 00:36:55 +000012333static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012334s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
12335 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012336{
12337 IRTemp op2 = newTemp(Ity_I64);
12338
12339 assign(op2, get_gpr_dw0(r2));
12340 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
12341
12342 return "cxgbr";
12343}
12344
florian55085f82012-11-21 00:36:55 +000012345static const HChar *
floriand2129202012-09-01 20:01:39 +000012346s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
12347 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012348{
floriane75dafa2012-09-01 17:54:09 +000012349 if (! s390_host_has_fpext) {
12350 emulation_failure(EmFail_S390X_fpext);
12351 } else {
12352 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000012353
floriane75dafa2012-09-01 17:54:09 +000012354 assign(op2, get_gpr_dw0(r2));
12355 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
12356 }
florian1c8f7ff2012-09-01 00:12:11 +000012357 return "cxlgbr";
12358}
12359
florian55085f82012-11-21 00:36:55 +000012360static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012361s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
12362 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012363{
12364 IRTemp op = newTemp(Ity_F128);
12365 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012366 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012367
12368 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012369 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012370 mkexpr(op)));
12371 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012372 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012373
12374 return "cfxbr";
12375}
12376
florian55085f82012-11-21 00:36:55 +000012377static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012378s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12379 UChar r1, UChar r2)
12380{
floriane75dafa2012-09-01 17:54:09 +000012381 if (! s390_host_has_fpext) {
12382 emulation_failure(EmFail_S390X_fpext);
12383 } else {
12384 IRTemp op = newTemp(Ity_F128);
12385 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012386 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012387
floriane75dafa2012-09-01 17:54:09 +000012388 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012389 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012390 mkexpr(op)));
12391 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012392 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012393 }
florian1c8f7ff2012-09-01 00:12:11 +000012394 return "clfxbr";
12395}
12396
12397
florian55085f82012-11-21 00:36:55 +000012398static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012399s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12400 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012401{
12402 IRTemp op = newTemp(Ity_F128);
12403 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012404 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012405
12406 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012407 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012408 mkexpr(op)));
12409 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012410 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012411
12412 return "cgxbr";
12413}
12414
florian55085f82012-11-21 00:36:55 +000012415static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012416s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12417 UChar r1, UChar r2)
12418{
floriane75dafa2012-09-01 17:54:09 +000012419 if (! s390_host_has_fpext) {
12420 emulation_failure(EmFail_S390X_fpext);
12421 } else {
12422 IRTemp op = newTemp(Ity_F128);
12423 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012424 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012425
floriane75dafa2012-09-01 17:54:09 +000012426 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012427 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012428 mkexpr(op)));
12429 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012430 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12431 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012432 }
florian1c8f7ff2012-09-01 00:12:11 +000012433 return "clgxbr";
12434}
12435
florian55085f82012-11-21 00:36:55 +000012436static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012437s390_irgen_DXBR(UChar r1, UChar r2)
12438{
12439 IRTemp op1 = newTemp(Ity_F128);
12440 IRTemp op2 = newTemp(Ity_F128);
12441 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012442 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012443
12444 assign(op1, get_fpr_pair(r1));
12445 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012446 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012447 mkexpr(op2)));
12448 put_fpr_pair(r1, mkexpr(result));
12449
12450 return "dxbr";
12451}
12452
florian55085f82012-11-21 00:36:55 +000012453static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012454s390_irgen_LTXBR(UChar r1, UChar r2)
12455{
12456 IRTemp result = newTemp(Ity_F128);
12457
12458 assign(result, get_fpr_pair(r2));
12459 put_fpr_pair(r1, mkexpr(result));
12460 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12461
12462 return "ltxbr";
12463}
12464
florian55085f82012-11-21 00:36:55 +000012465static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012466s390_irgen_LCXBR(UChar r1, UChar r2)
12467{
12468 IRTemp result = newTemp(Ity_F128);
12469
12470 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
12471 put_fpr_pair(r1, mkexpr(result));
12472 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12473
12474 return "lcxbr";
12475}
12476
florian55085f82012-11-21 00:36:55 +000012477static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012478s390_irgen_LXDBR(UChar r1, UChar r2)
12479{
12480 IRTemp op = newTemp(Ity_F64);
12481
12482 assign(op, get_fpr_dw0(r2));
12483 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12484
12485 return "lxdbr";
12486}
12487
florian55085f82012-11-21 00:36:55 +000012488static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012489s390_irgen_LXEBR(UChar r1, UChar r2)
12490{
12491 IRTemp op = newTemp(Ity_F32);
12492
12493 assign(op, get_fpr_w0(r2));
12494 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12495
12496 return "lxebr";
12497}
12498
florian55085f82012-11-21 00:36:55 +000012499static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012500s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12501{
12502 IRTemp op = newTemp(Ity_F64);
12503
12504 assign(op, load(Ity_F64, mkexpr(op2addr)));
12505 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12506
12507 return "lxdb";
12508}
12509
florian55085f82012-11-21 00:36:55 +000012510static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012511s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12512{
12513 IRTemp op = newTemp(Ity_F32);
12514
12515 assign(op, load(Ity_F32, mkexpr(op2addr)));
12516 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12517
12518 return "lxeb";
12519}
12520
florian55085f82012-11-21 00:36:55 +000012521static const HChar *
florian6d0b0152015-07-09 20:59:24 +000012522s390_irgen_FIEBRA(UChar m3, UChar m4 __attribute__((unused)),
12523 UChar r1, UChar r2)
12524{
12525 IRTemp result = newTemp(Ity_F32);
12526
12527 assign(result, binop(Iop_RoundF32toInt, mkexpr(encode_bfp_rounding_mode(m3)),
12528 get_fpr_w0(r2)));
12529 put_fpr_w0(r1, mkexpr(result));
12530
12531 return "fiebra";
12532}
12533
12534static const HChar *
12535s390_irgen_FIDBRA(UChar m3, UChar m4 __attribute__((unused)),
12536 UChar r1, UChar r2)
12537{
12538 IRTemp result = newTemp(Ity_F64);
12539
12540 assign(result, binop(Iop_RoundF64toInt, mkexpr(encode_bfp_rounding_mode(m3)),
12541 get_fpr_dw0(r2)));
12542 put_fpr_dw0(r1, mkexpr(result));
12543
12544 return "fidbra";
12545}
12546
12547static const HChar *
florianb53f9482015-09-05 20:35:52 +000012548s390_irgen_FIXBRA(UChar m3, UChar m4 __attribute__((unused)),
12549 UChar r1, UChar r2)
12550{
12551 IRTemp result = newTemp(Ity_F128);
12552
12553 assign(result, binop(Iop_RoundF128toInt, mkexpr(encode_bfp_rounding_mode(m3)),
12554 get_fpr_pair(r2)));
12555 put_fpr_pair(r1, mkexpr(result));
12556
12557 return "fixbra";
12558}
12559
12560static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012561s390_irgen_LNEBR(UChar r1, UChar r2)
12562{
12563 IRTemp result = newTemp(Ity_F32);
12564
12565 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12566 put_fpr_w0(r1, mkexpr(result));
12567 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12568
12569 return "lnebr";
12570}
12571
florian55085f82012-11-21 00:36:55 +000012572static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012573s390_irgen_LNDBR(UChar r1, UChar r2)
12574{
12575 IRTemp result = newTemp(Ity_F64);
12576
12577 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12578 put_fpr_dw0(r1, mkexpr(result));
12579 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12580
12581 return "lndbr";
12582}
12583
florian55085f82012-11-21 00:36:55 +000012584static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012585s390_irgen_LNXBR(UChar r1, UChar r2)
12586{
12587 IRTemp result = newTemp(Ity_F128);
12588
12589 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12590 put_fpr_pair(r1, mkexpr(result));
12591 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12592
12593 return "lnxbr";
12594}
12595
florian55085f82012-11-21 00:36:55 +000012596static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012597s390_irgen_LPEBR(UChar r1, UChar r2)
12598{
12599 IRTemp result = newTemp(Ity_F32);
12600
12601 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12602 put_fpr_w0(r1, mkexpr(result));
12603 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12604
12605 return "lpebr";
12606}
12607
florian55085f82012-11-21 00:36:55 +000012608static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012609s390_irgen_LPDBR(UChar r1, UChar r2)
12610{
12611 IRTemp result = newTemp(Ity_F64);
12612
12613 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12614 put_fpr_dw0(r1, mkexpr(result));
12615 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12616
12617 return "lpdbr";
12618}
12619
florian55085f82012-11-21 00:36:55 +000012620static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012621s390_irgen_LPXBR(UChar r1, UChar r2)
12622{
12623 IRTemp result = newTemp(Ity_F128);
12624
12625 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12626 put_fpr_pair(r1, mkexpr(result));
12627 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12628
12629 return "lpxbr";
12630}
12631
florian55085f82012-11-21 00:36:55 +000012632static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012633s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12634 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012635{
florian125e20d2012-10-07 15:42:37 +000012636 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012637 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012638 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012639 }
sewardj2019a972011-03-07 16:04:07 +000012640 IRTemp result = newTemp(Ity_F64);
12641
floriandb4fcaa2012-09-05 19:54:08 +000012642 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012643 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012644 put_fpr_dw0(r1, mkexpr(result));
12645
12646 return "ldxbr";
12647}
12648
florian55085f82012-11-21 00:36:55 +000012649static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012650s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12651 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012652{
florian125e20d2012-10-07 15:42:37 +000012653 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012654 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012655 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012656 }
sewardj2019a972011-03-07 16:04:07 +000012657 IRTemp result = newTemp(Ity_F32);
12658
floriandb4fcaa2012-09-05 19:54:08 +000012659 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012660 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012661 put_fpr_w0(r1, mkexpr(result));
12662
12663 return "lexbr";
12664}
12665
florian55085f82012-11-21 00:36:55 +000012666static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012667s390_irgen_MXBR(UChar r1, UChar r2)
12668{
12669 IRTemp op1 = newTemp(Ity_F128);
12670 IRTemp op2 = newTemp(Ity_F128);
12671 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012672 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012673
12674 assign(op1, get_fpr_pair(r1));
12675 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012676 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012677 mkexpr(op2)));
12678 put_fpr_pair(r1, mkexpr(result));
12679
12680 return "mxbr";
12681}
12682
florian55085f82012-11-21 00:36:55 +000012683static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012684s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12685{
florian125e20d2012-10-07 15:42:37 +000012686 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012687
floriandb4fcaa2012-09-05 19:54:08 +000012688 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012689 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012690
12691 return "maebr";
12692}
12693
florian55085f82012-11-21 00:36:55 +000012694static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012695s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12696{
florian125e20d2012-10-07 15:42:37 +000012697 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012698
floriandb4fcaa2012-09-05 19:54:08 +000012699 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012700 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012701
12702 return "madbr";
12703}
12704
florian55085f82012-11-21 00:36:55 +000012705static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012706s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12707{
12708 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012709 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012710
floriandb4fcaa2012-09-05 19:54:08 +000012711 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012712 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012713
12714 return "maeb";
12715}
12716
florian55085f82012-11-21 00:36:55 +000012717static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012718s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12719{
12720 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012721 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012722
floriandb4fcaa2012-09-05 19:54:08 +000012723 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012724 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012725
12726 return "madb";
12727}
12728
florian55085f82012-11-21 00:36:55 +000012729static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012730s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12731{
florian125e20d2012-10-07 15:42:37 +000012732 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012733
floriandb4fcaa2012-09-05 19:54:08 +000012734 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012735 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012736
12737 return "msebr";
12738}
12739
florian55085f82012-11-21 00:36:55 +000012740static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012741s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12742{
florian125e20d2012-10-07 15:42:37 +000012743 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012744
floriandb4fcaa2012-09-05 19:54:08 +000012745 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012746 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012747
12748 return "msdbr";
12749}
12750
florian55085f82012-11-21 00:36:55 +000012751static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012752s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12753{
12754 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012755 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012756
floriandb4fcaa2012-09-05 19:54:08 +000012757 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012758 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012759
12760 return "mseb";
12761}
12762
florian55085f82012-11-21 00:36:55 +000012763static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012764s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12765{
12766 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012767 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012768
floriandb4fcaa2012-09-05 19:54:08 +000012769 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012770 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012771
12772 return "msdb";
12773}
12774
florian55085f82012-11-21 00:36:55 +000012775static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012776s390_irgen_SQEBR(UChar r1, UChar r2)
12777{
12778 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012779 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012780
floriandb4fcaa2012-09-05 19:54:08 +000012781 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012782 put_fpr_w0(r1, mkexpr(result));
12783
12784 return "sqebr";
12785}
12786
florian55085f82012-11-21 00:36:55 +000012787static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012788s390_irgen_SQDBR(UChar r1, UChar r2)
12789{
12790 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012791 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012792
floriandb4fcaa2012-09-05 19:54:08 +000012793 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012794 put_fpr_dw0(r1, mkexpr(result));
12795
12796 return "sqdbr";
12797}
12798
florian55085f82012-11-21 00:36:55 +000012799static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012800s390_irgen_SQXBR(UChar r1, UChar r2)
12801{
12802 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012803 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012804
floriandb4fcaa2012-09-05 19:54:08 +000012805 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12806 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012807 put_fpr_pair(r1, mkexpr(result));
12808
12809 return "sqxbr";
12810}
12811
florian55085f82012-11-21 00:36:55 +000012812static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012813s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12814{
12815 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012816 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012817
12818 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012819 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012820
12821 return "sqeb";
12822}
12823
florian55085f82012-11-21 00:36:55 +000012824static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012825s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12826{
12827 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012828 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012829
12830 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012831 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012832
12833 return "sqdb";
12834}
12835
florian55085f82012-11-21 00:36:55 +000012836static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012837s390_irgen_SXBR(UChar r1, UChar r2)
12838{
12839 IRTemp op1 = newTemp(Ity_F128);
12840 IRTemp op2 = newTemp(Ity_F128);
12841 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012842 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012843
12844 assign(op1, get_fpr_pair(r1));
12845 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012846 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012847 mkexpr(op2)));
12848 put_fpr_pair(r1, mkexpr(result));
12849 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12850
12851 return "sxbr";
12852}
12853
florian55085f82012-11-21 00:36:55 +000012854static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012855s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12856{
12857 IRTemp value = newTemp(Ity_F32);
12858
12859 assign(value, get_fpr_w0(r1));
12860
12861 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12862
12863 return "tceb";
12864}
12865
florian55085f82012-11-21 00:36:55 +000012866static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012867s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12868{
12869 IRTemp value = newTemp(Ity_F64);
12870
12871 assign(value, get_fpr_dw0(r1));
12872
12873 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12874
12875 return "tcdb";
12876}
12877
florian55085f82012-11-21 00:36:55 +000012878static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012879s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12880{
12881 IRTemp value = newTemp(Ity_F128);
12882
12883 assign(value, get_fpr_pair(r1));
12884
12885 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12886
12887 return "tcxb";
12888}
12889
florian55085f82012-11-21 00:36:55 +000012890static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012891s390_irgen_LCDFR(UChar r1, UChar r2)
12892{
12893 IRTemp result = newTemp(Ity_F64);
12894
12895 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12896 put_fpr_dw0(r1, mkexpr(result));
12897
12898 return "lcdfr";
12899}
12900
florian55085f82012-11-21 00:36:55 +000012901static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012902s390_irgen_LNDFR(UChar r1, UChar r2)
12903{
12904 IRTemp result = newTemp(Ity_F64);
12905
12906 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12907 put_fpr_dw0(r1, mkexpr(result));
12908
12909 return "lndfr";
12910}
12911
florian55085f82012-11-21 00:36:55 +000012912static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012913s390_irgen_LPDFR(UChar r1, UChar r2)
12914{
12915 IRTemp result = newTemp(Ity_F64);
12916
12917 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12918 put_fpr_dw0(r1, mkexpr(result));
12919
12920 return "lpdfr";
12921}
12922
florian55085f82012-11-21 00:36:55 +000012923static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012924s390_irgen_LDGR(UChar r1, UChar r2)
12925{
12926 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12927
12928 return "ldgr";
12929}
12930
florian55085f82012-11-21 00:36:55 +000012931static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012932s390_irgen_LGDR(UChar r1, UChar r2)
12933{
12934 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12935
12936 return "lgdr";
12937}
12938
12939
florian55085f82012-11-21 00:36:55 +000012940static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012941s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12942{
12943 IRTemp sign = newTemp(Ity_I64);
12944 IRTemp value = newTemp(Ity_I64);
12945
12946 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12947 mkU64(1ULL << 63)));
12948 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12949 mkU64((1ULL << 63) - 1)));
12950 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12951 mkexpr(sign))));
12952
12953 return "cpsdr";
12954}
12955
12956
sewardj2019a972011-03-07 16:04:07 +000012957static IRExpr *
12958s390_call_cvb(IRExpr *in)
12959{
12960 IRExpr **args, *call;
12961
12962 args = mkIRExprVec_1(in);
12963 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12964 "s390_do_cvb", &s390_do_cvb, args);
12965
12966 /* Nothing is excluded from definedness checking. */
12967 call->Iex.CCall.cee->mcx_mask = 0;
12968
12969 return call;
12970}
12971
florian55085f82012-11-21 00:36:55 +000012972static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012973s390_irgen_CVB(UChar r1, IRTemp op2addr)
12974{
12975 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12976
12977 return "cvb";
12978}
12979
florian55085f82012-11-21 00:36:55 +000012980static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012981s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12982{
12983 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12984
12985 return "cvby";
12986}
12987
12988
sewardj2019a972011-03-07 16:04:07 +000012989static IRExpr *
12990s390_call_cvd(IRExpr *in)
12991{
12992 IRExpr **args, *call;
12993
12994 args = mkIRExprVec_1(in);
12995 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12996 "s390_do_cvd", &s390_do_cvd, args);
12997
12998 /* Nothing is excluded from definedness checking. */
12999 call->Iex.CCall.cee->mcx_mask = 0;
13000
13001 return call;
13002}
13003
florian55085f82012-11-21 00:36:55 +000013004static const HChar *
sewardj2019a972011-03-07 16:04:07 +000013005s390_irgen_CVD(UChar r1, IRTemp op2addr)
13006{
florian11b8ee82012-08-06 13:35:33 +000013007 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000013008
13009 return "cvd";
13010}
13011
florian55085f82012-11-21 00:36:55 +000013012static const HChar *
sewardj2019a972011-03-07 16:04:07 +000013013s390_irgen_CVDY(UChar r1, IRTemp op2addr)
13014{
13015 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
13016
13017 return "cvdy";
13018}
13019
florian55085f82012-11-21 00:36:55 +000013020static const HChar *
sewardj2019a972011-03-07 16:04:07 +000013021s390_irgen_FLOGR(UChar r1, UChar r2)
13022{
13023 IRTemp input = newTemp(Ity_I64);
13024 IRTemp not_zero = newTemp(Ity_I64);
13025 IRTemp tmpnum = newTemp(Ity_I64);
13026 IRTemp num = newTemp(Ity_I64);
13027 IRTemp shift_amount = newTemp(Ity_I8);
13028
13029 /* We use the "count leading zeroes" operator because the number of
13030 leading zeroes is identical with the bit position of the first '1' bit.
13031 However, that operator does not work when the input value is zero.
13032 Therefore, we set the LSB of the input value to 1 and use Clz64 on
13033 the modified value. If input == 0, then the result is 64. Otherwise,
13034 the result of Clz64 is what we want. */
13035
13036 assign(input, get_gpr_dw0(r2));
13037 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
13038 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
13039
13040 /* num = (input == 0) ? 64 : tmpnum */
13041 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
13042 /* == 0 */ mkU64(64),
13043 /* != 0 */ mkexpr(tmpnum)));
13044
13045 put_gpr_dw0(r1, mkexpr(num));
13046
13047 /* Set the leftmost '1' bit of the input value to zero. The general scheme
13048 is to first shift the input value by NUM + 1 bits to the left which
13049 causes the leftmost '1' bit to disappear. Then we shift logically to
13050 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
13051 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
13052 the width of the value-to-be-shifted, we need to special case
13053 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
13054 For both such INPUT values the result will be 0. */
13055
13056 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
13057 mkU64(1))));
13058
13059 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000013060 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
13061 /* == 0 || == 1*/ mkU64(0),
13062 /* otherwise */
13063 binop(Iop_Shr64,
13064 binop(Iop_Shl64, mkexpr(input),
13065 mkexpr(shift_amount)),
13066 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000013067
13068 /* Compare the original value as an unsigned integer with 0. */
13069 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
13070 mktemp(Ity_I64, mkU64(0)), False);
13071
13072 return "flogr";
13073}
13074
florian55085f82012-11-21 00:36:55 +000013075static const HChar *
Elliott Hughesa0664b92017-04-18 17:46:52 -070013076s390_irgen_POPCNT(UChar r1, UChar r2)
13077{
13078 Int i;
13079 IRTemp val = newTemp(Ity_I64);
13080 IRTemp mask[3];
13081
13082 assign(val, get_gpr_dw0(r2));
13083 for (i = 0; i < 3; i++) {
13084 mask[i] = newTemp(Ity_I64);
13085 }
13086 assign(mask[0], mkU64(0x5555555555555555ULL));
13087 assign(mask[1], mkU64(0x3333333333333333ULL));
13088 assign(mask[2], mkU64(0x0F0F0F0F0F0F0F0FULL));
13089 for (i = 0; i < 3; i++) {
13090 IRTemp tmp = newTemp(Ity_I64);
13091
13092 assign(tmp,
13093 binop(Iop_Add64,
13094 binop(Iop_And64,
13095 mkexpr(val),
13096 mkexpr(mask[i])),
13097 binop(Iop_And64,
13098 binop(Iop_Shr64, mkexpr(val), mkU8(1 << i)),
13099 mkexpr(mask[i]))));
13100 val = tmp;
13101 }
13102 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, val);
13103 put_gpr_dw0(r1, mkexpr(val));
13104 return "popcnt";
13105}
13106
13107static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000013108s390_irgen_STCK(IRTemp op2addr)
13109{
13110 IRDirty *d;
13111 IRTemp cc = newTemp(Ity_I64);
13112
13113 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
13114 &s390x_dirtyhelper_STCK,
13115 mkIRExprVec_1(mkexpr(op2addr)));
13116 d->mFx = Ifx_Write;
13117 d->mAddr = mkexpr(op2addr);
13118 d->mSize = 8;
13119 stmt(IRStmt_Dirty(d));
13120 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
13121 mkexpr(cc), mkU64(0), mkU64(0));
13122 return "stck";
13123}
13124
florian55085f82012-11-21 00:36:55 +000013125static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000013126s390_irgen_STCKF(IRTemp op2addr)
13127{
florianc5c669b2012-08-26 14:32:28 +000013128 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000013129 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000013130 } else {
13131 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000013132
florianc5c669b2012-08-26 14:32:28 +000013133 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
13134 &s390x_dirtyhelper_STCKF,
13135 mkIRExprVec_1(mkexpr(op2addr)));
13136 d->mFx = Ifx_Write;
13137 d->mAddr = mkexpr(op2addr);
13138 d->mSize = 8;
13139 stmt(IRStmt_Dirty(d));
13140 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
13141 mkexpr(cc), mkU64(0), mkU64(0));
13142 }
sewardj1e5fea62011-05-17 16:18:36 +000013143 return "stckf";
13144}
13145
florian55085f82012-11-21 00:36:55 +000013146static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000013147s390_irgen_STCKE(IRTemp op2addr)
13148{
13149 IRDirty *d;
13150 IRTemp cc = newTemp(Ity_I64);
13151
13152 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
13153 &s390x_dirtyhelper_STCKE,
13154 mkIRExprVec_1(mkexpr(op2addr)));
13155 d->mFx = Ifx_Write;
13156 d->mAddr = mkexpr(op2addr);
13157 d->mSize = 16;
13158 stmt(IRStmt_Dirty(d));
13159 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
13160 mkexpr(cc), mkU64(0), mkU64(0));
13161 return "stcke";
13162}
13163
florian55085f82012-11-21 00:36:55 +000013164static const HChar *
florian933065d2011-07-11 01:48:02 +000013165s390_irgen_STFLE(IRTemp op2addr)
13166{
florian4e0083e2012-08-26 03:41:56 +000013167 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000013168 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000013169 return "stfle";
13170 }
13171
florian933065d2011-07-11 01:48:02 +000013172 IRDirty *d;
13173 IRTemp cc = newTemp(Ity_I64);
13174
Elliott Hughesed398002017-06-21 14:41:24 -070013175 /* IRExpr_GSPTR() => Need to pass pointer to guest state to helper */
florian933065d2011-07-11 01:48:02 +000013176 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
13177 &s390x_dirtyhelper_STFLE,
Elliott Hughesed398002017-06-21 14:41:24 -070013178 mkIRExprVec_2(IRExpr_GSPTR(), mkexpr(op2addr)));
florian933065d2011-07-11 01:48:02 +000013179
sewardjc9069f22012-06-01 16:09:50 +000013180 d->nFxState = 1;
13181 vex_bzero(&d->fxState, sizeof(d->fxState));
13182
florian933065d2011-07-11 01:48:02 +000013183 d->fxState[0].fx = Ifx_Modify; /* read then write */
13184 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
13185 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000013186
13187 d->mAddr = mkexpr(op2addr);
13188 /* Pretend all double words are written */
13189 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
13190 d->mFx = Ifx_Write;
13191
13192 stmt(IRStmt_Dirty(d));
13193
13194 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
13195
13196 return "stfle";
13197}
13198
florian55085f82012-11-21 00:36:55 +000013199static const HChar *
floriana4384a32011-08-11 16:58:45 +000013200s390_irgen_CKSM(UChar r1,UChar r2)
13201{
13202 IRTemp addr = newTemp(Ity_I64);
13203 IRTemp op = newTemp(Ity_I32);
13204 IRTemp len = newTemp(Ity_I64);
13205 IRTemp oldval = newTemp(Ity_I32);
13206 IRTemp mask = newTemp(Ity_I32);
13207 IRTemp newop = newTemp(Ity_I32);
13208 IRTemp result = newTemp(Ity_I32);
13209 IRTemp result1 = newTemp(Ity_I32);
13210 IRTemp inc = newTemp(Ity_I64);
13211
13212 assign(oldval, get_gpr_w1(r1));
13213 assign(addr, get_gpr_dw0(r2));
13214 assign(len, get_gpr_dw0(r2+1));
13215
13216 /* Condition code is always zero. */
13217 s390_cc_set(0);
13218
13219 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000013220 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000013221
13222 /* Assiging the increment variable to adjust address and length
13223 later on. */
13224 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
13225 mkexpr(len), mkU64(4)));
13226
13227 /* If length < 4 the final 4-byte 2nd operand value is computed by
13228 appending the remaining bytes to the right with 0. This is done
13229 by AND'ing the 4 bytes loaded from memory with an appropriate
13230 mask. If length >= 4, that mask is simply 0xffffffff. */
13231
13232 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
13233 /* Mask computation when len < 4:
13234 0xffffffff << (32 - (len % 4)*8) */
13235 binop(Iop_Shl32, mkU32(0xffffffff),
13236 unop(Iop_32to8,
13237 binop(Iop_Sub32, mkU32(32),
13238 binop(Iop_Shl32,
13239 unop(Iop_64to32,
13240 binop(Iop_And64,
13241 mkexpr(len), mkU64(3))),
13242 mkU8(3))))),
13243 mkU32(0xffffffff)));
13244
13245 assign(op, load(Ity_I32, mkexpr(addr)));
13246 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
13247 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
13248
13249 /* Checking for carry */
13250 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
13251 binop(Iop_Add32, mkexpr(result), mkU32(1)),
13252 mkexpr(result)));
13253
13254 put_gpr_w1(r1, mkexpr(result1));
13255 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
13256 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
13257
florian6820ba52012-07-26 02:01:50 +000013258 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000013259
13260 return "cksm";
13261}
13262
florian55085f82012-11-21 00:36:55 +000013263static const HChar *
florian9af37692012-01-15 21:01:16 +000013264s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
13265{
13266 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13267 src_addr = newTemp(Ity_I64);
13268 des_addr = newTemp(Ity_I64);
13269 tab_addr = newTemp(Ity_I64);
13270 test_byte = newTemp(Ity_I8);
13271 src_len = newTemp(Ity_I64);
13272
13273 assign(src_addr, get_gpr_dw0(r2));
13274 assign(des_addr, get_gpr_dw0(r1));
13275 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000013276 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000013277 assign(test_byte, get_gpr_b7(0));
13278
13279 IRTemp op = newTemp(Ity_I8);
13280 IRTemp op1 = newTemp(Ity_I8);
13281 IRTemp result = newTemp(Ity_I64);
13282
13283 /* End of source string? We're done; proceed to next insn */
13284 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013285 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000013286
13287 /* Load character from source string, index translation table and
13288 store translated character in op1. */
13289 assign(op, load(Ity_I8, mkexpr(src_addr)));
13290
13291 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13292 mkexpr(tab_addr)));
13293 assign(op1, load(Ity_I8, mkexpr(result)));
13294
13295 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13296 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013297 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000013298 }
13299 store(get_gpr_dw0(r1), mkexpr(op1));
13300
13301 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13302 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13303 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13304
florian6820ba52012-07-26 02:01:50 +000013305 iterate();
florian9af37692012-01-15 21:01:16 +000013306
13307 return "troo";
13308}
13309
florian55085f82012-11-21 00:36:55 +000013310static const HChar *
florian730448f2012-02-04 17:07:07 +000013311s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
13312{
13313 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13314 src_addr = newTemp(Ity_I64);
13315 des_addr = newTemp(Ity_I64);
13316 tab_addr = newTemp(Ity_I64);
13317 test_byte = newTemp(Ity_I8);
13318 src_len = newTemp(Ity_I64);
13319
13320 assign(src_addr, get_gpr_dw0(r2));
13321 assign(des_addr, get_gpr_dw0(r1));
13322 assign(tab_addr, get_gpr_dw0(1));
13323 assign(src_len, get_gpr_dw0(r1+1));
13324 assign(test_byte, get_gpr_b7(0));
13325
13326 IRTemp op = newTemp(Ity_I16);
13327 IRTemp op1 = newTemp(Ity_I8);
13328 IRTemp result = newTemp(Ity_I64);
13329
13330 /* End of source string? We're done; proceed to next insn */
13331 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013332 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013333
13334 /* Load character from source string, index translation table and
13335 store translated character in op1. */
13336 assign(op, load(Ity_I16, mkexpr(src_addr)));
13337
13338 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13339 mkexpr(tab_addr)));
13340
13341 assign(op1, load(Ity_I8, mkexpr(result)));
13342
13343 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13344 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013345 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013346 }
13347 store(get_gpr_dw0(r1), mkexpr(op1));
13348
13349 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13350 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13351 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13352
florian6820ba52012-07-26 02:01:50 +000013353 iterate();
florian730448f2012-02-04 17:07:07 +000013354
13355 return "trto";
13356}
13357
florian55085f82012-11-21 00:36:55 +000013358static const HChar *
florian730448f2012-02-04 17:07:07 +000013359s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
13360{
13361 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13362 src_addr = newTemp(Ity_I64);
13363 des_addr = newTemp(Ity_I64);
13364 tab_addr = newTemp(Ity_I64);
13365 test_byte = newTemp(Ity_I16);
13366 src_len = newTemp(Ity_I64);
13367
13368 assign(src_addr, get_gpr_dw0(r2));
13369 assign(des_addr, get_gpr_dw0(r1));
13370 assign(tab_addr, get_gpr_dw0(1));
13371 assign(src_len, get_gpr_dw0(r1+1));
13372 assign(test_byte, get_gpr_hw3(0));
13373
13374 IRTemp op = newTemp(Ity_I8);
13375 IRTemp op1 = newTemp(Ity_I16);
13376 IRTemp result = newTemp(Ity_I64);
13377
13378 /* End of source string? We're done; proceed to next insn */
13379 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013380 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013381
13382 /* Load character from source string, index translation table and
13383 store translated character in op1. */
13384 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
13385
13386 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13387 mkexpr(tab_addr)));
13388 assign(op1, load(Ity_I16, mkexpr(result)));
13389
13390 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13391 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013392 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013393 }
13394 store(get_gpr_dw0(r1), mkexpr(op1));
13395
13396 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13397 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13398 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13399
florian6820ba52012-07-26 02:01:50 +000013400 iterate();
florian730448f2012-02-04 17:07:07 +000013401
13402 return "trot";
13403}
13404
florian55085f82012-11-21 00:36:55 +000013405static const HChar *
florian730448f2012-02-04 17:07:07 +000013406s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
13407{
13408 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13409 src_addr = newTemp(Ity_I64);
13410 des_addr = newTemp(Ity_I64);
13411 tab_addr = newTemp(Ity_I64);
13412 test_byte = newTemp(Ity_I16);
13413 src_len = newTemp(Ity_I64);
13414
13415 assign(src_addr, get_gpr_dw0(r2));
13416 assign(des_addr, get_gpr_dw0(r1));
13417 assign(tab_addr, get_gpr_dw0(1));
13418 assign(src_len, get_gpr_dw0(r1+1));
13419 assign(test_byte, get_gpr_hw3(0));
13420
13421 IRTemp op = newTemp(Ity_I16);
13422 IRTemp op1 = newTemp(Ity_I16);
13423 IRTemp result = newTemp(Ity_I64);
13424
13425 /* End of source string? We're done; proceed to next insn */
13426 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013427 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013428
13429 /* Load character from source string, index translation table and
13430 store translated character in op1. */
13431 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
13432
13433 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13434 mkexpr(tab_addr)));
13435 assign(op1, load(Ity_I16, mkexpr(result)));
13436
13437 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13438 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013439 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013440 }
13441
13442 store(get_gpr_dw0(r1), mkexpr(op1));
13443
13444 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13445 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13446 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13447
florian6820ba52012-07-26 02:01:50 +000013448 iterate();
florian730448f2012-02-04 17:07:07 +000013449
13450 return "trtt";
13451}
13452
florian55085f82012-11-21 00:36:55 +000013453static const HChar *
florian730448f2012-02-04 17:07:07 +000013454s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13455{
florianf87d4fb2012-05-05 02:55:24 +000013456 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000013457
florianf87d4fb2012-05-05 02:55:24 +000013458 assign(len, mkU64(length));
13459 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000013460
13461 return "tr";
13462}
13463
florian55085f82012-11-21 00:36:55 +000013464static const HChar *
florian730448f2012-02-04 17:07:07 +000013465s390_irgen_TRE(UChar r1,UChar r2)
13466{
13467 IRTemp src_addr, tab_addr, src_len, test_byte;
13468 src_addr = newTemp(Ity_I64);
13469 tab_addr = newTemp(Ity_I64);
13470 src_len = newTemp(Ity_I64);
13471 test_byte = newTemp(Ity_I8);
13472
13473 assign(src_addr, get_gpr_dw0(r1));
13474 assign(src_len, get_gpr_dw0(r1+1));
13475 assign(tab_addr, get_gpr_dw0(r2));
13476 assign(test_byte, get_gpr_b7(0));
13477
13478 IRTemp op = newTemp(Ity_I8);
13479 IRTemp op1 = newTemp(Ity_I8);
13480 IRTemp result = newTemp(Ity_I64);
13481
13482 /* End of source string? We're done; proceed to next insn */
13483 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013484 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013485
13486 /* Load character from source string and compare with test byte */
13487 assign(op, load(Ity_I8, mkexpr(src_addr)));
13488
13489 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013490 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013491
13492 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13493 mkexpr(tab_addr)));
13494
13495 assign(op1, load(Ity_I8, mkexpr(result)));
13496
13497 store(get_gpr_dw0(r1), mkexpr(op1));
13498 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13499 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13500
florian6820ba52012-07-26 02:01:50 +000013501 iterate();
florian730448f2012-02-04 17:07:07 +000013502
13503 return "tre";
13504}
13505
floriana0100c92012-07-20 00:06:35 +000013506static IRExpr *
13507s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13508{
13509 IRExpr **args, *call;
13510 args = mkIRExprVec_2(srcval, low_surrogate);
13511 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13512 "s390_do_cu21", &s390_do_cu21, args);
13513
13514 /* Nothing is excluded from definedness checking. */
13515 call->Iex.CCall.cee->mcx_mask = 0;
13516
13517 return call;
13518}
13519
florian55085f82012-11-21 00:36:55 +000013520static const HChar *
floriana0100c92012-07-20 00:06:35 +000013521s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13522{
13523 IRTemp addr1 = newTemp(Ity_I64);
13524 IRTemp addr2 = newTemp(Ity_I64);
13525 IRTemp len1 = newTemp(Ity_I64);
13526 IRTemp len2 = newTemp(Ity_I64);
13527
13528 assign(addr1, get_gpr_dw0(r1));
13529 assign(addr2, get_gpr_dw0(r2));
13530 assign(len1, get_gpr_dw0(r1 + 1));
13531 assign(len2, get_gpr_dw0(r2 + 1));
13532
13533 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13534 there are less than 2 bytes left, then the 2nd operand is exhausted
13535 and we're done here. cc = 0 */
13536 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013537 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000013538
13539 /* There are at least two bytes there. Read them. */
13540 IRTemp srcval = newTemp(Ity_I32);
13541 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13542
13543 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13544 inside the interval [0xd800 - 0xdbff] */
13545 IRTemp is_high_surrogate = newTemp(Ity_I32);
13546 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13547 mkU32(1), mkU32(0));
13548 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13549 mkU32(1), mkU32(0));
13550 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13551
13552 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13553 then the 2nd operand is exhausted and we're done here. cc = 0 */
13554 IRExpr *not_enough_bytes =
13555 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13556
florian6820ba52012-07-26 02:01:50 +000013557 next_insn_if(binop(Iop_CmpEQ32,
13558 binop(Iop_And32, mkexpr(is_high_surrogate),
13559 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000013560
13561 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13562 surrogate, read the next two bytes (low surrogate). */
13563 IRTemp low_surrogate = newTemp(Ity_I32);
13564 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13565
13566 assign(low_surrogate,
13567 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13568 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13569 mkU32(0))); // any value is fine; it will not be used
13570
13571 /* Call the helper */
13572 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013573 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13574 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000013575
13576 /* Before we can test whether the 1st operand is exhausted we need to
13577 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13578 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13579 IRExpr *invalid_low_surrogate =
13580 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13581
13582 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013583 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000013584 }
13585
13586 /* Now test whether the 1st operand is exhausted */
13587 IRTemp num_bytes = newTemp(Ity_I64);
13588 assign(num_bytes, binop(Iop_And64,
13589 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13590 mkU64(0xff)));
13591 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013592 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000013593
13594 /* Extract the bytes to be stored at addr1 */
13595 IRTemp data = newTemp(Ity_I64);
13596 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13597
13598 /* To store the bytes construct 4 dirty helper calls. The helper calls
13599 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13600 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013601 UInt i;
floriana0100c92012-07-20 00:06:35 +000013602 for (i = 1; i <= 4; ++i) {
13603 IRDirty *d;
13604
13605 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13606 &s390x_dirtyhelper_CUxy,
13607 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13608 mkexpr(num_bytes)));
13609 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13610 d->mFx = Ifx_Write;
13611 d->mAddr = mkexpr(addr1);
13612 d->mSize = i;
13613 stmt(IRStmt_Dirty(d));
13614 }
13615
13616 /* Update source address and length */
13617 IRTemp num_src_bytes = newTemp(Ity_I64);
13618 assign(num_src_bytes,
13619 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13620 mkU64(4), mkU64(2)));
13621 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13622 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13623
13624 /* Update destination address and length */
13625 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13626 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13627
florian6820ba52012-07-26 02:01:50 +000013628 iterate();
floriana0100c92012-07-20 00:06:35 +000013629
13630 return "cu21";
13631}
13632
florian2a415a12012-07-21 17:41:36 +000013633static IRExpr *
13634s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13635{
13636 IRExpr **args, *call;
13637 args = mkIRExprVec_2(srcval, low_surrogate);
13638 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13639 "s390_do_cu24", &s390_do_cu24, args);
13640
13641 /* Nothing is excluded from definedness checking. */
13642 call->Iex.CCall.cee->mcx_mask = 0;
13643
13644 return call;
13645}
13646
florian55085f82012-11-21 00:36:55 +000013647static const HChar *
florian2a415a12012-07-21 17:41:36 +000013648s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13649{
13650 IRTemp addr1 = newTemp(Ity_I64);
13651 IRTemp addr2 = newTemp(Ity_I64);
13652 IRTemp len1 = newTemp(Ity_I64);
13653 IRTemp len2 = newTemp(Ity_I64);
13654
13655 assign(addr1, get_gpr_dw0(r1));
13656 assign(addr2, get_gpr_dw0(r2));
13657 assign(len1, get_gpr_dw0(r1 + 1));
13658 assign(len2, get_gpr_dw0(r2 + 1));
13659
13660 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13661 there are less than 2 bytes left, then the 2nd operand is exhausted
13662 and we're done here. cc = 0 */
13663 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013664 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000013665
13666 /* There are at least two bytes there. Read them. */
13667 IRTemp srcval = newTemp(Ity_I32);
13668 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13669
13670 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13671 inside the interval [0xd800 - 0xdbff] */
13672 IRTemp is_high_surrogate = newTemp(Ity_I32);
13673 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13674 mkU32(1), mkU32(0));
13675 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13676 mkU32(1), mkU32(0));
13677 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13678
13679 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13680 then the 2nd operand is exhausted and we're done here. cc = 0 */
13681 IRExpr *not_enough_bytes =
13682 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13683
florian6820ba52012-07-26 02:01:50 +000013684 next_insn_if(binop(Iop_CmpEQ32,
13685 binop(Iop_And32, mkexpr(is_high_surrogate),
13686 not_enough_bytes),
13687 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000013688
13689 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13690 surrogate, read the next two bytes (low surrogate). */
13691 IRTemp low_surrogate = newTemp(Ity_I32);
13692 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13693
13694 assign(low_surrogate,
13695 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13696 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13697 mkU32(0))); // any value is fine; it will not be used
13698
13699 /* Call the helper */
13700 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013701 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13702 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000013703
13704 /* Before we can test whether the 1st operand is exhausted we need to
13705 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13706 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13707 IRExpr *invalid_low_surrogate =
13708 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13709
13710 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013711 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000013712 }
13713
13714 /* Now test whether the 1st operand is exhausted */
13715 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013716 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000013717
13718 /* Extract the bytes to be stored at addr1 */
13719 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13720
13721 store(mkexpr(addr1), data);
13722
13723 /* Update source address and length */
13724 IRTemp num_src_bytes = newTemp(Ity_I64);
13725 assign(num_src_bytes,
13726 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13727 mkU64(4), mkU64(2)));
13728 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13729 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13730
13731 /* Update destination address and length */
13732 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13733 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
13734
florian6820ba52012-07-26 02:01:50 +000013735 iterate();
florian2a415a12012-07-21 17:41:36 +000013736
13737 return "cu24";
13738}
floriana4384a32011-08-11 16:58:45 +000013739
florian956194b2012-07-28 22:18:32 +000013740static IRExpr *
13741s390_call_cu42(IRExpr *srcval)
13742{
13743 IRExpr **args, *call;
13744 args = mkIRExprVec_1(srcval);
13745 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13746 "s390_do_cu42", &s390_do_cu42, args);
13747
13748 /* Nothing is excluded from definedness checking. */
13749 call->Iex.CCall.cee->mcx_mask = 0;
13750
13751 return call;
13752}
13753
florian55085f82012-11-21 00:36:55 +000013754static const HChar *
florian956194b2012-07-28 22:18:32 +000013755s390_irgen_CU42(UChar r1, UChar r2)
13756{
13757 IRTemp addr1 = newTemp(Ity_I64);
13758 IRTemp addr2 = newTemp(Ity_I64);
13759 IRTemp len1 = newTemp(Ity_I64);
13760 IRTemp len2 = newTemp(Ity_I64);
13761
13762 assign(addr1, get_gpr_dw0(r1));
13763 assign(addr2, get_gpr_dw0(r2));
13764 assign(len1, get_gpr_dw0(r1 + 1));
13765 assign(len2, get_gpr_dw0(r2 + 1));
13766
13767 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13768 there are less than 4 bytes left, then the 2nd operand is exhausted
13769 and we're done here. cc = 0 */
13770 s390_cc_set(0);
13771 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13772
13773 /* Read the 2nd operand. */
13774 IRTemp srcval = newTemp(Ity_I32);
13775 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13776
13777 /* Call the helper */
13778 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013779 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000013780
13781 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13782 cc=2 outranks cc=1 (1st operand exhausted) */
13783 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13784
13785 s390_cc_set(2);
13786 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13787
13788 /* Now test whether the 1st operand is exhausted */
13789 IRTemp num_bytes = newTemp(Ity_I64);
13790 assign(num_bytes, binop(Iop_And64,
13791 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13792 mkU64(0xff)));
13793 s390_cc_set(1);
13794 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13795
13796 /* Extract the bytes to be stored at addr1 */
13797 IRTemp data = newTemp(Ity_I64);
13798 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13799
13800 /* To store the bytes construct 2 dirty helper calls. The helper calls
13801 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13802 that only one of them will be called at runtime. */
13803
13804 Int i;
13805 for (i = 2; i <= 4; ++i) {
13806 IRDirty *d;
13807
13808 if (i == 3) continue; // skip this one
13809
13810 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13811 &s390x_dirtyhelper_CUxy,
13812 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13813 mkexpr(num_bytes)));
13814 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13815 d->mFx = Ifx_Write;
13816 d->mAddr = mkexpr(addr1);
13817 d->mSize = i;
13818 stmt(IRStmt_Dirty(d));
13819 }
13820
13821 /* Update source address and length */
13822 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13823 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13824
13825 /* Update destination address and length */
13826 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13827 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13828
13829 iterate();
13830
13831 return "cu42";
13832}
13833
florian6d9b9b22012-08-03 18:35:39 +000013834static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000013835s390_call_cu41(IRExpr *srcval)
13836{
13837 IRExpr **args, *call;
13838 args = mkIRExprVec_1(srcval);
13839 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13840 "s390_do_cu41", &s390_do_cu41, args);
13841
13842 /* Nothing is excluded from definedness checking. */
13843 call->Iex.CCall.cee->mcx_mask = 0;
13844
13845 return call;
13846}
13847
florian55085f82012-11-21 00:36:55 +000013848static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013849s390_irgen_CU41(UChar r1, UChar r2)
13850{
13851 IRTemp addr1 = newTemp(Ity_I64);
13852 IRTemp addr2 = newTemp(Ity_I64);
13853 IRTemp len1 = newTemp(Ity_I64);
13854 IRTemp len2 = newTemp(Ity_I64);
13855
13856 assign(addr1, get_gpr_dw0(r1));
13857 assign(addr2, get_gpr_dw0(r2));
13858 assign(len1, get_gpr_dw0(r1 + 1));
13859 assign(len2, get_gpr_dw0(r2 + 1));
13860
13861 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13862 there are less than 4 bytes left, then the 2nd operand is exhausted
13863 and we're done here. cc = 0 */
13864 s390_cc_set(0);
13865 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13866
13867 /* Read the 2nd operand. */
13868 IRTemp srcval = newTemp(Ity_I32);
13869 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13870
13871 /* Call the helper */
13872 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013873 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013874
13875 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13876 cc=2 outranks cc=1 (1st operand exhausted) */
13877 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13878
13879 s390_cc_set(2);
13880 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13881
13882 /* Now test whether the 1st operand is exhausted */
13883 IRTemp num_bytes = newTemp(Ity_I64);
13884 assign(num_bytes, binop(Iop_And64,
13885 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13886 mkU64(0xff)));
13887 s390_cc_set(1);
13888 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13889
13890 /* Extract the bytes to be stored at addr1 */
13891 IRTemp data = newTemp(Ity_I64);
13892 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13893
13894 /* To store the bytes construct 4 dirty helper calls. The helper calls
13895 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13896 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013897 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013898 for (i = 1; i <= 4; ++i) {
13899 IRDirty *d;
13900
13901 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13902 &s390x_dirtyhelper_CUxy,
13903 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13904 mkexpr(num_bytes)));
13905 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13906 d->mFx = Ifx_Write;
13907 d->mAddr = mkexpr(addr1);
13908 d->mSize = i;
13909 stmt(IRStmt_Dirty(d));
13910 }
13911
13912 /* Update source address and length */
13913 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13914 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13915
13916 /* Update destination address and length */
13917 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13918 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13919
13920 iterate();
13921
13922 return "cu41";
13923}
13924
13925static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013926s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013927{
13928 IRExpr **args, *call;
13929 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013930 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13931 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013932
13933 /* Nothing is excluded from definedness checking. */
13934 call->Iex.CCall.cee->mcx_mask = 0;
13935
13936 return call;
13937}
13938
13939static IRExpr *
13940s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13941 IRExpr *byte4, IRExpr *stuff)
13942{
13943 IRExpr **args, *call;
13944 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13945 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13946 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13947
13948 /* Nothing is excluded from definedness checking. */
13949 call->Iex.CCall.cee->mcx_mask = 0;
13950
13951 return call;
13952}
13953
florian3f8a96a2012-08-05 02:59:55 +000013954static IRExpr *
13955s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13956 IRExpr *byte4, IRExpr *stuff)
13957{
13958 IRExpr **args, *call;
13959 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13960 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13961 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13962
13963 /* Nothing is excluded from definedness checking. */
13964 call->Iex.CCall.cee->mcx_mask = 0;
13965
13966 return call;
13967}
13968
13969static void
13970s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013971{
13972 IRTemp addr1 = newTemp(Ity_I64);
13973 IRTemp addr2 = newTemp(Ity_I64);
13974 IRTemp len1 = newTemp(Ity_I64);
13975 IRTemp len2 = newTemp(Ity_I64);
13976
13977 assign(addr1, get_gpr_dw0(r1));
13978 assign(addr2, get_gpr_dw0(r2));
13979 assign(len1, get_gpr_dw0(r1 + 1));
13980 assign(len2, get_gpr_dw0(r2 + 1));
13981
13982 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13983
13984 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13985 there is less than 1 byte left, then the 2nd operand is exhausted
13986 and we're done here. cc = 0 */
13987 s390_cc_set(0);
13988 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13989
13990 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013991 IRTemp byte1 = newTemp(Ity_I64);
13992 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013993
13994 /* Call the helper to get number of bytes and invalid byte indicator */
13995 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013996 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013997 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013998
13999 /* Check for invalid 1st byte */
14000 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
14001 s390_cc_set(2);
14002 next_insn_if(is_invalid);
14003
14004 /* How many bytes do we have to read? */
14005 IRTemp num_src_bytes = newTemp(Ity_I64);
14006 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
14007
14008 /* Now test whether the 2nd operand is exhausted */
14009 s390_cc_set(0);
14010 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
14011
14012 /* Read the remaining bytes */
14013 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
14014
14015 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
14016 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000014017 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000014018 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
14019 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000014020 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000014021 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
14022 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000014023 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000014024
14025 /* Call the helper to get the converted value and invalid byte indicator.
14026 We can pass at most 5 arguments; therefore some encoding is needed
14027 here */
14028 IRExpr *stuff = binop(Iop_Or64,
14029 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
14030 mkU64(extended_checking));
14031 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000014032
14033 if (is_cu12) {
14034 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
14035 byte4, stuff));
14036 } else {
14037 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
14038 byte4, stuff));
14039 }
florian6d9b9b22012-08-03 18:35:39 +000014040
14041 /* Check for invalid character */
14042 s390_cc_set(2);
14043 is_invalid = unop(Iop_64to1, mkexpr(retval2));
14044 next_insn_if(is_invalid);
14045
14046 /* Now test whether the 1st operand is exhausted */
14047 IRTemp num_bytes = newTemp(Ity_I64);
14048 assign(num_bytes, binop(Iop_And64,
14049 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
14050 mkU64(0xff)));
14051 s390_cc_set(1);
14052 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
14053
14054 /* Extract the bytes to be stored at addr1 */
14055 IRTemp data = newTemp(Ity_I64);
14056 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
14057
florian3f8a96a2012-08-05 02:59:55 +000014058 if (is_cu12) {
14059 /* To store the bytes construct 2 dirty helper calls. The helper calls
14060 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
14061 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000014062
florian3f8a96a2012-08-05 02:59:55 +000014063 Int i;
14064 for (i = 2; i <= 4; ++i) {
14065 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000014066
florian3f8a96a2012-08-05 02:59:55 +000014067 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000014068
florian3f8a96a2012-08-05 02:59:55 +000014069 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
14070 &s390x_dirtyhelper_CUxy,
14071 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
14072 mkexpr(num_bytes)));
14073 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
14074 d->mFx = Ifx_Write;
14075 d->mAddr = mkexpr(addr1);
14076 d->mSize = i;
14077 stmt(IRStmt_Dirty(d));
14078 }
14079 } else {
14080 // cu14
14081 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000014082 }
14083
14084 /* Update source address and length */
14085 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
14086 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
14087
14088 /* Update destination address and length */
14089 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
14090 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
14091
14092 iterate();
florian3f8a96a2012-08-05 02:59:55 +000014093}
14094
florian55085f82012-11-21 00:36:55 +000014095static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000014096s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
14097{
14098 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000014099
14100 return "cu12";
14101}
14102
florian55085f82012-11-21 00:36:55 +000014103static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000014104s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
14105{
14106 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
14107
14108 return "cu14";
14109}
14110
florian8c88cb62012-08-26 18:58:13 +000014111static IRExpr *
14112s390_call_ecag(IRExpr *op2addr)
14113{
14114 IRExpr **args, *call;
14115
14116 args = mkIRExprVec_1(op2addr);
14117 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
14118 "s390_do_ecag", &s390_do_ecag, args);
14119
14120 /* Nothing is excluded from definedness checking. */
14121 call->Iex.CCall.cee->mcx_mask = 0;
14122
14123 return call;
14124}
14125
florian55085f82012-11-21 00:36:55 +000014126static const HChar *
floriand2129202012-09-01 20:01:39 +000014127s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000014128{
14129 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000014130 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000014131 } else {
14132 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
14133 }
14134
14135 return "ecag";
14136}
14137
14138
florianb7def222012-12-04 04:45:32 +000014139/* New insns are added here.
14140 If an insn is contingent on a facility being installed also
14141 check whether the list of supported facilities in function
14142 s390x_dirtyhelper_STFLE needs updating */
14143
sewardj2019a972011-03-07 16:04:07 +000014144/*------------------------------------------------------------*/
14145/*--- Build IR for special instructions ---*/
14146/*------------------------------------------------------------*/
14147
florianb4df7682011-07-05 02:09:01 +000014148static void
sewardj2019a972011-03-07 16:04:07 +000014149s390_irgen_client_request(void)
14150{
14151 if (0)
14152 vex_printf("%%R3 = client_request ( %%R2 )\n");
14153
florianf9e1ed72012-04-17 02:41:56 +000014154 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
14155 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000014156
florianf9e1ed72012-04-17 02:41:56 +000014157 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000014158 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014159
14160 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000014161}
14162
florianb4df7682011-07-05 02:09:01 +000014163static void
sewardj2019a972011-03-07 16:04:07 +000014164s390_irgen_guest_NRADDR(void)
14165{
14166 if (0)
14167 vex_printf("%%R3 = guest_NRADDR\n");
14168
floriane88b3c92011-07-05 02:48:39 +000014169 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000014170}
14171
florianb4df7682011-07-05 02:09:01 +000014172static void
sewardj2019a972011-03-07 16:04:07 +000014173s390_irgen_call_noredir(void)
14174{
florianf9e1ed72012-04-17 02:41:56 +000014175 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
14176 + S390_SPECIAL_OP_SIZE;
14177
sewardj2019a972011-03-07 16:04:07 +000014178 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000014179 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000014180
14181 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000014182 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000014183
14184 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014185 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000014186}
14187
14188/* Force proper alignment for the structures below. */
14189#pragma pack(1)
14190
14191
14192static s390_decode_t
florian8462d112014-09-24 15:18:09 +000014193s390_decode_2byte_and_irgen(const UChar *bytes)
sewardj2019a972011-03-07 16:04:07 +000014194{
14195 typedef union {
14196 struct {
14197 unsigned int op : 16;
14198 } E;
14199 struct {
14200 unsigned int op : 8;
14201 unsigned int i : 8;
14202 } I;
14203 struct {
14204 unsigned int op : 8;
14205 unsigned int r1 : 4;
14206 unsigned int r2 : 4;
14207 } RR;
14208 } formats;
14209 union {
14210 formats fmt;
14211 UShort value;
14212 } ovl;
14213
14214 vassert(sizeof(formats) == 2);
14215
florianffbd84d2012-12-09 02:06:29 +000014216 ((UChar *)(&ovl.value))[0] = bytes[0];
14217 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000014218
14219 switch (ovl.value & 0xffff) {
14220 case 0x0101: /* PR */ goto unimplemented;
14221 case 0x0102: /* UPT */ goto unimplemented;
14222 case 0x0104: /* PTFF */ goto unimplemented;
14223 case 0x0107: /* SCKPF */ goto unimplemented;
florian78d5ef72013-05-11 15:02:58 +000014224 case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014225 case 0x010b: /* TAM */ goto unimplemented;
14226 case 0x010c: /* SAM24 */ goto unimplemented;
14227 case 0x010d: /* SAM31 */ goto unimplemented;
14228 case 0x010e: /* SAM64 */ goto unimplemented;
14229 case 0x01ff: /* TRAP2 */ goto unimplemented;
14230 }
14231
14232 switch ((ovl.value & 0xff00) >> 8) {
14233 case 0x04: /* SPM */ goto unimplemented;
14234 case 0x05: /* BALR */ goto unimplemented;
14235 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14236 goto ok;
14237 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14238 goto ok;
14239 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
14240 case 0x0b: /* BSM */ goto unimplemented;
14241 case 0x0c: /* BASSM */ goto unimplemented;
14242 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14243 goto ok;
florianb0c9a132011-09-08 15:37:39 +000014244 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14245 goto ok;
14246 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14247 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014248 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14249 goto ok;
14250 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14251 goto ok;
14252 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14253 goto ok;
14254 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14255 goto ok;
14256 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14257 goto ok;
14258 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14259 goto ok;
14260 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14261 goto ok;
14262 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14263 goto ok;
14264 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14265 goto ok;
14266 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14267 goto ok;
14268 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14269 goto ok;
14270 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14271 goto ok;
14272 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14273 goto ok;
14274 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14275 goto ok;
14276 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14277 goto ok;
14278 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14279 goto ok;
14280 case 0x20: /* LPDR */ goto unimplemented;
14281 case 0x21: /* LNDR */ goto unimplemented;
14282 case 0x22: /* LTDR */ goto unimplemented;
14283 case 0x23: /* LCDR */ goto unimplemented;
14284 case 0x24: /* HDR */ goto unimplemented;
14285 case 0x25: /* LDXR */ goto unimplemented;
14286 case 0x26: /* MXR */ goto unimplemented;
14287 case 0x27: /* MXDR */ goto unimplemented;
14288 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14289 goto ok;
14290 case 0x29: /* CDR */ goto unimplemented;
14291 case 0x2a: /* ADR */ goto unimplemented;
14292 case 0x2b: /* SDR */ goto unimplemented;
14293 case 0x2c: /* MDR */ goto unimplemented;
14294 case 0x2d: /* DDR */ goto unimplemented;
14295 case 0x2e: /* AWR */ goto unimplemented;
14296 case 0x2f: /* SWR */ goto unimplemented;
14297 case 0x30: /* LPER */ goto unimplemented;
14298 case 0x31: /* LNER */ goto unimplemented;
14299 case 0x32: /* LTER */ goto unimplemented;
14300 case 0x33: /* LCER */ goto unimplemented;
14301 case 0x34: /* HER */ goto unimplemented;
14302 case 0x35: /* LEDR */ goto unimplemented;
14303 case 0x36: /* AXR */ goto unimplemented;
14304 case 0x37: /* SXR */ goto unimplemented;
14305 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14306 goto ok;
14307 case 0x39: /* CER */ goto unimplemented;
14308 case 0x3a: /* AER */ goto unimplemented;
14309 case 0x3b: /* SER */ goto unimplemented;
14310 case 0x3c: /* MDER */ goto unimplemented;
14311 case 0x3d: /* DER */ goto unimplemented;
14312 case 0x3e: /* AUR */ goto unimplemented;
14313 case 0x3f: /* SUR */ goto unimplemented;
14314 }
14315
14316 return S390_DECODE_UNKNOWN_INSN;
14317
14318ok:
14319 return S390_DECODE_OK;
14320
14321unimplemented:
14322 return S390_DECODE_UNIMPLEMENTED_INSN;
14323}
14324
14325static s390_decode_t
florian8462d112014-09-24 15:18:09 +000014326s390_decode_4byte_and_irgen(const UChar *bytes)
sewardj2019a972011-03-07 16:04:07 +000014327{
14328 typedef union {
14329 struct {
14330 unsigned int op1 : 8;
14331 unsigned int r1 : 4;
14332 unsigned int op2 : 4;
14333 unsigned int i2 : 16;
14334 } RI;
14335 struct {
14336 unsigned int op : 16;
14337 unsigned int : 8;
14338 unsigned int r1 : 4;
14339 unsigned int r2 : 4;
14340 } RRE;
14341 struct {
14342 unsigned int op : 16;
14343 unsigned int r1 : 4;
14344 unsigned int : 4;
14345 unsigned int r3 : 4;
14346 unsigned int r2 : 4;
14347 } RRF;
14348 struct {
14349 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000014350 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000014351 unsigned int m4 : 4;
14352 unsigned int r1 : 4;
14353 unsigned int r2 : 4;
14354 } RRF2;
14355 struct {
14356 unsigned int op : 16;
14357 unsigned int r3 : 4;
14358 unsigned int : 4;
14359 unsigned int r1 : 4;
14360 unsigned int r2 : 4;
14361 } RRF3;
14362 struct {
14363 unsigned int op : 16;
14364 unsigned int r3 : 4;
14365 unsigned int : 4;
14366 unsigned int r1 : 4;
14367 unsigned int r2 : 4;
14368 } RRR;
14369 struct {
14370 unsigned int op : 16;
14371 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000014372 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000014373 unsigned int r1 : 4;
14374 unsigned int r2 : 4;
14375 } RRF4;
14376 struct {
floriane38f6412012-12-21 17:32:12 +000014377 unsigned int op : 16;
14378 unsigned int : 4;
14379 unsigned int m4 : 4;
14380 unsigned int r1 : 4;
14381 unsigned int r2 : 4;
14382 } RRF5;
14383 struct {
sewardj2019a972011-03-07 16:04:07 +000014384 unsigned int op : 8;
14385 unsigned int r1 : 4;
14386 unsigned int r3 : 4;
14387 unsigned int b2 : 4;
14388 unsigned int d2 : 12;
14389 } RS;
14390 struct {
14391 unsigned int op : 8;
14392 unsigned int r1 : 4;
14393 unsigned int r3 : 4;
14394 unsigned int i2 : 16;
14395 } RSI;
14396 struct {
14397 unsigned int op : 8;
14398 unsigned int r1 : 4;
14399 unsigned int x2 : 4;
14400 unsigned int b2 : 4;
14401 unsigned int d2 : 12;
14402 } RX;
14403 struct {
14404 unsigned int op : 16;
14405 unsigned int b2 : 4;
14406 unsigned int d2 : 12;
14407 } S;
14408 struct {
14409 unsigned int op : 8;
14410 unsigned int i2 : 8;
14411 unsigned int b1 : 4;
14412 unsigned int d1 : 12;
14413 } SI;
14414 } formats;
14415 union {
14416 formats fmt;
14417 UInt value;
14418 } ovl;
14419
14420 vassert(sizeof(formats) == 4);
14421
florianffbd84d2012-12-09 02:06:29 +000014422 ((UChar *)(&ovl.value))[0] = bytes[0];
14423 ((UChar *)(&ovl.value))[1] = bytes[1];
14424 ((UChar *)(&ovl.value))[2] = bytes[2];
14425 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000014426
14427 switch ((ovl.value & 0xff0f0000) >> 16) {
14428 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
14429 ovl.fmt.RI.i2); goto ok;
14430 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
14431 ovl.fmt.RI.i2); goto ok;
14432 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14433 ovl.fmt.RI.i2); goto ok;
14434 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14435 ovl.fmt.RI.i2); goto ok;
14436 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14437 ovl.fmt.RI.i2); goto ok;
14438 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14439 ovl.fmt.RI.i2); goto ok;
14440 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14441 ovl.fmt.RI.i2); goto ok;
14442 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14443 ovl.fmt.RI.i2); goto ok;
14444 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14445 ovl.fmt.RI.i2); goto ok;
14446 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14447 ovl.fmt.RI.i2); goto ok;
14448 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14449 ovl.fmt.RI.i2); goto ok;
14450 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14451 ovl.fmt.RI.i2); goto ok;
14452 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14453 ovl.fmt.RI.i2); goto ok;
14454 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14455 ovl.fmt.RI.i2); goto ok;
14456 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14457 ovl.fmt.RI.i2); goto ok;
14458 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14459 ovl.fmt.RI.i2); goto ok;
14460 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14461 ovl.fmt.RI.i2); goto ok;
14462 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14463 ovl.fmt.RI.i2); goto ok;
14464 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14465 ovl.fmt.RI.i2); goto ok;
14466 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14467 ovl.fmt.RI.i2); goto ok;
14468 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14469 goto ok;
14470 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14471 ovl.fmt.RI.i2); goto ok;
14472 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14473 ovl.fmt.RI.i2); goto ok;
14474 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14475 ovl.fmt.RI.i2); goto ok;
14476 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14477 goto ok;
14478 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14479 ovl.fmt.RI.i2); goto ok;
14480 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14481 goto ok;
14482 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14483 ovl.fmt.RI.i2); goto ok;
14484 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14485 goto ok;
14486 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14487 ovl.fmt.RI.i2); goto ok;
14488 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14489 goto ok;
14490 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14491 ovl.fmt.RI.i2); goto ok;
14492 }
14493
14494 switch ((ovl.value & 0xffff0000) >> 16) {
14495 case 0x8000: /* SSM */ goto unimplemented;
14496 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014497 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014498 case 0xb202: /* STIDP */ goto unimplemented;
14499 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014500 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14501 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014502 case 0xb206: /* SCKC */ goto unimplemented;
14503 case 0xb207: /* STCKC */ goto unimplemented;
14504 case 0xb208: /* SPT */ goto unimplemented;
14505 case 0xb209: /* STPT */ goto unimplemented;
14506 case 0xb20a: /* SPKA */ goto unimplemented;
14507 case 0xb20b: /* IPK */ goto unimplemented;
14508 case 0xb20d: /* PTLB */ goto unimplemented;
14509 case 0xb210: /* SPX */ goto unimplemented;
14510 case 0xb211: /* STPX */ goto unimplemented;
14511 case 0xb212: /* STAP */ goto unimplemented;
14512 case 0xb214: /* SIE */ goto unimplemented;
14513 case 0xb218: /* PC */ goto unimplemented;
14514 case 0xb219: /* SAC */ goto unimplemented;
14515 case 0xb21a: /* CFC */ goto unimplemented;
14516 case 0xb221: /* IPTE */ goto unimplemented;
14517 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
14518 case 0xb223: /* IVSK */ goto unimplemented;
14519 case 0xb224: /* IAC */ goto unimplemented;
14520 case 0xb225: /* SSAR */ goto unimplemented;
14521 case 0xb226: /* EPAR */ goto unimplemented;
14522 case 0xb227: /* ESAR */ goto unimplemented;
14523 case 0xb228: /* PT */ goto unimplemented;
14524 case 0xb229: /* ISKE */ goto unimplemented;
14525 case 0xb22a: /* RRBE */ goto unimplemented;
14526 case 0xb22b: /* SSKE */ goto unimplemented;
14527 case 0xb22c: /* TB */ goto unimplemented;
14528 case 0xb22d: /* DXR */ goto unimplemented;
14529 case 0xb22e: /* PGIN */ goto unimplemented;
14530 case 0xb22f: /* PGOUT */ goto unimplemented;
14531 case 0xb230: /* CSCH */ goto unimplemented;
14532 case 0xb231: /* HSCH */ goto unimplemented;
14533 case 0xb232: /* MSCH */ goto unimplemented;
14534 case 0xb233: /* SSCH */ goto unimplemented;
14535 case 0xb234: /* STSCH */ goto unimplemented;
14536 case 0xb235: /* TSCH */ goto unimplemented;
14537 case 0xb236: /* TPI */ goto unimplemented;
14538 case 0xb237: /* SAL */ goto unimplemented;
14539 case 0xb238: /* RSCH */ goto unimplemented;
14540 case 0xb239: /* STCRW */ goto unimplemented;
14541 case 0xb23a: /* STCPS */ goto unimplemented;
14542 case 0xb23b: /* RCHP */ goto unimplemented;
14543 case 0xb23c: /* SCHM */ goto unimplemented;
14544 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000014545 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14546 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014547 case 0xb244: /* SQDR */ goto unimplemented;
14548 case 0xb245: /* SQER */ goto unimplemented;
14549 case 0xb246: /* STURA */ goto unimplemented;
14550 case 0xb247: /* MSTA */ goto unimplemented;
14551 case 0xb248: /* PALB */ goto unimplemented;
14552 case 0xb249: /* EREG */ goto unimplemented;
14553 case 0xb24a: /* ESTA */ goto unimplemented;
14554 case 0xb24b: /* LURA */ goto unimplemented;
14555 case 0xb24c: /* TAR */ goto unimplemented;
14556 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14557 ovl.fmt.RRE.r2); goto ok;
14558 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14559 goto ok;
14560 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14561 goto ok;
14562 case 0xb250: /* CSP */ goto unimplemented;
14563 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14564 ovl.fmt.RRE.r2); goto ok;
14565 case 0xb254: /* MVPG */ goto unimplemented;
14566 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14567 ovl.fmt.RRE.r2); goto ok;
14568 case 0xb257: /* CUSE */ goto unimplemented;
14569 case 0xb258: /* BSG */ goto unimplemented;
14570 case 0xb25a: /* BSA */ goto unimplemented;
14571 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14572 ovl.fmt.RRE.r2); goto ok;
14573 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14574 ovl.fmt.RRE.r2); goto ok;
14575 case 0xb263: /* CMPSC */ goto unimplemented;
14576 case 0xb274: /* SIGA */ goto unimplemented;
14577 case 0xb276: /* XSCH */ goto unimplemented;
14578 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014579 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 +000014580 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014581 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 +000014582 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014583 case 0xb280: /* LPP */ goto unimplemented;
14584 case 0xb284: /* LCCTL */ goto unimplemented;
14585 case 0xb285: /* LPCTL */ goto unimplemented;
14586 case 0xb286: /* QSI */ goto unimplemented;
14587 case 0xb287: /* LSCTL */ goto unimplemented;
14588 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014589 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14590 goto ok;
14591 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14592 goto ok;
14593 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14594 goto ok;
florian730448f2012-02-04 17:07:07 +000014595 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 +000014596 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14597 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14598 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000014599 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14600 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14601 goto ok;
florian933065d2011-07-11 01:48:02 +000014602 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14603 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014604 case 0xb2b1: /* STFL */ goto unimplemented;
14605 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000014606 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14607 goto ok;
florian82cdba62013-03-12 01:31:24 +000014608 case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14609 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014610 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014611 case 0xb2e0: /* SCCTR */ goto unimplemented;
14612 case 0xb2e1: /* SPCTR */ goto unimplemented;
14613 case 0xb2e4: /* ECCTR */ goto unimplemented;
14614 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014615 case 0xb2e8: /* PPA */ goto unimplemented;
14616 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014617 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014618 case 0xb2f8: /* TEND */ goto unimplemented;
14619 case 0xb2fa: /* NIAI */ goto unimplemented;
14620 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014621 case 0xb2ff: /* TRAP4 */ goto unimplemented;
14622 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14623 ovl.fmt.RRE.r2); goto ok;
14624 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14625 ovl.fmt.RRE.r2); goto ok;
14626 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14627 ovl.fmt.RRE.r2); goto ok;
14628 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14629 ovl.fmt.RRE.r2); goto ok;
14630 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14631 ovl.fmt.RRE.r2); goto ok;
14632 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14633 ovl.fmt.RRE.r2); goto ok;
14634 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14635 ovl.fmt.RRE.r2); goto ok;
14636 case 0xb307: /* MXDBR */ goto unimplemented;
14637 case 0xb308: /* KEBR */ goto unimplemented;
14638 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14639 ovl.fmt.RRE.r2); goto ok;
14640 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14641 ovl.fmt.RRE.r2); goto ok;
14642 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14643 ovl.fmt.RRE.r2); goto ok;
14644 case 0xb30c: /* MDEBR */ goto unimplemented;
14645 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14646 ovl.fmt.RRE.r2); goto ok;
14647 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14648 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14649 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14650 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14651 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14652 ovl.fmt.RRE.r2); goto ok;
14653 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14654 ovl.fmt.RRE.r2); goto ok;
14655 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14656 ovl.fmt.RRE.r2); goto ok;
14657 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14658 ovl.fmt.RRE.r2); goto ok;
14659 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14660 ovl.fmt.RRE.r2); goto ok;
14661 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14662 ovl.fmt.RRE.r2); goto ok;
14663 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14664 ovl.fmt.RRE.r2); goto ok;
14665 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14666 ovl.fmt.RRE.r2); goto ok;
14667 case 0xb318: /* KDBR */ goto unimplemented;
14668 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14669 ovl.fmt.RRE.r2); goto ok;
14670 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14671 ovl.fmt.RRE.r2); goto ok;
14672 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14673 ovl.fmt.RRE.r2); goto ok;
14674 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14675 ovl.fmt.RRE.r2); goto ok;
14676 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14677 ovl.fmt.RRE.r2); goto ok;
14678 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14679 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14680 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14681 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
Elliott Hughesa0664b92017-04-18 17:46:52 -070014682 case 0xb324: s390_format_RRE_FF(s390_irgen_LDER, ovl.fmt.RRE.r1,
14683 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014684 case 0xb325: /* LXDR */ goto unimplemented;
14685 case 0xb326: /* LXER */ goto unimplemented;
14686 case 0xb32e: /* MAER */ goto unimplemented;
14687 case 0xb32f: /* MSER */ goto unimplemented;
14688 case 0xb336: /* SQXR */ goto unimplemented;
14689 case 0xb337: /* MEER */ goto unimplemented;
14690 case 0xb338: /* MAYLR */ goto unimplemented;
14691 case 0xb339: /* MYLR */ goto unimplemented;
14692 case 0xb33a: /* MAYR */ goto unimplemented;
14693 case 0xb33b: /* MYR */ goto unimplemented;
14694 case 0xb33c: /* MAYHR */ goto unimplemented;
14695 case 0xb33d: /* MYHR */ goto unimplemented;
14696 case 0xb33e: /* MADR */ goto unimplemented;
14697 case 0xb33f: /* MSDR */ goto unimplemented;
14698 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14699 ovl.fmt.RRE.r2); goto ok;
14700 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14701 ovl.fmt.RRE.r2); goto ok;
14702 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14703 ovl.fmt.RRE.r2); goto ok;
14704 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14705 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014706 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14707 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14708 ovl.fmt.RRF2.r2); goto ok;
14709 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14710 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14711 ovl.fmt.RRF2.r2); goto ok;
14712 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14713 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14714 ovl.fmt.RRF2.r2); goto ok;
florianb53f9482015-09-05 20:35:52 +000014715 case 0xb347: s390_format_RRF_UUFF(s390_irgen_FIXBRA, ovl.fmt.RRF2.m3,
14716 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14717 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014718 case 0xb348: /* KXBR */ goto unimplemented;
14719 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14720 ovl.fmt.RRE.r2); goto ok;
14721 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14722 ovl.fmt.RRE.r2); goto ok;
14723 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14724 ovl.fmt.RRE.r2); goto ok;
14725 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14726 ovl.fmt.RRE.r2); goto ok;
14727 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14728 ovl.fmt.RRE.r2); goto ok;
14729 case 0xb350: /* TBEDR */ goto unimplemented;
14730 case 0xb351: /* TBDR */ goto unimplemented;
14731 case 0xb353: /* DIEBR */ goto unimplemented;
florian6d0b0152015-07-09 20:59:24 +000014732 case 0xb357: s390_format_RRF_UUFF(s390_irgen_FIEBRA, ovl.fmt.RRF2.m3,
14733 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14734 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014735 case 0xb358: /* THDER */ goto unimplemented;
14736 case 0xb359: /* THDR */ goto unimplemented;
14737 case 0xb35b: /* DIDBR */ goto unimplemented;
florian6d0b0152015-07-09 20:59:24 +000014738 case 0xb35f: s390_format_RRF_UUFF(s390_irgen_FIDBRA, ovl.fmt.RRF2.m3,
14739 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14740 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014741 case 0xb360: /* LPXR */ goto unimplemented;
14742 case 0xb361: /* LNXR */ goto unimplemented;
14743 case 0xb362: /* LTXR */ goto unimplemented;
14744 case 0xb363: /* LCXR */ goto unimplemented;
14745 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14746 ovl.fmt.RRE.r2); goto ok;
14747 case 0xb366: /* LEXR */ goto unimplemented;
14748 case 0xb367: /* FIXR */ goto unimplemented;
14749 case 0xb369: /* CXR */ goto unimplemented;
14750 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14751 ovl.fmt.RRE.r2); goto ok;
14752 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14753 ovl.fmt.RRE.r2); goto ok;
14754 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14755 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14756 goto ok;
14757 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14758 ovl.fmt.RRE.r2); goto ok;
14759 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
14760 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
14761 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
14762 case 0xb377: /* FIER */ goto unimplemented;
14763 case 0xb37f: /* FIDR */ goto unimplemented;
14764 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
14765 case 0xb385: /* SFASR */ goto unimplemented;
14766 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014767 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14768 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14769 ovl.fmt.RRF2.r2); goto ok;
14770 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14771 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14772 ovl.fmt.RRF2.r2); goto ok;
14773 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14774 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14775 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014776 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14777 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14778 ovl.fmt.RRF2.r2); goto ok;
14779 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14780 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14781 ovl.fmt.RRF2.r2); goto ok;
14782 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14783 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14784 ovl.fmt.RRF2.r2); goto ok;
14785 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14786 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14787 ovl.fmt.RRF2.r2); goto ok;
14788 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14789 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14790 ovl.fmt.RRF2.r2); goto ok;
14791 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14792 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14793 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014794 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14795 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14796 ovl.fmt.RRF2.r2); goto ok;
14797 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14798 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14799 ovl.fmt.RRF2.r2); goto ok;
14800 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14801 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14802 ovl.fmt.RRF2.r2); goto ok;
14803 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14804 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14805 ovl.fmt.RRF2.r2); goto ok;
14806 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14807 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14808 ovl.fmt.RRF2.r2); goto ok;
14809 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14810 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14811 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014812 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14813 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14814 ovl.fmt.RRF2.r2); goto ok;
14815 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14816 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14817 ovl.fmt.RRF2.r2); goto ok;
14818 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14819 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14820 ovl.fmt.RRF2.r2); goto ok;
14821 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14822 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14823 ovl.fmt.RRF2.r2); goto ok;
14824 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14825 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14826 ovl.fmt.RRF2.r2); goto ok;
14827 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14828 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14829 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014830 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14831 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14832 ovl.fmt.RRF2.r2); goto ok;
14833 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14834 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14835 ovl.fmt.RRF2.r2); goto ok;
14836 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14837 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14838 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014839 case 0xb3b4: /* CEFR */ goto unimplemented;
14840 case 0xb3b5: /* CDFR */ goto unimplemented;
14841 case 0xb3b6: /* CXFR */ goto unimplemented;
14842 case 0xb3b8: /* CFER */ goto unimplemented;
14843 case 0xb3b9: /* CFDR */ goto unimplemented;
14844 case 0xb3ba: /* CFXR */ goto unimplemented;
14845 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14846 ovl.fmt.RRE.r2); goto ok;
14847 case 0xb3c4: /* CEGR */ goto unimplemented;
14848 case 0xb3c5: /* CDGR */ goto unimplemented;
14849 case 0xb3c6: /* CXGR */ goto unimplemented;
14850 case 0xb3c8: /* CGER */ goto unimplemented;
14851 case 0xb3c9: /* CGDR */ goto unimplemented;
14852 case 0xb3ca: /* CGXR */ goto unimplemented;
14853 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14854 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014855 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14856 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14857 ovl.fmt.RRF4.r2); goto ok;
14858 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14859 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14860 ovl.fmt.RRF4.r2); goto ok;
14861 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14862 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14863 ovl.fmt.RRF4.r2); goto ok;
14864 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14865 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14866 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014867 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14868 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14869 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14870 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14871 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014872 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14873 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014874 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014875 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14876 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14877 ovl.fmt.RRF4.r2); goto ok;
14878 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14879 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14880 ovl.fmt.RRF4.r2); goto ok;
14881 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14882 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14883 ovl.fmt.RRF4.r2); goto ok;
14884 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14885 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14886 ovl.fmt.RRF4.r2); goto ok;
14887 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14888 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14889 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14890 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14891 ovl.fmt.RRF2.r2); goto ok;
14892 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14893 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014894 case 0xb3df: /* FIXTR */ goto unimplemented;
14895 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014896 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14897 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14898 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014899 case 0xb3e2: /* CUDTR */ goto unimplemented;
14900 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014901 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14902 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014903 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14904 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014905 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14906 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014907 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014908 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14909 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14910 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014911 case 0xb3ea: /* CUXTR */ goto unimplemented;
14912 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014913 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14914 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014915 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14916 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014917 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14918 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014919 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14920 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14921 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014922 case 0xb3f2: /* CDUTR */ goto unimplemented;
14923 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014924 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14925 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014926 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14927 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14928 ovl.fmt.RRF4.r2); goto ok;
14929 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14930 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14931 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14932 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14933 ovl.fmt.RRF4.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014934 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14935 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14936 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014937 case 0xb3fa: /* CXUTR */ goto unimplemented;
14938 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014939 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14940 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014941 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14942 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14943 ovl.fmt.RRF4.r2); goto ok;
14944 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14945 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14946 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14947 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14948 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014949 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14950 ovl.fmt.RRE.r2); goto ok;
14951 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14952 ovl.fmt.RRE.r2); goto ok;
14953 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14954 ovl.fmt.RRE.r2); goto ok;
14955 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14956 ovl.fmt.RRE.r2); goto ok;
14957 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14958 ovl.fmt.RRE.r2); goto ok;
14959 case 0xb905: /* LURAG */ goto unimplemented;
14960 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14961 ovl.fmt.RRE.r2); goto ok;
14962 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14963 ovl.fmt.RRE.r2); goto ok;
14964 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14965 ovl.fmt.RRE.r2); goto ok;
14966 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14967 ovl.fmt.RRE.r2); goto ok;
14968 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14969 ovl.fmt.RRE.r2); goto ok;
14970 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14971 ovl.fmt.RRE.r2); goto ok;
14972 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14973 ovl.fmt.RRE.r2); goto ok;
14974 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14975 ovl.fmt.RRE.r2); goto ok;
14976 case 0xb90e: /* EREGG */ goto unimplemented;
14977 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14978 ovl.fmt.RRE.r2); goto ok;
14979 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14980 ovl.fmt.RRE.r2); goto ok;
14981 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14982 ovl.fmt.RRE.r2); goto ok;
14983 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14984 ovl.fmt.RRE.r2); goto ok;
14985 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14986 ovl.fmt.RRE.r2); goto ok;
14987 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14988 ovl.fmt.RRE.r2); goto ok;
14989 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14990 ovl.fmt.RRE.r2); goto ok;
14991 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14992 ovl.fmt.RRE.r2); goto ok;
14993 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14994 ovl.fmt.RRE.r2); goto ok;
14995 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14996 ovl.fmt.RRE.r2); goto ok;
14997 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14998 ovl.fmt.RRE.r2); goto ok;
14999 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
15000 ovl.fmt.RRE.r2); goto ok;
15001 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
15002 ovl.fmt.RRE.r2); goto ok;
15003 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
15004 ovl.fmt.RRE.r2); goto ok;
15005 case 0xb91e: /* KMAC */ goto unimplemented;
15006 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
15007 ovl.fmt.RRE.r2); goto ok;
15008 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
15009 ovl.fmt.RRE.r2); goto ok;
15010 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
15011 ovl.fmt.RRE.r2); goto ok;
15012 case 0xb925: /* STURG */ goto unimplemented;
15013 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
15014 ovl.fmt.RRE.r2); goto ok;
15015 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
15016 ovl.fmt.RRE.r2); goto ok;
15017 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000015018 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015019 case 0xb92b: /* KMO */ goto unimplemented;
15020 case 0xb92c: /* PCC */ goto unimplemented;
15021 case 0xb92d: /* KMCTR */ goto unimplemented;
15022 case 0xb92e: /* KM */ goto unimplemented;
15023 case 0xb92f: /* KMC */ goto unimplemented;
15024 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
15025 ovl.fmt.RRE.r2); goto ok;
15026 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
15027 ovl.fmt.RRE.r2); goto ok;
15028 case 0xb93e: /* KIMD */ goto unimplemented;
15029 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000015030 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
15031 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15032 ovl.fmt.RRF2.r2); goto ok;
15033 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
15034 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15035 ovl.fmt.RRF2.r2); goto ok;
15036 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
15037 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15038 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015039 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
15040 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000015041 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
15042 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15043 ovl.fmt.RRF2.r2); goto ok;
15044 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
15045 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15046 ovl.fmt.RRF2.r2); goto ok;
15047 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
15048 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15049 ovl.fmt.RRF2.r2); goto ok;
15050 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
15051 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15052 ovl.fmt.RRF2.r2); goto ok;
15053 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
15054 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15055 ovl.fmt.RRF2.r2); goto ok;
15056 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
15057 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15058 ovl.fmt.RRF2.r2); goto ok;
15059 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
15060 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15061 ovl.fmt.RRF2.r2); goto ok;
15062 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
15063 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15064 ovl.fmt.RRF2.r2); goto ok;
15065 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
15066 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
15067 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015068 case 0xb960: /* CGRT */ goto unimplemented;
15069 case 0xb961: /* CLGRT */ goto unimplemented;
15070 case 0xb972: /* CRT */ goto unimplemented;
15071 case 0xb973: /* CLRT */ goto unimplemented;
15072 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
15073 ovl.fmt.RRE.r2); goto ok;
15074 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
15075 ovl.fmt.RRE.r2); goto ok;
15076 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
15077 ovl.fmt.RRE.r2); goto ok;
15078 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
15079 ovl.fmt.RRE.r2); goto ok;
15080 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
15081 ovl.fmt.RRE.r2); goto ok;
15082 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
15083 ovl.fmt.RRE.r2); goto ok;
15084 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
15085 ovl.fmt.RRE.r2); goto ok;
15086 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
15087 ovl.fmt.RRE.r2); goto ok;
15088 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
15089 ovl.fmt.RRE.r2); goto ok;
15090 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
15091 ovl.fmt.RRE.r2); goto ok;
15092 case 0xb98a: /* CSPG */ goto unimplemented;
15093 case 0xb98d: /* EPSW */ goto unimplemented;
15094 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000015095 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000015096 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
15097 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
15098 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
15099 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
15100 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
15101 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000015102 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
15103 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015104 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
15105 ovl.fmt.RRE.r2); goto ok;
15106 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
15107 ovl.fmt.RRE.r2); goto ok;
15108 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
15109 ovl.fmt.RRE.r2); goto ok;
15110 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
15111 ovl.fmt.RRE.r2); goto ok;
15112 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
15113 ovl.fmt.RRE.r2); goto ok;
15114 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
15115 ovl.fmt.RRE.r2); goto ok;
15116 case 0xb99a: /* EPAIR */ goto unimplemented;
15117 case 0xb99b: /* ESAIR */ goto unimplemented;
15118 case 0xb99d: /* ESEA */ goto unimplemented;
15119 case 0xb99e: /* PTI */ goto unimplemented;
15120 case 0xb99f: /* SSAIR */ goto unimplemented;
15121 case 0xb9a2: /* PTF */ goto unimplemented;
15122 case 0xb9aa: /* LPTEA */ goto unimplemented;
15123 case 0xb9ae: /* RRBM */ goto unimplemented;
15124 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000015125 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
15126 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
15127 goto ok;
florian2a415a12012-07-21 17:41:36 +000015128 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
15129 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
15130 goto ok;
florianaf2194f2012-08-06 00:07:54 +000015131 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
15132 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000015133 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
15134 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015135 case 0xb9bd: /* TRTRE */ goto unimplemented;
15136 case 0xb9be: /* SRSTU */ goto unimplemented;
15137 case 0xb9bf: /* TRTE */ goto unimplemented;
15138 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
15139 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15140 goto ok;
15141 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
15142 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15143 goto ok;
15144 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
15145 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15146 goto ok;
15147 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
15148 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15149 goto ok;
15150 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
15151 ovl.fmt.RRE.r2); goto ok;
15152 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
15153 ovl.fmt.RRE.r2); goto ok;
15154 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
15155 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15156 goto ok;
15157 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
15158 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15159 goto ok;
15160 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
15161 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15162 goto ok;
15163 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
15164 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15165 goto ok;
15166 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
15167 ovl.fmt.RRE.r2); goto ok;
15168 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
15169 ovl.fmt.RRE.r2); goto ok;
Elliott Hughesa0664b92017-04-18 17:46:52 -070015170 case 0xb9e1: s390_format_RRE_RR(s390_irgen_POPCNT, ovl.fmt.RRE.r1,
15171 ovl.fmt.RRE.r2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015172 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
15173 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
15174 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015175 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
15176 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15177 goto ok;
15178 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
15179 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15180 goto ok;
15181 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
15182 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15183 goto ok;
15184 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
15185 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15186 goto ok;
15187 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
15188 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15189 goto ok;
15190 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
15191 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15192 goto ok;
15193 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
15194 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15195 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015196 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
15197 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
15198 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015199 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
15200 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15201 goto ok;
15202 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
15203 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15204 goto ok;
15205 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
15206 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15207 goto ok;
15208 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
15209 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15210 goto ok;
15211 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
15212 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15213 goto ok;
15214 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
15215 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15216 goto ok;
15217 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
15218 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15219 goto ok;
15220 }
15221
15222 switch ((ovl.value & 0xff000000) >> 24) {
15223 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15224 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15225 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15226 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15227 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15228 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15229 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15230 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15231 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15232 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15233 case 0x45: /* BAL */ goto unimplemented;
15234 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15235 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15236 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15237 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15238 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15239 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15240 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15241 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15242 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15243 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15244 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15245 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15246 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15247 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15248 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15249 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15250 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15251 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15252 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15253 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15254 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15255 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15256 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15257 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15258 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15259 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15260 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15261 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15262 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15263 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15264 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15265 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15266 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15267 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15268 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15269 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15270 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15271 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15272 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15273 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15274 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15275 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15276 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15277 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15278 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15279 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15280 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15281 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15282 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15283 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15284 case 0x67: /* MXD */ goto unimplemented;
15285 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15286 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15287 case 0x69: /* CD */ goto unimplemented;
15288 case 0x6a: /* AD */ goto unimplemented;
15289 case 0x6b: /* SD */ goto unimplemented;
15290 case 0x6c: /* MD */ goto unimplemented;
15291 case 0x6d: /* DD */ goto unimplemented;
15292 case 0x6e: /* AW */ goto unimplemented;
15293 case 0x6f: /* SW */ goto unimplemented;
15294 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15295 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15296 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15297 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15298 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15299 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15300 case 0x79: /* CE */ goto unimplemented;
15301 case 0x7a: /* AE */ goto unimplemented;
15302 case 0x7b: /* SE */ goto unimplemented;
15303 case 0x7c: /* MDE */ goto unimplemented;
15304 case 0x7d: /* DE */ goto unimplemented;
15305 case 0x7e: /* AU */ goto unimplemented;
15306 case 0x7f: /* SU */ goto unimplemented;
15307 case 0x83: /* DIAG */ goto unimplemented;
15308 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
15309 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15310 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
15311 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15312 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15313 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15314 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15315 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15316 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15317 ovl.fmt.RS.d2); goto ok;
15318 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15319 ovl.fmt.RS.d2); goto ok;
15320 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15321 ovl.fmt.RS.d2); goto ok;
15322 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15323 ovl.fmt.RS.d2); goto ok;
15324 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15325 ovl.fmt.RS.d2); goto ok;
15326 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15327 ovl.fmt.RS.d2); goto ok;
15328 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15329 ovl.fmt.RS.d2); goto ok;
15330 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15331 ovl.fmt.RS.d2); goto ok;
15332 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15333 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15334 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15335 ovl.fmt.SI.d1); goto ok;
15336 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15337 ovl.fmt.SI.d1); goto ok;
15338 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15339 ovl.fmt.SI.d1); goto ok;
15340 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15341 ovl.fmt.SI.d1); goto ok;
15342 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15343 ovl.fmt.SI.d1); goto ok;
15344 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15345 ovl.fmt.SI.d1); goto ok;
15346 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15347 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15348 case 0x99: /* TRACE */ goto unimplemented;
15349 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15350 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15351 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15352 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15353 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
15354 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15355 goto ok;
15356 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
15357 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15358 goto ok;
15359 case 0xac: /* STNSM */ goto unimplemented;
15360 case 0xad: /* STOSM */ goto unimplemented;
15361 case 0xae: /* SIGP */ goto unimplemented;
15362 case 0xaf: /* MC */ goto unimplemented;
15363 case 0xb1: /* LRA */ goto unimplemented;
15364 case 0xb6: /* STCTL */ goto unimplemented;
15365 case 0xb7: /* LCTL */ goto unimplemented;
15366 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15367 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015368 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15369 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015370 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15371 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15372 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15373 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15374 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15375 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15376 }
15377
15378 return S390_DECODE_UNKNOWN_INSN;
15379
15380ok:
15381 return S390_DECODE_OK;
15382
15383unimplemented:
15384 return S390_DECODE_UNIMPLEMENTED_INSN;
15385}
15386
15387static s390_decode_t
florian8462d112014-09-24 15:18:09 +000015388s390_decode_6byte_and_irgen(const UChar *bytes)
sewardj2019a972011-03-07 16:04:07 +000015389{
15390 typedef union {
15391 struct {
15392 unsigned int op1 : 8;
15393 unsigned int r1 : 4;
15394 unsigned int r3 : 4;
15395 unsigned int i2 : 16;
15396 unsigned int : 8;
15397 unsigned int op2 : 8;
15398 } RIE;
15399 struct {
15400 unsigned int op1 : 8;
15401 unsigned int r1 : 4;
15402 unsigned int r2 : 4;
15403 unsigned int i3 : 8;
15404 unsigned int i4 : 8;
15405 unsigned int i5 : 8;
15406 unsigned int op2 : 8;
15407 } RIE_RRUUU;
15408 struct {
15409 unsigned int op1 : 8;
15410 unsigned int r1 : 4;
15411 unsigned int : 4;
15412 unsigned int i2 : 16;
15413 unsigned int m3 : 4;
15414 unsigned int : 4;
15415 unsigned int op2 : 8;
15416 } RIEv1;
15417 struct {
15418 unsigned int op1 : 8;
15419 unsigned int r1 : 4;
15420 unsigned int r2 : 4;
15421 unsigned int i4 : 16;
15422 unsigned int m3 : 4;
15423 unsigned int : 4;
15424 unsigned int op2 : 8;
15425 } RIE_RRPU;
15426 struct {
15427 unsigned int op1 : 8;
15428 unsigned int r1 : 4;
15429 unsigned int m3 : 4;
15430 unsigned int i4 : 16;
15431 unsigned int i2 : 8;
15432 unsigned int op2 : 8;
15433 } RIEv3;
15434 struct {
15435 unsigned int op1 : 8;
15436 unsigned int r1 : 4;
15437 unsigned int op2 : 4;
15438 unsigned int i2 : 32;
15439 } RIL;
15440 struct {
15441 unsigned int op1 : 8;
15442 unsigned int r1 : 4;
15443 unsigned int m3 : 4;
15444 unsigned int b4 : 4;
15445 unsigned int d4 : 12;
15446 unsigned int i2 : 8;
15447 unsigned int op2 : 8;
15448 } RIS;
15449 struct {
15450 unsigned int op1 : 8;
15451 unsigned int r1 : 4;
15452 unsigned int r2 : 4;
15453 unsigned int b4 : 4;
15454 unsigned int d4 : 12;
15455 unsigned int m3 : 4;
15456 unsigned int : 4;
15457 unsigned int op2 : 8;
15458 } RRS;
15459 struct {
15460 unsigned int op1 : 8;
15461 unsigned int l1 : 4;
15462 unsigned int : 4;
15463 unsigned int b1 : 4;
15464 unsigned int d1 : 12;
15465 unsigned int : 8;
15466 unsigned int op2 : 8;
15467 } RSL;
15468 struct {
15469 unsigned int op1 : 8;
15470 unsigned int r1 : 4;
15471 unsigned int r3 : 4;
15472 unsigned int b2 : 4;
15473 unsigned int dl2 : 12;
15474 unsigned int dh2 : 8;
15475 unsigned int op2 : 8;
15476 } RSY;
15477 struct {
15478 unsigned int op1 : 8;
15479 unsigned int r1 : 4;
15480 unsigned int x2 : 4;
15481 unsigned int b2 : 4;
15482 unsigned int d2 : 12;
15483 unsigned int : 8;
15484 unsigned int op2 : 8;
15485 } RXE;
15486 struct {
15487 unsigned int op1 : 8;
15488 unsigned int r3 : 4;
15489 unsigned int x2 : 4;
15490 unsigned int b2 : 4;
15491 unsigned int d2 : 12;
15492 unsigned int r1 : 4;
15493 unsigned int : 4;
15494 unsigned int op2 : 8;
15495 } RXF;
15496 struct {
15497 unsigned int op1 : 8;
15498 unsigned int r1 : 4;
15499 unsigned int x2 : 4;
15500 unsigned int b2 : 4;
15501 unsigned int dl2 : 12;
15502 unsigned int dh2 : 8;
15503 unsigned int op2 : 8;
15504 } RXY;
15505 struct {
15506 unsigned int op1 : 8;
15507 unsigned int i2 : 8;
15508 unsigned int b1 : 4;
15509 unsigned int dl1 : 12;
15510 unsigned int dh1 : 8;
15511 unsigned int op2 : 8;
15512 } SIY;
15513 struct {
15514 unsigned int op : 8;
15515 unsigned int l : 8;
15516 unsigned int b1 : 4;
15517 unsigned int d1 : 12;
15518 unsigned int b2 : 4;
15519 unsigned int d2 : 12;
15520 } SS;
15521 struct {
15522 unsigned int op : 8;
15523 unsigned int l1 : 4;
15524 unsigned int l2 : 4;
15525 unsigned int b1 : 4;
15526 unsigned int d1 : 12;
15527 unsigned int b2 : 4;
15528 unsigned int d2 : 12;
15529 } SS_LLRDRD;
15530 struct {
15531 unsigned int op : 8;
15532 unsigned int r1 : 4;
15533 unsigned int r3 : 4;
15534 unsigned int b2 : 4;
15535 unsigned int d2 : 12;
15536 unsigned int b4 : 4;
15537 unsigned int d4 : 12;
15538 } SS_RRRDRD2;
15539 struct {
15540 unsigned int op : 16;
15541 unsigned int b1 : 4;
15542 unsigned int d1 : 12;
15543 unsigned int b2 : 4;
15544 unsigned int d2 : 12;
15545 } SSE;
15546 struct {
15547 unsigned int op1 : 8;
15548 unsigned int r3 : 4;
15549 unsigned int op2 : 4;
15550 unsigned int b1 : 4;
15551 unsigned int d1 : 12;
15552 unsigned int b2 : 4;
15553 unsigned int d2 : 12;
15554 } SSF;
15555 struct {
15556 unsigned int op : 16;
15557 unsigned int b1 : 4;
15558 unsigned int d1 : 12;
15559 unsigned int i2 : 16;
15560 } SIL;
15561 } formats;
15562 union {
15563 formats fmt;
15564 ULong value;
15565 } ovl;
15566
15567 vassert(sizeof(formats) == 6);
15568
florianffbd84d2012-12-09 02:06:29 +000015569 ((UChar *)(&ovl.value))[0] = bytes[0];
15570 ((UChar *)(&ovl.value))[1] = bytes[1];
15571 ((UChar *)(&ovl.value))[2] = bytes[2];
15572 ((UChar *)(&ovl.value))[3] = bytes[3];
15573 ((UChar *)(&ovl.value))[4] = bytes[4];
15574 ((UChar *)(&ovl.value))[5] = bytes[5];
15575 ((UChar *)(&ovl.value))[6] = 0x0;
15576 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000015577
15578 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15579 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15580 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15581 ovl.fmt.RXY.dl2,
15582 ovl.fmt.RXY.dh2); goto ok;
15583 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15584 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15585 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15586 ovl.fmt.RXY.dl2,
15587 ovl.fmt.RXY.dh2); goto ok;
15588 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15589 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15590 ovl.fmt.RXY.dl2,
15591 ovl.fmt.RXY.dh2); goto ok;
15592 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15593 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15594 ovl.fmt.RXY.dl2,
15595 ovl.fmt.RXY.dh2); goto ok;
15596 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15597 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15598 ovl.fmt.RXY.dl2,
15599 ovl.fmt.RXY.dh2); goto ok;
15600 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15601 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15602 ovl.fmt.RXY.dl2,
15603 ovl.fmt.RXY.dh2); goto ok;
15604 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15605 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15606 ovl.fmt.RXY.dl2,
15607 ovl.fmt.RXY.dh2); goto ok;
15608 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15609 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15610 ovl.fmt.RXY.dl2,
15611 ovl.fmt.RXY.dh2); goto ok;
15612 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15613 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15614 ovl.fmt.RXY.dl2,
15615 ovl.fmt.RXY.dh2); goto ok;
15616 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15617 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, 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 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, 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 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15626 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15627 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15628 ovl.fmt.RXY.dl2,
15629 ovl.fmt.RXY.dh2); goto ok;
15630 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15631 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15632 ovl.fmt.RXY.dl2,
15633 ovl.fmt.RXY.dh2); goto ok;
15634 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, 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 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, 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 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, 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 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, 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 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15651 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15652 ovl.fmt.RXY.dl2,
15653 ovl.fmt.RXY.dh2); goto ok;
15654 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15655 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15656 ovl.fmt.RXY.dl2,
15657 ovl.fmt.RXY.dh2); goto ok;
15658 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15659 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15660 ovl.fmt.RXY.dl2,
15661 ovl.fmt.RXY.dh2); goto ok;
15662 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15663 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15664 ovl.fmt.RXY.dl2,
15665 ovl.fmt.RXY.dh2); goto ok;
15666 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15667 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15668 ovl.fmt.RXY.dl2,
15669 ovl.fmt.RXY.dh2); goto ok;
15670 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15671 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15672 ovl.fmt.RXY.dl2,
15673 ovl.fmt.RXY.dh2); goto ok;
15674 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15675 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15676 ovl.fmt.RXY.dl2,
15677 ovl.fmt.RXY.dh2); goto ok;
15678 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15679 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15680 ovl.fmt.RXY.dl2,
15681 ovl.fmt.RXY.dh2); goto ok;
15682 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15683 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15684 ovl.fmt.RXY.dl2,
15685 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015686 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015687 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15688 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15689 ovl.fmt.RXY.dl2,
15690 ovl.fmt.RXY.dh2); goto ok;
15691 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15692 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15693 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15694 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15695 ovl.fmt.RXY.dh2); goto ok;
15696 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15697 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15698 ovl.fmt.RXY.dl2,
15699 ovl.fmt.RXY.dh2); goto ok;
15700 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15701 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15702 ovl.fmt.RXY.dl2,
15703 ovl.fmt.RXY.dh2); goto ok;
15704 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15705 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15706 ovl.fmt.RXY.dl2,
15707 ovl.fmt.RXY.dh2); goto ok;
15708 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15709 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15710 ovl.fmt.RXY.dl2,
15711 ovl.fmt.RXY.dh2); goto ok;
15712 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15713 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15714 ovl.fmt.RXY.dl2,
15715 ovl.fmt.RXY.dh2); goto ok;
15716 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15717 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15718 ovl.fmt.RXY.dl2,
15719 ovl.fmt.RXY.dh2); goto ok;
15720 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15721 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15722 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15723 ovl.fmt.RXY.dh2); goto ok;
15724 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15725 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15726 ovl.fmt.RXY.dl2,
15727 ovl.fmt.RXY.dh2); goto ok;
15728 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15729 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15730 ovl.fmt.RXY.dl2,
15731 ovl.fmt.RXY.dh2); goto ok;
15732 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15733 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15734 ovl.fmt.RXY.dl2,
15735 ovl.fmt.RXY.dh2); goto ok;
15736 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15737 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15738 ovl.fmt.RXY.dl2,
15739 ovl.fmt.RXY.dh2); goto ok;
15740 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15741 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15742 ovl.fmt.RXY.dl2,
15743 ovl.fmt.RXY.dh2); goto ok;
15744 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15745 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15746 ovl.fmt.RXY.dl2,
15747 ovl.fmt.RXY.dh2); goto ok;
15748 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15749 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15750 ovl.fmt.RXY.dl2,
15751 ovl.fmt.RXY.dh2); goto ok;
15752 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15753 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15754 ovl.fmt.RXY.dl2,
15755 ovl.fmt.RXY.dh2); goto ok;
15756 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15757 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15758 ovl.fmt.RXY.dl2,
15759 ovl.fmt.RXY.dh2); goto ok;
15760 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15761 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15762 ovl.fmt.RXY.dl2,
15763 ovl.fmt.RXY.dh2); goto ok;
15764 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15765 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15766 ovl.fmt.RXY.dl2,
15767 ovl.fmt.RXY.dh2); goto ok;
15768 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15769 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15770 ovl.fmt.RXY.dl2,
15771 ovl.fmt.RXY.dh2); goto ok;
15772 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15773 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15774 ovl.fmt.RXY.dl2,
15775 ovl.fmt.RXY.dh2); goto ok;
15776 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15777 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15778 ovl.fmt.RXY.dl2,
15779 ovl.fmt.RXY.dh2); goto ok;
15780 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15781 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15782 ovl.fmt.RXY.dl2,
15783 ovl.fmt.RXY.dh2); goto ok;
15784 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15785 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15786 ovl.fmt.RXY.dl2,
15787 ovl.fmt.RXY.dh2); goto ok;
15788 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15789 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15790 ovl.fmt.RXY.dl2,
15791 ovl.fmt.RXY.dh2); goto ok;
15792 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15793 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15794 ovl.fmt.RXY.dl2,
15795 ovl.fmt.RXY.dh2); goto ok;
15796 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15797 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15798 ovl.fmt.RXY.dl2,
15799 ovl.fmt.RXY.dh2); goto ok;
15800 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15801 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15802 ovl.fmt.RXY.dl2,
15803 ovl.fmt.RXY.dh2); goto ok;
15804 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15805 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15806 ovl.fmt.RXY.dl2,
15807 ovl.fmt.RXY.dh2); goto ok;
15808 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15809 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15810 ovl.fmt.RXY.dl2,
15811 ovl.fmt.RXY.dh2); goto ok;
15812 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15813 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15814 ovl.fmt.RXY.dl2,
15815 ovl.fmt.RXY.dh2); goto ok;
15816 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15817 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15818 ovl.fmt.RXY.dl2,
15819 ovl.fmt.RXY.dh2); goto ok;
15820 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15821 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15822 ovl.fmt.RXY.dl2,
15823 ovl.fmt.RXY.dh2); goto ok;
15824 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15825 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15826 ovl.fmt.RXY.dl2,
15827 ovl.fmt.RXY.dh2); goto ok;
15828 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15829 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15830 ovl.fmt.RXY.dl2,
15831 ovl.fmt.RXY.dh2); goto ok;
15832 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15833 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15834 ovl.fmt.RXY.dl2,
15835 ovl.fmt.RXY.dh2); goto ok;
15836 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15837 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15838 ovl.fmt.RXY.dl2,
15839 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015840 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015841 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15842 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15843 ovl.fmt.RXY.dl2,
15844 ovl.fmt.RXY.dh2); goto ok;
15845 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15846 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15847 ovl.fmt.RXY.dl2,
15848 ovl.fmt.RXY.dh2); goto ok;
15849 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15850 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15851 ovl.fmt.RXY.dl2,
15852 ovl.fmt.RXY.dh2); goto ok;
15853 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15854 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15855 ovl.fmt.RXY.dl2,
15856 ovl.fmt.RXY.dh2); goto ok;
15857 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15858 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15859 ovl.fmt.RXY.dl2,
15860 ovl.fmt.RXY.dh2); goto ok;
15861 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15862 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15863 ovl.fmt.RXY.dl2,
15864 ovl.fmt.RXY.dh2); goto ok;
15865 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15866 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15867 ovl.fmt.RXY.dl2,
15868 ovl.fmt.RXY.dh2); goto ok;
15869 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15870 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15871 ovl.fmt.RXY.dl2,
15872 ovl.fmt.RXY.dh2); goto ok;
15873 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15874 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15875 ovl.fmt.RXY.dl2,
15876 ovl.fmt.RXY.dh2); goto ok;
15877 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15878 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15879 ovl.fmt.RXY.dl2,
15880 ovl.fmt.RXY.dh2); goto ok;
15881 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15882 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15883 ovl.fmt.RXY.dl2,
15884 ovl.fmt.RXY.dh2); goto ok;
15885 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15886 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15887 ovl.fmt.RXY.dl2,
15888 ovl.fmt.RXY.dh2); goto ok;
15889 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15890 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15891 ovl.fmt.RXY.dl2,
15892 ovl.fmt.RXY.dh2); goto ok;
15893 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15894 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15895 ovl.fmt.RXY.dl2,
15896 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015897 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15898 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15899 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015900 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15901 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15902 ovl.fmt.RXY.dl2,
15903 ovl.fmt.RXY.dh2); goto ok;
15904 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15905 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15906 ovl.fmt.RXY.dl2,
15907 ovl.fmt.RXY.dh2); goto ok;
15908 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15909 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15910 ovl.fmt.RXY.dl2,
15911 ovl.fmt.RXY.dh2); goto ok;
15912 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15913 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15914 ovl.fmt.RXY.dl2,
15915 ovl.fmt.RXY.dh2); goto ok;
15916 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15917 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15918 ovl.fmt.RXY.dl2,
15919 ovl.fmt.RXY.dh2); goto ok;
15920 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15921 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15922 ovl.fmt.RXY.dl2,
15923 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015924 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015925 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15926 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15927 ovl.fmt.RXY.dl2,
15928 ovl.fmt.RXY.dh2); goto ok;
15929 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15930 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15931 ovl.fmt.RXY.dl2,
15932 ovl.fmt.RXY.dh2); goto ok;
15933 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15934 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15935 ovl.fmt.RXY.dl2,
15936 ovl.fmt.RXY.dh2); goto ok;
15937 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15938 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15939 ovl.fmt.RXY.dl2,
15940 ovl.fmt.RXY.dh2); goto ok;
15941 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15942 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15943 ovl.fmt.RSY.dl2,
15944 ovl.fmt.RSY.dh2); goto ok;
15945 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15946 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15947 ovl.fmt.RSY.dl2,
15948 ovl.fmt.RSY.dh2); goto ok;
15949 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15950 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15951 ovl.fmt.RSY.dl2,
15952 ovl.fmt.RSY.dh2); goto ok;
15953 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15954 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15955 ovl.fmt.RSY.dl2,
15956 ovl.fmt.RSY.dh2); goto ok;
15957 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15958 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15959 ovl.fmt.RSY.dl2,
15960 ovl.fmt.RSY.dh2); goto ok;
15961 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15962 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15963 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15964 ovl.fmt.RSY.dl2,
15965 ovl.fmt.RSY.dh2); goto ok;
15966 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15967 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15968 ovl.fmt.RSY.dl2,
15969 ovl.fmt.RSY.dh2); goto ok;
15970 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15971 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15972 ovl.fmt.RSY.dl2,
15973 ovl.fmt.RSY.dh2); goto ok;
15974 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15975 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15976 ovl.fmt.RSY.dl2,
15977 ovl.fmt.RSY.dh2); goto ok;
15978 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15979 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15980 ovl.fmt.RSY.dl2,
15981 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015982 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015983 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15984 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15985 ovl.fmt.RSY.dl2,
15986 ovl.fmt.RSY.dh2); goto ok;
15987 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15988 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15989 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15990 ovl.fmt.RSY.dl2,
15991 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015992 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015993 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15994 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15995 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15996 ovl.fmt.RSY.dh2); goto ok;
15997 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15998 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15999 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16000 ovl.fmt.RSY.dh2); goto ok;
16001 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
16002 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
16003 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16004 ovl.fmt.RSY.dl2,
16005 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000016006 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
16007 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16008 ovl.fmt.RSY.dl2,
16009 ovl.fmt.RSY.dh2); goto ok;
16010 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
16011 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16012 ovl.fmt.RSY.dl2,
16013 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016014 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
16015 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16016 ovl.fmt.RSY.dl2,
16017 ovl.fmt.RSY.dh2); goto ok;
16018 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
16019 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
16020 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16021 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000016022 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
16023 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16024 ovl.fmt.RSY.dl2,
16025 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016026 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
16027 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16028 ovl.fmt.SIY.dh1); goto ok;
16029 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
16030 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16031 ovl.fmt.SIY.dh1); goto ok;
16032 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
16033 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16034 ovl.fmt.SIY.dh1); goto ok;
16035 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
16036 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16037 ovl.fmt.SIY.dh1); goto ok;
16038 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
16039 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16040 ovl.fmt.SIY.dh1); goto ok;
16041 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
16042 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16043 ovl.fmt.SIY.dh1); goto ok;
16044 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
16045 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16046 ovl.fmt.SIY.dh1); goto ok;
16047 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
16048 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16049 ovl.fmt.SIY.dh1); goto ok;
16050 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
16051 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16052 ovl.fmt.SIY.dh1); goto ok;
16053 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
16054 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
16055 ovl.fmt.SIY.dh1); goto ok;
16056 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
16057 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16058 ovl.fmt.RSY.dl2,
16059 ovl.fmt.RSY.dh2); goto ok;
16060 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
16061 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16062 ovl.fmt.RSY.dl2,
16063 ovl.fmt.RSY.dh2); goto ok;
16064 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
16065 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
16066 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
16067 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16068 ovl.fmt.RSY.dl2,
16069 ovl.fmt.RSY.dh2); goto ok;
16070 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
16071 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16072 ovl.fmt.RSY.dl2,
16073 ovl.fmt.RSY.dh2); goto ok;
16074 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
16075 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16076 ovl.fmt.RSY.dl2,
16077 ovl.fmt.RSY.dh2); goto ok;
16078 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
16079 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16080 ovl.fmt.RSY.dl2,
16081 ovl.fmt.RSY.dh2); goto ok;
16082 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
16083 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
16084 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16085 ovl.fmt.RSY.dh2); goto ok;
16086 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
16087 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
16088 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16089 ovl.fmt.RSY.dl2,
16090 ovl.fmt.RSY.dh2); goto ok;
16091 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
16092 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16093 ovl.fmt.RSY.dl2,
16094 ovl.fmt.RSY.dh2); goto ok;
16095 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
16096 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16097 ovl.fmt.RSY.dl2,
16098 ovl.fmt.RSY.dh2); goto ok;
16099 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
16100 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16101 ovl.fmt.RSY.dl2,
16102 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000016103 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
16104 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16105 ovl.fmt.RSY.dl2,
16106 ovl.fmt.RSY.dh2,
16107 S390_XMNM_LOCG); goto ok;
16108 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
16109 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
16110 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16111 ovl.fmt.RSY.dh2,
16112 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016113 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
16114 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16115 ovl.fmt.RSY.dl2,
16116 ovl.fmt.RSY.dh2); goto ok;
16117 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
16118 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16119 ovl.fmt.RSY.dl2,
16120 ovl.fmt.RSY.dh2); goto ok;
16121 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
16122 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16123 ovl.fmt.RSY.dl2,
16124 ovl.fmt.RSY.dh2); goto ok;
16125 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
16126 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16127 ovl.fmt.RSY.dl2,
16128 ovl.fmt.RSY.dh2); goto ok;
16129 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
16130 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
16131 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
16132 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000016133 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
16134 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16135 ovl.fmt.RSY.dl2,
16136 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
16137 goto ok;
16138 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
16139 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16140 ovl.fmt.RSY.dl2,
16141 ovl.fmt.RSY.dh2,
16142 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016143 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
16144 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16145 ovl.fmt.RSY.dl2,
16146 ovl.fmt.RSY.dh2); goto ok;
16147 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
16148 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16149 ovl.fmt.RSY.dl2,
16150 ovl.fmt.RSY.dh2); goto ok;
16151 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
16152 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16153 ovl.fmt.RSY.dl2,
16154 ovl.fmt.RSY.dh2); goto ok;
16155 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
16156 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16157 ovl.fmt.RSY.dl2,
16158 ovl.fmt.RSY.dh2); goto ok;
16159 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
16160 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
16161 ovl.fmt.RSY.dl2,
16162 ovl.fmt.RSY.dh2); goto ok;
16163 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
16164 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
16165 goto ok;
16166 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
16167 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
16168 goto ok;
Elliott Hughesa0664b92017-04-18 17:46:52 -070016169 case 0xec0000000051ULL: s390_format_RIE_RRUUU(s390_irgen_RISBLG,
16170 ovl.fmt.RIE_RRUUU.r1,
16171 ovl.fmt.RIE_RRUUU.r2,
16172 ovl.fmt.RIE_RRUUU.i3,
16173 ovl.fmt.RIE_RRUUU.i4,
16174 ovl.fmt.RIE_RRUUU.i5);
16175 goto ok;
sewardj2019a972011-03-07 16:04:07 +000016176 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
16177 ovl.fmt.RIE_RRUUU.r1,
16178 ovl.fmt.RIE_RRUUU.r2,
16179 ovl.fmt.RIE_RRUUU.i3,
16180 ovl.fmt.RIE_RRUUU.i4,
16181 ovl.fmt.RIE_RRUUU.i5);
16182 goto ok;
16183 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
16184 ovl.fmt.RIE_RRUUU.r1,
16185 ovl.fmt.RIE_RRUUU.r2,
16186 ovl.fmt.RIE_RRUUU.i3,
16187 ovl.fmt.RIE_RRUUU.i4,
16188 ovl.fmt.RIE_RRUUU.i5);
16189 goto ok;
16190 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
16191 ovl.fmt.RIE_RRUUU.r1,
16192 ovl.fmt.RIE_RRUUU.r2,
16193 ovl.fmt.RIE_RRUUU.i3,
16194 ovl.fmt.RIE_RRUUU.i4,
16195 ovl.fmt.RIE_RRUUU.i5);
16196 goto ok;
16197 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
16198 ovl.fmt.RIE_RRUUU.r1,
16199 ovl.fmt.RIE_RRUUU.r2,
16200 ovl.fmt.RIE_RRUUU.i3,
16201 ovl.fmt.RIE_RRUUU.i4,
16202 ovl.fmt.RIE_RRUUU.i5);
16203 goto ok;
Elliott Hughesa0664b92017-04-18 17:46:52 -070016204 case 0xec0000000059ULL: s390_format_RIE_RRUUU(s390_irgen_RISBGN,
16205 ovl.fmt.RIE_RRUUU.r1,
16206 ovl.fmt.RIE_RRUUU.r2,
16207 ovl.fmt.RIE_RRUUU.i3,
16208 ovl.fmt.RIE_RRUUU.i4,
16209 ovl.fmt.RIE_RRUUU.i5);
16210 goto ok;
16211 case 0xec000000005dULL: s390_format_RIE_RRUUU(s390_irgen_RISBHG,
16212 ovl.fmt.RIE_RRUUU.r1,
16213 ovl.fmt.RIE_RRUUU.r2,
16214 ovl.fmt.RIE_RRUUU.i3,
16215 ovl.fmt.RIE_RRUUU.i4,
16216 ovl.fmt.RIE_RRUUU.i5);
16217 goto ok;
sewardj2019a972011-03-07 16:04:07 +000016218 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
16219 ovl.fmt.RIE_RRPU.r1,
16220 ovl.fmt.RIE_RRPU.r2,
16221 ovl.fmt.RIE_RRPU.i4,
16222 ovl.fmt.RIE_RRPU.m3); goto ok;
16223 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
16224 ovl.fmt.RIE_RRPU.r1,
16225 ovl.fmt.RIE_RRPU.r2,
16226 ovl.fmt.RIE_RRPU.i4,
16227 ovl.fmt.RIE_RRPU.m3); goto ok;
16228 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
16229 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
16230 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
16231 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
16232 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
16233 ovl.fmt.RIE_RRPU.r1,
16234 ovl.fmt.RIE_RRPU.r2,
16235 ovl.fmt.RIE_RRPU.i4,
16236 ovl.fmt.RIE_RRPU.m3); goto ok;
16237 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
16238 ovl.fmt.RIE_RRPU.r1,
16239 ovl.fmt.RIE_RRPU.r2,
16240 ovl.fmt.RIE_RRPU.i4,
16241 ovl.fmt.RIE_RRPU.m3); goto ok;
16242 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
16243 ovl.fmt.RIEv3.r1,
16244 ovl.fmt.RIEv3.m3,
16245 ovl.fmt.RIEv3.i4,
16246 ovl.fmt.RIEv3.i2); goto ok;
16247 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
16248 ovl.fmt.RIEv3.r1,
16249 ovl.fmt.RIEv3.m3,
16250 ovl.fmt.RIEv3.i4,
16251 ovl.fmt.RIEv3.i2); goto ok;
16252 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
16253 ovl.fmt.RIEv3.r1,
16254 ovl.fmt.RIEv3.m3,
16255 ovl.fmt.RIEv3.i4,
16256 ovl.fmt.RIEv3.i2); goto ok;
16257 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
16258 ovl.fmt.RIEv3.r1,
16259 ovl.fmt.RIEv3.m3,
16260 ovl.fmt.RIEv3.i4,
16261 ovl.fmt.RIEv3.i2); goto ok;
16262 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
16263 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
16264 goto ok;
16265 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
16266 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16267 ovl.fmt.RIE.i2); goto ok;
16268 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
16269 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16270 ovl.fmt.RIE.i2); goto ok;
16271 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
16272 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16273 ovl.fmt.RIE.i2); goto ok;
16274 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
16275 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16276 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16277 goto ok;
16278 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
16279 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16280 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16281 goto ok;
16282 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
16283 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16284 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16285 goto ok;
16286 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
16287 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16288 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16289 goto ok;
16290 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
16291 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16292 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16293 ovl.fmt.RIS.i2); goto ok;
16294 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
16295 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16296 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16297 ovl.fmt.RIS.i2); goto ok;
16298 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
16299 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
16300 ovl.fmt.RIS.d4,
16301 ovl.fmt.RIS.i2); goto ok;
16302 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
16303 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16304 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16305 ovl.fmt.RIS.i2); goto ok;
16306 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
16307 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16308 ovl.fmt.RXE.d2); goto ok;
16309 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
16310 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16311 ovl.fmt.RXE.d2); goto ok;
16312 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
16313 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16314 ovl.fmt.RXE.d2); goto ok;
16315 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
16316 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
16317 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
16318 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16319 ovl.fmt.RXE.d2); goto ok;
16320 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
16321 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16322 ovl.fmt.RXE.d2); goto ok;
16323 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
16324 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16325 ovl.fmt.RXE.d2); goto ok;
16326 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
16327 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
16328 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16329 ovl.fmt.RXE.d2); goto ok;
16330 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
16331 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16332 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16333 ovl.fmt.RXF.r1); goto ok;
16334 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
16335 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16336 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16337 ovl.fmt.RXF.r1); goto ok;
16338 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
16339 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16340 ovl.fmt.RXE.d2); goto ok;
16341 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
16342 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16343 ovl.fmt.RXE.d2); goto ok;
16344 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
16345 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16346 ovl.fmt.RXE.d2); goto ok;
16347 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
16348 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16349 ovl.fmt.RXE.d2); goto ok;
16350 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
16351 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16352 ovl.fmt.RXE.d2); goto ok;
16353 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
16354 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16355 ovl.fmt.RXE.d2); goto ok;
16356 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
16357 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
16358 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16359 ovl.fmt.RXE.d2); goto ok;
16360 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
16361 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16362 ovl.fmt.RXE.d2); goto ok;
16363 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
16364 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16365 ovl.fmt.RXE.d2); goto ok;
16366 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
16367 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16368 ovl.fmt.RXE.d2); goto ok;
16369 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
16370 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16371 ovl.fmt.RXE.d2); goto ok;
16372 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
16373 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16374 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16375 ovl.fmt.RXF.r1); goto ok;
16376 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
16377 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16378 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16379 ovl.fmt.RXF.r1); goto ok;
Elliott Hughesa0664b92017-04-18 17:46:52 -070016380 case 0xed0000000024ULL: s390_format_RXE_FRRD(s390_irgen_LDE,
16381 ovl.fmt.RXE.r1, ovl.fmt.RXE.x2,
16382 ovl.fmt.RXE.b2,
16383 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016384 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
16385 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
16386 case 0xed000000002eULL: /* MAE */ goto unimplemented;
16387 case 0xed000000002fULL: /* MSE */ goto unimplemented;
16388 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
16389 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
16390 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
16391 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
16392 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
16393 case 0xed000000003aULL: /* MAY */ goto unimplemented;
16394 case 0xed000000003bULL: /* MY */ goto unimplemented;
16395 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
16396 case 0xed000000003dULL: /* MYH */ goto unimplemented;
16397 case 0xed000000003eULL: /* MAD */ goto unimplemented;
16398 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000016399 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
16400 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16401 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16402 ovl.fmt.RXF.r1); goto ok;
16403 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
16404 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16405 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16406 ovl.fmt.RXF.r1); goto ok;
16407 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
16408 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16409 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16410 ovl.fmt.RXF.r1); goto ok;
16411 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
16412 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16413 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16414 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000016415 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
16416 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16417 ovl.fmt.RXE.d2); goto ok;
16418 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
16419 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16420 ovl.fmt.RXE.d2); goto ok;
16421 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
16422 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16423 ovl.fmt.RXE.d2); goto ok;
16424 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
16425 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16426 ovl.fmt.RXE.d2); goto ok;
16427 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
16428 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16429 ovl.fmt.RXE.d2); goto ok;
16430 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
16431 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16432 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016433 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
16434 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16435 ovl.fmt.RXY.dl2,
16436 ovl.fmt.RXY.dh2); goto ok;
16437 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
16438 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16439 ovl.fmt.RXY.dl2,
16440 ovl.fmt.RXY.dh2); goto ok;
16441 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
16442 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16443 ovl.fmt.RXY.dl2,
16444 ovl.fmt.RXY.dh2); goto ok;
16445 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
16446 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16447 ovl.fmt.RXY.dl2,
16448 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000016449 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
16450 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
16451 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
16452 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016453 }
16454
16455 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
16456 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
16457 ovl.fmt.RIL.i2); goto ok;
16458 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
16459 ovl.fmt.RIL.i2); goto ok;
16460 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
16461 ovl.fmt.RIL.i2); goto ok;
16462 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16463 ovl.fmt.RIL.i2); goto ok;
16464 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16465 ovl.fmt.RIL.i2); goto ok;
16466 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16467 ovl.fmt.RIL.i2); goto ok;
16468 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16469 ovl.fmt.RIL.i2); goto ok;
16470 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16471 ovl.fmt.RIL.i2); goto ok;
16472 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16473 ovl.fmt.RIL.i2); goto ok;
16474 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16475 ovl.fmt.RIL.i2); goto ok;
16476 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16477 ovl.fmt.RIL.i2); goto ok;
16478 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16479 ovl.fmt.RIL.i2); goto ok;
16480 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16481 ovl.fmt.RIL.i2); goto ok;
16482 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16483 ovl.fmt.RIL.i2); goto ok;
16484 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16485 ovl.fmt.RIL.i2); goto ok;
16486 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16487 ovl.fmt.RIL.i2); goto ok;
16488 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16489 ovl.fmt.RIL.i2); goto ok;
16490 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16491 ovl.fmt.RIL.i2); goto ok;
16492 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16493 ovl.fmt.RIL.i2); goto ok;
16494 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16495 ovl.fmt.RIL.i2); goto ok;
16496 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16497 ovl.fmt.RIL.i2); goto ok;
16498 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16499 ovl.fmt.RIL.i2); goto ok;
16500 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16501 ovl.fmt.RIL.i2); goto ok;
16502 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16503 ovl.fmt.RIL.i2); goto ok;
16504 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16505 ovl.fmt.RIL.i2); goto ok;
16506 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16507 ovl.fmt.RIL.i2); goto ok;
16508 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16509 ovl.fmt.RIL.i2); goto ok;
16510 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16511 ovl.fmt.RIL.i2); goto ok;
16512 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16513 ovl.fmt.RIL.i2); goto ok;
16514 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16515 ovl.fmt.RIL.i2); goto ok;
16516 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16517 ovl.fmt.RIL.i2); goto ok;
16518 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16519 ovl.fmt.RIL.i2); goto ok;
16520 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16521 ovl.fmt.RIL.i2); goto ok;
16522 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16523 ovl.fmt.RIL.i2); goto ok;
16524 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16525 ovl.fmt.RIL.i2); goto ok;
16526 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16527 ovl.fmt.RIL.i2); goto ok;
16528 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16529 ovl.fmt.RIL.i2); goto ok;
16530 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16531 ovl.fmt.RIL.i2); goto ok;
16532 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16533 ovl.fmt.RIL.i2); goto ok;
16534 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16535 ovl.fmt.RIL.i2); goto ok;
16536 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16537 ovl.fmt.RIL.i2); goto ok;
16538 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16539 ovl.fmt.RIL.i2); goto ok;
16540 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16541 ovl.fmt.RIL.i2); goto ok;
16542 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16543 ovl.fmt.RIL.i2); goto ok;
16544 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16545 ovl.fmt.RIL.i2); goto ok;
16546 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16547 ovl.fmt.RIL.i2); goto ok;
16548 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16549 ovl.fmt.RIL.i2); goto ok;
16550 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16551 ovl.fmt.RIL.i2); goto ok;
16552 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16553 ovl.fmt.RIL.i2); goto ok;
16554 case 0xc800ULL: /* MVCOS */ goto unimplemented;
16555 case 0xc801ULL: /* ECTG */ goto unimplemented;
16556 case 0xc802ULL: /* CSST */ goto unimplemented;
16557 case 0xc804ULL: /* LPD */ goto unimplemented;
16558 case 0xc805ULL: /* LPDG */ goto unimplemented;
Elliott Hughesa0664b92017-04-18 17:46:52 -070016559 case 0xcc06ULL: s390_format_RIL_RP(s390_irgen_BRCTH, ovl.fmt.RIL.r1,
16560 ovl.fmt.RIL.i2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016561 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16562 ovl.fmt.RIL.i2); goto ok;
16563 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16564 ovl.fmt.RIL.i2); goto ok;
16565 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16566 ovl.fmt.RIL.i2); goto ok;
16567 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16568 ovl.fmt.RIL.i2); goto ok;
16569 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16570 ovl.fmt.RIL.i2); goto ok;
16571 }
16572
16573 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000016574 case 0xc5ULL: /* BPRP */ goto unimplemented;
16575 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016576 case 0xd0ULL: /* TRTR */ goto unimplemented;
16577 case 0xd1ULL: /* MVN */ goto unimplemented;
16578 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16579 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16580 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16581 case 0xd3ULL: /* MVZ */ goto unimplemented;
16582 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16583 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16584 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16585 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16586 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16587 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16588 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16589 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16590 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000016591 case 0xd7ULL:
16592 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16593 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16594 else
16595 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16596 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16597 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16598 goto ok;
sewardj2019a972011-03-07 16:04:07 +000016599 case 0xd9ULL: /* MVCK */ goto unimplemented;
16600 case 0xdaULL: /* MVCP */ goto unimplemented;
16601 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000016602 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16603 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16604 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016605 case 0xddULL: /* TRT */ goto unimplemented;
16606 case 0xdeULL: /* ED */ goto unimplemented;
16607 case 0xdfULL: /* EDMK */ goto unimplemented;
16608 case 0xe1ULL: /* PKU */ goto unimplemented;
16609 case 0xe2ULL: /* UNPKU */ goto unimplemented;
Elliott Hughesa0664b92017-04-18 17:46:52 -070016610 case 0xe8ULL: s390_format_SS_L0RDRD(s390_irgen_MVCIN, ovl.fmt.SS.l,
16611 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16612 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016613 case 0xe9ULL: /* PKA */ goto unimplemented;
16614 case 0xeaULL: /* UNPKA */ goto unimplemented;
16615 case 0xeeULL: /* PLO */ goto unimplemented;
16616 case 0xefULL: /* LMD */ goto unimplemented;
16617 case 0xf0ULL: /* SRP */ goto unimplemented;
16618 case 0xf1ULL: /* MVO */ goto unimplemented;
16619 case 0xf2ULL: /* PACK */ goto unimplemented;
16620 case 0xf3ULL: /* UNPK */ goto unimplemented;
16621 case 0xf8ULL: /* ZAP */ goto unimplemented;
16622 case 0xf9ULL: /* CP */ goto unimplemented;
16623 case 0xfaULL: /* AP */ goto unimplemented;
16624 case 0xfbULL: /* SP */ goto unimplemented;
16625 case 0xfcULL: /* MP */ goto unimplemented;
16626 case 0xfdULL: /* DP */ goto unimplemented;
16627 }
16628
16629 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16630 case 0xe500ULL: /* LASP */ goto unimplemented;
16631 case 0xe501ULL: /* TPROT */ goto unimplemented;
16632 case 0xe502ULL: /* STRAG */ goto unimplemented;
16633 case 0xe50eULL: /* MVCSK */ goto unimplemented;
16634 case 0xe50fULL: /* MVCDK */ goto unimplemented;
16635 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16636 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16637 goto ok;
16638 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16639 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16640 goto ok;
16641 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16642 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16643 goto ok;
16644 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16645 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16646 goto ok;
16647 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16648 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16649 goto ok;
16650 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16651 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16652 goto ok;
16653 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16654 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16655 goto ok;
16656 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16657 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16658 goto ok;
16659 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16660 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16661 goto ok;
florian2289cd42012-12-05 04:23:42 +000016662 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16663 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016664 }
16665
16666 return S390_DECODE_UNKNOWN_INSN;
16667
16668ok:
16669 return S390_DECODE_OK;
16670
16671unimplemented:
16672 return S390_DECODE_UNIMPLEMENTED_INSN;
16673}
16674
16675/* Handle "special" instructions. */
16676static s390_decode_t
florian8462d112014-09-24 15:18:09 +000016677s390_decode_special_and_irgen(const UChar *bytes)
sewardj2019a972011-03-07 16:04:07 +000016678{
16679 s390_decode_t status = S390_DECODE_OK;
16680
16681 /* Got a "Special" instruction preamble. Which one is it? */
16682 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16683 s390_irgen_client_request();
16684 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16685 s390_irgen_guest_NRADDR();
16686 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16687 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000016688 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16689 vex_inject_ir(irsb, Iend_BE);
16690
16691 /* Invalidate the current insn. The reason is that the IRop we're
16692 injecting here can change. In which case the translation has to
16693 be redone. For ease of handling, we simply invalidate all the
16694 time. */
sewardj05f5e012014-05-04 10:52:11 +000016695 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian2245ce92012-08-28 16:49:30 +000016696 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000016697 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN),
florian2245ce92012-08-28 16:49:30 +000016698 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16699 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16700 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16701
16702 put_IA(mkaddr_expr(guest_IA_next_instr));
16703 dis_res->whatNext = Dis_StopHere;
sewardj05f5e012014-05-04 10:52:11 +000016704 dis_res->jk_StopHere = Ijk_InvalICache;
sewardj2019a972011-03-07 16:04:07 +000016705 } else {
16706 /* We don't know what it is. */
16707 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16708 }
16709
16710 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16711
16712 return status;
16713}
16714
16715
16716/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000016717static UInt
florian8462d112014-09-24 15:18:09 +000016718s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres)
sewardj2019a972011-03-07 16:04:07 +000016719{
16720 s390_decode_t status;
16721
16722 dis_res = dres;
16723
16724 /* Spot the 8-byte preamble: 18ff lr r15,r15
16725 1811 lr r1,r1
16726 1822 lr r2,r2
16727 1833 lr r3,r3 */
16728 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16729 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16730 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16731
16732 /* Handle special instruction that follows that preamble. */
16733 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000016734
16735 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16736 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16737
16738 status =
16739 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000016740 } else {
16741 /* Handle normal instructions. */
16742 switch (insn_length) {
16743 case 2:
16744 status = s390_decode_2byte_and_irgen(bytes);
16745 break;
16746
16747 case 4:
16748 status = s390_decode_4byte_and_irgen(bytes);
16749 break;
16750
16751 case 6:
16752 status = s390_decode_6byte_and_irgen(bytes);
16753 break;
16754
16755 default:
16756 status = S390_DECODE_ERROR;
16757 break;
16758 }
16759 }
florian5fcbba22011-07-27 20:40:22 +000016760 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000016761 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16762 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000016763 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000016764 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000016765 }
16766
16767 if (status == S390_DECODE_OK) return insn_length; /* OK */
16768
16769 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000016770 if (sigill_diag) {
16771 vex_printf("vex s390->IR: ");
16772 switch (status) {
16773 case S390_DECODE_UNKNOWN_INSN:
16774 vex_printf("unknown insn: ");
16775 break;
sewardj2019a972011-03-07 16:04:07 +000016776
sewardj442e51a2012-12-06 18:08:04 +000016777 case S390_DECODE_UNIMPLEMENTED_INSN:
16778 vex_printf("unimplemented insn: ");
16779 break;
sewardj2019a972011-03-07 16:04:07 +000016780
sewardj442e51a2012-12-06 18:08:04 +000016781 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16782 vex_printf("unimplemented special insn: ");
16783 break;
sewardj2019a972011-03-07 16:04:07 +000016784
sewardj442e51a2012-12-06 18:08:04 +000016785 case S390_DECODE_ERROR:
16786 vex_printf("decoding error: ");
16787 break;
florian2580da42014-09-16 21:49:45 +000016788
16789 default:
16790 vpanic("s390_decode_and_irgen");
sewardj442e51a2012-12-06 18:08:04 +000016791 }
16792
16793 vex_printf("%02x%02x", bytes[0], bytes[1]);
16794 if (insn_length > 2) {
16795 vex_printf(" %02x%02x", bytes[2], bytes[3]);
16796 }
16797 if (insn_length > 4) {
16798 vex_printf(" %02x%02x", bytes[4], bytes[5]);
16799 }
16800 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000016801 }
16802
sewardj2019a972011-03-07 16:04:07 +000016803 return 0; /* Failed */
16804}
16805
16806
sewardj2019a972011-03-07 16:04:07 +000016807/* Disassemble a single instruction INSN into IR. */
16808static DisResult
florian8462d112014-09-24 15:18:09 +000016809disInstr_S390_WRK(const UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000016810{
16811 UChar byte;
16812 UInt insn_length;
16813 DisResult dres;
16814
16815 /* ---------------------------------------------------- */
16816 /* --- Compute instruction length -- */
16817 /* ---------------------------------------------------- */
16818
16819 /* Get the first byte of the insn. */
16820 byte = insn[0];
16821
16822 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16823 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16824 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16825
16826 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16827
16828 /* ---------------------------------------------------- */
16829 /* --- Initialise the DisResult data -- */
16830 /* ---------------------------------------------------- */
16831 dres.whatNext = Dis_Continue;
16832 dres.len = insn_length;
16833 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016834 dres.jk_StopHere = Ijk_INVALID;
Elliott Hughesed398002017-06-21 14:41:24 -070016835 dres.hint = Dis_HintNone;
sewardj2019a972011-03-07 16:04:07 +000016836
floriana99f20e2011-07-17 14:16:41 +000016837 /* fixs390: consider chasing of conditional jumps */
16838
sewardj2019a972011-03-07 16:04:07 +000016839 /* Normal and special instruction handling starts here. */
16840 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16841 /* All decode failures end up here. The decoder has already issued an
16842 error message.
16843 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000016844 not been executed, and (is currently) the next to be executed.
16845 The insn address in the guest state needs to be set to
16846 guest_IA_curr_instr, otherwise the complaint will report an
16847 incorrect address. */
16848 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000016849
philippe2faf5912014-08-11 22:45:47 +000016850 dres.len = 0;
florian8844a632012-04-13 04:04:06 +000016851 dres.whatNext = Dis_StopHere;
16852 dres.jk_StopHere = Ijk_NoDecode;
16853 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016854 } else {
16855 /* Decode success */
16856 switch (dres.whatNext) {
16857 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000016858 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000016859 break;
16860 case Dis_ResteerU:
16861 case Dis_ResteerC:
16862 put_IA(mkaddr_expr(dres.continueAt));
16863 break;
16864 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000016865 if (dres.jk_StopHere == Ijk_EmWarn ||
16866 dres.jk_StopHere == Ijk_EmFail) {
16867 /* We assume here, that emulation warnings are not given for
16868 insns that transfer control. There is no good way to
16869 do that. */
16870 put_IA(mkaddr_expr(guest_IA_next_instr));
16871 }
florian8844a632012-04-13 04:04:06 +000016872 break;
16873 default:
florian2580da42014-09-16 21:49:45 +000016874 vpanic("disInstr_S390_WRK");
florian8844a632012-04-13 04:04:06 +000016875 }
sewardj2019a972011-03-07 16:04:07 +000016876 }
16877
16878 return dres;
16879}
16880
16881
16882/*------------------------------------------------------------*/
16883/*--- Top-level fn ---*/
16884/*------------------------------------------------------------*/
16885
16886/* Disassemble a single instruction into IR. The instruction
16887 is located in host memory at &guest_code[delta]. */
16888
16889DisResult
16890disInstr_S390(IRSB *irsb_IN,
florianbeac5302014-12-31 12:09:38 +000016891 Bool (*resteerOkFn)(void *, Addr),
sewardj2019a972011-03-07 16:04:07 +000016892 Bool resteerCisOk,
16893 void *callback_opaque,
florian8462d112014-09-24 15:18:09 +000016894 const UChar *guest_code,
sewardj2019a972011-03-07 16:04:07 +000016895 Long delta,
floriand4cc0de2015-01-02 11:44:12 +000016896 Addr guest_IP,
sewardj2019a972011-03-07 16:04:07 +000016897 VexArch guest_arch,
floriancacba8e2014-12-15 18:58:07 +000016898 const VexArchInfo *archinfo,
16899 const VexAbiInfo *abiinfo,
sewardj9b769162014-07-24 12:42:03 +000016900 VexEndness host_endness,
sewardj442e51a2012-12-06 18:08:04 +000016901 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016902{
16903 vassert(guest_arch == VexArchS390X);
16904
16905 /* The instruction decoder requires a big-endian machine. */
sewardj9b769162014-07-24 12:42:03 +000016906 vassert(host_endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +000016907
16908 /* Set globals (see top of this file) */
16909 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016910 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016911 resteer_fn = resteerOkFn;
16912 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016913 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016914
florian420c5012011-07-22 02:12:28 +000016915 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016916}
16917
16918/*---------------------------------------------------------------*/
16919/*--- end guest_s390_toIR.c ---*/
16920/*---------------------------------------------------------------*/