blob: 023cb7d9b15293982c78aac138422b8dfe740bbd [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
sewardj89ae8472013-10-18 14:12:58 +000011 Copyright IBM Corp. 2010-2013
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
florianb0b67102012-12-24 00:14:31 +000044#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h" /* s390_host_has_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000046
sewardj2019a972011-03-07 16:04:07 +000047
48/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000049/*--- Forward declarations ---*/
50/*------------------------------------------------------------*/
florian8462d112014-09-24 15:18:09 +000051static UInt s390_decode_and_irgen(const UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
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 *
sewardj2019a972011-03-07 16:04:07 +00003834s390_irgen_BRCTG(UChar r1, UShort i2)
3835{
3836 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3837 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3838 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3839
3840 return "brctg";
3841}
3842
florian55085f82012-11-21 00:36:55 +00003843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003844s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3845{
3846 IRTemp value = newTemp(Ity_I32);
3847
3848 assign(value, get_gpr_w1(r3 | 1));
3849 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3850 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3851 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3852
3853 return "brxh";
3854}
3855
florian55085f82012-11-21 00:36:55 +00003856static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003857s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3858{
3859 IRTemp value = newTemp(Ity_I64);
3860
3861 assign(value, get_gpr_dw0(r3 | 1));
3862 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3863 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3864 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3865
3866 return "brxhg";
3867}
3868
florian55085f82012-11-21 00:36:55 +00003869static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003870s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3871{
3872 IRTemp value = newTemp(Ity_I32);
3873
3874 assign(value, get_gpr_w1(r3 | 1));
3875 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3876 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3877 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3878
3879 return "brxle";
3880}
3881
florian55085f82012-11-21 00:36:55 +00003882static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003883s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3884{
3885 IRTemp value = newTemp(Ity_I64);
3886
3887 assign(value, get_gpr_dw0(r3 | 1));
3888 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3889 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3890 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3891
3892 return "brxlg";
3893}
3894
florian55085f82012-11-21 00:36:55 +00003895static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003896s390_irgen_CR(UChar r1, UChar r2)
3897{
3898 IRTemp op1 = newTemp(Ity_I32);
3899 IRTemp op2 = newTemp(Ity_I32);
3900
3901 assign(op1, get_gpr_w1(r1));
3902 assign(op2, get_gpr_w1(r2));
3903 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3904
3905 return "cr";
3906}
3907
florian55085f82012-11-21 00:36:55 +00003908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003909s390_irgen_CGR(UChar r1, UChar r2)
3910{
3911 IRTemp op1 = newTemp(Ity_I64);
3912 IRTemp op2 = newTemp(Ity_I64);
3913
3914 assign(op1, get_gpr_dw0(r1));
3915 assign(op2, get_gpr_dw0(r2));
3916 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3917
3918 return "cgr";
3919}
3920
florian55085f82012-11-21 00:36:55 +00003921static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003922s390_irgen_CGFR(UChar r1, UChar r2)
3923{
3924 IRTemp op1 = newTemp(Ity_I64);
3925 IRTemp op2 = newTemp(Ity_I64);
3926
3927 assign(op1, get_gpr_dw0(r1));
3928 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3929 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3930
3931 return "cgfr";
3932}
3933
florian55085f82012-11-21 00:36:55 +00003934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003935s390_irgen_C(UChar r1, IRTemp op2addr)
3936{
3937 IRTemp op1 = newTemp(Ity_I32);
3938 IRTemp op2 = newTemp(Ity_I32);
3939
3940 assign(op1, get_gpr_w1(r1));
3941 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3942 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3943
3944 return "c";
3945}
3946
florian55085f82012-11-21 00:36:55 +00003947static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003948s390_irgen_CY(UChar r1, IRTemp op2addr)
3949{
3950 IRTemp op1 = newTemp(Ity_I32);
3951 IRTemp op2 = newTemp(Ity_I32);
3952
3953 assign(op1, get_gpr_w1(r1));
3954 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3955 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3956
3957 return "cy";
3958}
3959
florian55085f82012-11-21 00:36:55 +00003960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003961s390_irgen_CG(UChar r1, IRTemp op2addr)
3962{
3963 IRTemp op1 = newTemp(Ity_I64);
3964 IRTemp op2 = newTemp(Ity_I64);
3965
3966 assign(op1, get_gpr_dw0(r1));
3967 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3968 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3969
3970 return "cg";
3971}
3972
florian55085f82012-11-21 00:36:55 +00003973static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003974s390_irgen_CGF(UChar r1, IRTemp op2addr)
3975{
3976 IRTemp op1 = newTemp(Ity_I64);
3977 IRTemp op2 = newTemp(Ity_I64);
3978
3979 assign(op1, get_gpr_dw0(r1));
3980 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3981 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3982
3983 return "cgf";
3984}
3985
florian55085f82012-11-21 00:36:55 +00003986static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003987s390_irgen_CFI(UChar r1, UInt i2)
3988{
3989 IRTemp op1 = newTemp(Ity_I32);
3990 Int op2;
3991
3992 assign(op1, get_gpr_w1(r1));
3993 op2 = (Int)i2;
3994 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3995 mkU32((UInt)op2)));
3996
3997 return "cfi";
3998}
3999
florian55085f82012-11-21 00:36:55 +00004000static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004001s390_irgen_CGFI(UChar r1, UInt i2)
4002{
4003 IRTemp op1 = newTemp(Ity_I64);
4004 Long op2;
4005
4006 assign(op1, get_gpr_dw0(r1));
4007 op2 = (Long)(Int)i2;
4008 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4009 mkU64((ULong)op2)));
4010
4011 return "cgfi";
4012}
4013
florian55085f82012-11-21 00:36:55 +00004014static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004015s390_irgen_CRL(UChar r1, UInt i2)
4016{
4017 IRTemp op1 = newTemp(Ity_I32);
4018 IRTemp op2 = newTemp(Ity_I32);
4019
4020 assign(op1, get_gpr_w1(r1));
4021 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4022 i2 << 1))));
4023 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4024
4025 return "crl";
4026}
4027
florian55085f82012-11-21 00:36:55 +00004028static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004029s390_irgen_CGRL(UChar r1, UInt i2)
4030{
4031 IRTemp op1 = newTemp(Ity_I64);
4032 IRTemp op2 = newTemp(Ity_I64);
4033
4034 assign(op1, get_gpr_dw0(r1));
4035 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4036 i2 << 1))));
4037 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4038
4039 return "cgrl";
4040}
4041
florian55085f82012-11-21 00:36:55 +00004042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004043s390_irgen_CGFRL(UChar r1, UInt i2)
4044{
4045 IRTemp op1 = newTemp(Ity_I64);
4046 IRTemp op2 = newTemp(Ity_I64);
4047
4048 assign(op1, get_gpr_dw0(r1));
4049 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4050 ((ULong)(Long)(Int)i2 << 1)))));
4051 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4052
4053 return "cgfrl";
4054}
4055
florian55085f82012-11-21 00:36:55 +00004056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004057s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4058{
4059 IRTemp op1 = newTemp(Ity_I32);
4060 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004061 IRTemp cond = newTemp(Ity_I32);
4062
4063 if (m3 == 0) {
4064 } else {
4065 if (m3 == 14) {
4066 always_goto(mkexpr(op4addr));
4067 } else {
4068 assign(op1, get_gpr_w1(r1));
4069 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004070 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4071 op1, op2));
florianf321da72012-07-21 20:32:57 +00004072 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4073 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004074 }
4075 }
4076
4077 return "crb";
4078}
4079
florian55085f82012-11-21 00:36:55 +00004080static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004081s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4082{
4083 IRTemp op1 = newTemp(Ity_I64);
4084 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004085 IRTemp cond = newTemp(Ity_I32);
4086
4087 if (m3 == 0) {
4088 } else {
4089 if (m3 == 14) {
4090 always_goto(mkexpr(op4addr));
4091 } else {
4092 assign(op1, get_gpr_dw0(r1));
4093 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004094 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4095 op1, op2));
florianf321da72012-07-21 20:32:57 +00004096 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4097 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004098 }
4099 }
4100
4101 return "cgrb";
4102}
4103
florian55085f82012-11-21 00:36:55 +00004104static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004105s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4106{
4107 IRTemp op1 = newTemp(Ity_I32);
4108 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004109 IRTemp cond = newTemp(Ity_I32);
4110
4111 if (m3 == 0) {
4112 } else {
4113 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004114 always_goto_and_chase(
4115 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004116 } else {
4117 assign(op1, get_gpr_w1(r1));
4118 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004119 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4120 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004121 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4122 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4123
4124 }
4125 }
4126
4127 return "crj";
4128}
4129
florian55085f82012-11-21 00:36:55 +00004130static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004131s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4132{
4133 IRTemp op1 = newTemp(Ity_I64);
4134 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004135 IRTemp cond = newTemp(Ity_I32);
4136
4137 if (m3 == 0) {
4138 } else {
4139 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004140 always_goto_and_chase(
4141 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004142 } else {
4143 assign(op1, get_gpr_dw0(r1));
4144 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004145 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4146 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004147 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4148 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4149
4150 }
4151 }
4152
4153 return "cgrj";
4154}
4155
florian55085f82012-11-21 00:36:55 +00004156static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004157s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4158{
4159 IRTemp op1 = newTemp(Ity_I32);
4160 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004161 IRTemp cond = newTemp(Ity_I32);
4162
4163 if (m3 == 0) {
4164 } else {
4165 if (m3 == 14) {
4166 always_goto(mkexpr(op4addr));
4167 } else {
4168 assign(op1, get_gpr_w1(r1));
4169 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004170 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4171 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004172 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4173 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004174 }
4175 }
4176
4177 return "cib";
4178}
4179
florian55085f82012-11-21 00:36:55 +00004180static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004181s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4182{
4183 IRTemp op1 = newTemp(Ity_I64);
4184 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004185 IRTemp cond = newTemp(Ity_I32);
4186
4187 if (m3 == 0) {
4188 } else {
4189 if (m3 == 14) {
4190 always_goto(mkexpr(op4addr));
4191 } else {
4192 assign(op1, get_gpr_dw0(r1));
4193 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004194 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4195 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004196 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4197 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004198 }
4199 }
4200
4201 return "cgib";
4202}
4203
florian55085f82012-11-21 00:36:55 +00004204static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004205s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4206{
4207 IRTemp op1 = newTemp(Ity_I32);
4208 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004209 IRTemp cond = newTemp(Ity_I32);
4210
4211 if (m3 == 0) {
4212 } else {
4213 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004214 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004215 } else {
4216 assign(op1, get_gpr_w1(r1));
4217 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004218 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4219 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004220 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4221 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4222
4223 }
4224 }
4225
4226 return "cij";
4227}
4228
florian55085f82012-11-21 00:36:55 +00004229static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004230s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4231{
4232 IRTemp op1 = newTemp(Ity_I64);
4233 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004234 IRTemp cond = newTemp(Ity_I32);
4235
4236 if (m3 == 0) {
4237 } else {
4238 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004239 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004240 } else {
4241 assign(op1, get_gpr_dw0(r1));
4242 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004243 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4244 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004245 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4246 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4247
4248 }
4249 }
4250
4251 return "cgij";
4252}
4253
florian55085f82012-11-21 00:36:55 +00004254static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004255s390_irgen_CH(UChar r1, IRTemp op2addr)
4256{
4257 IRTemp op1 = newTemp(Ity_I32);
4258 IRTemp op2 = newTemp(Ity_I32);
4259
4260 assign(op1, get_gpr_w1(r1));
4261 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4262 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4263
4264 return "ch";
4265}
4266
florian55085f82012-11-21 00:36:55 +00004267static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004268s390_irgen_CHY(UChar r1, IRTemp op2addr)
4269{
4270 IRTemp op1 = newTemp(Ity_I32);
4271 IRTemp op2 = newTemp(Ity_I32);
4272
4273 assign(op1, get_gpr_w1(r1));
4274 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4275 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4276
4277 return "chy";
4278}
4279
florian55085f82012-11-21 00:36:55 +00004280static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004281s390_irgen_CGH(UChar r1, IRTemp op2addr)
4282{
4283 IRTemp op1 = newTemp(Ity_I64);
4284 IRTemp op2 = newTemp(Ity_I64);
4285
4286 assign(op1, get_gpr_dw0(r1));
4287 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4288 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4289
4290 return "cgh";
4291}
4292
florian55085f82012-11-21 00:36:55 +00004293static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004294s390_irgen_CHI(UChar r1, UShort i2)
4295{
4296 IRTemp op1 = newTemp(Ity_I32);
4297 Int op2;
4298
4299 assign(op1, get_gpr_w1(r1));
4300 op2 = (Int)(Short)i2;
4301 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4302 mkU32((UInt)op2)));
4303
4304 return "chi";
4305}
4306
florian55085f82012-11-21 00:36:55 +00004307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004308s390_irgen_CGHI(UChar r1, UShort i2)
4309{
4310 IRTemp op1 = newTemp(Ity_I64);
4311 Long op2;
4312
4313 assign(op1, get_gpr_dw0(r1));
4314 op2 = (Long)(Short)i2;
4315 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4316 mkU64((ULong)op2)));
4317
4318 return "cghi";
4319}
4320
florian55085f82012-11-21 00:36:55 +00004321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004322s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4323{
4324 IRTemp op1 = newTemp(Ity_I16);
4325 Short op2;
4326
4327 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4328 op2 = (Short)i2;
4329 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4330 mkU16((UShort)op2)));
4331
4332 return "chhsi";
4333}
4334
florian55085f82012-11-21 00:36:55 +00004335static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004336s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4337{
4338 IRTemp op1 = newTemp(Ity_I32);
4339 Int op2;
4340
4341 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4342 op2 = (Int)(Short)i2;
4343 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4344 mkU32((UInt)op2)));
4345
4346 return "chsi";
4347}
4348
florian55085f82012-11-21 00:36:55 +00004349static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004350s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4351{
4352 IRTemp op1 = newTemp(Ity_I64);
4353 Long op2;
4354
4355 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4356 op2 = (Long)(Short)i2;
4357 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4358 mkU64((ULong)op2)));
4359
4360 return "cghsi";
4361}
4362
florian55085f82012-11-21 00:36:55 +00004363static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004364s390_irgen_CHRL(UChar r1, UInt i2)
4365{
4366 IRTemp op1 = newTemp(Ity_I32);
4367 IRTemp op2 = newTemp(Ity_I32);
4368
4369 assign(op1, get_gpr_w1(r1));
4370 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4371 ((ULong)(Long)(Int)i2 << 1)))));
4372 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4373
4374 return "chrl";
4375}
4376
florian55085f82012-11-21 00:36:55 +00004377static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004378s390_irgen_CGHRL(UChar r1, UInt i2)
4379{
4380 IRTemp op1 = newTemp(Ity_I64);
4381 IRTemp op2 = newTemp(Ity_I64);
4382
4383 assign(op1, get_gpr_dw0(r1));
4384 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4385 ((ULong)(Long)(Int)i2 << 1)))));
4386 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4387
4388 return "cghrl";
4389}
4390
florian55085f82012-11-21 00:36:55 +00004391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004392s390_irgen_CHHR(UChar r1, UChar r2)
4393{
4394 IRTemp op1 = newTemp(Ity_I32);
4395 IRTemp op2 = newTemp(Ity_I32);
4396
4397 assign(op1, get_gpr_w0(r1));
4398 assign(op2, get_gpr_w0(r2));
4399 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4400
4401 return "chhr";
4402}
4403
florian55085f82012-11-21 00:36:55 +00004404static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004405s390_irgen_CHLR(UChar r1, UChar r2)
4406{
4407 IRTemp op1 = newTemp(Ity_I32);
4408 IRTemp op2 = newTemp(Ity_I32);
4409
4410 assign(op1, get_gpr_w0(r1));
4411 assign(op2, get_gpr_w1(r2));
4412 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4413
4414 return "chlr";
4415}
4416
florian55085f82012-11-21 00:36:55 +00004417static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004418s390_irgen_CHF(UChar r1, IRTemp op2addr)
4419{
4420 IRTemp op1 = newTemp(Ity_I32);
4421 IRTemp op2 = newTemp(Ity_I32);
4422
4423 assign(op1, get_gpr_w0(r1));
4424 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4425 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4426
4427 return "chf";
4428}
4429
florian55085f82012-11-21 00:36:55 +00004430static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004431s390_irgen_CIH(UChar r1, UInt i2)
4432{
4433 IRTemp op1 = newTemp(Ity_I32);
4434 Int op2;
4435
4436 assign(op1, get_gpr_w0(r1));
4437 op2 = (Int)i2;
4438 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4439 mkU32((UInt)op2)));
4440
4441 return "cih";
4442}
4443
florian55085f82012-11-21 00:36:55 +00004444static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004445s390_irgen_CLR(UChar r1, UChar r2)
4446{
4447 IRTemp op1 = newTemp(Ity_I32);
4448 IRTemp op2 = newTemp(Ity_I32);
4449
4450 assign(op1, get_gpr_w1(r1));
4451 assign(op2, get_gpr_w1(r2));
4452 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4453
4454 return "clr";
4455}
4456
florian55085f82012-11-21 00:36:55 +00004457static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004458s390_irgen_CLGR(UChar r1, UChar r2)
4459{
4460 IRTemp op1 = newTemp(Ity_I64);
4461 IRTemp op2 = newTemp(Ity_I64);
4462
4463 assign(op1, get_gpr_dw0(r1));
4464 assign(op2, get_gpr_dw0(r2));
4465 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4466
4467 return "clgr";
4468}
4469
florian55085f82012-11-21 00:36:55 +00004470static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004471s390_irgen_CLGFR(UChar r1, UChar r2)
4472{
4473 IRTemp op1 = newTemp(Ity_I64);
4474 IRTemp op2 = newTemp(Ity_I64);
4475
4476 assign(op1, get_gpr_dw0(r1));
4477 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4478 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4479
4480 return "clgfr";
4481}
4482
florian55085f82012-11-21 00:36:55 +00004483static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004484s390_irgen_CL(UChar r1, IRTemp op2addr)
4485{
4486 IRTemp op1 = newTemp(Ity_I32);
4487 IRTemp op2 = newTemp(Ity_I32);
4488
4489 assign(op1, get_gpr_w1(r1));
4490 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4491 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4492
4493 return "cl";
4494}
4495
florian55085f82012-11-21 00:36:55 +00004496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004497s390_irgen_CLY(UChar r1, IRTemp op2addr)
4498{
4499 IRTemp op1 = newTemp(Ity_I32);
4500 IRTemp op2 = newTemp(Ity_I32);
4501
4502 assign(op1, get_gpr_w1(r1));
4503 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4504 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4505
4506 return "cly";
4507}
4508
florian55085f82012-11-21 00:36:55 +00004509static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004510s390_irgen_CLG(UChar r1, IRTemp op2addr)
4511{
4512 IRTemp op1 = newTemp(Ity_I64);
4513 IRTemp op2 = newTemp(Ity_I64);
4514
4515 assign(op1, get_gpr_dw0(r1));
4516 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4517 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4518
4519 return "clg";
4520}
4521
florian55085f82012-11-21 00:36:55 +00004522static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004523s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4524{
4525 IRTemp op1 = newTemp(Ity_I64);
4526 IRTemp op2 = newTemp(Ity_I64);
4527
4528 assign(op1, get_gpr_dw0(r1));
4529 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4530 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4531
4532 return "clgf";
4533}
4534
florian55085f82012-11-21 00:36:55 +00004535static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004536s390_irgen_CLFI(UChar r1, UInt i2)
4537{
4538 IRTemp op1 = newTemp(Ity_I32);
4539 UInt op2;
4540
4541 assign(op1, get_gpr_w1(r1));
4542 op2 = i2;
4543 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4544 mkU32(op2)));
4545
4546 return "clfi";
4547}
4548
florian55085f82012-11-21 00:36:55 +00004549static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004550s390_irgen_CLGFI(UChar r1, UInt i2)
4551{
4552 IRTemp op1 = newTemp(Ity_I64);
4553 ULong op2;
4554
4555 assign(op1, get_gpr_dw0(r1));
4556 op2 = (ULong)i2;
4557 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4558 mkU64(op2)));
4559
4560 return "clgfi";
4561}
4562
florian55085f82012-11-21 00:36:55 +00004563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004564s390_irgen_CLI(UChar i2, IRTemp op1addr)
4565{
4566 IRTemp op1 = newTemp(Ity_I8);
4567 UChar op2;
4568
4569 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4570 op2 = i2;
4571 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4572 mkU8(op2)));
4573
4574 return "cli";
4575}
4576
florian55085f82012-11-21 00:36:55 +00004577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004578s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4579{
4580 IRTemp op1 = newTemp(Ity_I8);
4581 UChar op2;
4582
4583 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4584 op2 = i2;
4585 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4586 mkU8(op2)));
4587
4588 return "cliy";
4589}
4590
florian55085f82012-11-21 00:36:55 +00004591static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004592s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4593{
4594 IRTemp op1 = newTemp(Ity_I32);
4595 UInt op2;
4596
4597 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4598 op2 = (UInt)i2;
4599 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4600 mkU32(op2)));
4601
4602 return "clfhsi";
4603}
4604
florian55085f82012-11-21 00:36:55 +00004605static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004606s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4607{
4608 IRTemp op1 = newTemp(Ity_I64);
4609 ULong op2;
4610
4611 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4612 op2 = (ULong)i2;
4613 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4614 mkU64(op2)));
4615
4616 return "clghsi";
4617}
4618
florian55085f82012-11-21 00:36:55 +00004619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004620s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4621{
4622 IRTemp op1 = newTemp(Ity_I16);
4623 UShort op2;
4624
4625 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4626 op2 = i2;
4627 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4628 mkU16(op2)));
4629
4630 return "clhhsi";
4631}
4632
florian55085f82012-11-21 00:36:55 +00004633static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004634s390_irgen_CLRL(UChar r1, UInt i2)
4635{
4636 IRTemp op1 = newTemp(Ity_I32);
4637 IRTemp op2 = newTemp(Ity_I32);
4638
4639 assign(op1, get_gpr_w1(r1));
4640 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4641 i2 << 1))));
4642 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4643
4644 return "clrl";
4645}
4646
florian55085f82012-11-21 00:36:55 +00004647static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004648s390_irgen_CLGRL(UChar r1, UInt i2)
4649{
4650 IRTemp op1 = newTemp(Ity_I64);
4651 IRTemp op2 = newTemp(Ity_I64);
4652
4653 assign(op1, get_gpr_dw0(r1));
4654 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4655 i2 << 1))));
4656 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4657
4658 return "clgrl";
4659}
4660
florian55085f82012-11-21 00:36:55 +00004661static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004662s390_irgen_CLGFRL(UChar r1, UInt i2)
4663{
4664 IRTemp op1 = newTemp(Ity_I64);
4665 IRTemp op2 = newTemp(Ity_I64);
4666
4667 assign(op1, get_gpr_dw0(r1));
4668 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4669 ((ULong)(Long)(Int)i2 << 1)))));
4670 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4671
4672 return "clgfrl";
4673}
4674
florian55085f82012-11-21 00:36:55 +00004675static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004676s390_irgen_CLHRL(UChar r1, UInt i2)
4677{
4678 IRTemp op1 = newTemp(Ity_I32);
4679 IRTemp op2 = newTemp(Ity_I32);
4680
4681 assign(op1, get_gpr_w1(r1));
4682 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4683 ((ULong)(Long)(Int)i2 << 1)))));
4684 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4685
4686 return "clhrl";
4687}
4688
florian55085f82012-11-21 00:36:55 +00004689static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004690s390_irgen_CLGHRL(UChar r1, UInt i2)
4691{
4692 IRTemp op1 = newTemp(Ity_I64);
4693 IRTemp op2 = newTemp(Ity_I64);
4694
4695 assign(op1, get_gpr_dw0(r1));
4696 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4697 ((ULong)(Long)(Int)i2 << 1)))));
4698 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4699
4700 return "clghrl";
4701}
4702
florian55085f82012-11-21 00:36:55 +00004703static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004704s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4705{
4706 IRTemp op1 = newTemp(Ity_I32);
4707 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004708 IRTemp cond = newTemp(Ity_I32);
4709
4710 if (m3 == 0) {
4711 } else {
4712 if (m3 == 14) {
4713 always_goto(mkexpr(op4addr));
4714 } else {
4715 assign(op1, get_gpr_w1(r1));
4716 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004717 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4718 op1, op2));
florianf321da72012-07-21 20:32:57 +00004719 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4720 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004721 }
4722 }
4723
4724 return "clrb";
4725}
4726
florian55085f82012-11-21 00:36:55 +00004727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004728s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4729{
4730 IRTemp op1 = newTemp(Ity_I64);
4731 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004732 IRTemp cond = newTemp(Ity_I32);
4733
4734 if (m3 == 0) {
4735 } else {
4736 if (m3 == 14) {
4737 always_goto(mkexpr(op4addr));
4738 } else {
4739 assign(op1, get_gpr_dw0(r1));
4740 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004741 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4742 op1, op2));
florianf321da72012-07-21 20:32:57 +00004743 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4744 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004745 }
4746 }
4747
4748 return "clgrb";
4749}
4750
florian55085f82012-11-21 00:36:55 +00004751static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004752s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4753{
4754 IRTemp op1 = newTemp(Ity_I32);
4755 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004756 IRTemp cond = newTemp(Ity_I32);
4757
4758 if (m3 == 0) {
4759 } else {
4760 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004761 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004762 } else {
4763 assign(op1, get_gpr_w1(r1));
4764 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004765 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4766 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004767 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4768 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4769
4770 }
4771 }
4772
4773 return "clrj";
4774}
4775
florian55085f82012-11-21 00:36:55 +00004776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004777s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4778{
4779 IRTemp op1 = newTemp(Ity_I64);
4780 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004781 IRTemp cond = newTemp(Ity_I32);
4782
4783 if (m3 == 0) {
4784 } else {
4785 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004786 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004787 } else {
4788 assign(op1, get_gpr_dw0(r1));
4789 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004790 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4791 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004792 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4793 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4794
4795 }
4796 }
4797
4798 return "clgrj";
4799}
4800
florian55085f82012-11-21 00:36:55 +00004801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004802s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4803{
4804 IRTemp op1 = newTemp(Ity_I32);
4805 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004806 IRTemp cond = newTemp(Ity_I32);
4807
4808 if (m3 == 0) {
4809 } else {
4810 if (m3 == 14) {
4811 always_goto(mkexpr(op4addr));
4812 } else {
4813 assign(op1, get_gpr_w1(r1));
4814 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004815 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4816 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004817 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4818 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004819 }
4820 }
4821
4822 return "clib";
4823}
4824
florian55085f82012-11-21 00:36:55 +00004825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004826s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4827{
4828 IRTemp op1 = newTemp(Ity_I64);
4829 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004830 IRTemp cond = newTemp(Ity_I32);
4831
4832 if (m3 == 0) {
4833 } else {
4834 if (m3 == 14) {
4835 always_goto(mkexpr(op4addr));
4836 } else {
4837 assign(op1, get_gpr_dw0(r1));
4838 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004839 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4840 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004841 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4842 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004843 }
4844 }
4845
4846 return "clgib";
4847}
4848
florian55085f82012-11-21 00:36:55 +00004849static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004850s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4851{
4852 IRTemp op1 = newTemp(Ity_I32);
4853 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004854 IRTemp cond = newTemp(Ity_I32);
4855
4856 if (m3 == 0) {
4857 } else {
4858 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004859 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004860 } else {
4861 assign(op1, get_gpr_w1(r1));
4862 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004863 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4864 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004865 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4866 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4867
4868 }
4869 }
4870
4871 return "clij";
4872}
4873
florian55085f82012-11-21 00:36:55 +00004874static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004875s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4876{
4877 IRTemp op1 = newTemp(Ity_I64);
4878 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004879 IRTemp cond = newTemp(Ity_I32);
4880
4881 if (m3 == 0) {
4882 } else {
4883 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004884 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004885 } else {
4886 assign(op1, get_gpr_dw0(r1));
4887 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004888 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4889 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004890 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4891 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4892
4893 }
4894 }
4895
4896 return "clgij";
4897}
4898
florian55085f82012-11-21 00:36:55 +00004899static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004900s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4901{
4902 IRTemp op1 = newTemp(Ity_I32);
4903 IRTemp op2 = newTemp(Ity_I32);
4904 IRTemp b0 = newTemp(Ity_I32);
4905 IRTemp b1 = newTemp(Ity_I32);
4906 IRTemp b2 = newTemp(Ity_I32);
4907 IRTemp b3 = newTemp(Ity_I32);
4908 IRTemp c0 = newTemp(Ity_I32);
4909 IRTemp c1 = newTemp(Ity_I32);
4910 IRTemp c2 = newTemp(Ity_I32);
4911 IRTemp c3 = newTemp(Ity_I32);
4912 UChar n;
4913
4914 n = 0;
4915 if ((r3 & 8) != 0) {
4916 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4917 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4918 n = n + 1;
4919 } else {
4920 assign(b0, mkU32(0));
4921 assign(c0, mkU32(0));
4922 }
4923 if ((r3 & 4) != 0) {
4924 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4925 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4926 mkU64(n)))));
4927 n = n + 1;
4928 } else {
4929 assign(b1, mkU32(0));
4930 assign(c1, mkU32(0));
4931 }
4932 if ((r3 & 2) != 0) {
4933 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4934 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4935 mkU64(n)))));
4936 n = n + 1;
4937 } else {
4938 assign(b2, mkU32(0));
4939 assign(c2, mkU32(0));
4940 }
4941 if ((r3 & 1) != 0) {
4942 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4943 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4944 mkU64(n)))));
4945 n = n + 1;
4946 } else {
4947 assign(b3, mkU32(0));
4948 assign(c3, mkU32(0));
4949 }
4950 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4951 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4952 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4953 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4954 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4955 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4956 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4957
4958 return "clm";
4959}
4960
florian55085f82012-11-21 00:36:55 +00004961static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004962s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4963{
4964 IRTemp op1 = newTemp(Ity_I32);
4965 IRTemp op2 = newTemp(Ity_I32);
4966 IRTemp b0 = newTemp(Ity_I32);
4967 IRTemp b1 = newTemp(Ity_I32);
4968 IRTemp b2 = newTemp(Ity_I32);
4969 IRTemp b3 = newTemp(Ity_I32);
4970 IRTemp c0 = newTemp(Ity_I32);
4971 IRTemp c1 = newTemp(Ity_I32);
4972 IRTemp c2 = newTemp(Ity_I32);
4973 IRTemp c3 = newTemp(Ity_I32);
4974 UChar n;
4975
4976 n = 0;
4977 if ((r3 & 8) != 0) {
4978 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4979 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4980 n = n + 1;
4981 } else {
4982 assign(b0, mkU32(0));
4983 assign(c0, mkU32(0));
4984 }
4985 if ((r3 & 4) != 0) {
4986 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4987 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4988 mkU64(n)))));
4989 n = n + 1;
4990 } else {
4991 assign(b1, mkU32(0));
4992 assign(c1, mkU32(0));
4993 }
4994 if ((r3 & 2) != 0) {
4995 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4996 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4997 mkU64(n)))));
4998 n = n + 1;
4999 } else {
5000 assign(b2, mkU32(0));
5001 assign(c2, mkU32(0));
5002 }
5003 if ((r3 & 1) != 0) {
5004 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
5005 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5006 mkU64(n)))));
5007 n = n + 1;
5008 } else {
5009 assign(b3, mkU32(0));
5010 assign(c3, mkU32(0));
5011 }
5012 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5013 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5014 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5015 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5016 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5017 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5018 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5019
5020 return "clmy";
5021}
5022
florian55085f82012-11-21 00:36:55 +00005023static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005024s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5025{
5026 IRTemp op1 = newTemp(Ity_I32);
5027 IRTemp op2 = newTemp(Ity_I32);
5028 IRTemp b0 = newTemp(Ity_I32);
5029 IRTemp b1 = newTemp(Ity_I32);
5030 IRTemp b2 = newTemp(Ity_I32);
5031 IRTemp b3 = newTemp(Ity_I32);
5032 IRTemp c0 = newTemp(Ity_I32);
5033 IRTemp c1 = newTemp(Ity_I32);
5034 IRTemp c2 = newTemp(Ity_I32);
5035 IRTemp c3 = newTemp(Ity_I32);
5036 UChar n;
5037
5038 n = 0;
5039 if ((r3 & 8) != 0) {
5040 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5041 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5042 n = n + 1;
5043 } else {
5044 assign(b0, mkU32(0));
5045 assign(c0, mkU32(0));
5046 }
5047 if ((r3 & 4) != 0) {
5048 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5049 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5050 mkU64(n)))));
5051 n = n + 1;
5052 } else {
5053 assign(b1, mkU32(0));
5054 assign(c1, mkU32(0));
5055 }
5056 if ((r3 & 2) != 0) {
5057 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5058 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5059 mkU64(n)))));
5060 n = n + 1;
5061 } else {
5062 assign(b2, mkU32(0));
5063 assign(c2, mkU32(0));
5064 }
5065 if ((r3 & 1) != 0) {
5066 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5067 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5068 mkU64(n)))));
5069 n = n + 1;
5070 } else {
5071 assign(b3, mkU32(0));
5072 assign(c3, mkU32(0));
5073 }
5074 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5075 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5076 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5077 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5078 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5079 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5080 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5081
5082 return "clmh";
5083}
5084
florian55085f82012-11-21 00:36:55 +00005085static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005086s390_irgen_CLHHR(UChar r1, UChar r2)
5087{
5088 IRTemp op1 = newTemp(Ity_I32);
5089 IRTemp op2 = newTemp(Ity_I32);
5090
5091 assign(op1, get_gpr_w0(r1));
5092 assign(op2, get_gpr_w0(r2));
5093 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5094
5095 return "clhhr";
5096}
5097
florian55085f82012-11-21 00:36:55 +00005098static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005099s390_irgen_CLHLR(UChar r1, UChar r2)
5100{
5101 IRTemp op1 = newTemp(Ity_I32);
5102 IRTemp op2 = newTemp(Ity_I32);
5103
5104 assign(op1, get_gpr_w0(r1));
5105 assign(op2, get_gpr_w1(r2));
5106 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5107
5108 return "clhlr";
5109}
5110
florian55085f82012-11-21 00:36:55 +00005111static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005112s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5113{
5114 IRTemp op1 = newTemp(Ity_I32);
5115 IRTemp op2 = newTemp(Ity_I32);
5116
5117 assign(op1, get_gpr_w0(r1));
5118 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5119 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5120
5121 return "clhf";
5122}
5123
florian55085f82012-11-21 00:36:55 +00005124static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005125s390_irgen_CLIH(UChar r1, UInt i2)
5126{
5127 IRTemp op1 = newTemp(Ity_I32);
5128 UInt op2;
5129
5130 assign(op1, get_gpr_w0(r1));
5131 op2 = i2;
5132 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5133 mkU32(op2)));
5134
5135 return "clih";
5136}
5137
florian55085f82012-11-21 00:36:55 +00005138static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005139s390_irgen_CPYA(UChar r1, UChar r2)
5140{
5141 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005142 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005143 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5144
5145 return "cpya";
5146}
5147
florian55085f82012-11-21 00:36:55 +00005148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005149s390_irgen_XR(UChar r1, UChar r2)
5150{
5151 IRTemp op1 = newTemp(Ity_I32);
5152 IRTemp op2 = newTemp(Ity_I32);
5153 IRTemp result = newTemp(Ity_I32);
5154
5155 if (r1 == r2) {
5156 assign(result, mkU32(0));
5157 } else {
5158 assign(op1, get_gpr_w1(r1));
5159 assign(op2, get_gpr_w1(r2));
5160 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5161 }
5162 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5163 put_gpr_w1(r1, mkexpr(result));
5164
5165 return "xr";
5166}
5167
florian55085f82012-11-21 00:36:55 +00005168static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005169s390_irgen_XGR(UChar r1, UChar r2)
5170{
5171 IRTemp op1 = newTemp(Ity_I64);
5172 IRTemp op2 = newTemp(Ity_I64);
5173 IRTemp result = newTemp(Ity_I64);
5174
5175 if (r1 == r2) {
5176 assign(result, mkU64(0));
5177 } else {
5178 assign(op1, get_gpr_dw0(r1));
5179 assign(op2, get_gpr_dw0(r2));
5180 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5181 }
5182 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5183 put_gpr_dw0(r1, mkexpr(result));
5184
5185 return "xgr";
5186}
5187
florian55085f82012-11-21 00:36:55 +00005188static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005189s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5190{
5191 IRTemp op2 = newTemp(Ity_I32);
5192 IRTemp op3 = newTemp(Ity_I32);
5193 IRTemp result = newTemp(Ity_I32);
5194
5195 assign(op2, get_gpr_w1(r2));
5196 assign(op3, get_gpr_w1(r3));
5197 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5198 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5199 put_gpr_w1(r1, mkexpr(result));
5200
5201 return "xrk";
5202}
5203
florian55085f82012-11-21 00:36:55 +00005204static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005205s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5206{
5207 IRTemp op2 = newTemp(Ity_I64);
5208 IRTemp op3 = newTemp(Ity_I64);
5209 IRTemp result = newTemp(Ity_I64);
5210
5211 assign(op2, get_gpr_dw0(r2));
5212 assign(op3, get_gpr_dw0(r3));
5213 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5214 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5215 put_gpr_dw0(r1, mkexpr(result));
5216
5217 return "xgrk";
5218}
5219
florian55085f82012-11-21 00:36:55 +00005220static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005221s390_irgen_X(UChar r1, IRTemp op2addr)
5222{
5223 IRTemp op1 = newTemp(Ity_I32);
5224 IRTemp op2 = newTemp(Ity_I32);
5225 IRTemp result = newTemp(Ity_I32);
5226
5227 assign(op1, get_gpr_w1(r1));
5228 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5229 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5230 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5231 put_gpr_w1(r1, mkexpr(result));
5232
5233 return "x";
5234}
5235
florian55085f82012-11-21 00:36:55 +00005236static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005237s390_irgen_XY(UChar r1, IRTemp op2addr)
5238{
5239 IRTemp op1 = newTemp(Ity_I32);
5240 IRTemp op2 = newTemp(Ity_I32);
5241 IRTemp result = newTemp(Ity_I32);
5242
5243 assign(op1, get_gpr_w1(r1));
5244 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5245 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5246 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5247 put_gpr_w1(r1, mkexpr(result));
5248
5249 return "xy";
5250}
5251
florian55085f82012-11-21 00:36:55 +00005252static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005253s390_irgen_XG(UChar r1, IRTemp op2addr)
5254{
5255 IRTemp op1 = newTemp(Ity_I64);
5256 IRTemp op2 = newTemp(Ity_I64);
5257 IRTemp result = newTemp(Ity_I64);
5258
5259 assign(op1, get_gpr_dw0(r1));
5260 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5261 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5262 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5263 put_gpr_dw0(r1, mkexpr(result));
5264
5265 return "xg";
5266}
5267
florian55085f82012-11-21 00:36:55 +00005268static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005269s390_irgen_XI(UChar i2, IRTemp op1addr)
5270{
5271 IRTemp op1 = newTemp(Ity_I8);
5272 UChar op2;
5273 IRTemp result = newTemp(Ity_I8);
5274
5275 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5276 op2 = i2;
5277 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5278 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5279 store(mkexpr(op1addr), mkexpr(result));
5280
5281 return "xi";
5282}
5283
florian55085f82012-11-21 00:36:55 +00005284static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005285s390_irgen_XIY(UChar i2, IRTemp op1addr)
5286{
5287 IRTemp op1 = newTemp(Ity_I8);
5288 UChar op2;
5289 IRTemp result = newTemp(Ity_I8);
5290
5291 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5292 op2 = i2;
5293 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5294 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5295 store(mkexpr(op1addr), mkexpr(result));
5296
5297 return "xiy";
5298}
5299
florian55085f82012-11-21 00:36:55 +00005300static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005301s390_irgen_XIHF(UChar r1, UInt i2)
5302{
5303 IRTemp op1 = newTemp(Ity_I32);
5304 UInt op2;
5305 IRTemp result = newTemp(Ity_I32);
5306
5307 assign(op1, get_gpr_w0(r1));
5308 op2 = i2;
5309 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5310 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5311 put_gpr_w0(r1, mkexpr(result));
5312
5313 return "xihf";
5314}
5315
florian55085f82012-11-21 00:36:55 +00005316static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005317s390_irgen_XILF(UChar r1, UInt i2)
5318{
5319 IRTemp op1 = newTemp(Ity_I32);
5320 UInt op2;
5321 IRTemp result = newTemp(Ity_I32);
5322
5323 assign(op1, get_gpr_w1(r1));
5324 op2 = i2;
5325 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5326 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5327 put_gpr_w1(r1, mkexpr(result));
5328
5329 return "xilf";
5330}
5331
florian55085f82012-11-21 00:36:55 +00005332static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005333s390_irgen_EAR(UChar r1, UChar r2)
5334{
5335 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005336 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005337 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5338
5339 return "ear";
5340}
5341
florian55085f82012-11-21 00:36:55 +00005342static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005343s390_irgen_IC(UChar r1, IRTemp op2addr)
5344{
5345 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5346
5347 return "ic";
5348}
5349
florian55085f82012-11-21 00:36:55 +00005350static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005351s390_irgen_ICY(UChar r1, IRTemp op2addr)
5352{
5353 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5354
5355 return "icy";
5356}
5357
florian55085f82012-11-21 00:36:55 +00005358static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005359s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5360{
5361 UChar n;
5362 IRTemp result = newTemp(Ity_I32);
5363 UInt mask;
5364
5365 n = 0;
5366 mask = (UInt)r3;
5367 if ((mask & 8) != 0) {
5368 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5369 n = n + 1;
5370 }
5371 if ((mask & 4) != 0) {
5372 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5373
5374 n = n + 1;
5375 }
5376 if ((mask & 2) != 0) {
5377 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5378
5379 n = n + 1;
5380 }
5381 if ((mask & 1) != 0) {
5382 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5383
5384 n = n + 1;
5385 }
5386 assign(result, get_gpr_w1(r1));
5387 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5388 mkU32(mask)));
5389
5390 return "icm";
5391}
5392
florian55085f82012-11-21 00:36:55 +00005393static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005394s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5395{
5396 UChar n;
5397 IRTemp result = newTemp(Ity_I32);
5398 UInt mask;
5399
5400 n = 0;
5401 mask = (UInt)r3;
5402 if ((mask & 8) != 0) {
5403 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5404 n = n + 1;
5405 }
5406 if ((mask & 4) != 0) {
5407 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5408
5409 n = n + 1;
5410 }
5411 if ((mask & 2) != 0) {
5412 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5413
5414 n = n + 1;
5415 }
5416 if ((mask & 1) != 0) {
5417 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5418
5419 n = n + 1;
5420 }
5421 assign(result, get_gpr_w1(r1));
5422 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5423 mkU32(mask)));
5424
5425 return "icmy";
5426}
5427
florian55085f82012-11-21 00:36:55 +00005428static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005429s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5430{
5431 UChar n;
5432 IRTemp result = newTemp(Ity_I32);
5433 UInt mask;
5434
5435 n = 0;
5436 mask = (UInt)r3;
5437 if ((mask & 8) != 0) {
5438 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5439 n = n + 1;
5440 }
5441 if ((mask & 4) != 0) {
5442 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5443
5444 n = n + 1;
5445 }
5446 if ((mask & 2) != 0) {
5447 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5448
5449 n = n + 1;
5450 }
5451 if ((mask & 1) != 0) {
5452 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5453
5454 n = n + 1;
5455 }
5456 assign(result, get_gpr_w0(r1));
5457 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5458 mkU32(mask)));
5459
5460 return "icmh";
5461}
5462
florian55085f82012-11-21 00:36:55 +00005463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005464s390_irgen_IIHF(UChar r1, UInt i2)
5465{
5466 put_gpr_w0(r1, mkU32(i2));
5467
5468 return "iihf";
5469}
5470
florian55085f82012-11-21 00:36:55 +00005471static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005472s390_irgen_IIHH(UChar r1, UShort i2)
5473{
5474 put_gpr_hw0(r1, mkU16(i2));
5475
5476 return "iihh";
5477}
5478
florian55085f82012-11-21 00:36:55 +00005479static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005480s390_irgen_IIHL(UChar r1, UShort i2)
5481{
5482 put_gpr_hw1(r1, mkU16(i2));
5483
5484 return "iihl";
5485}
5486
florian55085f82012-11-21 00:36:55 +00005487static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005488s390_irgen_IILF(UChar r1, UInt i2)
5489{
5490 put_gpr_w1(r1, mkU32(i2));
5491
5492 return "iilf";
5493}
5494
florian55085f82012-11-21 00:36:55 +00005495static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005496s390_irgen_IILH(UChar r1, UShort i2)
5497{
5498 put_gpr_hw2(r1, mkU16(i2));
5499
5500 return "iilh";
5501}
5502
florian55085f82012-11-21 00:36:55 +00005503static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005504s390_irgen_IILL(UChar r1, UShort i2)
5505{
5506 put_gpr_hw3(r1, mkU16(i2));
5507
5508 return "iill";
5509}
5510
florian55085f82012-11-21 00:36:55 +00005511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005512s390_irgen_LR(UChar r1, UChar r2)
5513{
5514 put_gpr_w1(r1, get_gpr_w1(r2));
5515
5516 return "lr";
5517}
5518
florian55085f82012-11-21 00:36:55 +00005519static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005520s390_irgen_LGR(UChar r1, UChar r2)
5521{
5522 put_gpr_dw0(r1, get_gpr_dw0(r2));
5523
5524 return "lgr";
5525}
5526
florian55085f82012-11-21 00:36:55 +00005527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005528s390_irgen_LGFR(UChar r1, UChar r2)
5529{
5530 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5531
5532 return "lgfr";
5533}
5534
florian55085f82012-11-21 00:36:55 +00005535static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005536s390_irgen_L(UChar r1, IRTemp op2addr)
5537{
5538 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5539
5540 return "l";
5541}
5542
florian55085f82012-11-21 00:36:55 +00005543static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005544s390_irgen_LY(UChar r1, IRTemp op2addr)
5545{
5546 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5547
5548 return "ly";
5549}
5550
florian55085f82012-11-21 00:36:55 +00005551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005552s390_irgen_LG(UChar r1, IRTemp op2addr)
5553{
5554 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5555
5556 return "lg";
5557}
5558
florian55085f82012-11-21 00:36:55 +00005559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005560s390_irgen_LGF(UChar r1, IRTemp op2addr)
5561{
5562 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5563
5564 return "lgf";
5565}
5566
florian55085f82012-11-21 00:36:55 +00005567static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005568s390_irgen_LGFI(UChar r1, UInt i2)
5569{
5570 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5571
5572 return "lgfi";
5573}
5574
florian55085f82012-11-21 00:36:55 +00005575static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005576s390_irgen_LRL(UChar r1, UInt i2)
5577{
5578 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5579 i2 << 1))));
5580
5581 return "lrl";
5582}
5583
florian55085f82012-11-21 00:36:55 +00005584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005585s390_irgen_LGRL(UChar r1, UInt i2)
5586{
5587 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5588 i2 << 1))));
5589
5590 return "lgrl";
5591}
5592
florian55085f82012-11-21 00:36:55 +00005593static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005594s390_irgen_LGFRL(UChar r1, UInt i2)
5595{
5596 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5597 ((ULong)(Long)(Int)i2 << 1)))));
5598
5599 return "lgfrl";
5600}
5601
florian55085f82012-11-21 00:36:55 +00005602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005603s390_irgen_LA(UChar r1, IRTemp op2addr)
5604{
5605 put_gpr_dw0(r1, mkexpr(op2addr));
5606
5607 return "la";
5608}
5609
florian55085f82012-11-21 00:36:55 +00005610static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005611s390_irgen_LAY(UChar r1, IRTemp op2addr)
5612{
5613 put_gpr_dw0(r1, mkexpr(op2addr));
5614
5615 return "lay";
5616}
5617
florian55085f82012-11-21 00:36:55 +00005618static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005619s390_irgen_LAE(UChar r1, IRTemp op2addr)
5620{
5621 put_gpr_dw0(r1, mkexpr(op2addr));
5622
5623 return "lae";
5624}
5625
florian55085f82012-11-21 00:36:55 +00005626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005627s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5628{
5629 put_gpr_dw0(r1, mkexpr(op2addr));
5630
5631 return "laey";
5632}
5633
florian55085f82012-11-21 00:36:55 +00005634static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005635s390_irgen_LARL(UChar r1, UInt i2)
5636{
5637 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5638
5639 return "larl";
5640}
5641
floriana265ee72012-12-02 20:58:17 +00005642/* The IR representation of LAA and friends is an approximation of what
5643 happens natively. Essentially a loop containing a compare-and-swap is
5644 constructed which will iterate until the CAS succeeds. As a consequence,
5645 instrumenters may see more memory accesses than happen natively. See also
5646 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005647static void
5648s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005649{
floriana265ee72012-12-02 20:58:17 +00005650 IRCAS *cas;
5651 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005652 IRTemp op2 = newTemp(Ity_I32);
5653 IRTemp op3 = newTemp(Ity_I32);
5654 IRTemp result = newTemp(Ity_I32);
5655
5656 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5657 assign(op3, get_gpr_w1(r3));
5658 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005659
5660 /* Place the addition of second operand and third operand at the
5661 second-operand location everytime */
5662 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5663 Iend_BE, mkexpr(op2addr),
5664 NULL, mkexpr(op2), /* expected value */
5665 NULL, mkexpr(result) /* new value */);
5666 stmt(IRStmt_CAS(cas));
5667
florianffc94012012-12-02 21:31:15 +00005668 /* Set CC according to 32-bit addition */
5669 if (is_signed) {
5670 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5671 } else {
5672 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5673 }
floriana265ee72012-12-02 20:58:17 +00005674
5675 /* If old_mem contains the expected value, then the CAS succeeded.
5676 Otherwise, it did not */
5677 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5678 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005679}
5680
5681static void
5682s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5683{
5684 IRCAS *cas;
5685 IRTemp old_mem = newTemp(Ity_I64);
5686 IRTemp op2 = newTemp(Ity_I64);
5687 IRTemp op3 = newTemp(Ity_I64);
5688 IRTemp result = newTemp(Ity_I64);
5689
5690 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5691 assign(op3, get_gpr_dw0(r3));
5692 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5693
5694 /* Place the addition of second operand and third operand at the
5695 second-operand location everytime */
5696 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5697 Iend_BE, mkexpr(op2addr),
5698 NULL, mkexpr(op2), /* expected value */
5699 NULL, mkexpr(result) /* new value */);
5700 stmt(IRStmt_CAS(cas));
5701
5702 /* Set CC according to 64-bit addition */
5703 if (is_signed) {
5704 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5705 } else {
5706 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5707 }
5708
5709 /* If old_mem contains the expected value, then the CAS succeeded.
5710 Otherwise, it did not */
5711 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5712 put_gpr_dw0(r1, mkexpr(old_mem));
5713}
5714
5715static void
5716s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5717{
5718 IRCAS *cas;
5719 IRTemp old_mem = newTemp(Ity_I32);
5720 IRTemp op2 = newTemp(Ity_I32);
5721 IRTemp op3 = newTemp(Ity_I32);
5722 IRTemp result = newTemp(Ity_I32);
5723
5724 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5725 assign(op3, get_gpr_w1(r3));
5726 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5727
5728 /* Place the addition of second operand and third operand at the
5729 second-operand location everytime */
5730 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5731 Iend_BE, mkexpr(op2addr),
5732 NULL, mkexpr(op2), /* expected value */
5733 NULL, mkexpr(result) /* new value */);
5734 stmt(IRStmt_CAS(cas));
5735
5736 /* Set CC according to bitwise operation */
5737 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5738
5739 /* If old_mem contains the expected value, then the CAS succeeded.
5740 Otherwise, it did not */
5741 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5742 put_gpr_w1(r1, mkexpr(old_mem));
5743}
5744
5745static void
5746s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5747{
5748 IRCAS *cas;
5749 IRTemp old_mem = newTemp(Ity_I64);
5750 IRTemp op2 = newTemp(Ity_I64);
5751 IRTemp op3 = newTemp(Ity_I64);
5752 IRTemp result = newTemp(Ity_I64);
5753
5754 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5755 assign(op3, get_gpr_dw0(r3));
5756 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5757
5758 /* Place the addition of second operand and third operand at the
5759 second-operand location everytime */
5760 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5761 Iend_BE, mkexpr(op2addr),
5762 NULL, mkexpr(op2), /* expected value */
5763 NULL, mkexpr(result) /* new value */);
5764 stmt(IRStmt_CAS(cas));
5765
5766 /* Set CC according to bitwise operation */
5767 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5768
5769 /* If old_mem contains the expected value, then the CAS succeeded.
5770 Otherwise, it did not */
5771 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5772 put_gpr_dw0(r1, mkexpr(old_mem));
5773}
5774
5775static const HChar *
5776s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5777{
5778 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005779
5780 return "laa";
5781}
5782
florian55085f82012-11-21 00:36:55 +00005783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005784s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5785{
florianffc94012012-12-02 21:31:15 +00005786 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005787
5788 return "laag";
5789}
5790
florian55085f82012-11-21 00:36:55 +00005791static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005792s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5793{
florianffc94012012-12-02 21:31:15 +00005794 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005795
5796 return "laal";
5797}
5798
florian55085f82012-11-21 00:36:55 +00005799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005800s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5801{
florianffc94012012-12-02 21:31:15 +00005802 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005803
5804 return "laalg";
5805}
5806
florian55085f82012-11-21 00:36:55 +00005807static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005808s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5809{
florianffc94012012-12-02 21:31:15 +00005810 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005811
5812 return "lan";
5813}
5814
florian55085f82012-11-21 00:36:55 +00005815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005816s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5817{
florianffc94012012-12-02 21:31:15 +00005818 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005819
5820 return "lang";
5821}
5822
florian55085f82012-11-21 00:36:55 +00005823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005824s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5825{
florianffc94012012-12-02 21:31:15 +00005826 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005827
5828 return "lax";
5829}
5830
florian55085f82012-11-21 00:36:55 +00005831static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005832s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5833{
florianffc94012012-12-02 21:31:15 +00005834 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005835
5836 return "laxg";
5837}
5838
florian55085f82012-11-21 00:36:55 +00005839static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005840s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5841{
florianffc94012012-12-02 21:31:15 +00005842 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005843
5844 return "lao";
5845}
5846
florian55085f82012-11-21 00:36:55 +00005847static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005848s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5849{
florianffc94012012-12-02 21:31:15 +00005850 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005851
5852 return "laog";
5853}
5854
florian55085f82012-11-21 00:36:55 +00005855static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005856s390_irgen_LTR(UChar r1, UChar r2)
5857{
5858 IRTemp op2 = newTemp(Ity_I32);
5859
5860 assign(op2, get_gpr_w1(r2));
5861 put_gpr_w1(r1, mkexpr(op2));
5862 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5863
5864 return "ltr";
5865}
5866
florian55085f82012-11-21 00:36:55 +00005867static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005868s390_irgen_LTGR(UChar r1, UChar r2)
5869{
5870 IRTemp op2 = newTemp(Ity_I64);
5871
5872 assign(op2, get_gpr_dw0(r2));
5873 put_gpr_dw0(r1, mkexpr(op2));
5874 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5875
5876 return "ltgr";
5877}
5878
florian55085f82012-11-21 00:36:55 +00005879static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005880s390_irgen_LTGFR(UChar r1, UChar r2)
5881{
5882 IRTemp op2 = newTemp(Ity_I64);
5883
5884 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5885 put_gpr_dw0(r1, mkexpr(op2));
5886 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5887
5888 return "ltgfr";
5889}
5890
florian55085f82012-11-21 00:36:55 +00005891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005892s390_irgen_LT(UChar r1, IRTemp op2addr)
5893{
5894 IRTemp op2 = newTemp(Ity_I32);
5895
5896 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5897 put_gpr_w1(r1, mkexpr(op2));
5898 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5899
5900 return "lt";
5901}
5902
florian55085f82012-11-21 00:36:55 +00005903static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005904s390_irgen_LTG(UChar r1, IRTemp op2addr)
5905{
5906 IRTemp op2 = newTemp(Ity_I64);
5907
5908 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5909 put_gpr_dw0(r1, mkexpr(op2));
5910 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5911
5912 return "ltg";
5913}
5914
florian55085f82012-11-21 00:36:55 +00005915static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005916s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5917{
5918 IRTemp op2 = newTemp(Ity_I64);
5919
5920 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5921 put_gpr_dw0(r1, mkexpr(op2));
5922 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5923
5924 return "ltgf";
5925}
5926
florian55085f82012-11-21 00:36:55 +00005927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005928s390_irgen_LBR(UChar r1, UChar r2)
5929{
5930 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5931
5932 return "lbr";
5933}
5934
florian55085f82012-11-21 00:36:55 +00005935static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005936s390_irgen_LGBR(UChar r1, UChar r2)
5937{
5938 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5939
5940 return "lgbr";
5941}
5942
florian55085f82012-11-21 00:36:55 +00005943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005944s390_irgen_LB(UChar r1, IRTemp op2addr)
5945{
5946 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5947
5948 return "lb";
5949}
5950
florian55085f82012-11-21 00:36:55 +00005951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005952s390_irgen_LGB(UChar r1, IRTemp op2addr)
5953{
5954 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5955
5956 return "lgb";
5957}
5958
florian55085f82012-11-21 00:36:55 +00005959static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005960s390_irgen_LBH(UChar r1, IRTemp op2addr)
5961{
5962 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5963
5964 return "lbh";
5965}
5966
florian55085f82012-11-21 00:36:55 +00005967static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005968s390_irgen_LCR(UChar r1, UChar r2)
5969{
5970 Int op1;
5971 IRTemp op2 = newTemp(Ity_I32);
5972 IRTemp result = newTemp(Ity_I32);
5973
5974 op1 = 0;
5975 assign(op2, get_gpr_w1(r2));
5976 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5977 put_gpr_w1(r1, mkexpr(result));
5978 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5979 op1)), op2);
5980
5981 return "lcr";
5982}
5983
florian55085f82012-11-21 00:36:55 +00005984static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005985s390_irgen_LCGR(UChar r1, UChar r2)
5986{
5987 Long op1;
5988 IRTemp op2 = newTemp(Ity_I64);
5989 IRTemp result = newTemp(Ity_I64);
5990
5991 op1 = 0ULL;
5992 assign(op2, get_gpr_dw0(r2));
5993 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5994 put_gpr_dw0(r1, mkexpr(result));
5995 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5996 op1)), op2);
5997
5998 return "lcgr";
5999}
6000
florian55085f82012-11-21 00:36:55 +00006001static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006002s390_irgen_LCGFR(UChar r1, UChar r2)
6003{
6004 Long op1;
6005 IRTemp op2 = newTemp(Ity_I64);
6006 IRTemp result = newTemp(Ity_I64);
6007
6008 op1 = 0ULL;
6009 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6010 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6011 put_gpr_dw0(r1, mkexpr(result));
6012 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6013 op1)), op2);
6014
6015 return "lcgfr";
6016}
6017
florian55085f82012-11-21 00:36:55 +00006018static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006019s390_irgen_LHR(UChar r1, UChar r2)
6020{
6021 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
6022
6023 return "lhr";
6024}
6025
florian55085f82012-11-21 00:36:55 +00006026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006027s390_irgen_LGHR(UChar r1, UChar r2)
6028{
6029 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6030
6031 return "lghr";
6032}
6033
florian55085f82012-11-21 00:36:55 +00006034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006035s390_irgen_LH(UChar r1, IRTemp op2addr)
6036{
6037 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6038
6039 return "lh";
6040}
6041
florian55085f82012-11-21 00:36:55 +00006042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006043s390_irgen_LHY(UChar r1, IRTemp op2addr)
6044{
6045 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6046
6047 return "lhy";
6048}
6049
florian55085f82012-11-21 00:36:55 +00006050static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006051s390_irgen_LGH(UChar r1, IRTemp op2addr)
6052{
6053 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6054
6055 return "lgh";
6056}
6057
florian55085f82012-11-21 00:36:55 +00006058static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006059s390_irgen_LHI(UChar r1, UShort i2)
6060{
6061 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6062
6063 return "lhi";
6064}
6065
florian55085f82012-11-21 00:36:55 +00006066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006067s390_irgen_LGHI(UChar r1, UShort i2)
6068{
6069 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6070
6071 return "lghi";
6072}
6073
florian55085f82012-11-21 00:36:55 +00006074static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006075s390_irgen_LHRL(UChar r1, UInt i2)
6076{
6077 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6078 ((ULong)(Long)(Int)i2 << 1)))));
6079
6080 return "lhrl";
6081}
6082
florian55085f82012-11-21 00:36:55 +00006083static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006084s390_irgen_LGHRL(UChar r1, UInt i2)
6085{
6086 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6087 ((ULong)(Long)(Int)i2 << 1)))));
6088
6089 return "lghrl";
6090}
6091
florian55085f82012-11-21 00:36:55 +00006092static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006093s390_irgen_LHH(UChar r1, IRTemp op2addr)
6094{
6095 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6096
6097 return "lhh";
6098}
6099
florian55085f82012-11-21 00:36:55 +00006100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006101s390_irgen_LFH(UChar r1, IRTemp op2addr)
6102{
6103 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6104
6105 return "lfh";
6106}
6107
florian55085f82012-11-21 00:36:55 +00006108static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006109s390_irgen_LLGFR(UChar r1, UChar r2)
6110{
6111 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6112
6113 return "llgfr";
6114}
6115
florian55085f82012-11-21 00:36:55 +00006116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006117s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6118{
6119 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6120
6121 return "llgf";
6122}
6123
florian55085f82012-11-21 00:36:55 +00006124static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006125s390_irgen_LLGFRL(UChar r1, UInt i2)
6126{
6127 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6128 ((ULong)(Long)(Int)i2 << 1)))));
6129
6130 return "llgfrl";
6131}
6132
florian55085f82012-11-21 00:36:55 +00006133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006134s390_irgen_LLCR(UChar r1, UChar r2)
6135{
6136 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6137
6138 return "llcr";
6139}
6140
florian55085f82012-11-21 00:36:55 +00006141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006142s390_irgen_LLGCR(UChar r1, UChar r2)
6143{
6144 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6145
6146 return "llgcr";
6147}
6148
florian55085f82012-11-21 00:36:55 +00006149static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006150s390_irgen_LLC(UChar r1, IRTemp op2addr)
6151{
6152 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6153
6154 return "llc";
6155}
6156
florian55085f82012-11-21 00:36:55 +00006157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006158s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6159{
6160 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6161
6162 return "llgc";
6163}
6164
florian55085f82012-11-21 00:36:55 +00006165static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006166s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6167{
6168 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6169
6170 return "llch";
6171}
6172
florian55085f82012-11-21 00:36:55 +00006173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006174s390_irgen_LLHR(UChar r1, UChar r2)
6175{
6176 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6177
6178 return "llhr";
6179}
6180
florian55085f82012-11-21 00:36:55 +00006181static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006182s390_irgen_LLGHR(UChar r1, UChar r2)
6183{
6184 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6185
6186 return "llghr";
6187}
6188
florian55085f82012-11-21 00:36:55 +00006189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006190s390_irgen_LLH(UChar r1, IRTemp op2addr)
6191{
6192 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6193
6194 return "llh";
6195}
6196
florian55085f82012-11-21 00:36:55 +00006197static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006198s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6199{
6200 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6201
6202 return "llgh";
6203}
6204
florian55085f82012-11-21 00:36:55 +00006205static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006206s390_irgen_LLHRL(UChar r1, UInt i2)
6207{
6208 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6209 ((ULong)(Long)(Int)i2 << 1)))));
6210
6211 return "llhrl";
6212}
6213
florian55085f82012-11-21 00:36:55 +00006214static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006215s390_irgen_LLGHRL(UChar r1, UInt i2)
6216{
6217 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6218 ((ULong)(Long)(Int)i2 << 1)))));
6219
6220 return "llghrl";
6221}
6222
florian55085f82012-11-21 00:36:55 +00006223static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006224s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6225{
6226 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6227
6228 return "llhh";
6229}
6230
florian55085f82012-11-21 00:36:55 +00006231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006232s390_irgen_LLIHF(UChar r1, UInt i2)
6233{
6234 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6235
6236 return "llihf";
6237}
6238
florian55085f82012-11-21 00:36:55 +00006239static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006240s390_irgen_LLIHH(UChar r1, UShort i2)
6241{
6242 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6243
6244 return "llihh";
6245}
6246
florian55085f82012-11-21 00:36:55 +00006247static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006248s390_irgen_LLIHL(UChar r1, UShort i2)
6249{
6250 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6251
6252 return "llihl";
6253}
6254
florian55085f82012-11-21 00:36:55 +00006255static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006256s390_irgen_LLILF(UChar r1, UInt i2)
6257{
6258 put_gpr_dw0(r1, mkU64(i2));
6259
6260 return "llilf";
6261}
6262
florian55085f82012-11-21 00:36:55 +00006263static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006264s390_irgen_LLILH(UChar r1, UShort i2)
6265{
6266 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6267
6268 return "llilh";
6269}
6270
florian55085f82012-11-21 00:36:55 +00006271static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006272s390_irgen_LLILL(UChar r1, UShort i2)
6273{
6274 put_gpr_dw0(r1, mkU64(i2));
6275
6276 return "llill";
6277}
6278
florian55085f82012-11-21 00:36:55 +00006279static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006280s390_irgen_LLGTR(UChar r1, UChar r2)
6281{
6282 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6283 mkU32(2147483647))));
6284
6285 return "llgtr";
6286}
6287
florian55085f82012-11-21 00:36:55 +00006288static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006289s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6290{
6291 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6292 mkexpr(op2addr)), mkU32(2147483647))));
6293
6294 return "llgt";
6295}
6296
florian55085f82012-11-21 00:36:55 +00006297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006298s390_irgen_LNR(UChar r1, UChar r2)
6299{
6300 IRTemp op2 = newTemp(Ity_I32);
6301 IRTemp result = newTemp(Ity_I32);
6302
6303 assign(op2, get_gpr_w1(r2));
6304 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6305 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6306 put_gpr_w1(r1, mkexpr(result));
6307 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6308
6309 return "lnr";
6310}
6311
florian55085f82012-11-21 00:36:55 +00006312static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006313s390_irgen_LNGR(UChar r1, UChar r2)
6314{
6315 IRTemp op2 = newTemp(Ity_I64);
6316 IRTemp result = newTemp(Ity_I64);
6317
6318 assign(op2, get_gpr_dw0(r2));
6319 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6320 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6321 put_gpr_dw0(r1, mkexpr(result));
6322 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6323
6324 return "lngr";
6325}
6326
florian55085f82012-11-21 00:36:55 +00006327static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006328s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6329{
6330 IRTemp op2 = newTemp(Ity_I64);
6331 IRTemp result = newTemp(Ity_I64);
6332
6333 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6334 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6335 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6336 put_gpr_dw0(r1, mkexpr(result));
6337 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6338
6339 return "lngfr";
6340}
6341
florian55085f82012-11-21 00:36:55 +00006342static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006343s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6344{
florian6820ba52012-07-26 02:01:50 +00006345 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006346 put_gpr_w1(r1, get_gpr_w1(r2));
6347
6348 return "locr";
6349}
6350
florian55085f82012-11-21 00:36:55 +00006351static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006352s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6353{
florian6820ba52012-07-26 02:01:50 +00006354 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006355 put_gpr_dw0(r1, get_gpr_dw0(r2));
6356
6357 return "locgr";
6358}
6359
florian55085f82012-11-21 00:36:55 +00006360static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006361s390_irgen_LOC(UChar r1, IRTemp op2addr)
6362{
6363 /* condition is checked in format handler */
6364 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6365
6366 return "loc";
6367}
6368
florian55085f82012-11-21 00:36:55 +00006369static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006370s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6371{
6372 /* condition is checked in format handler */
6373 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6374
6375 return "locg";
6376}
6377
florian55085f82012-11-21 00:36:55 +00006378static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006379s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6380{
6381 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6382 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6383 ));
6384
6385 return "lpq";
6386}
6387
florian55085f82012-11-21 00:36:55 +00006388static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006389s390_irgen_LPR(UChar r1, UChar r2)
6390{
6391 IRTemp op2 = newTemp(Ity_I32);
6392 IRTemp result = newTemp(Ity_I32);
6393
6394 assign(op2, get_gpr_w1(r2));
6395 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6396 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6397 put_gpr_w1(r1, mkexpr(result));
6398 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6399
6400 return "lpr";
6401}
6402
florian55085f82012-11-21 00:36:55 +00006403static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006404s390_irgen_LPGR(UChar r1, UChar r2)
6405{
6406 IRTemp op2 = newTemp(Ity_I64);
6407 IRTemp result = newTemp(Ity_I64);
6408
6409 assign(op2, get_gpr_dw0(r2));
6410 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6411 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6412 put_gpr_dw0(r1, mkexpr(result));
6413 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6414
6415 return "lpgr";
6416}
6417
florian55085f82012-11-21 00:36:55 +00006418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006419s390_irgen_LPGFR(UChar r1, UChar r2)
6420{
6421 IRTemp op2 = newTemp(Ity_I64);
6422 IRTemp result = newTemp(Ity_I64);
6423
6424 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6425 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6426 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6427 put_gpr_dw0(r1, mkexpr(result));
6428 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6429
6430 return "lpgfr";
6431}
6432
florian55085f82012-11-21 00:36:55 +00006433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006434s390_irgen_LRVR(UChar r1, UChar r2)
6435{
6436 IRTemp b0 = newTemp(Ity_I8);
6437 IRTemp b1 = newTemp(Ity_I8);
6438 IRTemp b2 = newTemp(Ity_I8);
6439 IRTemp b3 = newTemp(Ity_I8);
6440
6441 assign(b3, get_gpr_b7(r2));
6442 assign(b2, get_gpr_b6(r2));
6443 assign(b1, get_gpr_b5(r2));
6444 assign(b0, get_gpr_b4(r2));
6445 put_gpr_b4(r1, mkexpr(b3));
6446 put_gpr_b5(r1, mkexpr(b2));
6447 put_gpr_b6(r1, mkexpr(b1));
6448 put_gpr_b7(r1, mkexpr(b0));
6449
6450 return "lrvr";
6451}
6452
florian55085f82012-11-21 00:36:55 +00006453static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006454s390_irgen_LRVGR(UChar r1, UChar r2)
6455{
6456 IRTemp b0 = newTemp(Ity_I8);
6457 IRTemp b1 = newTemp(Ity_I8);
6458 IRTemp b2 = newTemp(Ity_I8);
6459 IRTemp b3 = newTemp(Ity_I8);
6460 IRTemp b4 = newTemp(Ity_I8);
6461 IRTemp b5 = newTemp(Ity_I8);
6462 IRTemp b6 = newTemp(Ity_I8);
6463 IRTemp b7 = newTemp(Ity_I8);
6464
6465 assign(b7, get_gpr_b7(r2));
6466 assign(b6, get_gpr_b6(r2));
6467 assign(b5, get_gpr_b5(r2));
6468 assign(b4, get_gpr_b4(r2));
6469 assign(b3, get_gpr_b3(r2));
6470 assign(b2, get_gpr_b2(r2));
6471 assign(b1, get_gpr_b1(r2));
6472 assign(b0, get_gpr_b0(r2));
6473 put_gpr_b0(r1, mkexpr(b7));
6474 put_gpr_b1(r1, mkexpr(b6));
6475 put_gpr_b2(r1, mkexpr(b5));
6476 put_gpr_b3(r1, mkexpr(b4));
6477 put_gpr_b4(r1, mkexpr(b3));
6478 put_gpr_b5(r1, mkexpr(b2));
6479 put_gpr_b6(r1, mkexpr(b1));
6480 put_gpr_b7(r1, mkexpr(b0));
6481
6482 return "lrvgr";
6483}
6484
florian55085f82012-11-21 00:36:55 +00006485static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006486s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6487{
6488 IRTemp op2 = newTemp(Ity_I16);
6489
6490 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6491 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6492 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6493
6494 return "lrvh";
6495}
6496
florian55085f82012-11-21 00:36:55 +00006497static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006498s390_irgen_LRV(UChar r1, IRTemp op2addr)
6499{
6500 IRTemp op2 = newTemp(Ity_I32);
6501
6502 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6503 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6504 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6505 mkU8(8)), mkU32(255))));
6506 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6507 mkU8(16)), mkU32(255))));
6508 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6509 mkU8(24)), mkU32(255))));
6510
6511 return "lrv";
6512}
6513
florian55085f82012-11-21 00:36:55 +00006514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006515s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6516{
6517 IRTemp op2 = newTemp(Ity_I64);
6518
6519 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6520 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6521 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6522 mkU8(8)), mkU64(255))));
6523 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6524 mkU8(16)), mkU64(255))));
6525 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6526 mkU8(24)), mkU64(255))));
6527 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6528 mkU8(32)), mkU64(255))));
6529 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6530 mkU8(40)), mkU64(255))));
6531 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6532 mkU8(48)), mkU64(255))));
6533 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6534 mkU8(56)), mkU64(255))));
6535
6536 return "lrvg";
6537}
6538
florian55085f82012-11-21 00:36:55 +00006539static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006540s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6541{
6542 store(mkexpr(op1addr), mkU16(i2));
6543
6544 return "mvhhi";
6545}
6546
florian55085f82012-11-21 00:36:55 +00006547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006548s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6549{
6550 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6551
6552 return "mvhi";
6553}
6554
florian55085f82012-11-21 00:36:55 +00006555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006556s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6557{
6558 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6559
6560 return "mvghi";
6561}
6562
florian55085f82012-11-21 00:36:55 +00006563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006564s390_irgen_MVI(UChar i2, IRTemp op1addr)
6565{
6566 store(mkexpr(op1addr), mkU8(i2));
6567
6568 return "mvi";
6569}
6570
florian55085f82012-11-21 00:36:55 +00006571static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006572s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6573{
6574 store(mkexpr(op1addr), mkU8(i2));
6575
6576 return "mviy";
6577}
6578
florian55085f82012-11-21 00:36:55 +00006579static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006580s390_irgen_MR(UChar r1, UChar r2)
6581{
6582 IRTemp op1 = newTemp(Ity_I32);
6583 IRTemp op2 = newTemp(Ity_I32);
6584 IRTemp result = newTemp(Ity_I64);
6585
6586 assign(op1, get_gpr_w1(r1 + 1));
6587 assign(op2, get_gpr_w1(r2));
6588 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6589 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6590 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6591
6592 return "mr";
6593}
6594
florian55085f82012-11-21 00:36:55 +00006595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006596s390_irgen_M(UChar r1, IRTemp op2addr)
6597{
6598 IRTemp op1 = newTemp(Ity_I32);
6599 IRTemp op2 = newTemp(Ity_I32);
6600 IRTemp result = newTemp(Ity_I64);
6601
6602 assign(op1, get_gpr_w1(r1 + 1));
6603 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6604 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6605 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6606 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6607
6608 return "m";
6609}
6610
florian55085f82012-11-21 00:36:55 +00006611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006612s390_irgen_MFY(UChar r1, IRTemp op2addr)
6613{
6614 IRTemp op1 = newTemp(Ity_I32);
6615 IRTemp op2 = newTemp(Ity_I32);
6616 IRTemp result = newTemp(Ity_I64);
6617
6618 assign(op1, get_gpr_w1(r1 + 1));
6619 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6620 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6621 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6622 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6623
6624 return "mfy";
6625}
6626
florian55085f82012-11-21 00:36:55 +00006627static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006628s390_irgen_MH(UChar r1, IRTemp op2addr)
6629{
6630 IRTemp op1 = newTemp(Ity_I32);
6631 IRTemp op2 = newTemp(Ity_I16);
6632 IRTemp result = newTemp(Ity_I64);
6633
6634 assign(op1, get_gpr_w1(r1));
6635 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6636 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6637 ));
6638 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6639
6640 return "mh";
6641}
6642
florian55085f82012-11-21 00:36:55 +00006643static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006644s390_irgen_MHY(UChar r1, IRTemp op2addr)
6645{
6646 IRTemp op1 = newTemp(Ity_I32);
6647 IRTemp op2 = newTemp(Ity_I16);
6648 IRTemp result = newTemp(Ity_I64);
6649
6650 assign(op1, get_gpr_w1(r1));
6651 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6652 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6653 ));
6654 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6655
6656 return "mhy";
6657}
6658
florian55085f82012-11-21 00:36:55 +00006659static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006660s390_irgen_MHI(UChar r1, UShort i2)
6661{
6662 IRTemp op1 = newTemp(Ity_I32);
6663 Short op2;
6664 IRTemp result = newTemp(Ity_I64);
6665
6666 assign(op1, get_gpr_w1(r1));
6667 op2 = (Short)i2;
6668 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6669 mkU16((UShort)op2))));
6670 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6671
6672 return "mhi";
6673}
6674
florian55085f82012-11-21 00:36:55 +00006675static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006676s390_irgen_MGHI(UChar r1, UShort i2)
6677{
6678 IRTemp op1 = newTemp(Ity_I64);
6679 Short op2;
6680 IRTemp result = newTemp(Ity_I128);
6681
6682 assign(op1, get_gpr_dw0(r1));
6683 op2 = (Short)i2;
6684 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6685 mkU16((UShort)op2))));
6686 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6687
6688 return "mghi";
6689}
6690
florian55085f82012-11-21 00:36:55 +00006691static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006692s390_irgen_MLR(UChar r1, UChar r2)
6693{
6694 IRTemp op1 = newTemp(Ity_I32);
6695 IRTemp op2 = newTemp(Ity_I32);
6696 IRTemp result = newTemp(Ity_I64);
6697
6698 assign(op1, get_gpr_w1(r1 + 1));
6699 assign(op2, get_gpr_w1(r2));
6700 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6701 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6702 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6703
6704 return "mlr";
6705}
6706
florian55085f82012-11-21 00:36:55 +00006707static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006708s390_irgen_MLGR(UChar r1, UChar r2)
6709{
6710 IRTemp op1 = newTemp(Ity_I64);
6711 IRTemp op2 = newTemp(Ity_I64);
6712 IRTemp result = newTemp(Ity_I128);
6713
6714 assign(op1, get_gpr_dw0(r1 + 1));
6715 assign(op2, get_gpr_dw0(r2));
6716 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6717 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6718 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6719
6720 return "mlgr";
6721}
6722
florian55085f82012-11-21 00:36:55 +00006723static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006724s390_irgen_ML(UChar r1, IRTemp op2addr)
6725{
6726 IRTemp op1 = newTemp(Ity_I32);
6727 IRTemp op2 = newTemp(Ity_I32);
6728 IRTemp result = newTemp(Ity_I64);
6729
6730 assign(op1, get_gpr_w1(r1 + 1));
6731 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6732 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6733 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6734 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6735
6736 return "ml";
6737}
6738
florian55085f82012-11-21 00:36:55 +00006739static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006740s390_irgen_MLG(UChar r1, IRTemp op2addr)
6741{
6742 IRTemp op1 = newTemp(Ity_I64);
6743 IRTemp op2 = newTemp(Ity_I64);
6744 IRTemp result = newTemp(Ity_I128);
6745
6746 assign(op1, get_gpr_dw0(r1 + 1));
6747 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6748 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6749 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6750 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6751
6752 return "mlg";
6753}
6754
florian55085f82012-11-21 00:36:55 +00006755static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006756s390_irgen_MSR(UChar r1, UChar r2)
6757{
6758 IRTemp op1 = newTemp(Ity_I32);
6759 IRTemp op2 = newTemp(Ity_I32);
6760 IRTemp result = newTemp(Ity_I64);
6761
6762 assign(op1, get_gpr_w1(r1));
6763 assign(op2, get_gpr_w1(r2));
6764 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6765 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6766
6767 return "msr";
6768}
6769
florian55085f82012-11-21 00:36:55 +00006770static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006771s390_irgen_MSGR(UChar r1, UChar r2)
6772{
6773 IRTemp op1 = newTemp(Ity_I64);
6774 IRTemp op2 = newTemp(Ity_I64);
6775 IRTemp result = newTemp(Ity_I128);
6776
6777 assign(op1, get_gpr_dw0(r1));
6778 assign(op2, get_gpr_dw0(r2));
6779 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6780 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6781
6782 return "msgr";
6783}
6784
florian55085f82012-11-21 00:36:55 +00006785static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006786s390_irgen_MSGFR(UChar r1, UChar r2)
6787{
6788 IRTemp op1 = newTemp(Ity_I64);
6789 IRTemp op2 = newTemp(Ity_I32);
6790 IRTemp result = newTemp(Ity_I128);
6791
6792 assign(op1, get_gpr_dw0(r1));
6793 assign(op2, get_gpr_w1(r2));
6794 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6795 ));
6796 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6797
6798 return "msgfr";
6799}
6800
florian55085f82012-11-21 00:36:55 +00006801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006802s390_irgen_MS(UChar r1, IRTemp op2addr)
6803{
6804 IRTemp op1 = newTemp(Ity_I32);
6805 IRTemp op2 = newTemp(Ity_I32);
6806 IRTemp result = newTemp(Ity_I64);
6807
6808 assign(op1, get_gpr_w1(r1));
6809 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6810 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6811 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6812
6813 return "ms";
6814}
6815
florian55085f82012-11-21 00:36:55 +00006816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006817s390_irgen_MSY(UChar r1, IRTemp op2addr)
6818{
6819 IRTemp op1 = newTemp(Ity_I32);
6820 IRTemp op2 = newTemp(Ity_I32);
6821 IRTemp result = newTemp(Ity_I64);
6822
6823 assign(op1, get_gpr_w1(r1));
6824 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6825 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6826 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6827
6828 return "msy";
6829}
6830
florian55085f82012-11-21 00:36:55 +00006831static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006832s390_irgen_MSG(UChar r1, IRTemp op2addr)
6833{
6834 IRTemp op1 = newTemp(Ity_I64);
6835 IRTemp op2 = newTemp(Ity_I64);
6836 IRTemp result = newTemp(Ity_I128);
6837
6838 assign(op1, get_gpr_dw0(r1));
6839 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6840 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6841 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6842
6843 return "msg";
6844}
6845
florian55085f82012-11-21 00:36:55 +00006846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006847s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6848{
6849 IRTemp op1 = newTemp(Ity_I64);
6850 IRTemp op2 = newTemp(Ity_I32);
6851 IRTemp result = newTemp(Ity_I128);
6852
6853 assign(op1, get_gpr_dw0(r1));
6854 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6855 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6856 ));
6857 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6858
6859 return "msgf";
6860}
6861
florian55085f82012-11-21 00:36:55 +00006862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006863s390_irgen_MSFI(UChar r1, UInt i2)
6864{
6865 IRTemp op1 = newTemp(Ity_I32);
6866 Int op2;
6867 IRTemp result = newTemp(Ity_I64);
6868
6869 assign(op1, get_gpr_w1(r1));
6870 op2 = (Int)i2;
6871 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6872 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6873
6874 return "msfi";
6875}
6876
florian55085f82012-11-21 00:36:55 +00006877static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006878s390_irgen_MSGFI(UChar r1, UInt i2)
6879{
6880 IRTemp op1 = newTemp(Ity_I64);
6881 Int op2;
6882 IRTemp result = newTemp(Ity_I128);
6883
6884 assign(op1, get_gpr_dw0(r1));
6885 op2 = (Int)i2;
6886 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6887 op2))));
6888 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6889
6890 return "msgfi";
6891}
6892
florian55085f82012-11-21 00:36:55 +00006893static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006894s390_irgen_OR(UChar r1, UChar r2)
6895{
6896 IRTemp op1 = newTemp(Ity_I32);
6897 IRTemp op2 = newTemp(Ity_I32);
6898 IRTemp result = newTemp(Ity_I32);
6899
6900 assign(op1, get_gpr_w1(r1));
6901 assign(op2, get_gpr_w1(r2));
6902 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6903 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6904 put_gpr_w1(r1, mkexpr(result));
6905
6906 return "or";
6907}
6908
florian55085f82012-11-21 00:36:55 +00006909static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006910s390_irgen_OGR(UChar r1, UChar r2)
6911{
6912 IRTemp op1 = newTemp(Ity_I64);
6913 IRTemp op2 = newTemp(Ity_I64);
6914 IRTemp result = newTemp(Ity_I64);
6915
6916 assign(op1, get_gpr_dw0(r1));
6917 assign(op2, get_gpr_dw0(r2));
6918 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6919 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6920 put_gpr_dw0(r1, mkexpr(result));
6921
6922 return "ogr";
6923}
6924
florian55085f82012-11-21 00:36:55 +00006925static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006926s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6927{
6928 IRTemp op2 = newTemp(Ity_I32);
6929 IRTemp op3 = newTemp(Ity_I32);
6930 IRTemp result = newTemp(Ity_I32);
6931
6932 assign(op2, get_gpr_w1(r2));
6933 assign(op3, get_gpr_w1(r3));
6934 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6935 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6936 put_gpr_w1(r1, mkexpr(result));
6937
6938 return "ork";
6939}
6940
florian55085f82012-11-21 00:36:55 +00006941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006942s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6943{
6944 IRTemp op2 = newTemp(Ity_I64);
6945 IRTemp op3 = newTemp(Ity_I64);
6946 IRTemp result = newTemp(Ity_I64);
6947
6948 assign(op2, get_gpr_dw0(r2));
6949 assign(op3, get_gpr_dw0(r3));
6950 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6951 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6952 put_gpr_dw0(r1, mkexpr(result));
6953
6954 return "ogrk";
6955}
6956
florian55085f82012-11-21 00:36:55 +00006957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006958s390_irgen_O(UChar r1, IRTemp op2addr)
6959{
6960 IRTemp op1 = newTemp(Ity_I32);
6961 IRTemp op2 = newTemp(Ity_I32);
6962 IRTemp result = newTemp(Ity_I32);
6963
6964 assign(op1, get_gpr_w1(r1));
6965 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6966 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6967 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6968 put_gpr_w1(r1, mkexpr(result));
6969
6970 return "o";
6971}
6972
florian55085f82012-11-21 00:36:55 +00006973static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006974s390_irgen_OY(UChar r1, IRTemp op2addr)
6975{
6976 IRTemp op1 = newTemp(Ity_I32);
6977 IRTemp op2 = newTemp(Ity_I32);
6978 IRTemp result = newTemp(Ity_I32);
6979
6980 assign(op1, get_gpr_w1(r1));
6981 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6982 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6983 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6984 put_gpr_w1(r1, mkexpr(result));
6985
6986 return "oy";
6987}
6988
florian55085f82012-11-21 00:36:55 +00006989static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006990s390_irgen_OG(UChar r1, IRTemp op2addr)
6991{
6992 IRTemp op1 = newTemp(Ity_I64);
6993 IRTemp op2 = newTemp(Ity_I64);
6994 IRTemp result = newTemp(Ity_I64);
6995
6996 assign(op1, get_gpr_dw0(r1));
6997 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6998 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6999 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7000 put_gpr_dw0(r1, mkexpr(result));
7001
7002 return "og";
7003}
7004
florian55085f82012-11-21 00:36:55 +00007005static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007006s390_irgen_OI(UChar i2, IRTemp op1addr)
7007{
7008 IRTemp op1 = newTemp(Ity_I8);
7009 UChar op2;
7010 IRTemp result = newTemp(Ity_I8);
7011
7012 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7013 op2 = i2;
7014 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7015 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7016 store(mkexpr(op1addr), mkexpr(result));
7017
7018 return "oi";
7019}
7020
florian55085f82012-11-21 00:36:55 +00007021static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007022s390_irgen_OIY(UChar i2, IRTemp op1addr)
7023{
7024 IRTemp op1 = newTemp(Ity_I8);
7025 UChar op2;
7026 IRTemp result = newTemp(Ity_I8);
7027
7028 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7029 op2 = i2;
7030 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7031 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7032 store(mkexpr(op1addr), mkexpr(result));
7033
7034 return "oiy";
7035}
7036
florian55085f82012-11-21 00:36:55 +00007037static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007038s390_irgen_OIHF(UChar r1, UInt i2)
7039{
7040 IRTemp op1 = newTemp(Ity_I32);
7041 UInt op2;
7042 IRTemp result = newTemp(Ity_I32);
7043
7044 assign(op1, get_gpr_w0(r1));
7045 op2 = i2;
7046 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7047 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7048 put_gpr_w0(r1, mkexpr(result));
7049
7050 return "oihf";
7051}
7052
florian55085f82012-11-21 00:36:55 +00007053static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007054s390_irgen_OIHH(UChar r1, UShort i2)
7055{
7056 IRTemp op1 = newTemp(Ity_I16);
7057 UShort op2;
7058 IRTemp result = newTemp(Ity_I16);
7059
7060 assign(op1, get_gpr_hw0(r1));
7061 op2 = i2;
7062 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7063 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7064 put_gpr_hw0(r1, mkexpr(result));
7065
7066 return "oihh";
7067}
7068
florian55085f82012-11-21 00:36:55 +00007069static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007070s390_irgen_OIHL(UChar r1, UShort i2)
7071{
7072 IRTemp op1 = newTemp(Ity_I16);
7073 UShort op2;
7074 IRTemp result = newTemp(Ity_I16);
7075
7076 assign(op1, get_gpr_hw1(r1));
7077 op2 = i2;
7078 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7079 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7080 put_gpr_hw1(r1, mkexpr(result));
7081
7082 return "oihl";
7083}
7084
florian55085f82012-11-21 00:36:55 +00007085static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007086s390_irgen_OILF(UChar r1, UInt i2)
7087{
7088 IRTemp op1 = newTemp(Ity_I32);
7089 UInt op2;
7090 IRTemp result = newTemp(Ity_I32);
7091
7092 assign(op1, get_gpr_w1(r1));
7093 op2 = i2;
7094 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7095 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7096 put_gpr_w1(r1, mkexpr(result));
7097
7098 return "oilf";
7099}
7100
florian55085f82012-11-21 00:36:55 +00007101static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007102s390_irgen_OILH(UChar r1, UShort i2)
7103{
7104 IRTemp op1 = newTemp(Ity_I16);
7105 UShort op2;
7106 IRTemp result = newTemp(Ity_I16);
7107
7108 assign(op1, get_gpr_hw2(r1));
7109 op2 = i2;
7110 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7111 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7112 put_gpr_hw2(r1, mkexpr(result));
7113
7114 return "oilh";
7115}
7116
florian55085f82012-11-21 00:36:55 +00007117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007118s390_irgen_OILL(UChar r1, UShort i2)
7119{
7120 IRTemp op1 = newTemp(Ity_I16);
7121 UShort op2;
7122 IRTemp result = newTemp(Ity_I16);
7123
7124 assign(op1, get_gpr_hw3(r1));
7125 op2 = i2;
7126 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7127 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7128 put_gpr_hw3(r1, mkexpr(result));
7129
7130 return "oill";
7131}
7132
florian55085f82012-11-21 00:36:55 +00007133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007134s390_irgen_PFD(void)
7135{
7136
7137 return "pfd";
7138}
7139
florian55085f82012-11-21 00:36:55 +00007140static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007141s390_irgen_PFDRL(void)
7142{
7143
7144 return "pfdrl";
7145}
7146
florian78d5ef72013-05-11 15:02:58 +00007147static IRExpr *
7148get_rounding_mode_from_gr0(void)
7149{
7150 IRTemp rm_bits = newTemp(Ity_I32);
7151 IRExpr *s390rm;
7152 IRExpr *irrm;
7153
florian78d5ef72013-05-11 15:02:58 +00007154 /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7155 when PFPO insn is called. So, extract the bits at [60:63] */
7156 assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7157 s390rm = mkexpr(rm_bits);
7158 irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7159 mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7160 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7161 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7162 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7163 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7164 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7165 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7166 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7167 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7168 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7169 mkexpr(encode_dfp_rounding_mode(
7170 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7171 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7172 mkexpr(encode_dfp_rounding_mode(
7173 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7174 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7175 mkexpr(encode_dfp_rounding_mode(
7176 S390_DFP_ROUND_AWAY_0)),
7177 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7178 mkexpr(encode_dfp_rounding_mode(
7179 S390_DFP_ROUND_PREPARE_SHORT_15)),
7180 /* if rounding mode is 0 or invalid (2-7)
7181 set S390_DFP_ROUND_PER_FPC_0 */
7182 mkexpr(encode_dfp_rounding_mode(
7183 S390_DFP_ROUND_PER_FPC_0)))))))))));
7184
7185 return irrm;
7186}
7187
7188static IRExpr *
7189s390_call_pfpo_helper(IRExpr *gr0)
7190{
7191 IRExpr **args, *call;
7192
7193 args = mkIRExprVec_1(gr0);
7194 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7195 "s390_do_pfpo", &s390_do_pfpo, args);
7196 /* Nothing is excluded from definedness checking. */
7197 call->Iex.CCall.cee->mcx_mask = 0;
7198
7199 return call;
7200}
7201
7202static const HChar *
7203s390_irgen_PFPO(void)
7204{
7205 IRTemp gr0 = newTemp(Ity_I32); /* word 1 [32:63] of GR 0 */
7206 IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7207 IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */
7208 IRTemp ef = newTemp(Ity_I32); /* Emulation Failure */
florian7ab421d2013-06-17 21:03:56 +00007209 IRTemp src1 = newTemp(Ity_F32);
7210 IRTemp dst1 = newTemp(Ity_D32);
7211 IRTemp src2 = newTemp(Ity_F32);
7212 IRTemp dst2 = newTemp(Ity_D64);
7213 IRTemp src3 = newTemp(Ity_F32);
florian78d5ef72013-05-11 15:02:58 +00007214 IRTemp dst3 = newTemp(Ity_D128);
florian7ab421d2013-06-17 21:03:56 +00007215 IRTemp src4 = newTemp(Ity_F64);
7216 IRTemp dst4 = newTemp(Ity_D32);
7217 IRTemp src5 = newTemp(Ity_F64);
7218 IRTemp dst5 = newTemp(Ity_D64);
7219 IRTemp src6 = newTemp(Ity_F64);
7220 IRTemp dst6 = newTemp(Ity_D128);
7221 IRTemp src7 = newTemp(Ity_F128);
7222 IRTemp dst7 = newTemp(Ity_D32);
7223 IRTemp src8 = newTemp(Ity_F128);
7224 IRTemp dst8 = newTemp(Ity_D64);
7225 IRTemp src9 = newTemp(Ity_F128);
7226 IRTemp dst9 = newTemp(Ity_D128);
7227 IRTemp src10 = newTemp(Ity_D32);
7228 IRTemp dst10 = newTemp(Ity_F32);
7229 IRTemp src11 = newTemp(Ity_D32);
7230 IRTemp dst11 = newTemp(Ity_F64);
7231 IRTemp src12 = newTemp(Ity_D32);
7232 IRTemp dst12 = newTemp(Ity_F128);
7233 IRTemp src13 = newTemp(Ity_D64);
7234 IRTemp dst13 = newTemp(Ity_F32);
7235 IRTemp src14 = newTemp(Ity_D64);
7236 IRTemp dst14 = newTemp(Ity_F64);
7237 IRTemp src15 = newTemp(Ity_D64);
7238 IRTemp dst15 = newTemp(Ity_F128);
7239 IRTemp src16 = newTemp(Ity_D128);
7240 IRTemp dst16 = newTemp(Ity_F32);
7241 IRTemp src17 = newTemp(Ity_D128);
7242 IRTemp dst17 = newTemp(Ity_F64);
7243 IRTemp src18 = newTemp(Ity_D128);
7244 IRTemp dst18 = newTemp(Ity_F128);
florian78d5ef72013-05-11 15:02:58 +00007245 IRExpr *irrm;
7246
florianad00ea92014-12-05 18:55:39 +00007247 if (! s390_host_has_pfpo) {
7248 emulation_failure(EmFail_S390X_pfpo);
7249 goto done;
7250 }
florian78d5ef72013-05-11 15:02:58 +00007251
7252 assign(gr0, get_gpr_w1(0));
7253 /* get function code */
7254 assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7255 mkU32(0x7fffff)));
7256 /* get validity test bit */
7257 assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7258 mkU32(0x1)));
7259 irrm = get_rounding_mode_from_gr0();
7260
7261 /* test_bit is 1 */
florian7ab421d2013-06-17 21:03:56 +00007262 assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
florian78d5ef72013-05-11 15:02:58 +00007263 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7264
7265 /* Return code set in GR1 is usually 0. Non-zero value is set only
7266 when exceptions are raised. See Programming Notes point 5 in the
7267 instrcution description of pfpo in POP. Since valgrind does not
7268 model exception, it might be safe to just set 0 to GR 1. */
7269 put_gpr_w1(1, mkU32(0x0));
7270 next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7271
7272 /* Check validity of function code in GR 0 */
7273 assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
florianafa3f042014-09-06 21:43:28 +00007274 emulation_failure_with_expr(mkexpr(ef));
florian78d5ef72013-05-11 15:02:58 +00007275
7276 stmt(
7277 IRStmt_Exit(
7278 binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7279 Ijk_EmFail,
7280 IRConst_U64(guest_IA_next_instr),
7281 S390X_GUEST_OFFSET(guest_IA)
7282 )
7283 );
7284
florian7ab421d2013-06-17 21:03:56 +00007285 /* F32 -> D32 */
florian78d5ef72013-05-11 15:02:58 +00007286 /* get source from FPR 4,6 - already set in src1 */
florian7ab421d2013-06-17 21:03:56 +00007287 assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
7288 put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007289 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007290 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
7291 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
florian78d5ef72013-05-11 15:02:58 +00007292
florian7ab421d2013-06-17 21:03:56 +00007293 /* F32 -> D64 */
7294 assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
7295 assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
7296 put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007297 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007298 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
7299 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007300
florian7ab421d2013-06-17 21:03:56 +00007301 /* F32 -> D128 */
7302 assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
7303 assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
florian78d5ef72013-05-11 15:02:58 +00007304 put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7305 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007306 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
7307 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
7308
7309 /* F64 -> D32 */
7310 assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7311 assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
7312 put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7313 put_gpr_w1(1, mkU32(0x0));
7314 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
7315 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
7316
7317 /* F64 -> D64 */
7318 assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7319 assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
7320 put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7321 put_gpr_w1(1, mkU32(0x0));
7322 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
7323 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7324
7325 /* F64 -> D128 */
7326 assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7327 assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
7328 put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7329 put_gpr_w1(1, mkU32(0x0));
7330 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
florian78d5ef72013-05-11 15:02:58 +00007331 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7332
florian7ab421d2013-06-17 21:03:56 +00007333 /* F128 -> D32 */
7334 assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
7335 assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
7336 put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007337 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007338 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
7339 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
7340
7341 /* F128 -> D64 */
7342 assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
7343 assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
7344 put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
7345 put_gpr_w1(1, mkU32(0x0));
7346 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
7347 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007348
7349 /* F128 -> D128 */
florian7ab421d2013-06-17 21:03:56 +00007350 assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
7351 assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
7352 put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007353 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007354 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
florian78d5ef72013-05-11 15:02:58 +00007355 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7356
florian7ab421d2013-06-17 21:03:56 +00007357 /* D32 -> F32 */
7358 assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
7359 assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
7360 put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007361 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007362 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
7363 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
7364
7365 /* D32 -> F64 */
7366 assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
7367 assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
7368 put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
7369 put_gpr_w1(1, mkU32(0x0));
7370 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
7371 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
7372
7373 /* D32 -> F128 */
7374 assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
7375 assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
7376 put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
7377 put_gpr_w1(1, mkU32(0x0));
7378 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
7379 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
7380
7381 /* D64 -> F32 */
7382 assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7383 assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
7384 put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
7385 put_gpr_w1(1, mkU32(0x0));
7386 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
7387 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
7388
7389 /* D64 -> F64 */
7390 assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7391 assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
7392 put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
7393 put_gpr_w1(1, mkU32(0x0));
7394 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
7395 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7396
7397 /* D64 -> F128 */
7398 assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7399 assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
7400 put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
7401 put_gpr_w1(1, mkU32(0x0));
7402 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
7403 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
7404
7405 /* D128 -> F32 */
7406 assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
7407 assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
7408 put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
7409 put_gpr_w1(1, mkU32(0x0));
7410 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
7411 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
7412
7413 /* D128 -> F64 */
7414 assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
7415 assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
7416 put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
7417 put_gpr_w1(1, mkU32(0x0));
7418 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
7419 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7420
7421 /* D128 -> F128 */
7422 assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
7423 assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
7424 put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
7425 put_gpr_w1(1, mkU32(0x0));
7426 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
florian78d5ef72013-05-11 15:02:58 +00007427 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7428
florianad00ea92014-12-05 18:55:39 +00007429 done:
florian78d5ef72013-05-11 15:02:58 +00007430 return "pfpo";
7431}
7432
florian55085f82012-11-21 00:36:55 +00007433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007434s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7435{
7436 IRTemp amount = newTemp(Ity_I64);
7437 IRTemp op = newTemp(Ity_I32);
7438
7439 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7440 assign(op, get_gpr_w1(r3));
7441 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7442 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7443 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7444
7445 return "rll";
7446}
7447
florian55085f82012-11-21 00:36:55 +00007448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007449s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7450{
7451 IRTemp amount = newTemp(Ity_I64);
7452 IRTemp op = newTemp(Ity_I64);
7453
7454 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7455 assign(op, get_gpr_dw0(r3));
7456 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7457 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7458 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7459
7460 return "rllg";
7461}
7462
florian55085f82012-11-21 00:36:55 +00007463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007464s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7465{
7466 UChar from;
7467 UChar to;
7468 UChar rot;
7469 UChar t_bit;
7470 ULong mask;
7471 ULong maskc;
7472 IRTemp result = newTemp(Ity_I64);
7473 IRTemp op2 = newTemp(Ity_I64);
7474
7475 from = i3 & 63;
7476 to = i4 & 63;
7477 rot = i5 & 63;
7478 t_bit = i3 & 128;
7479 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7480 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7481 mkU8(64 - rot))));
7482 if (from <= to) {
7483 mask = ~0ULL;
7484 mask = (mask >> from) & (mask << (63 - to));
7485 maskc = ~mask;
7486 } else {
7487 maskc = ~0ULL;
7488 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7489 mask = ~maskc;
7490 }
7491 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7492 ), mkU64(mask)));
7493 if (t_bit == 0) {
7494 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7495 mkU64(maskc)), mkexpr(result)));
7496 }
7497 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7498
7499 return "rnsbg";
7500}
7501
florian55085f82012-11-21 00:36:55 +00007502static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007503s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7504{
7505 UChar from;
7506 UChar to;
7507 UChar rot;
7508 UChar t_bit;
7509 ULong mask;
7510 ULong maskc;
7511 IRTemp result = newTemp(Ity_I64);
7512 IRTemp op2 = newTemp(Ity_I64);
7513
7514 from = i3 & 63;
7515 to = i4 & 63;
7516 rot = i5 & 63;
7517 t_bit = i3 & 128;
7518 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7519 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7520 mkU8(64 - rot))));
7521 if (from <= to) {
7522 mask = ~0ULL;
7523 mask = (mask >> from) & (mask << (63 - to));
7524 maskc = ~mask;
7525 } else {
7526 maskc = ~0ULL;
7527 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7528 mask = ~maskc;
7529 }
7530 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7531 ), mkU64(mask)));
7532 if (t_bit == 0) {
7533 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7534 mkU64(maskc)), mkexpr(result)));
7535 }
7536 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7537
7538 return "rxsbg";
7539}
7540
florian55085f82012-11-21 00:36:55 +00007541static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007542s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7543{
7544 UChar from;
7545 UChar to;
7546 UChar rot;
7547 UChar t_bit;
7548 ULong mask;
7549 ULong maskc;
7550 IRTemp result = newTemp(Ity_I64);
7551 IRTemp op2 = newTemp(Ity_I64);
7552
7553 from = i3 & 63;
7554 to = i4 & 63;
7555 rot = i5 & 63;
7556 t_bit = i3 & 128;
7557 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7558 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7559 mkU8(64 - rot))));
7560 if (from <= to) {
7561 mask = ~0ULL;
7562 mask = (mask >> from) & (mask << (63 - to));
7563 maskc = ~mask;
7564 } else {
7565 maskc = ~0ULL;
7566 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7567 mask = ~maskc;
7568 }
7569 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7570 ), mkU64(mask)));
7571 if (t_bit == 0) {
7572 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7573 mkU64(maskc)), mkexpr(result)));
7574 }
7575 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7576
7577 return "rosbg";
7578}
7579
florian55085f82012-11-21 00:36:55 +00007580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007581s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7582{
7583 UChar from;
7584 UChar to;
7585 UChar rot;
7586 UChar z_bit;
7587 ULong mask;
7588 ULong maskc;
7589 IRTemp op2 = newTemp(Ity_I64);
7590 IRTemp result = newTemp(Ity_I64);
7591
7592 from = i3 & 63;
7593 to = i4 & 63;
7594 rot = i5 & 63;
7595 z_bit = i4 & 128;
7596 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7597 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7598 mkU8(64 - rot))));
7599 if (from <= to) {
7600 mask = ~0ULL;
7601 mask = (mask >> from) & (mask << (63 - to));
7602 maskc = ~mask;
7603 } else {
7604 maskc = ~0ULL;
7605 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7606 mask = ~maskc;
7607 }
7608 if (z_bit == 0) {
7609 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7610 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7611 } else {
7612 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7613 }
7614 assign(result, get_gpr_dw0(r1));
cborntrae03b6002013-11-07 21:37:28 +00007615 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
sewardj2019a972011-03-07 16:04:07 +00007616
7617 return "risbg";
7618}
7619
florian55085f82012-11-21 00:36:55 +00007620static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007621s390_irgen_SAR(UChar r1, UChar r2)
7622{
7623 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007624 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007625 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7626
7627 return "sar";
7628}
7629
florian55085f82012-11-21 00:36:55 +00007630static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007631s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7632{
7633 IRTemp p1 = newTemp(Ity_I64);
7634 IRTemp p2 = newTemp(Ity_I64);
7635 IRTemp op = newTemp(Ity_I64);
7636 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007637 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007638 IRTemp shift_amount = newTemp(Ity_I64);
7639
7640 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7641 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7642 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7643 ));
7644 sign_mask = 1ULL << 63;
7645 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7646 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007647 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7648 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007649 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7650 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7651 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7652
7653 return "slda";
7654}
7655
florian55085f82012-11-21 00:36:55 +00007656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007657s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7658{
7659 IRTemp p1 = newTemp(Ity_I64);
7660 IRTemp p2 = newTemp(Ity_I64);
7661 IRTemp result = newTemp(Ity_I64);
7662
7663 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7664 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7665 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7666 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7667 mkexpr(op2addr), mkU64(63)))));
7668 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7669 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7670
7671 return "sldl";
7672}
7673
florian55085f82012-11-21 00:36:55 +00007674static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007675s390_irgen_SLA(UChar r1, IRTemp op2addr)
7676{
7677 IRTemp uop = newTemp(Ity_I32);
7678 IRTemp result = newTemp(Ity_I32);
7679 UInt sign_mask;
7680 IRTemp shift_amount = newTemp(Ity_I64);
7681 IRTemp op = newTemp(Ity_I32);
7682
7683 assign(op, get_gpr_w1(r1));
7684 assign(uop, get_gpr_w1(r1));
7685 sign_mask = 2147483648U;
7686 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7687 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7688 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7689 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7690 put_gpr_w1(r1, mkexpr(result));
7691 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7692
7693 return "sla";
7694}
7695
florian55085f82012-11-21 00:36:55 +00007696static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007697s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7698{
7699 IRTemp uop = newTemp(Ity_I32);
7700 IRTemp result = newTemp(Ity_I32);
7701 UInt sign_mask;
7702 IRTemp shift_amount = newTemp(Ity_I64);
7703 IRTemp op = newTemp(Ity_I32);
7704
7705 assign(op, get_gpr_w1(r3));
7706 assign(uop, get_gpr_w1(r3));
7707 sign_mask = 2147483648U;
7708 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7709 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7710 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7711 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7712 put_gpr_w1(r1, mkexpr(result));
7713 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7714
7715 return "slak";
7716}
7717
florian55085f82012-11-21 00:36:55 +00007718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007719s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7720{
7721 IRTemp uop = newTemp(Ity_I64);
7722 IRTemp result = newTemp(Ity_I64);
7723 ULong sign_mask;
7724 IRTemp shift_amount = newTemp(Ity_I64);
7725 IRTemp op = newTemp(Ity_I64);
7726
7727 assign(op, get_gpr_dw0(r3));
7728 assign(uop, get_gpr_dw0(r3));
7729 sign_mask = 9223372036854775808ULL;
7730 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7731 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7732 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7733 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7734 put_gpr_dw0(r1, mkexpr(result));
7735 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7736
7737 return "slag";
7738}
7739
florian55085f82012-11-21 00:36:55 +00007740static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007741s390_irgen_SLL(UChar r1, IRTemp op2addr)
7742{
7743 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7744 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7745
7746 return "sll";
7747}
7748
florian55085f82012-11-21 00:36:55 +00007749static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007750s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7751{
7752 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7753 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7754
7755 return "sllk";
7756}
7757
florian55085f82012-11-21 00:36:55 +00007758static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007759s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7760{
7761 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7762 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7763
7764 return "sllg";
7765}
7766
florian55085f82012-11-21 00:36:55 +00007767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007768s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7769{
7770 IRTemp p1 = newTemp(Ity_I64);
7771 IRTemp p2 = newTemp(Ity_I64);
7772 IRTemp result = newTemp(Ity_I64);
7773
7774 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7775 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7776 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7777 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7778 mkexpr(op2addr), mkU64(63)))));
7779 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7780 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7781 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7782
7783 return "srda";
7784}
7785
florian55085f82012-11-21 00:36:55 +00007786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007787s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7788{
7789 IRTemp p1 = newTemp(Ity_I64);
7790 IRTemp p2 = newTemp(Ity_I64);
7791 IRTemp result = newTemp(Ity_I64);
7792
7793 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7794 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7795 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7796 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7797 mkexpr(op2addr), mkU64(63)))));
7798 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7799 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7800
7801 return "srdl";
7802}
7803
florian55085f82012-11-21 00:36:55 +00007804static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007805s390_irgen_SRA(UChar r1, IRTemp op2addr)
7806{
7807 IRTemp result = newTemp(Ity_I32);
7808 IRTemp op = newTemp(Ity_I32);
7809
7810 assign(op, get_gpr_w1(r1));
7811 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7812 mkexpr(op2addr), mkU64(63)))));
7813 put_gpr_w1(r1, mkexpr(result));
7814 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7815
7816 return "sra";
7817}
7818
florian55085f82012-11-21 00:36:55 +00007819static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007820s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7821{
7822 IRTemp result = newTemp(Ity_I32);
7823 IRTemp op = newTemp(Ity_I32);
7824
7825 assign(op, get_gpr_w1(r3));
7826 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7827 mkexpr(op2addr), mkU64(63)))));
7828 put_gpr_w1(r1, mkexpr(result));
7829 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7830
7831 return "srak";
7832}
7833
florian55085f82012-11-21 00:36:55 +00007834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007835s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7836{
7837 IRTemp result = newTemp(Ity_I64);
7838 IRTemp op = newTemp(Ity_I64);
7839
7840 assign(op, get_gpr_dw0(r3));
7841 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7842 mkexpr(op2addr), mkU64(63)))));
7843 put_gpr_dw0(r1, mkexpr(result));
7844 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7845
7846 return "srag";
7847}
7848
florian55085f82012-11-21 00:36:55 +00007849static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007850s390_irgen_SRL(UChar r1, IRTemp op2addr)
7851{
7852 IRTemp op = newTemp(Ity_I32);
7853
7854 assign(op, get_gpr_w1(r1));
7855 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7856 mkexpr(op2addr), mkU64(63)))));
7857
7858 return "srl";
7859}
7860
florian55085f82012-11-21 00:36:55 +00007861static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007862s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7863{
7864 IRTemp op = newTemp(Ity_I32);
7865
7866 assign(op, get_gpr_w1(r3));
7867 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7868 mkexpr(op2addr), mkU64(63)))));
7869
7870 return "srlk";
7871}
7872
florian55085f82012-11-21 00:36:55 +00007873static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007874s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7875{
7876 IRTemp op = newTemp(Ity_I64);
7877
7878 assign(op, get_gpr_dw0(r3));
7879 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7880 mkexpr(op2addr), mkU64(63)))));
7881
7882 return "srlg";
7883}
7884
florian55085f82012-11-21 00:36:55 +00007885static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007886s390_irgen_ST(UChar r1, IRTemp op2addr)
7887{
7888 store(mkexpr(op2addr), get_gpr_w1(r1));
7889
7890 return "st";
7891}
7892
florian55085f82012-11-21 00:36:55 +00007893static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007894s390_irgen_STY(UChar r1, IRTemp op2addr)
7895{
7896 store(mkexpr(op2addr), get_gpr_w1(r1));
7897
7898 return "sty";
7899}
7900
florian55085f82012-11-21 00:36:55 +00007901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007902s390_irgen_STG(UChar r1, IRTemp op2addr)
7903{
7904 store(mkexpr(op2addr), get_gpr_dw0(r1));
7905
7906 return "stg";
7907}
7908
florian55085f82012-11-21 00:36:55 +00007909static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007910s390_irgen_STRL(UChar r1, UInt i2)
7911{
7912 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7913 get_gpr_w1(r1));
7914
7915 return "strl";
7916}
7917
florian55085f82012-11-21 00:36:55 +00007918static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007919s390_irgen_STGRL(UChar r1, UInt i2)
7920{
7921 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7922 get_gpr_dw0(r1));
7923
7924 return "stgrl";
7925}
7926
florian55085f82012-11-21 00:36:55 +00007927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007928s390_irgen_STC(UChar r1, IRTemp op2addr)
7929{
7930 store(mkexpr(op2addr), get_gpr_b7(r1));
7931
7932 return "stc";
7933}
7934
florian55085f82012-11-21 00:36:55 +00007935static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007936s390_irgen_STCY(UChar r1, IRTemp op2addr)
7937{
7938 store(mkexpr(op2addr), get_gpr_b7(r1));
7939
7940 return "stcy";
7941}
7942
florian55085f82012-11-21 00:36:55 +00007943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007944s390_irgen_STCH(UChar r1, IRTemp op2addr)
7945{
7946 store(mkexpr(op2addr), get_gpr_b3(r1));
7947
7948 return "stch";
7949}
7950
florian55085f82012-11-21 00:36:55 +00007951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007952s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7953{
7954 UChar mask;
7955 UChar n;
7956
7957 mask = (UChar)r3;
7958 n = 0;
7959 if ((mask & 8) != 0) {
7960 store(mkexpr(op2addr), get_gpr_b4(r1));
7961 n = n + 1;
7962 }
7963 if ((mask & 4) != 0) {
7964 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7965 n = n + 1;
7966 }
7967 if ((mask & 2) != 0) {
7968 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7969 n = n + 1;
7970 }
7971 if ((mask & 1) != 0) {
7972 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7973 }
7974
7975 return "stcm";
7976}
7977
florian55085f82012-11-21 00:36:55 +00007978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007979s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7980{
7981 UChar mask;
7982 UChar n;
7983
7984 mask = (UChar)r3;
7985 n = 0;
7986 if ((mask & 8) != 0) {
7987 store(mkexpr(op2addr), get_gpr_b4(r1));
7988 n = n + 1;
7989 }
7990 if ((mask & 4) != 0) {
7991 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7992 n = n + 1;
7993 }
7994 if ((mask & 2) != 0) {
7995 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7996 n = n + 1;
7997 }
7998 if ((mask & 1) != 0) {
7999 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
8000 }
8001
8002 return "stcmy";
8003}
8004
florian55085f82012-11-21 00:36:55 +00008005static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008006s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
8007{
8008 UChar mask;
8009 UChar n;
8010
8011 mask = (UChar)r3;
8012 n = 0;
8013 if ((mask & 8) != 0) {
8014 store(mkexpr(op2addr), get_gpr_b0(r1));
8015 n = n + 1;
8016 }
8017 if ((mask & 4) != 0) {
8018 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
8019 n = n + 1;
8020 }
8021 if ((mask & 2) != 0) {
8022 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
8023 n = n + 1;
8024 }
8025 if ((mask & 1) != 0) {
8026 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
8027 }
8028
8029 return "stcmh";
8030}
8031
florian55085f82012-11-21 00:36:55 +00008032static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008033s390_irgen_STH(UChar r1, IRTemp op2addr)
8034{
8035 store(mkexpr(op2addr), get_gpr_hw3(r1));
8036
8037 return "sth";
8038}
8039
florian55085f82012-11-21 00:36:55 +00008040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008041s390_irgen_STHY(UChar r1, IRTemp op2addr)
8042{
8043 store(mkexpr(op2addr), get_gpr_hw3(r1));
8044
8045 return "sthy";
8046}
8047
florian55085f82012-11-21 00:36:55 +00008048static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008049s390_irgen_STHRL(UChar r1, UInt i2)
8050{
8051 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8052 get_gpr_hw3(r1));
8053
8054 return "sthrl";
8055}
8056
florian55085f82012-11-21 00:36:55 +00008057static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008058s390_irgen_STHH(UChar r1, IRTemp op2addr)
8059{
8060 store(mkexpr(op2addr), get_gpr_hw1(r1));
8061
8062 return "sthh";
8063}
8064
florian55085f82012-11-21 00:36:55 +00008065static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008066s390_irgen_STFH(UChar r1, IRTemp op2addr)
8067{
8068 store(mkexpr(op2addr), get_gpr_w0(r1));
8069
8070 return "stfh";
8071}
8072
florian55085f82012-11-21 00:36:55 +00008073static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008074s390_irgen_STOC(UChar r1, IRTemp op2addr)
8075{
8076 /* condition is checked in format handler */
8077 store(mkexpr(op2addr), get_gpr_w1(r1));
8078
8079 return "stoc";
8080}
8081
florian55085f82012-11-21 00:36:55 +00008082static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008083s390_irgen_STOCG(UChar r1, IRTemp op2addr)
8084{
8085 /* condition is checked in format handler */
8086 store(mkexpr(op2addr), get_gpr_dw0(r1));
8087
8088 return "stocg";
8089}
8090
florian55085f82012-11-21 00:36:55 +00008091static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008092s390_irgen_STPQ(UChar r1, IRTemp op2addr)
8093{
8094 store(mkexpr(op2addr), get_gpr_dw0(r1));
8095 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
8096
8097 return "stpq";
8098}
8099
florian55085f82012-11-21 00:36:55 +00008100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008101s390_irgen_STRVH(UChar r1, IRTemp op2addr)
8102{
8103 store(mkexpr(op2addr), get_gpr_b7(r1));
8104 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8105
8106 return "strvh";
8107}
8108
florian55085f82012-11-21 00:36:55 +00008109static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008110s390_irgen_STRV(UChar r1, IRTemp op2addr)
8111{
8112 store(mkexpr(op2addr), get_gpr_b7(r1));
8113 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8114 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8115 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8116
8117 return "strv";
8118}
8119
florian55085f82012-11-21 00:36:55 +00008120static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008121s390_irgen_STRVG(UChar r1, IRTemp op2addr)
8122{
8123 store(mkexpr(op2addr), get_gpr_b7(r1));
8124 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8125 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8126 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8127 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
8128 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
8129 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
8130 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
8131
8132 return "strvg";
8133}
8134
florian55085f82012-11-21 00:36:55 +00008135static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008136s390_irgen_SR(UChar r1, UChar r2)
8137{
8138 IRTemp op1 = newTemp(Ity_I32);
8139 IRTemp op2 = newTemp(Ity_I32);
8140 IRTemp result = newTemp(Ity_I32);
8141
8142 assign(op1, get_gpr_w1(r1));
8143 assign(op2, get_gpr_w1(r2));
8144 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8145 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8146 put_gpr_w1(r1, mkexpr(result));
8147
8148 return "sr";
8149}
8150
florian55085f82012-11-21 00:36:55 +00008151static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008152s390_irgen_SGR(UChar r1, UChar r2)
8153{
8154 IRTemp op1 = newTemp(Ity_I64);
8155 IRTemp op2 = newTemp(Ity_I64);
8156 IRTemp result = newTemp(Ity_I64);
8157
8158 assign(op1, get_gpr_dw0(r1));
8159 assign(op2, get_gpr_dw0(r2));
8160 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8161 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8162 put_gpr_dw0(r1, mkexpr(result));
8163
8164 return "sgr";
8165}
8166
florian55085f82012-11-21 00:36:55 +00008167static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008168s390_irgen_SGFR(UChar r1, UChar r2)
8169{
8170 IRTemp op1 = newTemp(Ity_I64);
8171 IRTemp op2 = newTemp(Ity_I64);
8172 IRTemp result = newTemp(Ity_I64);
8173
8174 assign(op1, get_gpr_dw0(r1));
8175 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8176 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8177 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8178 put_gpr_dw0(r1, mkexpr(result));
8179
8180 return "sgfr";
8181}
8182
florian55085f82012-11-21 00:36:55 +00008183static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008184s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8185{
8186 IRTemp op2 = newTemp(Ity_I32);
8187 IRTemp op3 = newTemp(Ity_I32);
8188 IRTemp result = newTemp(Ity_I32);
8189
8190 assign(op2, get_gpr_w1(r2));
8191 assign(op3, get_gpr_w1(r3));
8192 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8193 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8194 put_gpr_w1(r1, mkexpr(result));
8195
8196 return "srk";
8197}
8198
florian55085f82012-11-21 00:36:55 +00008199static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008200s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8201{
8202 IRTemp op2 = newTemp(Ity_I64);
8203 IRTemp op3 = newTemp(Ity_I64);
8204 IRTemp result = newTemp(Ity_I64);
8205
8206 assign(op2, get_gpr_dw0(r2));
8207 assign(op3, get_gpr_dw0(r3));
8208 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8209 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8210 put_gpr_dw0(r1, mkexpr(result));
8211
8212 return "sgrk";
8213}
8214
florian55085f82012-11-21 00:36:55 +00008215static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008216s390_irgen_S(UChar r1, IRTemp op2addr)
8217{
8218 IRTemp op1 = newTemp(Ity_I32);
8219 IRTemp op2 = newTemp(Ity_I32);
8220 IRTemp result = newTemp(Ity_I32);
8221
8222 assign(op1, get_gpr_w1(r1));
8223 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8224 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8225 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8226 put_gpr_w1(r1, mkexpr(result));
8227
8228 return "s";
8229}
8230
florian55085f82012-11-21 00:36:55 +00008231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008232s390_irgen_SY(UChar r1, IRTemp op2addr)
8233{
8234 IRTemp op1 = newTemp(Ity_I32);
8235 IRTemp op2 = newTemp(Ity_I32);
8236 IRTemp result = newTemp(Ity_I32);
8237
8238 assign(op1, get_gpr_w1(r1));
8239 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8240 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8241 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8242 put_gpr_w1(r1, mkexpr(result));
8243
8244 return "sy";
8245}
8246
florian55085f82012-11-21 00:36:55 +00008247static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008248s390_irgen_SG(UChar r1, IRTemp op2addr)
8249{
8250 IRTemp op1 = newTemp(Ity_I64);
8251 IRTemp op2 = newTemp(Ity_I64);
8252 IRTemp result = newTemp(Ity_I64);
8253
8254 assign(op1, get_gpr_dw0(r1));
8255 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8256 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8257 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8258 put_gpr_dw0(r1, mkexpr(result));
8259
8260 return "sg";
8261}
8262
florian55085f82012-11-21 00:36:55 +00008263static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008264s390_irgen_SGF(UChar r1, IRTemp op2addr)
8265{
8266 IRTemp op1 = newTemp(Ity_I64);
8267 IRTemp op2 = newTemp(Ity_I64);
8268 IRTemp result = newTemp(Ity_I64);
8269
8270 assign(op1, get_gpr_dw0(r1));
8271 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8272 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8273 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8274 put_gpr_dw0(r1, mkexpr(result));
8275
8276 return "sgf";
8277}
8278
florian55085f82012-11-21 00:36:55 +00008279static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008280s390_irgen_SH(UChar r1, IRTemp op2addr)
8281{
8282 IRTemp op1 = newTemp(Ity_I32);
8283 IRTemp op2 = newTemp(Ity_I32);
8284 IRTemp result = newTemp(Ity_I32);
8285
8286 assign(op1, get_gpr_w1(r1));
8287 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8288 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8289 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8290 put_gpr_w1(r1, mkexpr(result));
8291
8292 return "sh";
8293}
8294
florian55085f82012-11-21 00:36:55 +00008295static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008296s390_irgen_SHY(UChar r1, IRTemp op2addr)
8297{
8298 IRTemp op1 = newTemp(Ity_I32);
8299 IRTemp op2 = newTemp(Ity_I32);
8300 IRTemp result = newTemp(Ity_I32);
8301
8302 assign(op1, get_gpr_w1(r1));
8303 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8304 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8305 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8306 put_gpr_w1(r1, mkexpr(result));
8307
8308 return "shy";
8309}
8310
florian55085f82012-11-21 00:36:55 +00008311static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008312s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8313{
8314 IRTemp op2 = newTemp(Ity_I32);
8315 IRTemp op3 = newTemp(Ity_I32);
8316 IRTemp result = newTemp(Ity_I32);
8317
8318 assign(op2, get_gpr_w0(r1));
8319 assign(op3, get_gpr_w0(r2));
8320 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8321 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8322 put_gpr_w0(r1, mkexpr(result));
8323
8324 return "shhhr";
8325}
8326
florian55085f82012-11-21 00:36:55 +00008327static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008328s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8329{
8330 IRTemp op2 = newTemp(Ity_I32);
8331 IRTemp op3 = newTemp(Ity_I32);
8332 IRTemp result = newTemp(Ity_I32);
8333
8334 assign(op2, get_gpr_w0(r1));
8335 assign(op3, get_gpr_w1(r2));
8336 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8337 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8338 put_gpr_w0(r1, mkexpr(result));
8339
8340 return "shhlr";
8341}
8342
florian55085f82012-11-21 00:36:55 +00008343static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008344s390_irgen_SLR(UChar r1, UChar r2)
8345{
8346 IRTemp op1 = newTemp(Ity_I32);
8347 IRTemp op2 = newTemp(Ity_I32);
8348 IRTemp result = newTemp(Ity_I32);
8349
8350 assign(op1, get_gpr_w1(r1));
8351 assign(op2, get_gpr_w1(r2));
8352 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8353 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8354 put_gpr_w1(r1, mkexpr(result));
8355
8356 return "slr";
8357}
8358
florian55085f82012-11-21 00:36:55 +00008359static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008360s390_irgen_SLGR(UChar r1, UChar r2)
8361{
8362 IRTemp op1 = newTemp(Ity_I64);
8363 IRTemp op2 = newTemp(Ity_I64);
8364 IRTemp result = newTemp(Ity_I64);
8365
8366 assign(op1, get_gpr_dw0(r1));
8367 assign(op2, get_gpr_dw0(r2));
8368 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8369 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8370 put_gpr_dw0(r1, mkexpr(result));
8371
8372 return "slgr";
8373}
8374
florian55085f82012-11-21 00:36:55 +00008375static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008376s390_irgen_SLGFR(UChar r1, UChar r2)
8377{
8378 IRTemp op1 = newTemp(Ity_I64);
8379 IRTemp op2 = newTemp(Ity_I64);
8380 IRTemp result = newTemp(Ity_I64);
8381
8382 assign(op1, get_gpr_dw0(r1));
8383 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8384 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8385 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8386 put_gpr_dw0(r1, mkexpr(result));
8387
8388 return "slgfr";
8389}
8390
florian55085f82012-11-21 00:36:55 +00008391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008392s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8393{
8394 IRTemp op2 = newTemp(Ity_I32);
8395 IRTemp op3 = newTemp(Ity_I32);
8396 IRTemp result = newTemp(Ity_I32);
8397
8398 assign(op2, get_gpr_w1(r2));
8399 assign(op3, get_gpr_w1(r3));
8400 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8401 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8402 put_gpr_w1(r1, mkexpr(result));
8403
8404 return "slrk";
8405}
8406
florian55085f82012-11-21 00:36:55 +00008407static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008408s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8409{
8410 IRTemp op2 = newTemp(Ity_I64);
8411 IRTemp op3 = newTemp(Ity_I64);
8412 IRTemp result = newTemp(Ity_I64);
8413
8414 assign(op2, get_gpr_dw0(r2));
8415 assign(op3, get_gpr_dw0(r3));
8416 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8417 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8418 put_gpr_dw0(r1, mkexpr(result));
8419
8420 return "slgrk";
8421}
8422
florian55085f82012-11-21 00:36:55 +00008423static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008424s390_irgen_SL(UChar r1, IRTemp op2addr)
8425{
8426 IRTemp op1 = newTemp(Ity_I32);
8427 IRTemp op2 = newTemp(Ity_I32);
8428 IRTemp result = newTemp(Ity_I32);
8429
8430 assign(op1, get_gpr_w1(r1));
8431 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8432 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8433 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8434 put_gpr_w1(r1, mkexpr(result));
8435
8436 return "sl";
8437}
8438
florian55085f82012-11-21 00:36:55 +00008439static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008440s390_irgen_SLY(UChar r1, IRTemp op2addr)
8441{
8442 IRTemp op1 = newTemp(Ity_I32);
8443 IRTemp op2 = newTemp(Ity_I32);
8444 IRTemp result = newTemp(Ity_I32);
8445
8446 assign(op1, get_gpr_w1(r1));
8447 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8448 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8449 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8450 put_gpr_w1(r1, mkexpr(result));
8451
8452 return "sly";
8453}
8454
florian55085f82012-11-21 00:36:55 +00008455static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008456s390_irgen_SLG(UChar r1, IRTemp op2addr)
8457{
8458 IRTemp op1 = newTemp(Ity_I64);
8459 IRTemp op2 = newTemp(Ity_I64);
8460 IRTemp result = newTemp(Ity_I64);
8461
8462 assign(op1, get_gpr_dw0(r1));
8463 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8464 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8465 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8466 put_gpr_dw0(r1, mkexpr(result));
8467
8468 return "slg";
8469}
8470
florian55085f82012-11-21 00:36:55 +00008471static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008472s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8473{
8474 IRTemp op1 = newTemp(Ity_I64);
8475 IRTemp op2 = newTemp(Ity_I64);
8476 IRTemp result = newTemp(Ity_I64);
8477
8478 assign(op1, get_gpr_dw0(r1));
8479 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8480 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8481 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8482 put_gpr_dw0(r1, mkexpr(result));
8483
8484 return "slgf";
8485}
8486
florian55085f82012-11-21 00:36:55 +00008487static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008488s390_irgen_SLFI(UChar r1, UInt i2)
8489{
8490 IRTemp op1 = newTemp(Ity_I32);
8491 UInt op2;
8492 IRTemp result = newTemp(Ity_I32);
8493
8494 assign(op1, get_gpr_w1(r1));
8495 op2 = i2;
8496 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8497 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8498 mkU32(op2)));
8499 put_gpr_w1(r1, mkexpr(result));
8500
8501 return "slfi";
8502}
8503
florian55085f82012-11-21 00:36:55 +00008504static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008505s390_irgen_SLGFI(UChar r1, UInt i2)
8506{
8507 IRTemp op1 = newTemp(Ity_I64);
8508 ULong op2;
8509 IRTemp result = newTemp(Ity_I64);
8510
8511 assign(op1, get_gpr_dw0(r1));
8512 op2 = (ULong)i2;
8513 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8514 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8515 mkU64(op2)));
8516 put_gpr_dw0(r1, mkexpr(result));
8517
8518 return "slgfi";
8519}
8520
florian55085f82012-11-21 00:36:55 +00008521static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008522s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8523{
8524 IRTemp op2 = newTemp(Ity_I32);
8525 IRTemp op3 = newTemp(Ity_I32);
8526 IRTemp result = newTemp(Ity_I32);
8527
8528 assign(op2, get_gpr_w0(r1));
8529 assign(op3, get_gpr_w0(r2));
8530 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8531 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8532 put_gpr_w0(r1, mkexpr(result));
8533
8534 return "slhhhr";
8535}
8536
florian55085f82012-11-21 00:36:55 +00008537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008538s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8539{
8540 IRTemp op2 = newTemp(Ity_I32);
8541 IRTemp op3 = newTemp(Ity_I32);
8542 IRTemp result = newTemp(Ity_I32);
8543
8544 assign(op2, get_gpr_w0(r1));
8545 assign(op3, get_gpr_w1(r2));
8546 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8547 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8548 put_gpr_w0(r1, mkexpr(result));
8549
8550 return "slhhlr";
8551}
8552
florian55085f82012-11-21 00:36:55 +00008553static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008554s390_irgen_SLBR(UChar r1, UChar r2)
8555{
8556 IRTemp op1 = newTemp(Ity_I32);
8557 IRTemp op2 = newTemp(Ity_I32);
8558 IRTemp result = newTemp(Ity_I32);
8559 IRTemp borrow_in = newTemp(Ity_I32);
8560
8561 assign(op1, get_gpr_w1(r1));
8562 assign(op2, get_gpr_w1(r2));
8563 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8564 s390_call_calculate_cc(), mkU8(1))));
8565 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8566 mkexpr(borrow_in)));
8567 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8568 put_gpr_w1(r1, mkexpr(result));
8569
8570 return "slbr";
8571}
8572
florian55085f82012-11-21 00:36:55 +00008573static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008574s390_irgen_SLBGR(UChar r1, UChar r2)
8575{
8576 IRTemp op1 = newTemp(Ity_I64);
8577 IRTemp op2 = newTemp(Ity_I64);
8578 IRTemp result = newTemp(Ity_I64);
8579 IRTemp borrow_in = newTemp(Ity_I64);
8580
8581 assign(op1, get_gpr_dw0(r1));
8582 assign(op2, get_gpr_dw0(r2));
8583 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8584 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8585 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8586 mkexpr(borrow_in)));
8587 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8588 put_gpr_dw0(r1, mkexpr(result));
8589
8590 return "slbgr";
8591}
8592
florian55085f82012-11-21 00:36:55 +00008593static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008594s390_irgen_SLB(UChar r1, IRTemp op2addr)
8595{
8596 IRTemp op1 = newTemp(Ity_I32);
8597 IRTemp op2 = newTemp(Ity_I32);
8598 IRTemp result = newTemp(Ity_I32);
8599 IRTemp borrow_in = newTemp(Ity_I32);
8600
8601 assign(op1, get_gpr_w1(r1));
8602 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8603 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8604 s390_call_calculate_cc(), mkU8(1))));
8605 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8606 mkexpr(borrow_in)));
8607 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8608 put_gpr_w1(r1, mkexpr(result));
8609
8610 return "slb";
8611}
8612
florian55085f82012-11-21 00:36:55 +00008613static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008614s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8615{
8616 IRTemp op1 = newTemp(Ity_I64);
8617 IRTemp op2 = newTemp(Ity_I64);
8618 IRTemp result = newTemp(Ity_I64);
8619 IRTemp borrow_in = newTemp(Ity_I64);
8620
8621 assign(op1, get_gpr_dw0(r1));
8622 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8623 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8624 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8625 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8626 mkexpr(borrow_in)));
8627 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8628 put_gpr_dw0(r1, mkexpr(result));
8629
8630 return "slbg";
8631}
8632
florian55085f82012-11-21 00:36:55 +00008633static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008634s390_irgen_SVC(UChar i)
8635{
8636 IRTemp sysno = newTemp(Ity_I64);
8637
8638 if (i != 0) {
8639 assign(sysno, mkU64(i));
8640 } else {
8641 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8642 }
8643 system_call(mkexpr(sysno));
8644
8645 return "svc";
8646}
8647
florian55085f82012-11-21 00:36:55 +00008648static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008649s390_irgen_TM(UChar i2, IRTemp op1addr)
8650{
8651 UChar mask;
8652 IRTemp value = newTemp(Ity_I8);
8653
8654 mask = i2;
8655 assign(value, load(Ity_I8, mkexpr(op1addr)));
8656 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8657 mkU8(mask)));
8658
8659 return "tm";
8660}
8661
florian55085f82012-11-21 00:36:55 +00008662static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008663s390_irgen_TMY(UChar i2, IRTemp op1addr)
8664{
8665 UChar mask;
8666 IRTemp value = newTemp(Ity_I8);
8667
8668 mask = i2;
8669 assign(value, load(Ity_I8, mkexpr(op1addr)));
8670 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8671 mkU8(mask)));
8672
8673 return "tmy";
8674}
8675
florian55085f82012-11-21 00:36:55 +00008676static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008677s390_irgen_TMHH(UChar r1, UShort i2)
8678{
8679 UShort mask;
8680 IRTemp value = newTemp(Ity_I16);
8681
8682 mask = i2;
8683 assign(value, get_gpr_hw0(r1));
8684 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8685 mkU16(mask)));
8686
8687 return "tmhh";
8688}
8689
florian55085f82012-11-21 00:36:55 +00008690static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008691s390_irgen_TMHL(UChar r1, UShort i2)
8692{
8693 UShort mask;
8694 IRTemp value = newTemp(Ity_I16);
8695
8696 mask = i2;
8697 assign(value, get_gpr_hw1(r1));
8698 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8699 mkU16(mask)));
8700
8701 return "tmhl";
8702}
8703
florian55085f82012-11-21 00:36:55 +00008704static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008705s390_irgen_TMLH(UChar r1, UShort i2)
8706{
8707 UShort mask;
8708 IRTemp value = newTemp(Ity_I16);
8709
8710 mask = i2;
8711 assign(value, get_gpr_hw2(r1));
8712 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8713 mkU16(mask)));
8714
8715 return "tmlh";
8716}
8717
florian55085f82012-11-21 00:36:55 +00008718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008719s390_irgen_TMLL(UChar r1, UShort i2)
8720{
8721 UShort mask;
8722 IRTemp value = newTemp(Ity_I16);
8723
8724 mask = i2;
8725 assign(value, get_gpr_hw3(r1));
8726 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8727 mkU16(mask)));
8728
8729 return "tmll";
8730}
8731
florian55085f82012-11-21 00:36:55 +00008732static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008733s390_irgen_EFPC(UChar r1)
8734{
8735 put_gpr_w1(r1, get_fpc_w0());
8736
8737 return "efpc";
8738}
8739
florian55085f82012-11-21 00:36:55 +00008740static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008741s390_irgen_LER(UChar r1, UChar r2)
8742{
8743 put_fpr_w0(r1, get_fpr_w0(r2));
8744
8745 return "ler";
8746}
8747
florian55085f82012-11-21 00:36:55 +00008748static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008749s390_irgen_LDR(UChar r1, UChar r2)
8750{
8751 put_fpr_dw0(r1, get_fpr_dw0(r2));
8752
8753 return "ldr";
8754}
8755
florian55085f82012-11-21 00:36:55 +00008756static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008757s390_irgen_LXR(UChar r1, UChar r2)
8758{
8759 put_fpr_dw0(r1, get_fpr_dw0(r2));
8760 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8761
8762 return "lxr";
8763}
8764
florian55085f82012-11-21 00:36:55 +00008765static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008766s390_irgen_LE(UChar r1, IRTemp op2addr)
8767{
8768 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8769
8770 return "le";
8771}
8772
florian55085f82012-11-21 00:36:55 +00008773static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008774s390_irgen_LD(UChar r1, IRTemp op2addr)
8775{
8776 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8777
8778 return "ld";
8779}
8780
florian55085f82012-11-21 00:36:55 +00008781static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008782s390_irgen_LEY(UChar r1, IRTemp op2addr)
8783{
8784 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8785
8786 return "ley";
8787}
8788
florian55085f82012-11-21 00:36:55 +00008789static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008790s390_irgen_LDY(UChar r1, IRTemp op2addr)
8791{
8792 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8793
8794 return "ldy";
8795}
8796
florian55085f82012-11-21 00:36:55 +00008797static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008798s390_irgen_LFPC(IRTemp op2addr)
8799{
8800 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8801
8802 return "lfpc";
8803}
8804
florian55085f82012-11-21 00:36:55 +00008805static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008806s390_irgen_LZER(UChar r1)
8807{
8808 put_fpr_w0(r1, mkF32i(0x0));
8809
8810 return "lzer";
8811}
8812
florian55085f82012-11-21 00:36:55 +00008813static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008814s390_irgen_LZDR(UChar r1)
8815{
8816 put_fpr_dw0(r1, mkF64i(0x0));
8817
8818 return "lzdr";
8819}
8820
florian55085f82012-11-21 00:36:55 +00008821static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008822s390_irgen_LZXR(UChar r1)
8823{
8824 put_fpr_dw0(r1, mkF64i(0x0));
8825 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8826
8827 return "lzxr";
8828}
8829
florian55085f82012-11-21 00:36:55 +00008830static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008831s390_irgen_SRNM(IRTemp op2addr)
8832{
florianf0fa1be2012-09-18 20:24:38 +00008833 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008834
florianf0fa1be2012-09-18 20:24:38 +00008835 input_mask = 3;
8836 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008837
florianf0fa1be2012-09-18 20:24:38 +00008838 put_fpc_w0(binop(Iop_Or32,
8839 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8840 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8841 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008842 return "srnm";
8843}
8844
florian55085f82012-11-21 00:36:55 +00008845static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008846s390_irgen_SRNMB(IRTemp op2addr)
8847{
8848 UInt input_mask, fpc_mask;
8849
8850 input_mask = 7;
8851 fpc_mask = 7;
8852
8853 put_fpc_w0(binop(Iop_Or32,
8854 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8855 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8856 mkU32(input_mask))));
8857 return "srnmb";
8858}
8859
florian81a4bfe2012-09-20 01:25:28 +00008860static void
florianf0fa1be2012-09-18 20:24:38 +00008861s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8862{
8863 if (b2 == 0) { /* This is the typical case */
8864 if (d2 > 3) {
8865 if (s390_host_has_fpext && d2 == 7) {
8866 /* ok */
8867 } else {
8868 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008869 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008870 }
8871 }
8872 }
8873
8874 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8875}
8876
florian82cdba62013-03-12 01:31:24 +00008877/* Wrapper to validate the parameter as in SRNMB is not required, as all
8878 the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8879static const HChar *
8880s390_irgen_SRNMT(IRTemp op2addr)
8881{
8882 UInt input_mask, fpc_mask;
8883
8884 input_mask = 7;
8885 fpc_mask = 0x70;
8886
8887 /* fpc[25:27] <- op2addr[61:63]
8888 fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8889 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8890 binop(Iop_Shl32, binop(Iop_And32,
8891 unop(Iop_64to32, mkexpr(op2addr)),
8892 mkU32(input_mask)), mkU8(4))));
8893 return "srnmt";
8894}
8895
florianf0fa1be2012-09-18 20:24:38 +00008896
florian55085f82012-11-21 00:36:55 +00008897static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008898s390_irgen_SFPC(UChar r1)
8899{
8900 put_fpc_w0(get_gpr_w1(r1));
8901
8902 return "sfpc";
8903}
8904
florian55085f82012-11-21 00:36:55 +00008905static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008906s390_irgen_STE(UChar r1, IRTemp op2addr)
8907{
8908 store(mkexpr(op2addr), get_fpr_w0(r1));
8909
8910 return "ste";
8911}
8912
florian55085f82012-11-21 00:36:55 +00008913static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008914s390_irgen_STD(UChar r1, IRTemp op2addr)
8915{
8916 store(mkexpr(op2addr), get_fpr_dw0(r1));
8917
8918 return "std";
8919}
8920
florian55085f82012-11-21 00:36:55 +00008921static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008922s390_irgen_STEY(UChar r1, IRTemp op2addr)
8923{
8924 store(mkexpr(op2addr), get_fpr_w0(r1));
8925
8926 return "stey";
8927}
8928
florian55085f82012-11-21 00:36:55 +00008929static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008930s390_irgen_STDY(UChar r1, IRTemp op2addr)
8931{
8932 store(mkexpr(op2addr), get_fpr_dw0(r1));
8933
8934 return "stdy";
8935}
8936
florian55085f82012-11-21 00:36:55 +00008937static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008938s390_irgen_STFPC(IRTemp op2addr)
8939{
8940 store(mkexpr(op2addr), get_fpc_w0());
8941
8942 return "stfpc";
8943}
8944
florian55085f82012-11-21 00:36:55 +00008945static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008946s390_irgen_AEBR(UChar r1, UChar r2)
8947{
8948 IRTemp op1 = newTemp(Ity_F32);
8949 IRTemp op2 = newTemp(Ity_F32);
8950 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008951 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008952
8953 assign(op1, get_fpr_w0(r1));
8954 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008955 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008956 mkexpr(op2)));
8957 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8958 put_fpr_w0(r1, mkexpr(result));
8959
8960 return "aebr";
8961}
8962
florian55085f82012-11-21 00:36:55 +00008963static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008964s390_irgen_ADBR(UChar r1, UChar r2)
8965{
8966 IRTemp op1 = newTemp(Ity_F64);
8967 IRTemp op2 = newTemp(Ity_F64);
8968 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008969 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008970
8971 assign(op1, get_fpr_dw0(r1));
8972 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008973 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008974 mkexpr(op2)));
8975 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8976 put_fpr_dw0(r1, mkexpr(result));
8977
8978 return "adbr";
8979}
8980
florian55085f82012-11-21 00:36:55 +00008981static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008982s390_irgen_AEB(UChar r1, IRTemp op2addr)
8983{
8984 IRTemp op1 = newTemp(Ity_F32);
8985 IRTemp op2 = newTemp(Ity_F32);
8986 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008987 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008988
8989 assign(op1, get_fpr_w0(r1));
8990 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008991 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008992 mkexpr(op2)));
8993 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8994 put_fpr_w0(r1, mkexpr(result));
8995
8996 return "aeb";
8997}
8998
florian55085f82012-11-21 00:36:55 +00008999static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009000s390_irgen_ADB(UChar r1, IRTemp op2addr)
9001{
9002 IRTemp op1 = newTemp(Ity_F64);
9003 IRTemp op2 = newTemp(Ity_F64);
9004 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009005 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009006
9007 assign(op1, get_fpr_dw0(r1));
9008 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009009 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009010 mkexpr(op2)));
9011 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9012 put_fpr_dw0(r1, mkexpr(result));
9013
9014 return "adb";
9015}
9016
florian55085f82012-11-21 00:36:55 +00009017static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009018s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
9019 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009020{
florian125e20d2012-10-07 15:42:37 +00009021 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009022 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009023 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009024 }
sewardj2019a972011-03-07 16:04:07 +00009025 IRTemp op2 = newTemp(Ity_I32);
9026
9027 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009028 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009029 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009030
9031 return "cefbr";
9032}
9033
florian55085f82012-11-21 00:36:55 +00009034static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009035s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
9036 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009037{
9038 IRTemp op2 = newTemp(Ity_I32);
9039
9040 assign(op2, get_gpr_w1(r2));
9041 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
9042
9043 return "cdfbr";
9044}
9045
florian55085f82012-11-21 00:36:55 +00009046static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009047s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
9048 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009049{
florian125e20d2012-10-07 15:42:37 +00009050 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009051 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009052 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009053 }
sewardj2019a972011-03-07 16:04:07 +00009054 IRTemp op2 = newTemp(Ity_I64);
9055
9056 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009057 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009058 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009059
9060 return "cegbr";
9061}
9062
florian55085f82012-11-21 00:36:55 +00009063static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009064s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
9065 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009066{
florian125e20d2012-10-07 15:42:37 +00009067 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009068 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009069 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009070 }
sewardj2019a972011-03-07 16:04:07 +00009071 IRTemp op2 = newTemp(Ity_I64);
9072
9073 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009074 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009075 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009076
9077 return "cdgbr";
9078}
9079
florian55085f82012-11-21 00:36:55 +00009080static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009081s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
9082 UChar r1, UChar r2)
9083{
floriane75dafa2012-09-01 17:54:09 +00009084 if (! s390_host_has_fpext) {
9085 emulation_failure(EmFail_S390X_fpext);
9086 } else {
9087 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009088
floriane75dafa2012-09-01 17:54:09 +00009089 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009090 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009091 mkexpr(op2)));
9092 }
florian1c8f7ff2012-09-01 00:12:11 +00009093 return "celfbr";
9094}
9095
florian55085f82012-11-21 00:36:55 +00009096static const HChar *
floriand2129202012-09-01 20:01:39 +00009097s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
9098 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00009099{
floriane75dafa2012-09-01 17:54:09 +00009100 if (! s390_host_has_fpext) {
9101 emulation_failure(EmFail_S390X_fpext);
9102 } else {
9103 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009104
floriane75dafa2012-09-01 17:54:09 +00009105 assign(op2, get_gpr_w1(r2));
9106 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
9107 }
florian1c8f7ff2012-09-01 00:12:11 +00009108 return "cdlfbr";
9109}
9110
florian55085f82012-11-21 00:36:55 +00009111static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009112s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
9113 UChar r1, UChar r2)
9114{
floriane75dafa2012-09-01 17:54:09 +00009115 if (! s390_host_has_fpext) {
9116 emulation_failure(EmFail_S390X_fpext);
9117 } else {
9118 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009119
floriane75dafa2012-09-01 17:54:09 +00009120 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009121 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009122 mkexpr(op2)));
9123 }
florian1c8f7ff2012-09-01 00:12:11 +00009124 return "celgbr";
9125}
9126
florian55085f82012-11-21 00:36:55 +00009127static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009128s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
9129 UChar r1, UChar r2)
9130{
floriane75dafa2012-09-01 17:54:09 +00009131 if (! s390_host_has_fpext) {
9132 emulation_failure(EmFail_S390X_fpext);
9133 } else {
9134 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009135
floriane75dafa2012-09-01 17:54:09 +00009136 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009137 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
9138 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009139 mkexpr(op2)));
9140 }
florian1c8f7ff2012-09-01 00:12:11 +00009141 return "cdlgbr";
9142}
9143
florian55085f82012-11-21 00:36:55 +00009144static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009145s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9146 UChar r1, UChar r2)
9147{
floriane75dafa2012-09-01 17:54:09 +00009148 if (! s390_host_has_fpext) {
9149 emulation_failure(EmFail_S390X_fpext);
9150 } else {
9151 IRTemp op = newTemp(Ity_F32);
9152 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009153 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009154
floriane75dafa2012-09-01 17:54:09 +00009155 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009156 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009157 mkexpr(op)));
9158 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009159 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009160 }
florian1c8f7ff2012-09-01 00:12:11 +00009161 return "clfebr";
9162}
9163
florian55085f82012-11-21 00:36:55 +00009164static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009165s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9166 UChar r1, UChar r2)
9167{
floriane75dafa2012-09-01 17:54:09 +00009168 if (! s390_host_has_fpext) {
9169 emulation_failure(EmFail_S390X_fpext);
9170 } else {
9171 IRTemp op = newTemp(Ity_F64);
9172 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009173 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009174
floriane75dafa2012-09-01 17:54:09 +00009175 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009176 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009177 mkexpr(op)));
9178 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009179 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009180 }
florian1c8f7ff2012-09-01 00:12:11 +00009181 return "clfdbr";
9182}
9183
florian55085f82012-11-21 00:36:55 +00009184static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009185s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9186 UChar r1, UChar r2)
9187{
floriane75dafa2012-09-01 17:54:09 +00009188 if (! s390_host_has_fpext) {
9189 emulation_failure(EmFail_S390X_fpext);
9190 } else {
9191 IRTemp op = newTemp(Ity_F32);
9192 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009193 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009194
floriane75dafa2012-09-01 17:54:09 +00009195 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009196 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009197 mkexpr(op)));
9198 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009199 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009200 }
florian1c8f7ff2012-09-01 00:12:11 +00009201 return "clgebr";
9202}
9203
florian55085f82012-11-21 00:36:55 +00009204static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009205s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9206 UChar r1, UChar r2)
9207{
floriane75dafa2012-09-01 17:54:09 +00009208 if (! s390_host_has_fpext) {
9209 emulation_failure(EmFail_S390X_fpext);
9210 } else {
9211 IRTemp op = newTemp(Ity_F64);
9212 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009213 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009214
floriane75dafa2012-09-01 17:54:09 +00009215 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009216 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009217 mkexpr(op)));
9218 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009219 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009220 }
florian1c8f7ff2012-09-01 00:12:11 +00009221 return "clgdbr";
9222}
9223
florian55085f82012-11-21 00:36:55 +00009224static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009225s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9226 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009227{
9228 IRTemp op = newTemp(Ity_F32);
9229 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009230 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009231
9232 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009233 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009234 mkexpr(op)));
9235 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009236 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009237
9238 return "cfebr";
9239}
9240
florian55085f82012-11-21 00:36:55 +00009241static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009242s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9243 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009244{
9245 IRTemp op = newTemp(Ity_F64);
9246 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009247 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009248
9249 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009250 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009251 mkexpr(op)));
9252 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009253 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009254
9255 return "cfdbr";
9256}
9257
florian55085f82012-11-21 00:36:55 +00009258static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009259s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9260 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009261{
9262 IRTemp op = newTemp(Ity_F32);
9263 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009264 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009265
9266 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009267 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009268 mkexpr(op)));
9269 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009270 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009271
9272 return "cgebr";
9273}
9274
florian55085f82012-11-21 00:36:55 +00009275static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009276s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9277 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009278{
9279 IRTemp op = newTemp(Ity_F64);
9280 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009281 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009282
9283 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009284 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009285 mkexpr(op)));
9286 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009287 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009288
9289 return "cgdbr";
9290}
9291
florian55085f82012-11-21 00:36:55 +00009292static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009293s390_irgen_DEBR(UChar r1, UChar r2)
9294{
9295 IRTemp op1 = newTemp(Ity_F32);
9296 IRTemp op2 = newTemp(Ity_F32);
9297 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009298 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009299
9300 assign(op1, get_fpr_w0(r1));
9301 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009302 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009303 mkexpr(op2)));
9304 put_fpr_w0(r1, mkexpr(result));
9305
9306 return "debr";
9307}
9308
florian55085f82012-11-21 00:36:55 +00009309static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009310s390_irgen_DDBR(UChar r1, UChar r2)
9311{
9312 IRTemp op1 = newTemp(Ity_F64);
9313 IRTemp op2 = newTemp(Ity_F64);
9314 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009315 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009316
9317 assign(op1, get_fpr_dw0(r1));
9318 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009319 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009320 mkexpr(op2)));
9321 put_fpr_dw0(r1, mkexpr(result));
9322
9323 return "ddbr";
9324}
9325
florian55085f82012-11-21 00:36:55 +00009326static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009327s390_irgen_DEB(UChar r1, IRTemp op2addr)
9328{
9329 IRTemp op1 = newTemp(Ity_F32);
9330 IRTemp op2 = newTemp(Ity_F32);
9331 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009332 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009333
9334 assign(op1, get_fpr_w0(r1));
9335 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009336 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009337 mkexpr(op2)));
9338 put_fpr_w0(r1, mkexpr(result));
9339
9340 return "deb";
9341}
9342
florian55085f82012-11-21 00:36:55 +00009343static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009344s390_irgen_DDB(UChar r1, IRTemp op2addr)
9345{
9346 IRTemp op1 = newTemp(Ity_F64);
9347 IRTemp op2 = newTemp(Ity_F64);
9348 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009349 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009350
9351 assign(op1, get_fpr_dw0(r1));
9352 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009353 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009354 mkexpr(op2)));
9355 put_fpr_dw0(r1, mkexpr(result));
9356
9357 return "ddb";
9358}
9359
florian55085f82012-11-21 00:36:55 +00009360static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009361s390_irgen_LTEBR(UChar r1, UChar r2)
9362{
9363 IRTemp result = newTemp(Ity_F32);
9364
9365 assign(result, get_fpr_w0(r2));
9366 put_fpr_w0(r1, mkexpr(result));
9367 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9368
9369 return "ltebr";
9370}
9371
florian55085f82012-11-21 00:36:55 +00009372static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009373s390_irgen_LTDBR(UChar r1, UChar r2)
9374{
9375 IRTemp result = newTemp(Ity_F64);
9376
9377 assign(result, get_fpr_dw0(r2));
9378 put_fpr_dw0(r1, mkexpr(result));
9379 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9380
9381 return "ltdbr";
9382}
9383
florian55085f82012-11-21 00:36:55 +00009384static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009385s390_irgen_LCEBR(UChar r1, UChar r2)
9386{
9387 IRTemp result = newTemp(Ity_F32);
9388
9389 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9390 put_fpr_w0(r1, mkexpr(result));
9391 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9392
9393 return "lcebr";
9394}
9395
florian55085f82012-11-21 00:36:55 +00009396static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009397s390_irgen_LCDBR(UChar r1, UChar r2)
9398{
9399 IRTemp result = newTemp(Ity_F64);
9400
9401 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9402 put_fpr_dw0(r1, mkexpr(result));
9403 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9404
9405 return "lcdbr";
9406}
9407
florian55085f82012-11-21 00:36:55 +00009408static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009409s390_irgen_LDEBR(UChar r1, UChar r2)
9410{
9411 IRTemp op = newTemp(Ity_F32);
9412
9413 assign(op, get_fpr_w0(r2));
9414 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9415
9416 return "ldebr";
9417}
9418
florian55085f82012-11-21 00:36:55 +00009419static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009420s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9421{
9422 IRTemp op = newTemp(Ity_F32);
9423
9424 assign(op, load(Ity_F32, mkexpr(op2addr)));
9425 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9426
9427 return "ldeb";
9428}
9429
florian55085f82012-11-21 00:36:55 +00009430static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009431s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9432 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009433{
florian125e20d2012-10-07 15:42:37 +00009434 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009435 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009436 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009437 }
sewardj2019a972011-03-07 16:04:07 +00009438 IRTemp op = newTemp(Ity_F64);
9439
9440 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009441 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009442 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009443
9444 return "ledbr";
9445}
9446
florian55085f82012-11-21 00:36:55 +00009447static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009448s390_irgen_MEEBR(UChar r1, UChar r2)
9449{
9450 IRTemp op1 = newTemp(Ity_F32);
9451 IRTemp op2 = newTemp(Ity_F32);
9452 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009453 IRRoundingMode rounding_mode =
9454 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009455
9456 assign(op1, get_fpr_w0(r1));
9457 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009458 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009459 mkexpr(op2)));
9460 put_fpr_w0(r1, mkexpr(result));
9461
9462 return "meebr";
9463}
9464
florian55085f82012-11-21 00:36:55 +00009465static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009466s390_irgen_MDBR(UChar r1, UChar r2)
9467{
9468 IRTemp op1 = newTemp(Ity_F64);
9469 IRTemp op2 = newTemp(Ity_F64);
9470 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009471 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009472
9473 assign(op1, get_fpr_dw0(r1));
9474 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009475 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009476 mkexpr(op2)));
9477 put_fpr_dw0(r1, mkexpr(result));
9478
9479 return "mdbr";
9480}
9481
florian55085f82012-11-21 00:36:55 +00009482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009483s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9484{
9485 IRTemp op1 = newTemp(Ity_F32);
9486 IRTemp op2 = newTemp(Ity_F32);
9487 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009488 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009489
9490 assign(op1, get_fpr_w0(r1));
9491 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009492 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009493 mkexpr(op2)));
9494 put_fpr_w0(r1, mkexpr(result));
9495
9496 return "meeb";
9497}
9498
florian55085f82012-11-21 00:36:55 +00009499static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009500s390_irgen_MDB(UChar r1, IRTemp op2addr)
9501{
9502 IRTemp op1 = newTemp(Ity_F64);
9503 IRTemp op2 = newTemp(Ity_F64);
9504 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009505 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009506
9507 assign(op1, get_fpr_dw0(r1));
9508 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009509 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009510 mkexpr(op2)));
9511 put_fpr_dw0(r1, mkexpr(result));
9512
9513 return "mdb";
9514}
9515
florian55085f82012-11-21 00:36:55 +00009516static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009517s390_irgen_SEBR(UChar r1, UChar r2)
9518{
9519 IRTemp op1 = newTemp(Ity_F32);
9520 IRTemp op2 = newTemp(Ity_F32);
9521 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009522 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009523
9524 assign(op1, get_fpr_w0(r1));
9525 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009526 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009527 mkexpr(op2)));
9528 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9529 put_fpr_w0(r1, mkexpr(result));
9530
9531 return "sebr";
9532}
9533
florian55085f82012-11-21 00:36:55 +00009534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009535s390_irgen_SDBR(UChar r1, UChar r2)
9536{
9537 IRTemp op1 = newTemp(Ity_F64);
9538 IRTemp op2 = newTemp(Ity_F64);
9539 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009540 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009541
9542 assign(op1, get_fpr_dw0(r1));
9543 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009544 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009545 mkexpr(op2)));
9546 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9547 put_fpr_dw0(r1, mkexpr(result));
9548
9549 return "sdbr";
9550}
9551
florian55085f82012-11-21 00:36:55 +00009552static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009553s390_irgen_SEB(UChar r1, IRTemp op2addr)
9554{
9555 IRTemp op1 = newTemp(Ity_F32);
9556 IRTemp op2 = newTemp(Ity_F32);
9557 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009558 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009559
9560 assign(op1, get_fpr_w0(r1));
9561 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009562 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009563 mkexpr(op2)));
9564 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9565 put_fpr_w0(r1, mkexpr(result));
9566
9567 return "seb";
9568}
9569
florian55085f82012-11-21 00:36:55 +00009570static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009571s390_irgen_SDB(UChar r1, IRTemp op2addr)
9572{
9573 IRTemp op1 = newTemp(Ity_F64);
9574 IRTemp op2 = newTemp(Ity_F64);
9575 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009576 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009577
9578 assign(op1, get_fpr_dw0(r1));
9579 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009580 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009581 mkexpr(op2)));
9582 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9583 put_fpr_dw0(r1, mkexpr(result));
9584
9585 return "sdb";
9586}
9587
florian55085f82012-11-21 00:36:55 +00009588static const HChar *
florian12390202012-11-10 22:34:14 +00009589s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9590{
florianfb596602014-12-06 16:34:48 +00009591 if (! s390_host_has_dfp) {
9592 emulation_failure(EmFail_S390X_DFP_insn);
9593 } else {
9594 IRTemp op1 = newTemp(Ity_D64);
9595 IRTemp op2 = newTemp(Ity_D64);
9596 IRTemp result = newTemp(Ity_D64);
9597 IRTemp rounding_mode;
florian12390202012-11-10 22:34:14 +00009598
florianfb596602014-12-06 16:34:48 +00009599 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9600 emulation_warning(EmWarn_S390X_fpext_rounding);
9601 m4 = S390_DFP_ROUND_PER_FPC_0;
9602 }
florian1bb7f6f2013-02-11 00:03:27 +00009603
florianfb596602014-12-06 16:34:48 +00009604 rounding_mode = encode_dfp_rounding_mode(m4);
9605 assign(op1, get_dpr_dw0(r2));
9606 assign(op2, get_dpr_dw0(r3));
9607 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9608 mkexpr(op2)));
9609 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9610 put_dpr_dw0(r1, mkexpr(result));
florian1bb7f6f2013-02-11 00:03:27 +00009611 }
florian12390202012-11-10 22:34:14 +00009612 return (m4 == 0) ? "adtr" : "adtra";
9613}
9614
florian55085f82012-11-21 00:36:55 +00009615static const HChar *
floriane38f6412012-12-21 17:32:12 +00009616s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9617{
florianfb596602014-12-06 16:34:48 +00009618 if (! s390_host_has_dfp) {
9619 emulation_failure(EmFail_S390X_DFP_insn);
9620 } else {
9621 IRTemp op1 = newTemp(Ity_D128);
9622 IRTemp op2 = newTemp(Ity_D128);
9623 IRTemp result = newTemp(Ity_D128);
9624 IRTemp rounding_mode;
floriane38f6412012-12-21 17:32:12 +00009625
florianfb596602014-12-06 16:34:48 +00009626 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9627 emulation_warning(EmWarn_S390X_fpext_rounding);
9628 m4 = S390_DFP_ROUND_PER_FPC_0;
9629 }
florian1bb7f6f2013-02-11 00:03:27 +00009630
florianfb596602014-12-06 16:34:48 +00009631 rounding_mode = encode_dfp_rounding_mode(m4);
9632 assign(op1, get_dpr_pair(r2));
9633 assign(op2, get_dpr_pair(r3));
9634 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9635 mkexpr(op2)));
9636 put_dpr_pair(r1, mkexpr(result));
9637
9638 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
florian1bb7f6f2013-02-11 00:03:27 +00009639 }
floriane38f6412012-12-21 17:32:12 +00009640 return (m4 == 0) ? "axtr" : "axtra";
9641}
9642
9643static const HChar *
9644s390_irgen_CDTR(UChar r1, UChar r2)
9645{
9646 IRTemp op1 = newTemp(Ity_D64);
9647 IRTemp op2 = newTemp(Ity_D64);
9648 IRTemp cc_vex = newTemp(Ity_I32);
9649 IRTemp cc_s390 = newTemp(Ity_I32);
9650
9651 assign(op1, get_dpr_dw0(r1));
9652 assign(op2, get_dpr_dw0(r2));
9653 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9654
florian2d3d87f2012-12-21 21:05:17 +00009655 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009656 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9657
9658 return "cdtr";
9659}
9660
9661static const HChar *
9662s390_irgen_CXTR(UChar r1, UChar r2)
9663{
9664 IRTemp op1 = newTemp(Ity_D128);
9665 IRTemp op2 = newTemp(Ity_D128);
9666 IRTemp cc_vex = newTemp(Ity_I32);
9667 IRTemp cc_s390 = newTemp(Ity_I32);
9668
9669 assign(op1, get_dpr_pair(r1));
9670 assign(op2, get_dpr_pair(r2));
9671 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9672
florian2d3d87f2012-12-21 21:05:17 +00009673 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009674 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9675
9676 return "cxtr";
9677}
9678
9679static const HChar *
florian5f034622013-01-13 02:29:05 +00009680s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9681 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9682{
florianfb596602014-12-06 16:34:48 +00009683 if (! s390_host_has_dfp) {
9684 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009685 } else {
florianfb596602014-12-06 16:34:48 +00009686 if (! s390_host_has_fpext) {
9687 emulation_failure(EmFail_S390X_fpext);
9688 } else {
9689 IRTemp op2 = newTemp(Ity_I32);
florian5f034622013-01-13 02:29:05 +00009690
florianfb596602014-12-06 16:34:48 +00009691 assign(op2, get_gpr_w1(r2));
9692 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9693 }
florian5f034622013-01-13 02:29:05 +00009694 }
9695 return "cdftr";
9696}
9697
9698static const HChar *
9699s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9700 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9701{
florianfb596602014-12-06 16:34:48 +00009702 if (! s390_host_has_dfp) {
9703 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009704 } else {
florianfb596602014-12-06 16:34:48 +00009705 if (! s390_host_has_fpext) {
9706 emulation_failure(EmFail_S390X_fpext);
9707 } else {
9708 IRTemp op2 = newTemp(Ity_I32);
florian5f034622013-01-13 02:29:05 +00009709
florianfb596602014-12-06 16:34:48 +00009710 assign(op2, get_gpr_w1(r2));
9711 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9712 }
florian5f034622013-01-13 02:29:05 +00009713 }
9714 return "cxftr";
9715}
9716
9717static const HChar *
floriana887acd2013-02-08 23:32:54 +00009718s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9719 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 op2 = newTemp(Ity_I64);
floriana887acd2013-02-08 23:32:54 +00009725
florianfb596602014-12-06 16:34:48 +00009726 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9727 emulation_warning(EmWarn_S390X_fpext_rounding);
9728 m3 = S390_DFP_ROUND_PER_FPC_0;
9729 }
9730
9731 assign(op2, get_gpr_dw0(r2));
9732 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9733 mkexpr(op2)));
floriana887acd2013-02-08 23:32:54 +00009734 }
floriana887acd2013-02-08 23:32:54 +00009735 return (m3 == 0) ? "cdgtr" : "cdgtra";
9736}
9737
9738static const HChar *
9739s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9740 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9741{
florianfb596602014-12-06 16:34:48 +00009742 if (! s390_host_has_dfp) {
9743 emulation_failure(EmFail_S390X_DFP_insn);
9744 } else {
9745 IRTemp op2 = newTemp(Ity_I64);
floriana887acd2013-02-08 23:32:54 +00009746
florianfb596602014-12-06 16:34:48 +00009747 /* No emulation warning here about an non-zero m3 on hosts without
9748 floating point extension facility. No rounding is performed */
floriana887acd2013-02-08 23:32:54 +00009749
florianfb596602014-12-06 16:34:48 +00009750 assign(op2, get_gpr_dw0(r2));
9751 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9752 }
floriana887acd2013-02-08 23:32:54 +00009753 return "cxgtr";
9754}
9755
9756static const HChar *
florian5f034622013-01-13 02:29:05 +00009757s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9758 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9759{
florianfb596602014-12-06 16:34:48 +00009760 if (! s390_host_has_dfp) {
9761 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009762 } else {
florianfb596602014-12-06 16:34:48 +00009763 if (! s390_host_has_fpext) {
9764 emulation_failure(EmFail_S390X_fpext);
9765 } else {
9766 IRTemp op2 = newTemp(Ity_I32);
florian5f034622013-01-13 02:29:05 +00009767
florianfb596602014-12-06 16:34:48 +00009768 assign(op2, get_gpr_w1(r2));
9769 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9770 }
florian5f034622013-01-13 02:29:05 +00009771 }
9772 return "cdlftr";
9773}
9774
9775static const HChar *
9776s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9777 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9778{
florianfb596602014-12-06 16:34:48 +00009779 if (! s390_host_has_dfp) {
9780 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009781 } else {
florianfb596602014-12-06 16:34:48 +00009782 if (! s390_host_has_fpext) {
9783 emulation_failure(EmFail_S390X_fpext);
9784 } else {
9785 IRTemp op2 = newTemp(Ity_I32);
florian5f034622013-01-13 02:29:05 +00009786
florianfb596602014-12-06 16:34:48 +00009787 assign(op2, get_gpr_w1(r2));
9788 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9789 }
florian5f034622013-01-13 02:29:05 +00009790 }
9791 return "cxlftr";
9792}
9793
9794static const HChar *
9795s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9796 UChar r1, UChar r2)
9797{
florianfb596602014-12-06 16:34:48 +00009798 if (! s390_host_has_dfp) {
9799 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009800 } else {
florianfb596602014-12-06 16:34:48 +00009801 if (! s390_host_has_fpext) {
9802 emulation_failure(EmFail_S390X_fpext);
9803 } else {
9804 IRTemp op2 = newTemp(Ity_I64);
florian5f034622013-01-13 02:29:05 +00009805
florianfb596602014-12-06 16:34:48 +00009806 assign(op2, get_gpr_dw0(r2));
9807 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9808 mkexpr(encode_dfp_rounding_mode(m3)),
9809 mkexpr(op2)));
9810 }
florian5f034622013-01-13 02:29:05 +00009811 }
9812 return "cdlgtr";
9813}
9814
9815static const HChar *
9816s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9817 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9818{
florianfb596602014-12-06 16:34:48 +00009819 if (! s390_host_has_dfp) {
9820 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009821 } else {
florianfb596602014-12-06 16:34:48 +00009822 if (! s390_host_has_fpext) {
9823 emulation_failure(EmFail_S390X_fpext);
9824 } else {
9825 IRTemp op2 = newTemp(Ity_I64);
florian5f034622013-01-13 02:29:05 +00009826
florianfb596602014-12-06 16:34:48 +00009827 assign(op2, get_gpr_dw0(r2));
9828 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9829 }
florian5f034622013-01-13 02:29:05 +00009830 }
9831 return "cxlgtr";
9832}
9833
9834static const HChar *
9835s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9836 UChar r1, UChar r2)
9837{
florianfb596602014-12-06 16:34:48 +00009838 if (! s390_host_has_dfp) {
9839 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009840 } else {
florianfb596602014-12-06 16:34:48 +00009841 if (! s390_host_has_fpext) {
9842 emulation_failure(EmFail_S390X_fpext);
9843 } else {
9844 IRTemp op = newTemp(Ity_D64);
9845 IRTemp result = newTemp(Ity_I32);
9846 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
florian5f034622013-01-13 02:29:05 +00009847
florianfb596602014-12-06 16:34:48 +00009848 assign(op, get_dpr_dw0(r2));
9849 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9850 mkexpr(op)));
9851 put_gpr_w1(r1, mkexpr(result));
9852 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9853 }
florian5f034622013-01-13 02:29:05 +00009854 }
9855 return "cfdtr";
9856}
9857
9858static const HChar *
9859s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9860 UChar r1, UChar r2)
9861{
florianfb596602014-12-06 16:34:48 +00009862 if (! s390_host_has_dfp) {
9863 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009864 } else {
florianfb596602014-12-06 16:34:48 +00009865 if (! s390_host_has_fpext) {
9866 emulation_failure(EmFail_S390X_fpext);
9867 } else {
9868 IRTemp op = newTemp(Ity_D128);
9869 IRTemp result = newTemp(Ity_I32);
9870 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
florian5f034622013-01-13 02:29:05 +00009871
florianfb596602014-12-06 16:34:48 +00009872 assign(op, get_dpr_pair(r2));
9873 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9874 mkexpr(op)));
9875 put_gpr_w1(r1, mkexpr(result));
9876 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op,
9877 rounding_mode);
9878 }
florian5f034622013-01-13 02:29:05 +00009879 }
9880 return "cfxtr";
9881}
9882
9883static const HChar *
floriana887acd2013-02-08 23:32:54 +00009884s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9885 UChar r1, UChar r2)
9886{
florianfb596602014-12-06 16:34:48 +00009887 if (! s390_host_has_dfp) {
9888 emulation_failure(EmFail_S390X_DFP_insn);
9889 } else {
9890 IRTemp op = newTemp(Ity_D64);
9891 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
floriana887acd2013-02-08 23:32:54 +00009892
florianfb596602014-12-06 16:34:48 +00009893 /* If fpext is not installed and m3 is in 1:7,
9894 rounding mode performed is unpredictable */
9895 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9896 emulation_warning(EmWarn_S390X_fpext_rounding);
9897 m3 = S390_DFP_ROUND_PER_FPC_0;
9898 }
floriana887acd2013-02-08 23:32:54 +00009899
florianfb596602014-12-06 16:34:48 +00009900 assign(op, get_dpr_dw0(r2));
9901 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9902 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
floriana887acd2013-02-08 23:32:54 +00009903 }
floriana887acd2013-02-08 23:32:54 +00009904 return "cgdtr";
9905}
9906
9907static const HChar *
9908s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9909 UChar r1, UChar r2)
9910{
florianfb596602014-12-06 16:34:48 +00009911 if (! s390_host_has_dfp) {
9912 emulation_failure(EmFail_S390X_DFP_insn);
9913 } else {
9914 IRTemp op = newTemp(Ity_D128);
9915 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
floriana887acd2013-02-08 23:32:54 +00009916
florianfb596602014-12-06 16:34:48 +00009917 /* If fpext is not installed and m3 is in 1:7,
9918 rounding mode performed is unpredictable */
9919 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9920 emulation_warning(EmWarn_S390X_fpext_rounding);
9921 m3 = S390_DFP_ROUND_PER_FPC_0;
9922 }
9923 assign(op, get_dpr_pair(r2));
9924 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9925 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
floriana887acd2013-02-08 23:32:54 +00009926 }
floriana887acd2013-02-08 23:32:54 +00009927 return "cgxtr";
9928}
9929
9930static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009931s390_irgen_CEDTR(UChar r1, UChar r2)
9932{
florianfb596602014-12-06 16:34:48 +00009933 if (! s390_host_has_dfp) {
9934 emulation_failure(EmFail_S390X_DFP_insn);
9935 } else {
9936 IRTemp op1 = newTemp(Ity_D64);
9937 IRTemp op2 = newTemp(Ity_D64);
9938 IRTemp cc_vex = newTemp(Ity_I32);
9939 IRTemp cc_s390 = newTemp(Ity_I32);
florian20c6bca2012-12-26 17:47:19 +00009940
florianfb596602014-12-06 16:34:48 +00009941 assign(op1, get_dpr_dw0(r1));
9942 assign(op2, get_dpr_dw0(r2));
9943 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
florian20c6bca2012-12-26 17:47:19 +00009944
florianfb596602014-12-06 16:34:48 +00009945 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9946 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9947 }
florian20c6bca2012-12-26 17:47:19 +00009948 return "cedtr";
9949}
9950
9951static const HChar *
9952s390_irgen_CEXTR(UChar r1, UChar r2)
9953{
florianfb596602014-12-06 16:34:48 +00009954 if (! s390_host_has_dfp) {
9955 emulation_failure(EmFail_S390X_DFP_insn);
9956 } else {
9957 IRTemp op1 = newTemp(Ity_D128);
9958 IRTemp op2 = newTemp(Ity_D128);
9959 IRTemp cc_vex = newTemp(Ity_I32);
9960 IRTemp cc_s390 = newTemp(Ity_I32);
florian20c6bca2012-12-26 17:47:19 +00009961
florianfb596602014-12-06 16:34:48 +00009962 assign(op1, get_dpr_pair(r1));
9963 assign(op2, get_dpr_pair(r2));
9964 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
florian20c6bca2012-12-26 17:47:19 +00009965
florianfb596602014-12-06 16:34:48 +00009966 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9967 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9968 }
florian20c6bca2012-12-26 17:47:19 +00009969 return "cextr";
9970}
9971
9972static const HChar *
florian5f034622013-01-13 02:29:05 +00009973s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9974 UChar r1, UChar r2)
9975{
florianfb596602014-12-06 16:34:48 +00009976 if (! s390_host_has_dfp) {
9977 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +00009978 } else {
florianfb596602014-12-06 16:34:48 +00009979 if (! s390_host_has_fpext) {
9980 emulation_failure(EmFail_S390X_fpext);
9981 } else {
9982 IRTemp op = newTemp(Ity_D64);
9983 IRTemp result = newTemp(Ity_I32);
9984 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
florian5f034622013-01-13 02:29:05 +00009985
florianfb596602014-12-06 16:34:48 +00009986 assign(op, get_dpr_dw0(r2));
9987 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9988 mkexpr(op)));
9989 put_gpr_w1(r1, mkexpr(result));
9990 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9991 }
florian5f034622013-01-13 02:29:05 +00009992 }
9993 return "clfdtr";
9994}
9995
9996static const HChar *
9997s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9998 UChar r1, UChar r2)
9999{
florianfb596602014-12-06 16:34:48 +000010000 if (! s390_host_has_dfp) {
10001 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +000010002 } else {
florianfb596602014-12-06 16:34:48 +000010003 if (! s390_host_has_fpext) {
10004 emulation_failure(EmFail_S390X_fpext);
10005 } else {
10006 IRTemp op = newTemp(Ity_D128);
10007 IRTemp result = newTemp(Ity_I32);
10008 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
florian5f034622013-01-13 02:29:05 +000010009
florianfb596602014-12-06 16:34:48 +000010010 assign(op, get_dpr_pair(r2));
10011 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
10012 mkexpr(op)));
10013 put_gpr_w1(r1, mkexpr(result));
10014 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op,
10015 rounding_mode);
10016 }
florian5f034622013-01-13 02:29:05 +000010017 }
10018 return "clfxtr";
10019}
10020
10021static const HChar *
10022s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
10023 UChar r1, UChar r2)
10024{
florianfb596602014-12-06 16:34:48 +000010025 if (! s390_host_has_dfp) {
10026 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +000010027 } else {
florianfb596602014-12-06 16:34:48 +000010028 if (! s390_host_has_fpext) {
10029 emulation_failure(EmFail_S390X_fpext);
10030 } else {
10031 IRTemp op = newTemp(Ity_D64);
10032 IRTemp result = newTemp(Ity_I64);
10033 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
florian5f034622013-01-13 02:29:05 +000010034
florianfb596602014-12-06 16:34:48 +000010035 assign(op, get_dpr_dw0(r2));
10036 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
10037 mkexpr(op)));
10038 put_gpr_dw0(r1, mkexpr(result));
10039 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
10040 }
florian5f034622013-01-13 02:29:05 +000010041 }
10042 return "clgdtr";
10043}
10044
10045static const HChar *
10046s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
10047 UChar r1, UChar r2)
10048{
florianfb596602014-12-06 16:34:48 +000010049 if (! s390_host_has_dfp) {
10050 emulation_failure(EmFail_S390X_DFP_insn);
florian5f034622013-01-13 02:29:05 +000010051 } else {
florianfb596602014-12-06 16:34:48 +000010052 if (! s390_host_has_fpext) {
10053 emulation_failure(EmFail_S390X_fpext);
10054 } else {
10055 IRTemp op = newTemp(Ity_D128);
10056 IRTemp result = newTemp(Ity_I64);
10057 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
florian5f034622013-01-13 02:29:05 +000010058
florianfb596602014-12-06 16:34:48 +000010059 assign(op, get_dpr_pair(r2));
10060 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
10061 mkexpr(op)));
10062 put_gpr_dw0(r1, mkexpr(result));
10063 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
10064 rounding_mode);
10065 }
florian5f034622013-01-13 02:29:05 +000010066 }
10067 return "clgxtr";
10068}
10069
10070static const HChar *
florian12390202012-11-10 22:34:14 +000010071s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10072{
florianfb596602014-12-06 16:34:48 +000010073 if (! s390_host_has_dfp) {
10074 emulation_failure(EmFail_S390X_DFP_insn);
10075 } else {
10076 IRTemp op1 = newTemp(Ity_D64);
10077 IRTemp op2 = newTemp(Ity_D64);
10078 IRTemp result = newTemp(Ity_D64);
10079 IRTemp rounding_mode;
florian12390202012-11-10 22:34:14 +000010080
florianfb596602014-12-06 16:34:48 +000010081 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10082 emulation_warning(EmWarn_S390X_fpext_rounding);
10083 m4 = S390_DFP_ROUND_PER_FPC_0;
10084 }
florian1bb7f6f2013-02-11 00:03:27 +000010085
florianfb596602014-12-06 16:34:48 +000010086 rounding_mode = encode_dfp_rounding_mode(m4);
10087 assign(op1, get_dpr_dw0(r2));
10088 assign(op2, get_dpr_dw0(r3));
10089 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
10090 mkexpr(op2)));
10091 put_dpr_dw0(r1, mkexpr(result));
florian1bb7f6f2013-02-11 00:03:27 +000010092 }
florian12390202012-11-10 22:34:14 +000010093 return (m4 == 0) ? "ddtr" : "ddtra";
10094}
10095
florian55085f82012-11-21 00:36:55 +000010096static const HChar *
floriane38f6412012-12-21 17:32:12 +000010097s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10098{
florianfb596602014-12-06 16:34:48 +000010099 if (! s390_host_has_dfp) {
10100 emulation_failure(EmFail_S390X_DFP_insn);
10101 } else {
10102 IRTemp op1 = newTemp(Ity_D128);
10103 IRTemp op2 = newTemp(Ity_D128);
10104 IRTemp result = newTemp(Ity_D128);
10105 IRTemp rounding_mode;
floriane38f6412012-12-21 17:32:12 +000010106
florianfb596602014-12-06 16:34:48 +000010107 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10108 emulation_warning(EmWarn_S390X_fpext_rounding);
10109 m4 = S390_DFP_ROUND_PER_FPC_0;
10110 }
florian1bb7f6f2013-02-11 00:03:27 +000010111
florianfb596602014-12-06 16:34:48 +000010112 rounding_mode = encode_dfp_rounding_mode(m4);
10113 assign(op1, get_dpr_pair(r2));
10114 assign(op2, get_dpr_pair(r3));
10115 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
10116 mkexpr(op2)));
10117 put_dpr_pair(r1, mkexpr(result));
florian1bb7f6f2013-02-11 00:03:27 +000010118 }
floriane38f6412012-12-21 17:32:12 +000010119 return (m4 == 0) ? "dxtr" : "dxtra";
10120}
10121
10122static const HChar *
florian5c539732013-02-14 14:27:12 +000010123s390_irgen_EEDTR(UChar r1, UChar r2)
10124{
florianfb596602014-12-06 16:34:48 +000010125 if (! s390_host_has_dfp) {
10126 emulation_failure(EmFail_S390X_DFP_insn);
10127 } else {
10128 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
10129 }
florian5c539732013-02-14 14:27:12 +000010130 return "eedtr";
10131}
10132
10133static const HChar *
10134s390_irgen_EEXTR(UChar r1, UChar r2)
10135{
florianfb596602014-12-06 16:34:48 +000010136 if (! s390_host_has_dfp) {
10137 emulation_failure(EmFail_S390X_DFP_insn);
10138 } else {
10139 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
10140 }
florian5c539732013-02-14 14:27:12 +000010141 return "eextr";
10142}
10143
10144static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010145s390_irgen_ESDTR(UChar r1, UChar r2)
10146{
florianfb596602014-12-06 16:34:48 +000010147 if (! s390_host_has_dfp) {
10148 emulation_failure(EmFail_S390X_DFP_insn);
10149 } else {
10150 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
10151 }
floriance9e3db2012-12-27 20:14:03 +000010152 return "esdtr";
10153}
10154
10155static const HChar *
10156s390_irgen_ESXTR(UChar r1, UChar r2)
10157{
florianfb596602014-12-06 16:34:48 +000010158 if (! s390_host_has_dfp) {
10159 emulation_failure(EmFail_S390X_DFP_insn);
10160 } else {
10161 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
10162 }
floriance9e3db2012-12-27 20:14:03 +000010163 return "esxtr";
10164}
10165
10166static const HChar *
florian5c539732013-02-14 14:27:12 +000010167s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
10168{
florianfb596602014-12-06 16:34:48 +000010169 if (! s390_host_has_dfp) {
10170 emulation_failure(EmFail_S390X_DFP_insn);
10171 } else {
10172 IRTemp op1 = newTemp(Ity_I64);
10173 IRTemp op2 = newTemp(Ity_D64);
10174 IRTemp result = newTemp(Ity_D64);
florian5c539732013-02-14 14:27:12 +000010175
florianfb596602014-12-06 16:34:48 +000010176 assign(op1, get_gpr_dw0(r2));
10177 assign(op2, get_dpr_dw0(r3));
10178 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
10179 put_dpr_dw0(r1, mkexpr(result));
10180 }
florian5c539732013-02-14 14:27:12 +000010181 return "iedtr";
10182}
10183
10184static const HChar *
10185s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
10186{
florianfb596602014-12-06 16:34:48 +000010187 if (! s390_host_has_dfp) {
10188 emulation_failure(EmFail_S390X_DFP_insn);
10189 } else {
10190 IRTemp op1 = newTemp(Ity_I64);
10191 IRTemp op2 = newTemp(Ity_D128);
10192 IRTemp result = newTemp(Ity_D128);
florian5c539732013-02-14 14:27:12 +000010193
florianfb596602014-12-06 16:34:48 +000010194 assign(op1, get_gpr_dw0(r2));
10195 assign(op2, get_dpr_pair(r3));
10196 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10197 put_dpr_pair(r1, mkexpr(result));
10198 }
florian5c539732013-02-14 14:27:12 +000010199 return "iextr";
10200}
10201
10202static const HChar *
floriane38f6412012-12-21 17:32:12 +000010203s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10204{
florianfb596602014-12-06 16:34:48 +000010205 if (! s390_host_has_dfp) {
10206 emulation_failure(EmFail_S390X_DFP_insn);
10207 } else {
10208 IRTemp op = newTemp(Ity_D32);
floriane38f6412012-12-21 17:32:12 +000010209
florianfb596602014-12-06 16:34:48 +000010210 assign(op, get_dpr_w0(r2));
10211 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10212 }
floriane38f6412012-12-21 17:32:12 +000010213 return "ldetr";
10214}
10215
10216static const HChar *
10217s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10218{
10219 IRTemp op = newTemp(Ity_D64);
10220
10221 assign(op, get_dpr_dw0(r2));
10222 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10223
10224 return "lxdtr";
10225}
10226
10227static const HChar *
10228s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10229 UChar r1, UChar r2)
10230{
florianfb596602014-12-06 16:34:48 +000010231 if (! s390_host_has_dfp) {
10232 emulation_failure(EmFail_S390X_DFP_insn);
10233 } else {
10234 /* If fpext is not installed and m3 is in 1:7,
10235 rounding mode performed is unpredictable */
10236 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10237 emulation_warning(EmWarn_S390X_fpext_rounding);
10238 m3 = S390_DFP_ROUND_PER_FPC_0;
10239 }
10240 IRTemp result = newTemp(Ity_D64);
florian1bb7f6f2013-02-11 00:03:27 +000010241
florianfb596602014-12-06 16:34:48 +000010242 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10243 get_dpr_pair(r2)));
10244 put_dpr_dw0(r1, mkexpr(result));
floriane38f6412012-12-21 17:32:12 +000010245 }
floriane38f6412012-12-21 17:32:12 +000010246 return "ldxtr";
10247}
10248
10249static const HChar *
10250s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10251 UChar r1, UChar r2)
10252{
florianfb596602014-12-06 16:34:48 +000010253 if (! s390_host_has_dfp) {
10254 emulation_failure(EmFail_S390X_DFP_insn);
10255 } else {
10256 /* If fpext is not installed and m3 is in 1:7,
10257 rounding mode performed is unpredictable */
10258 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
10259 emulation_warning(EmWarn_S390X_fpext_rounding);
10260 m3 = S390_DFP_ROUND_PER_FPC_0;
10261 }
10262 IRTemp op = newTemp(Ity_D64);
florian1bb7f6f2013-02-11 00:03:27 +000010263
florianfb596602014-12-06 16:34:48 +000010264 assign(op, get_dpr_dw0(r2));
10265 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10266 mkexpr(op)));
floriane38f6412012-12-21 17:32:12 +000010267 }
floriane38f6412012-12-21 17:32:12 +000010268 return "ledtr";
10269}
10270
10271static const HChar *
10272s390_irgen_LTDTR(UChar r1, UChar r2)
10273{
10274 IRTemp result = newTemp(Ity_D64);
10275
10276 assign(result, get_dpr_dw0(r2));
10277 put_dpr_dw0(r1, mkexpr(result));
10278 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10279
10280 return "ltdtr";
10281}
10282
10283static const HChar *
10284s390_irgen_LTXTR(UChar r1, UChar r2)
10285{
10286 IRTemp result = newTemp(Ity_D128);
10287
10288 assign(result, get_dpr_pair(r2));
10289 put_dpr_pair(r1, mkexpr(result));
10290 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10291
10292 return "ltxtr";
10293}
10294
10295static const HChar *
florian12390202012-11-10 22:34:14 +000010296s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10297{
florianfb596602014-12-06 16:34:48 +000010298 if (! s390_host_has_dfp) {
10299 emulation_failure(EmFail_S390X_DFP_insn);
10300 } else {
10301 IRTemp op1 = newTemp(Ity_D64);
10302 IRTemp op2 = newTemp(Ity_D64);
10303 IRTemp result = newTemp(Ity_D64);
10304 IRTemp rounding_mode;
florian12390202012-11-10 22:34:14 +000010305
florianfb596602014-12-06 16:34:48 +000010306 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10307 emulation_warning(EmWarn_S390X_fpext_rounding);
10308 m4 = S390_DFP_ROUND_PER_FPC_0;
10309 }
florian1bb7f6f2013-02-11 00:03:27 +000010310
florianfb596602014-12-06 16:34:48 +000010311 rounding_mode = encode_dfp_rounding_mode(m4);
10312 assign(op1, get_dpr_dw0(r2));
10313 assign(op2, get_dpr_dw0(r3));
10314 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10315 mkexpr(op2)));
10316 put_dpr_dw0(r1, mkexpr(result));
florian1bb7f6f2013-02-11 00:03:27 +000010317 }
florian12390202012-11-10 22:34:14 +000010318 return (m4 == 0) ? "mdtr" : "mdtra";
10319}
10320
florian55085f82012-11-21 00:36:55 +000010321static const HChar *
floriane38f6412012-12-21 17:32:12 +000010322s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10323{
florianfb596602014-12-06 16:34:48 +000010324 if (! s390_host_has_dfp) {
10325 emulation_failure(EmFail_S390X_DFP_insn);
10326 } else {
10327 IRTemp op1 = newTemp(Ity_D128);
10328 IRTemp op2 = newTemp(Ity_D128);
10329 IRTemp result = newTemp(Ity_D128);
10330 IRTemp rounding_mode;
floriane38f6412012-12-21 17:32:12 +000010331
florianfb596602014-12-06 16:34:48 +000010332 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10333 emulation_warning(EmWarn_S390X_fpext_rounding);
10334 m4 = S390_DFP_ROUND_PER_FPC_0;
10335 }
florian1bb7f6f2013-02-11 00:03:27 +000010336
florianfb596602014-12-06 16:34:48 +000010337 rounding_mode = encode_dfp_rounding_mode(m4);
10338 assign(op1, get_dpr_pair(r2));
10339 assign(op2, get_dpr_pair(r3));
10340 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10341 mkexpr(op2)));
10342 put_dpr_pair(r1, mkexpr(result));
florian1bb7f6f2013-02-11 00:03:27 +000010343 }
floriane38f6412012-12-21 17:32:12 +000010344 return (m4 == 0) ? "mxtr" : "mxtra";
10345}
10346
10347static const HChar *
florian5c539732013-02-14 14:27:12 +000010348s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10349{
florianfb596602014-12-06 16:34:48 +000010350 if (! s390_host_has_dfp) {
10351 emulation_failure(EmFail_S390X_DFP_insn);
10352 } else {
10353 IRTemp op1 = newTemp(Ity_D64);
10354 IRTemp op2 = newTemp(Ity_D64);
10355 IRTemp result = newTemp(Ity_D64);
10356 IRTemp rounding_mode;
florian5c539732013-02-14 14:27:12 +000010357
florianfb596602014-12-06 16:34:48 +000010358 /* If fpext is not installed and m4 is in 1:7,
10359 rounding mode performed is unpredictable */
10360 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10361 emulation_warning(EmWarn_S390X_fpext_rounding);
10362 m4 = S390_DFP_ROUND_PER_FPC_0;
10363 }
10364
10365 rounding_mode = encode_dfp_rounding_mode(m4);
10366 assign(op1, get_dpr_dw0(r2));
10367 assign(op2, get_dpr_dw0(r3));
10368 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10369 mkexpr(op2)));
10370 put_dpr_dw0(r1, mkexpr(result));
florian5c539732013-02-14 14:27:12 +000010371 }
florian5c539732013-02-14 14:27:12 +000010372 return "qadtr";
10373}
10374
10375static const HChar *
10376s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10377{
florianfb596602014-12-06 16:34:48 +000010378 if (! s390_host_has_dfp) {
10379 emulation_failure(EmFail_S390X_DFP_insn);
10380 } else {
10381 IRTemp op1 = newTemp(Ity_D128);
10382 IRTemp op2 = newTemp(Ity_D128);
10383 IRTemp result = newTemp(Ity_D128);
10384 IRTemp rounding_mode;
florian5c539732013-02-14 14:27:12 +000010385
florianfb596602014-12-06 16:34:48 +000010386 /* If fpext is not installed and m4 is in 1:7,
10387 rounding mode performed is unpredictable */
10388 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10389 emulation_warning(EmWarn_S390X_fpext_rounding);
10390 m4 = S390_DFP_ROUND_PER_FPC_0;
10391 }
10392
10393 rounding_mode = encode_dfp_rounding_mode(m4);
10394 assign(op1, get_dpr_pair(r2));
10395 assign(op2, get_dpr_pair(r3));
10396 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10397 mkexpr(op2)));
10398 put_dpr_pair(r1, mkexpr(result));
florian5c539732013-02-14 14:27:12 +000010399 }
florian5c539732013-02-14 14:27:12 +000010400 return "qaxtr";
10401}
10402
10403static const HChar *
10404s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10405{
florianfb596602014-12-06 16:34:48 +000010406 if (! s390_host_has_dfp) {
10407 emulation_failure(EmFail_S390X_DFP_insn);
10408 } else {
10409 IRTemp op1 = newTemp(Ity_I8);
10410 IRTemp op2 = newTemp(Ity_D64);
10411 IRTemp result = newTemp(Ity_D64);
10412 IRTemp rounding_mode;
florian5c539732013-02-14 14:27:12 +000010413
florianfb596602014-12-06 16:34:48 +000010414 /* If fpext is not installed and m4 is in 1:7,
10415 rounding mode performed is unpredictable */
10416 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10417 emulation_warning(EmWarn_S390X_fpext_rounding);
10418 m4 = S390_DFP_ROUND_PER_FPC_0;
10419 }
10420
10421 rounding_mode = encode_dfp_rounding_mode(m4);
10422 assign(op1, get_gpr_b7(r2));
10423 assign(op2, get_dpr_dw0(r3));
10424 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10425 mkexpr(op1), mkexpr(op2)));
10426 put_dpr_dw0(r1, mkexpr(result));
florian5c539732013-02-14 14:27:12 +000010427 }
florian5c539732013-02-14 14:27:12 +000010428 return "rrdtr";
10429}
10430
10431static const HChar *
10432s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10433{
florianfb596602014-12-06 16:34:48 +000010434 if (! s390_host_has_dfp) {
10435 emulation_failure(EmFail_S390X_DFP_insn);
10436 } else {
10437 IRTemp op1 = newTemp(Ity_I8);
10438 IRTemp op2 = newTemp(Ity_D128);
10439 IRTemp result = newTemp(Ity_D128);
10440 IRTemp rounding_mode;
florian5c539732013-02-14 14:27:12 +000010441
florianfb596602014-12-06 16:34:48 +000010442 /* If fpext is not installed and m4 is in 1:7,
10443 rounding mode performed is unpredictable */
10444 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10445 emulation_warning(EmWarn_S390X_fpext_rounding);
10446 m4 = S390_DFP_ROUND_PER_FPC_0;
10447 }
10448
10449 rounding_mode = encode_dfp_rounding_mode(m4);
10450 assign(op1, get_gpr_b7(r2));
10451 assign(op2, get_dpr_pair(r3));
10452 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10453 mkexpr(op1), mkexpr(op2)));
10454 put_dpr_pair(r1, mkexpr(result));
florian5c539732013-02-14 14:27:12 +000010455 }
florian5c539732013-02-14 14:27:12 +000010456 return "rrxtr";
10457}
10458
10459static const HChar *
florian12390202012-11-10 22:34:14 +000010460s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10461{
florianfb596602014-12-06 16:34:48 +000010462 if (! s390_host_has_dfp) {
10463 emulation_failure(EmFail_S390X_DFP_insn);
10464 } else {
10465 IRTemp op1 = newTemp(Ity_D64);
10466 IRTemp op2 = newTemp(Ity_D64);
10467 IRTemp result = newTemp(Ity_D64);
10468 IRTemp rounding_mode;
florian12390202012-11-10 22:34:14 +000010469
florianfb596602014-12-06 16:34:48 +000010470 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10471 emulation_warning(EmWarn_S390X_fpext_rounding);
10472 m4 = S390_DFP_ROUND_PER_FPC_0;
10473 }
florian1bb7f6f2013-02-11 00:03:27 +000010474
florianfb596602014-12-06 16:34:48 +000010475 rounding_mode = encode_dfp_rounding_mode(m4);
10476 assign(op1, get_dpr_dw0(r2));
10477 assign(op2, get_dpr_dw0(r3));
10478 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10479 mkexpr(op2)));
10480 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10481 put_dpr_dw0(r1, mkexpr(result));
florian1bb7f6f2013-02-11 00:03:27 +000010482 }
florian12390202012-11-10 22:34:14 +000010483 return (m4 == 0) ? "sdtr" : "sdtra";
10484}
10485
floriane38f6412012-12-21 17:32:12 +000010486static const HChar *
10487s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10488{
florianfb596602014-12-06 16:34:48 +000010489 if (! s390_host_has_dfp) {
10490 emulation_failure(EmFail_S390X_DFP_insn);
10491 } else {
10492 IRTemp op1 = newTemp(Ity_D128);
10493 IRTemp op2 = newTemp(Ity_D128);
10494 IRTemp result = newTemp(Ity_D128);
10495 IRTemp rounding_mode;
floriane38f6412012-12-21 17:32:12 +000010496
florianfb596602014-12-06 16:34:48 +000010497 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10498 emulation_warning(EmWarn_S390X_fpext_rounding);
10499 m4 = S390_DFP_ROUND_PER_FPC_0;
10500 }
florian1bb7f6f2013-02-11 00:03:27 +000010501
florianfb596602014-12-06 16:34:48 +000010502 rounding_mode = encode_dfp_rounding_mode(m4);
10503 assign(op1, get_dpr_pair(r2));
10504 assign(op2, get_dpr_pair(r3));
10505 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10506 mkexpr(op2)));
10507 put_dpr_pair(r1, mkexpr(result));
10508
10509 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
florian1bb7f6f2013-02-11 00:03:27 +000010510 }
floriane38f6412012-12-21 17:32:12 +000010511 return (m4 == 0) ? "sxtr" : "sxtra";
10512}
sewardj2019a972011-03-07 16:04:07 +000010513
florian55085f82012-11-21 00:36:55 +000010514static const HChar *
florian1b901d42013-01-01 22:19:24 +000010515s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10516{
florianfb596602014-12-06 16:34:48 +000010517 if (! s390_host_has_dfp) {
10518 emulation_failure(EmFail_S390X_DFP_insn);
10519 } else {
10520 IRTemp op = newTemp(Ity_D64);
florian1b901d42013-01-01 22:19:24 +000010521
florianfb596602014-12-06 16:34:48 +000010522 assign(op, get_dpr_dw0(r3));
10523 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op),
10524 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10525 mkU64(63)))));
10526 }
florian1b901d42013-01-01 22:19:24 +000010527 return "sldt";
10528}
10529
10530static const HChar *
10531s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10532{
florianfb596602014-12-06 16:34:48 +000010533 if (! s390_host_has_dfp) {
10534 emulation_failure(EmFail_S390X_DFP_insn);
10535 } else {
10536 IRTemp op = newTemp(Ity_D128);
florian1b901d42013-01-01 22:19:24 +000010537
florianfb596602014-12-06 16:34:48 +000010538 assign(op, get_dpr_pair(r3));
10539 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op),
10540 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10541 mkU64(63)))));
10542 }
florian1b901d42013-01-01 22:19:24 +000010543 return "slxt";
10544}
10545
10546static const HChar *
10547s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10548{
florianfb596602014-12-06 16:34:48 +000010549 if (! s390_host_has_dfp) {
10550 emulation_failure(EmFail_S390X_DFP_insn);
10551 } else {
10552 IRTemp op = newTemp(Ity_D64);
florian1b901d42013-01-01 22:19:24 +000010553
florianfb596602014-12-06 16:34:48 +000010554 assign(op, get_dpr_dw0(r3));
10555 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op),
10556 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10557 mkU64(63)))));
10558 }
florian1b901d42013-01-01 22:19:24 +000010559 return "srdt";
10560}
10561
10562static const HChar *
10563s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10564{
florianfb596602014-12-06 16:34:48 +000010565 if (! s390_host_has_dfp) {
10566 emulation_failure(EmFail_S390X_DFP_insn);
10567 } else {
10568 IRTemp op = newTemp(Ity_D128);
florian1b901d42013-01-01 22:19:24 +000010569
florianfb596602014-12-06 16:34:48 +000010570 assign(op, get_dpr_pair(r3));
10571 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op),
10572 unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
10573 mkU64(63)))));
10574 }
florian1b901d42013-01-01 22:19:24 +000010575 return "srxt";
10576}
10577
10578static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010579s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10580{
florianfb596602014-12-06 16:34:48 +000010581 if (! s390_host_has_dfp) {
10582 emulation_failure(EmFail_S390X_DFP_insn);
10583 } else {
10584 IRTemp value = newTemp(Ity_D32);
floriance9e3db2012-12-27 20:14:03 +000010585
florianfb596602014-12-06 16:34:48 +000010586 assign(value, get_dpr_w0(r1));
floriance9e3db2012-12-27 20:14:03 +000010587
florianfb596602014-12-06 16:34:48 +000010588 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10589 }
floriance9e3db2012-12-27 20:14:03 +000010590 return "tdcet";
10591}
10592
10593static const HChar *
10594s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10595{
florianfb596602014-12-06 16:34:48 +000010596 if (! s390_host_has_dfp) {
10597 emulation_failure(EmFail_S390X_DFP_insn);
10598 } else {
10599 IRTemp value = newTemp(Ity_D64);
floriance9e3db2012-12-27 20:14:03 +000010600
florianfb596602014-12-06 16:34:48 +000010601 assign(value, get_dpr_dw0(r1));
floriance9e3db2012-12-27 20:14:03 +000010602
florianfb596602014-12-06 16:34:48 +000010603 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10604 }
floriance9e3db2012-12-27 20:14:03 +000010605 return "tdcdt";
10606}
10607
10608static const HChar *
10609s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10610{
florianfb596602014-12-06 16:34:48 +000010611 if (! s390_host_has_dfp) {
10612 emulation_failure(EmFail_S390X_DFP_insn);
10613 } else {
10614 IRTemp value = newTemp(Ity_D128);
floriance9e3db2012-12-27 20:14:03 +000010615
florianfb596602014-12-06 16:34:48 +000010616 assign(value, get_dpr_pair(r1));
floriance9e3db2012-12-27 20:14:03 +000010617
florianfb596602014-12-06 16:34:48 +000010618 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10619 }
floriance9e3db2012-12-27 20:14:03 +000010620 return "tdcxt";
10621}
10622
10623static const HChar *
10624s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10625{
florianfb596602014-12-06 16:34:48 +000010626 if (! s390_host_has_dfp) {
10627 emulation_failure(EmFail_S390X_DFP_insn);
10628 } else {
10629 IRTemp value = newTemp(Ity_D32);
floriance9e3db2012-12-27 20:14:03 +000010630
florianfb596602014-12-06 16:34:48 +000010631 assign(value, get_dpr_w0(r1));
floriance9e3db2012-12-27 20:14:03 +000010632
florianfb596602014-12-06 16:34:48 +000010633 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10634 }
floriance9e3db2012-12-27 20:14:03 +000010635 return "tdget";
10636}
10637
10638static const HChar *
10639s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10640{
florianfb596602014-12-06 16:34:48 +000010641 if (! s390_host_has_dfp) {
10642 emulation_failure(EmFail_S390X_DFP_insn);
10643 } else {
10644 IRTemp value = newTemp(Ity_D64);
floriance9e3db2012-12-27 20:14:03 +000010645
florianfb596602014-12-06 16:34:48 +000010646 assign(value, get_dpr_dw0(r1));
floriance9e3db2012-12-27 20:14:03 +000010647
florianfb596602014-12-06 16:34:48 +000010648 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10649 }
floriance9e3db2012-12-27 20:14:03 +000010650 return "tdgdt";
10651}
10652
10653static const HChar *
10654s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10655{
florianfb596602014-12-06 16:34:48 +000010656 if (! s390_host_has_dfp) {
10657 emulation_failure(EmFail_S390X_DFP_insn);
10658 } else {
10659 IRTemp value = newTemp(Ity_D128);
floriance9e3db2012-12-27 20:14:03 +000010660
florianfb596602014-12-06 16:34:48 +000010661 assign(value, get_dpr_pair(r1));
floriance9e3db2012-12-27 20:14:03 +000010662
florianfb596602014-12-06 16:34:48 +000010663 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10664 }
floriance9e3db2012-12-27 20:14:03 +000010665 return "tdgxt";
10666}
10667
10668static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010669s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10670{
florian79e839e2012-05-05 02:20:30 +000010671 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010672
florian79e839e2012-05-05 02:20:30 +000010673 assign(len, mkU64(length));
10674 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010675
10676 return "clc";
10677}
10678
florian55085f82012-11-21 00:36:55 +000010679static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010680s390_irgen_CLCL(UChar r1, UChar r2)
10681{
10682 IRTemp addr1 = newTemp(Ity_I64);
10683 IRTemp addr2 = newTemp(Ity_I64);
10684 IRTemp addr1_load = newTemp(Ity_I64);
10685 IRTemp addr2_load = newTemp(Ity_I64);
10686 IRTemp len1 = newTemp(Ity_I32);
10687 IRTemp len2 = newTemp(Ity_I32);
10688 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10689 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10690 IRTemp single1 = newTemp(Ity_I8);
10691 IRTemp single2 = newTemp(Ity_I8);
10692 IRTemp pad = newTemp(Ity_I8);
10693
10694 assign(addr1, get_gpr_dw0(r1));
10695 assign(r1p1, get_gpr_w1(r1 + 1));
10696 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10697 assign(addr2, get_gpr_dw0(r2));
10698 assign(r2p1, get_gpr_w1(r2 + 1));
10699 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10700 assign(pad, get_gpr_b4(r2 + 1));
10701
10702 /* len1 == 0 and len2 == 0? Exit */
10703 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010704 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10705 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010706
10707 /* Because mkite evaluates both the then-clause and the else-clause
10708 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10709 may be NULL and loading from there would segfault. So we provide a
10710 valid dummy address in that case. Loading from there does no harm and
10711 the value will be discarded at runtime. */
10712 assign(addr1_load,
10713 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10714 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10715 assign(single1,
10716 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10717 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10718
10719 assign(addr2_load,
10720 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10721 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10722 assign(single2,
10723 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10724 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10725
10726 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10727 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010728 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010729
10730 /* Update len1 and addr1, unless len1 == 0. */
10731 put_gpr_dw0(r1,
10732 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10733 mkexpr(addr1),
10734 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10735
10736 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10737 put_gpr_w1(r1 + 1,
10738 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10739 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10740 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10741
10742 /* Update len2 and addr2, unless len2 == 0. */
10743 put_gpr_dw0(r2,
10744 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10745 mkexpr(addr2),
10746 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10747
10748 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10749 put_gpr_w1(r2 + 1,
10750 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10751 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10752 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10753
florian6820ba52012-07-26 02:01:50 +000010754 iterate();
florianb0c9a132011-09-08 15:37:39 +000010755
10756 return "clcl";
10757}
10758
florian55085f82012-11-21 00:36:55 +000010759static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010760s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10761{
10762 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10763
10764 addr1 = newTemp(Ity_I64);
10765 addr3 = newTemp(Ity_I64);
10766 addr1_load = newTemp(Ity_I64);
10767 addr3_load = newTemp(Ity_I64);
10768 len1 = newTemp(Ity_I64);
10769 len3 = newTemp(Ity_I64);
10770 single1 = newTemp(Ity_I8);
10771 single3 = newTemp(Ity_I8);
10772
10773 assign(addr1, get_gpr_dw0(r1));
10774 assign(len1, get_gpr_dw0(r1 + 1));
10775 assign(addr3, get_gpr_dw0(r3));
10776 assign(len3, get_gpr_dw0(r3 + 1));
10777
10778 /* len1 == 0 and len3 == 0? Exit */
10779 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010780 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10781 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010782
10783 /* A mux requires both ways to be possible. This is a way to prevent clcle
10784 from reading from addr1 if it should read from the pad. Since the pad
10785 has no address, just read from the instruction, we discard that anyway */
10786 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010787 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10788 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010789
10790 /* same for addr3 */
10791 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010792 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10793 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010794
10795 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010796 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10797 unop(Iop_64to8, mkexpr(pad2)),
10798 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010799
10800 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010801 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10802 unop(Iop_64to8, mkexpr(pad2)),
10803 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010804
10805 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10806 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010807 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010808
10809 /* If a length in 0 we must not change this length and the address */
10810 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010811 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10812 mkexpr(addr1),
10813 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010814
10815 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010816 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10817 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010818
10819 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010820 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10821 mkexpr(addr3),
10822 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010823
10824 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010825 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10826 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010827
florian6820ba52012-07-26 02:01:50 +000010828 iterate();
sewardj2019a972011-03-07 16:04:07 +000010829
10830 return "clcle";
10831}
floriana64c2432011-07-16 02:11:50 +000010832
florianb0bf6602012-05-05 00:01:16 +000010833
sewardj2019a972011-03-07 16:04:07 +000010834static void
10835s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10836{
florianb0bf6602012-05-05 00:01:16 +000010837 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10838}
sewardj2019a972011-03-07 16:04:07 +000010839
sewardj2019a972011-03-07 16:04:07 +000010840
florianb0bf6602012-05-05 00:01:16 +000010841static void
10842s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10843{
10844 s390_irgen_xonc(Iop_And8, length, start1, start2);
10845}
sewardj2019a972011-03-07 16:04:07 +000010846
sewardj2019a972011-03-07 16:04:07 +000010847
florianb0bf6602012-05-05 00:01:16 +000010848static void
10849s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10850{
10851 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010852}
10853
10854
10855static void
10856s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10857{
10858 IRTemp current1 = newTemp(Ity_I8);
10859 IRTemp current2 = newTemp(Ity_I8);
10860 IRTemp counter = newTemp(Ity_I64);
10861
10862 assign(counter, get_counter_dw0());
10863 put_counter_dw0(mkU64(0));
10864
10865 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10866 mkexpr(counter))));
10867 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10868 mkexpr(counter))));
10869 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10870 False);
10871
10872 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010873 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010874
10875 /* Check for end of field */
10876 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010877 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010878 put_counter_dw0(mkU64(0));
10879}
10880
10881static void
10882s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10883{
10884 IRTemp counter = newTemp(Ity_I64);
10885
10886 assign(counter, get_counter_dw0());
10887
10888 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10889 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10890
10891 /* Check for end of field */
10892 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010893 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010894 put_counter_dw0(mkU64(0));
10895}
10896
florianf87d4fb2012-05-05 02:55:24 +000010897static void
10898s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10899{
10900 IRTemp op = newTemp(Ity_I8);
10901 IRTemp op1 = newTemp(Ity_I8);
10902 IRTemp result = newTemp(Ity_I64);
10903 IRTemp counter = newTemp(Ity_I64);
10904
10905 assign(counter, get_counter_dw0());
10906
10907 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10908
10909 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10910
10911 assign(op1, load(Ity_I8, mkexpr(result)));
10912 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10913
10914 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010915 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010916 put_counter_dw0(mkU64(0));
10917}
sewardj2019a972011-03-07 16:04:07 +000010918
10919
10920static void
10921s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010922 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010923 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010924{
10925 struct SS {
10926 unsigned int op : 8;
10927 unsigned int l : 8;
10928 unsigned int b1 : 4;
10929 unsigned int d1 : 12;
10930 unsigned int b2 : 4;
10931 unsigned int d2 : 12;
10932 };
10933 union {
10934 struct SS dec;
10935 unsigned long bytes;
10936 } ss;
10937 IRTemp cond;
10938 IRDirty *d;
10939 IRTemp torun;
10940
10941 IRTemp start1 = newTemp(Ity_I64);
10942 IRTemp start2 = newTemp(Ity_I64);
10943 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10944 cond = newTemp(Ity_I1);
10945 torun = newTemp(Ity_I64);
10946
10947 assign(torun, load(Ity_I64, mkexpr(addr2)));
10948 /* Start with a check that the saved code is still correct */
10949 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10950 /* If not, save the new value */
10951 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10952 mkIRExprVec_1(mkexpr(torun)));
10953 d->guard = mkexpr(cond);
10954 stmt(IRStmt_Dirty(d));
10955
10956 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000010957 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian428dfdd2012-03-27 03:09:49 +000010958 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000010959 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010960 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010961
10962 ss.bytes = last_execute_target;
10963 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10964 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10965 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10966 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10967 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10968 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10969 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010970
sewardj2019a972011-03-07 16:04:07 +000010971 last_execute_target = 0;
10972}
10973
florian55085f82012-11-21 00:36:55 +000010974static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010975s390_irgen_EX(UChar r1, IRTemp addr2)
10976{
10977 switch(last_execute_target & 0xff00000000000000ULL) {
10978 case 0:
10979 {
10980 /* no code information yet */
10981 IRDirty *d;
10982
10983 /* so safe the code... */
10984 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10985 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10986 stmt(IRStmt_Dirty(d));
10987 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000010988 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian428dfdd2012-03-27 03:09:49 +000010989 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000010990 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010991 restart_if(IRExpr_Const(IRConst_U1(True)));
10992
sewardj2019a972011-03-07 16:04:07 +000010993 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010994 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010995 dis_res->whatNext = Dis_StopHere;
sewardj05f5e012014-05-04 10:52:11 +000010996 dis_res->jk_StopHere = Ijk_InvalICache;
sewardj2019a972011-03-07 16:04:07 +000010997 break;
10998 }
10999
11000 case 0xd200000000000000ULL:
11001 /* special case MVC */
11002 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000011003 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000011004
11005 case 0xd500000000000000ULL:
11006 /* special case CLC */
11007 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000011008 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000011009
11010 case 0xd700000000000000ULL:
11011 /* special case XC */
11012 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000011013 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000011014
florianb0bf6602012-05-05 00:01:16 +000011015 case 0xd600000000000000ULL:
11016 /* special case OC */
11017 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000011018 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000011019
11020 case 0xd400000000000000ULL:
11021 /* special case NC */
11022 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000011023 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000011024
florianf87d4fb2012-05-05 02:55:24 +000011025 case 0xdc00000000000000ULL:
11026 /* special case TR */
11027 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000011028 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000011029
sewardj2019a972011-03-07 16:04:07 +000011030 default:
11031 {
11032 /* everything else will get a self checking prefix that also checks the
11033 register content */
11034 IRDirty *d;
11035 UChar *bytes;
11036 IRTemp cond;
11037 IRTemp orperand;
11038 IRTemp torun;
11039
11040 cond = newTemp(Ity_I1);
11041 orperand = newTemp(Ity_I64);
11042 torun = newTemp(Ity_I64);
11043
11044 if (r1 == 0)
11045 assign(orperand, mkU64(0));
11046 else
11047 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
11048 /* This code is going to be translated */
11049 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
11050 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
11051
11052 /* Start with a check that saved code is still correct */
11053 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
11054 mkU64(last_execute_target)));
11055 /* If not, save the new value */
11056 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
11057 mkIRExprVec_1(mkexpr(torun)));
11058 d->guard = mkexpr(cond);
11059 stmt(IRStmt_Dirty(d));
11060
11061 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000011062 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART), mkU64(guest_IA_curr_instr)));
11063 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000011064 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000011065
11066 /* Now comes the actual translation */
11067 bytes = (UChar *) &last_execute_target;
11068 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
11069 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000011070 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000011071 vex_printf(" which was executed by\n");
11072 /* dont make useless translations in the next execute */
11073 last_execute_target = 0;
11074 }
11075 }
11076 return "ex";
11077}
11078
florian55085f82012-11-21 00:36:55 +000011079static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011080s390_irgen_EXRL(UChar r1, UInt offset)
11081{
11082 IRTemp addr = newTemp(Ity_I64);
11083 /* we might save one round trip because we know the target */
11084 if (!last_execute_target)
11085 last_execute_target = *(ULong *)(HWord)
11086 (guest_IA_curr_instr + offset * 2UL);
11087 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
11088 s390_irgen_EX(r1, addr);
11089 return "exrl";
11090}
11091
florian55085f82012-11-21 00:36:55 +000011092static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011093s390_irgen_IPM(UChar r1)
11094{
11095 // As long as we dont support SPM, lets just assume 0 as program mask
11096 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
11097 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
11098
11099 return "ipm";
11100}
11101
11102
florian55085f82012-11-21 00:36:55 +000011103static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011104s390_irgen_SRST(UChar r1, UChar r2)
11105{
11106 IRTemp address = newTemp(Ity_I64);
11107 IRTemp next = newTemp(Ity_I64);
11108 IRTemp delim = newTemp(Ity_I8);
11109 IRTemp counter = newTemp(Ity_I64);
11110 IRTemp byte = newTemp(Ity_I8);
11111
11112 assign(address, get_gpr_dw0(r2));
11113 assign(next, get_gpr_dw0(r1));
11114
11115 assign(counter, get_counter_dw0());
11116 put_counter_dw0(mkU64(0));
11117
11118 // start = next? CC=2 and out r1 and r2 unchanged
11119 s390_cc_set(2);
11120 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011121 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000011122
11123 assign(byte, load(Ity_I8, mkexpr(address)));
11124 assign(delim, get_gpr_b7(0));
11125
11126 // byte = delim? CC=1, R1=address
11127 s390_cc_set(1);
11128 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000011129 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011130
11131 // else: all equal, no end yet, loop
11132 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11133 put_gpr_dw0(r1, mkexpr(next));
11134 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011135
florian6820ba52012-07-26 02:01:50 +000011136 iterate();
sewardj2019a972011-03-07 16:04:07 +000011137
11138 return "srst";
11139}
11140
florian55085f82012-11-21 00:36:55 +000011141static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011142s390_irgen_CLST(UChar r1, UChar r2)
11143{
11144 IRTemp address1 = newTemp(Ity_I64);
11145 IRTemp address2 = newTemp(Ity_I64);
11146 IRTemp end = newTemp(Ity_I8);
11147 IRTemp counter = newTemp(Ity_I64);
11148 IRTemp byte1 = newTemp(Ity_I8);
11149 IRTemp byte2 = newTemp(Ity_I8);
11150
11151 assign(address1, get_gpr_dw0(r1));
11152 assign(address2, get_gpr_dw0(r2));
11153 assign(end, get_gpr_b7(0));
11154 assign(counter, get_counter_dw0());
11155 put_counter_dw0(mkU64(0));
11156 assign(byte1, load(Ity_I8, mkexpr(address1)));
11157 assign(byte2, load(Ity_I8, mkexpr(address2)));
11158
11159 // end in both? all equal, reset r1 and r2 to start values
11160 s390_cc_set(0);
11161 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
11162 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011163 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
11164 binop(Iop_Or8,
11165 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
11166 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000011167
11168 put_gpr_dw0(r1, mkexpr(address1));
11169 put_gpr_dw0(r2, mkexpr(address2));
11170
11171 // End found in string1
11172 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011173 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000011174
11175 // End found in string2
11176 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011177 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000011178
11179 // string1 < string2
11180 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011181 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
11182 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000011183
11184 // string2 < string1
11185 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011186 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
11187 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000011188
11189 // else: all equal, no end yet, loop
11190 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11191 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
11192 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011193
florian6820ba52012-07-26 02:01:50 +000011194 iterate();
sewardj2019a972011-03-07 16:04:07 +000011195
11196 return "clst";
11197}
11198
11199static void
11200s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11201{
11202 UChar reg;
11203 IRTemp addr = newTemp(Ity_I64);
11204
11205 assign(addr, mkexpr(op2addr));
11206 reg = r1;
11207 do {
11208 IRTemp old = addr;
11209
11210 reg %= 16;
11211 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
11212 addr = newTemp(Ity_I64);
11213 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11214 reg++;
11215 } while (reg != (r3 + 1));
11216}
11217
florian55085f82012-11-21 00:36:55 +000011218static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011219s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
11220{
11221 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11222
11223 return "lm";
11224}
11225
florian55085f82012-11-21 00:36:55 +000011226static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011227s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11228{
11229 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11230
11231 return "lmy";
11232}
11233
florian55085f82012-11-21 00:36:55 +000011234static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011235s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11236{
11237 UChar reg;
11238 IRTemp addr = newTemp(Ity_I64);
11239
11240 assign(addr, mkexpr(op2addr));
11241 reg = r1;
11242 do {
11243 IRTemp old = addr;
11244
11245 reg %= 16;
11246 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11247 addr = newTemp(Ity_I64);
11248 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11249 reg++;
11250 } while (reg != (r3 + 1));
11251
11252 return "lmh";
11253}
11254
florian55085f82012-11-21 00:36:55 +000011255static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011256s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11257{
11258 UChar reg;
11259 IRTemp addr = newTemp(Ity_I64);
11260
11261 assign(addr, mkexpr(op2addr));
11262 reg = r1;
11263 do {
11264 IRTemp old = addr;
11265
11266 reg %= 16;
11267 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11268 addr = newTemp(Ity_I64);
11269 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11270 reg++;
11271 } while (reg != (r3 + 1));
11272
11273 return "lmg";
11274}
11275
11276static void
11277s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11278{
11279 UChar reg;
11280 IRTemp addr = newTemp(Ity_I64);
11281
11282 assign(addr, mkexpr(op2addr));
11283 reg = r1;
11284 do {
11285 IRTemp old = addr;
11286
11287 reg %= 16;
11288 store(mkexpr(addr), get_gpr_w1(reg));
11289 addr = newTemp(Ity_I64);
11290 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11291 reg++;
11292 } while( reg != (r3 + 1));
11293}
11294
florian55085f82012-11-21 00:36:55 +000011295static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011296s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11297{
11298 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11299
11300 return "stm";
11301}
11302
florian55085f82012-11-21 00:36:55 +000011303static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011304s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11305{
11306 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11307
11308 return "stmy";
11309}
11310
florian55085f82012-11-21 00:36:55 +000011311static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011312s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11313{
11314 UChar reg;
11315 IRTemp addr = newTemp(Ity_I64);
11316
11317 assign(addr, mkexpr(op2addr));
11318 reg = r1;
11319 do {
11320 IRTemp old = addr;
11321
11322 reg %= 16;
11323 store(mkexpr(addr), get_gpr_w0(reg));
11324 addr = newTemp(Ity_I64);
11325 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11326 reg++;
11327 } while( reg != (r3 + 1));
11328
11329 return "stmh";
11330}
11331
florian55085f82012-11-21 00:36:55 +000011332static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011333s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11334{
11335 UChar reg;
11336 IRTemp addr = newTemp(Ity_I64);
11337
11338 assign(addr, mkexpr(op2addr));
11339 reg = r1;
11340 do {
11341 IRTemp old = addr;
11342
11343 reg %= 16;
11344 store(mkexpr(addr), get_gpr_dw0(reg));
11345 addr = newTemp(Ity_I64);
11346 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11347 reg++;
11348 } while( reg != (r3 + 1));
11349
11350 return "stmg";
11351}
11352
11353static void
florianb0bf6602012-05-05 00:01:16 +000011354s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000011355{
11356 IRTemp old1 = newTemp(Ity_I8);
11357 IRTemp old2 = newTemp(Ity_I8);
11358 IRTemp new1 = newTemp(Ity_I8);
11359 IRTemp counter = newTemp(Ity_I32);
11360 IRTemp addr1 = newTemp(Ity_I64);
11361
11362 assign(counter, get_counter_w0());
11363
11364 assign(addr1, binop(Iop_Add64, mkexpr(start1),
11365 unop(Iop_32Uto64, mkexpr(counter))));
11366
11367 assign(old1, load(Ity_I8, mkexpr(addr1)));
11368 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11369 unop(Iop_32Uto64,mkexpr(counter)))));
11370 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11371
11372 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000011373 if (op == Iop_Xor8) {
11374 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000011375 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11376 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000011377 } else
11378 store(mkexpr(addr1), mkexpr(new1));
11379 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11380 get_counter_w1()));
11381
11382 /* Check for end of field */
11383 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011384 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000011385 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11386 False);
11387 put_counter_dw0(mkU64(0));
11388}
11389
florian55085f82012-11-21 00:36:55 +000011390static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011391s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11392{
florianb0bf6602012-05-05 00:01:16 +000011393 IRTemp len = newTemp(Ity_I32);
11394
11395 assign(len, mkU32(length));
11396 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011397
11398 return "xc";
11399}
11400
sewardjb63967e2011-03-24 08:50:04 +000011401static void
11402s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11403{
11404 IRTemp counter = newTemp(Ity_I32);
11405 IRTemp start = newTemp(Ity_I64);
11406 IRTemp addr = newTemp(Ity_I64);
11407
11408 assign(start,
11409 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11410
11411 if (length < 8) {
11412 UInt i;
11413
11414 for (i = 0; i <= length; ++i) {
11415 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11416 }
11417 } else {
11418 assign(counter, get_counter_w0());
11419
11420 assign(addr, binop(Iop_Add64, mkexpr(start),
11421 unop(Iop_32Uto64, mkexpr(counter))));
11422
11423 store(mkexpr(addr), mkU8(0));
11424
11425 /* Check for end of field */
11426 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011427 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000011428
11429 /* Reset counter */
11430 put_counter_dw0(mkU64(0));
11431 }
11432
11433 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11434
sewardj7ee97522011-05-09 21:45:04 +000011435 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000011436 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11437}
11438
florian55085f82012-11-21 00:36:55 +000011439static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011440s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11441{
florianb0bf6602012-05-05 00:01:16 +000011442 IRTemp len = newTemp(Ity_I32);
11443
11444 assign(len, mkU32(length));
11445 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011446
11447 return "nc";
11448}
11449
florian55085f82012-11-21 00:36:55 +000011450static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011451s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11452{
florianb0bf6602012-05-05 00:01:16 +000011453 IRTemp len = newTemp(Ity_I32);
11454
11455 assign(len, mkU32(length));
11456 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011457
11458 return "oc";
11459}
11460
11461
florian55085f82012-11-21 00:36:55 +000011462static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011463s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11464{
florian79e839e2012-05-05 02:20:30 +000011465 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000011466
florian79e839e2012-05-05 02:20:30 +000011467 assign(len, mkU64(length));
11468 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011469
11470 return "mvc";
11471}
11472
florian55085f82012-11-21 00:36:55 +000011473static const HChar *
florianb0c9a132011-09-08 15:37:39 +000011474s390_irgen_MVCL(UChar r1, UChar r2)
11475{
11476 IRTemp addr1 = newTemp(Ity_I64);
11477 IRTemp addr2 = newTemp(Ity_I64);
11478 IRTemp addr2_load = newTemp(Ity_I64);
11479 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
11480 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
11481 IRTemp len1 = newTemp(Ity_I32);
11482 IRTemp len2 = newTemp(Ity_I32);
11483 IRTemp pad = newTemp(Ity_I8);
11484 IRTemp single = newTemp(Ity_I8);
11485
11486 assign(addr1, get_gpr_dw0(r1));
11487 assign(r1p1, get_gpr_w1(r1 + 1));
11488 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11489 assign(addr2, get_gpr_dw0(r2));
11490 assign(r2p1, get_gpr_w1(r2 + 1));
11491 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11492 assign(pad, get_gpr_b4(r2 + 1));
11493
11494 /* len1 == 0 ? */
11495 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011496 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000011497
11498 /* Check for destructive overlap:
11499 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11500 s390_cc_set(3);
11501 IRTemp cond1 = newTemp(Ity_I32);
11502 assign(cond1, unop(Iop_1Uto32,
11503 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11504 IRTemp cond2 = newTemp(Ity_I32);
11505 assign(cond2, unop(Iop_1Uto32,
11506 binop(Iop_CmpLT64U, mkexpr(addr1),
11507 binop(Iop_Add64, mkexpr(addr2),
11508 unop(Iop_32Uto64, mkexpr(len1))))));
11509 IRTemp cond3 = newTemp(Ity_I32);
11510 assign(cond3, unop(Iop_1Uto32,
11511 binop(Iop_CmpLT64U,
11512 mkexpr(addr1),
11513 binop(Iop_Add64, mkexpr(addr2),
11514 unop(Iop_32Uto64, mkexpr(len2))))));
11515
florian6820ba52012-07-26 02:01:50 +000011516 next_insn_if(binop(Iop_CmpEQ32,
11517 binop(Iop_And32,
11518 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11519 mkexpr(cond3)),
11520 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011521
11522 /* See s390_irgen_CLCL for explanation why we cannot load directly
11523 and need two steps. */
11524 assign(addr2_load,
11525 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11526 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11527 assign(single,
11528 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11529 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11530
11531 store(mkexpr(addr1), mkexpr(single));
11532
11533 /* Update addr1 and len1 */
11534 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11535 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11536
11537 /* Update addr2 and len2 */
11538 put_gpr_dw0(r2,
11539 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11540 mkexpr(addr2),
11541 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11542
11543 /* When updating len2 we must not modify bits (r2+1)[0:39] */
11544 put_gpr_w1(r2 + 1,
11545 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11546 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11547 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11548
11549 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011550 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011551
11552 return "mvcl";
11553}
11554
11555
florian55085f82012-11-21 00:36:55 +000011556static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011557s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11558{
11559 IRTemp addr1, addr3, addr3_load, len1, len3, single;
11560
11561 addr1 = newTemp(Ity_I64);
11562 addr3 = newTemp(Ity_I64);
11563 addr3_load = newTemp(Ity_I64);
11564 len1 = newTemp(Ity_I64);
11565 len3 = newTemp(Ity_I64);
11566 single = newTemp(Ity_I8);
11567
11568 assign(addr1, get_gpr_dw0(r1));
11569 assign(len1, get_gpr_dw0(r1 + 1));
11570 assign(addr3, get_gpr_dw0(r3));
11571 assign(len3, get_gpr_dw0(r3 + 1));
11572
11573 // len1 == 0 ?
11574 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011575 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000011576
11577 /* This is a hack to prevent mvcle from reading from addr3 if it
11578 should read from the pad. Since the pad has no address, just
11579 read from the instruction, we discard that anyway */
11580 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000011581 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11582 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000011583
11584 assign(single,
florian6ad49522011-09-09 02:38:55 +000011585 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11586 unop(Iop_64to8, mkexpr(pad2)),
11587 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000011588 store(mkexpr(addr1), mkexpr(single));
11589
11590 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11591
11592 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11593
11594 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000011595 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11596 mkexpr(addr3),
11597 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011598
11599 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000011600 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11601 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011602
sewardj2019a972011-03-07 16:04:07 +000011603 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011604 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000011605
11606 return "mvcle";
11607}
11608
florian55085f82012-11-21 00:36:55 +000011609static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011610s390_irgen_MVST(UChar r1, UChar r2)
11611{
11612 IRTemp addr1 = newTemp(Ity_I64);
11613 IRTemp addr2 = newTemp(Ity_I64);
11614 IRTemp end = newTemp(Ity_I8);
11615 IRTemp byte = newTemp(Ity_I8);
11616 IRTemp counter = newTemp(Ity_I64);
11617
11618 assign(addr1, get_gpr_dw0(r1));
11619 assign(addr2, get_gpr_dw0(r2));
11620 assign(counter, get_counter_dw0());
11621 assign(end, get_gpr_b7(0));
11622 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11623 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11624
11625 // We use unlimited as cpu-determined number
11626 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011627 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011628
11629 // and always set cc=1 at the end + update r1
11630 s390_cc_set(1);
11631 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11632 put_counter_dw0(mkU64(0));
11633
11634 return "mvst";
11635}
11636
11637static void
11638s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11639{
11640 IRTemp op1 = newTemp(Ity_I64);
11641 IRTemp result = newTemp(Ity_I64);
11642
11643 assign(op1, binop(Iop_32HLto64,
11644 get_gpr_w1(r1), // high 32 bits
11645 get_gpr_w1(r1 + 1))); // low 32 bits
11646 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11647 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11648 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11649}
11650
11651static void
11652s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11653{
11654 IRTemp op1 = newTemp(Ity_I128);
11655 IRTemp result = newTemp(Ity_I128);
11656
11657 assign(op1, binop(Iop_64HLto128,
11658 get_gpr_dw0(r1), // high 64 bits
11659 get_gpr_dw0(r1 + 1))); // low 64 bits
11660 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11661 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11662 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11663}
11664
11665static void
11666s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11667{
11668 IRTemp op1 = newTemp(Ity_I64);
11669 IRTemp result = newTemp(Ity_I128);
11670
11671 assign(op1, get_gpr_dw0(r1 + 1));
11672 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11673 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11674 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11675}
11676
florian55085f82012-11-21 00:36:55 +000011677static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011678s390_irgen_DR(UChar r1, UChar r2)
11679{
11680 IRTemp op2 = newTemp(Ity_I32);
11681
11682 assign(op2, get_gpr_w1(r2));
11683
11684 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11685
11686 return "dr";
11687}
11688
florian55085f82012-11-21 00:36:55 +000011689static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011690s390_irgen_D(UChar r1, IRTemp op2addr)
11691{
11692 IRTemp op2 = newTemp(Ity_I32);
11693
11694 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11695
11696 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11697
11698 return "d";
11699}
11700
florian55085f82012-11-21 00:36:55 +000011701static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011702s390_irgen_DLR(UChar r1, UChar r2)
11703{
11704 IRTemp op2 = newTemp(Ity_I32);
11705
11706 assign(op2, get_gpr_w1(r2));
11707
11708 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11709
florian7cd1cde2012-08-16 23:57:43 +000011710 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011711}
11712
florian55085f82012-11-21 00:36:55 +000011713static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011714s390_irgen_DL(UChar r1, IRTemp op2addr)
11715{
11716 IRTemp op2 = newTemp(Ity_I32);
11717
11718 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11719
11720 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11721
11722 return "dl";
11723}
11724
florian55085f82012-11-21 00:36:55 +000011725static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011726s390_irgen_DLG(UChar r1, IRTemp op2addr)
11727{
11728 IRTemp op2 = newTemp(Ity_I64);
11729
11730 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11731
11732 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11733
11734 return "dlg";
11735}
11736
florian55085f82012-11-21 00:36:55 +000011737static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011738s390_irgen_DLGR(UChar r1, UChar r2)
11739{
11740 IRTemp op2 = newTemp(Ity_I64);
11741
11742 assign(op2, get_gpr_dw0(r2));
11743
11744 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11745
11746 return "dlgr";
11747}
11748
florian55085f82012-11-21 00:36:55 +000011749static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011750s390_irgen_DSGR(UChar r1, UChar r2)
11751{
11752 IRTemp op2 = newTemp(Ity_I64);
11753
11754 assign(op2, get_gpr_dw0(r2));
11755
11756 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11757
11758 return "dsgr";
11759}
11760
florian55085f82012-11-21 00:36:55 +000011761static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011762s390_irgen_DSG(UChar r1, IRTemp op2addr)
11763{
11764 IRTemp op2 = newTemp(Ity_I64);
11765
11766 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11767
11768 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11769
11770 return "dsg";
11771}
11772
florian55085f82012-11-21 00:36:55 +000011773static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011774s390_irgen_DSGFR(UChar r1, UChar r2)
11775{
11776 IRTemp op2 = newTemp(Ity_I64);
11777
11778 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11779
11780 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11781
11782 return "dsgfr";
11783}
11784
florian55085f82012-11-21 00:36:55 +000011785static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011786s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11787{
11788 IRTemp op2 = newTemp(Ity_I64);
11789
11790 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11791
11792 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11793
11794 return "dsgf";
11795}
11796
11797static void
11798s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11799{
11800 UChar reg;
11801 IRTemp addr = newTemp(Ity_I64);
11802
11803 assign(addr, mkexpr(op2addr));
11804 reg = r1;
11805 do {
11806 IRTemp old = addr;
11807
11808 reg %= 16;
11809 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11810 addr = newTemp(Ity_I64);
11811 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11812 reg++;
11813 } while (reg != (r3 + 1));
11814}
11815
florian55085f82012-11-21 00:36:55 +000011816static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011817s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11818{
11819 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11820
11821 return "lam";
11822}
11823
florian55085f82012-11-21 00:36:55 +000011824static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011825s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11826{
11827 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11828
11829 return "lamy";
11830}
11831
11832static void
11833s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11834{
11835 UChar reg;
11836 IRTemp addr = newTemp(Ity_I64);
11837
11838 assign(addr, mkexpr(op2addr));
11839 reg = r1;
11840 do {
11841 IRTemp old = addr;
11842
11843 reg %= 16;
11844 store(mkexpr(addr), get_ar_w0(reg));
11845 addr = newTemp(Ity_I64);
11846 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11847 reg++;
11848 } while (reg != (r3 + 1));
11849}
11850
florian55085f82012-11-21 00:36:55 +000011851static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011852s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11853{
11854 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11855
11856 return "stam";
11857}
11858
florian55085f82012-11-21 00:36:55 +000011859static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011860s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11861{
11862 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11863
11864 return "stamy";
11865}
11866
11867
11868/* Implementation for 32-bit compare-and-swap */
11869static void
11870s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11871{
11872 IRCAS *cas;
11873 IRTemp op1 = newTemp(Ity_I32);
11874 IRTemp old_mem = newTemp(Ity_I32);
11875 IRTemp op3 = newTemp(Ity_I32);
11876 IRTemp result = newTemp(Ity_I32);
11877 IRTemp nequal = newTemp(Ity_I1);
11878
11879 assign(op1, get_gpr_w1(r1));
11880 assign(op3, get_gpr_w1(r3));
11881
11882 /* The first and second operands are compared. If they are equal,
11883 the third operand is stored at the second- operand location. */
11884 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11885 Iend_BE, mkexpr(op2addr),
11886 NULL, mkexpr(op1), /* expected value */
11887 NULL, mkexpr(op3) /* new value */);
11888 stmt(IRStmt_CAS(cas));
11889
11890 /* Set CC. Operands compared equal -> 0, else 1. */
11891 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11892 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11893
11894 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11895 Otherwise, store the old_value from memory in r1 and yield. */
11896 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11897 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011898 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011899}
11900
florian55085f82012-11-21 00:36:55 +000011901static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011902s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11903{
11904 s390_irgen_cas_32(r1, r3, op2addr);
11905
11906 return "cs";
11907}
11908
florian55085f82012-11-21 00:36:55 +000011909static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011910s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11911{
11912 s390_irgen_cas_32(r1, r3, op2addr);
11913
11914 return "csy";
11915}
11916
florian55085f82012-11-21 00:36:55 +000011917static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011918s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11919{
11920 IRCAS *cas;
11921 IRTemp op1 = newTemp(Ity_I64);
11922 IRTemp old_mem = newTemp(Ity_I64);
11923 IRTemp op3 = newTemp(Ity_I64);
11924 IRTemp result = newTemp(Ity_I64);
11925 IRTemp nequal = newTemp(Ity_I1);
11926
11927 assign(op1, get_gpr_dw0(r1));
11928 assign(op3, get_gpr_dw0(r3));
11929
11930 /* The first and second operands are compared. If they are equal,
11931 the third operand is stored at the second- operand location. */
11932 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11933 Iend_BE, mkexpr(op2addr),
11934 NULL, mkexpr(op1), /* expected value */
11935 NULL, mkexpr(op3) /* new value */);
11936 stmt(IRStmt_CAS(cas));
11937
11938 /* Set CC. Operands compared equal -> 0, else 1. */
11939 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11940 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11941
11942 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11943 Otherwise, store the old_value from memory in r1 and yield. */
11944 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11945 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011946 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011947
11948 return "csg";
11949}
11950
florian448cbba2012-06-06 02:26:01 +000011951/* Implementation for 32-bit compare-double-and-swap */
11952static void
11953s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11954{
11955 IRCAS *cas;
11956 IRTemp op1_high = newTemp(Ity_I32);
11957 IRTemp op1_low = newTemp(Ity_I32);
11958 IRTemp old_mem_high = newTemp(Ity_I32);
11959 IRTemp old_mem_low = newTemp(Ity_I32);
11960 IRTemp op3_high = newTemp(Ity_I32);
11961 IRTemp op3_low = newTemp(Ity_I32);
11962 IRTemp result = newTemp(Ity_I32);
11963 IRTemp nequal = newTemp(Ity_I1);
11964
11965 assign(op1_high, get_gpr_w1(r1));
11966 assign(op1_low, get_gpr_w1(r1+1));
11967 assign(op3_high, get_gpr_w1(r3));
11968 assign(op3_low, get_gpr_w1(r3+1));
11969
11970 /* The first and second operands are compared. If they are equal,
11971 the third operand is stored at the second-operand location. */
11972 cas = mkIRCAS(old_mem_high, old_mem_low,
11973 Iend_BE, mkexpr(op2addr),
11974 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11975 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11976 stmt(IRStmt_CAS(cas));
11977
11978 /* Set CC. Operands compared equal -> 0, else 1. */
11979 assign(result, unop(Iop_1Uto32,
11980 binop(Iop_CmpNE32,
11981 binop(Iop_Or32,
11982 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11983 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11984 mkU32(0))));
11985
11986 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11987
11988 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11989 Otherwise, store the old_value from memory in r1 and yield. */
11990 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11991 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11992 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011993 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011994}
11995
florian55085f82012-11-21 00:36:55 +000011996static const HChar *
florian448cbba2012-06-06 02:26:01 +000011997s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11998{
11999 s390_irgen_cdas_32(r1, r3, op2addr);
12000
12001 return "cds";
12002}
12003
florian55085f82012-11-21 00:36:55 +000012004static const HChar *
florian448cbba2012-06-06 02:26:01 +000012005s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
12006{
12007 s390_irgen_cdas_32(r1, r3, op2addr);
12008
12009 return "cdsy";
12010}
12011
florian55085f82012-11-21 00:36:55 +000012012static const HChar *
florian448cbba2012-06-06 02:26:01 +000012013s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
12014{
12015 IRCAS *cas;
12016 IRTemp op1_high = newTemp(Ity_I64);
12017 IRTemp op1_low = newTemp(Ity_I64);
12018 IRTemp old_mem_high = newTemp(Ity_I64);
12019 IRTemp old_mem_low = newTemp(Ity_I64);
12020 IRTemp op3_high = newTemp(Ity_I64);
12021 IRTemp op3_low = newTemp(Ity_I64);
12022 IRTemp result = newTemp(Ity_I64);
12023 IRTemp nequal = newTemp(Ity_I1);
12024
12025 assign(op1_high, get_gpr_dw0(r1));
12026 assign(op1_low, get_gpr_dw0(r1+1));
12027 assign(op3_high, get_gpr_dw0(r3));
12028 assign(op3_low, get_gpr_dw0(r3+1));
12029
12030 /* The first and second operands are compared. If they are equal,
12031 the third operand is stored at the second-operand location. */
12032 cas = mkIRCAS(old_mem_high, old_mem_low,
12033 Iend_BE, mkexpr(op2addr),
12034 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
12035 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
12036 stmt(IRStmt_CAS(cas));
12037
12038 /* Set CC. Operands compared equal -> 0, else 1. */
12039 assign(result, unop(Iop_1Uto64,
12040 binop(Iop_CmpNE64,
12041 binop(Iop_Or64,
12042 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
12043 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
12044 mkU64(0))));
12045
12046 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
12047
12048 /* If operands were equal (cc == 0) just store the old value op1 in r1.
12049 Otherwise, store the old_value from memory in r1 and yield. */
12050 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
12051 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
12052 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000012053 yield_if(mkexpr(nequal));
12054
florian448cbba2012-06-06 02:26:01 +000012055 return "cdsg";
12056}
12057
sewardj2019a972011-03-07 16:04:07 +000012058
12059/* Binary floating point */
12060
florian55085f82012-11-21 00:36:55 +000012061static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012062s390_irgen_AXBR(UChar r1, UChar r2)
12063{
12064 IRTemp op1 = newTemp(Ity_F128);
12065 IRTemp op2 = newTemp(Ity_F128);
12066 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012067 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012068
12069 assign(op1, get_fpr_pair(r1));
12070 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012071 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012072 mkexpr(op2)));
12073 put_fpr_pair(r1, mkexpr(result));
12074
12075 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12076
12077 return "axbr";
12078}
12079
florian55085f82012-11-21 00:36:55 +000012080static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012081s390_irgen_CEBR(UChar r1, UChar r2)
12082{
12083 IRTemp op1 = newTemp(Ity_F32);
12084 IRTemp op2 = newTemp(Ity_F32);
12085 IRTemp cc_vex = newTemp(Ity_I32);
12086 IRTemp cc_s390 = newTemp(Ity_I32);
12087
12088 assign(op1, get_fpr_w0(r1));
12089 assign(op2, get_fpr_w0(r2));
12090 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12091
florian2d3d87f2012-12-21 21:05:17 +000012092 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012093 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12094
12095 return "cebr";
12096}
12097
florian55085f82012-11-21 00:36:55 +000012098static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012099s390_irgen_CDBR(UChar r1, UChar r2)
12100{
12101 IRTemp op1 = newTemp(Ity_F64);
12102 IRTemp op2 = newTemp(Ity_F64);
12103 IRTemp cc_vex = newTemp(Ity_I32);
12104 IRTemp cc_s390 = newTemp(Ity_I32);
12105
12106 assign(op1, get_fpr_dw0(r1));
12107 assign(op2, get_fpr_dw0(r2));
12108 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12109
florian2d3d87f2012-12-21 21:05:17 +000012110 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012111 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12112
12113 return "cdbr";
12114}
12115
florian55085f82012-11-21 00:36:55 +000012116static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012117s390_irgen_CXBR(UChar r1, UChar r2)
12118{
12119 IRTemp op1 = newTemp(Ity_F128);
12120 IRTemp op2 = newTemp(Ity_F128);
12121 IRTemp cc_vex = newTemp(Ity_I32);
12122 IRTemp cc_s390 = newTemp(Ity_I32);
12123
12124 assign(op1, get_fpr_pair(r1));
12125 assign(op2, get_fpr_pair(r2));
12126 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
12127
florian2d3d87f2012-12-21 21:05:17 +000012128 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012129 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12130
12131 return "cxbr";
12132}
12133
florian55085f82012-11-21 00:36:55 +000012134static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012135s390_irgen_CEB(UChar r1, IRTemp op2addr)
12136{
12137 IRTemp op1 = newTemp(Ity_F32);
12138 IRTemp op2 = newTemp(Ity_F32);
12139 IRTemp cc_vex = newTemp(Ity_I32);
12140 IRTemp cc_s390 = newTemp(Ity_I32);
12141
12142 assign(op1, get_fpr_w0(r1));
12143 assign(op2, load(Ity_F32, mkexpr(op2addr)));
12144 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12145
florian2d3d87f2012-12-21 21:05:17 +000012146 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012147 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12148
12149 return "ceb";
12150}
12151
florian55085f82012-11-21 00:36:55 +000012152static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012153s390_irgen_CDB(UChar r1, IRTemp op2addr)
12154{
12155 IRTemp op1 = newTemp(Ity_F64);
12156 IRTemp op2 = newTemp(Ity_F64);
12157 IRTemp cc_vex = newTemp(Ity_I32);
12158 IRTemp cc_s390 = newTemp(Ity_I32);
12159
12160 assign(op1, get_fpr_dw0(r1));
12161 assign(op2, load(Ity_F64, mkexpr(op2addr)));
12162 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12163
florian2d3d87f2012-12-21 21:05:17 +000012164 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012165 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12166
12167 return "cdb";
12168}
12169
florian55085f82012-11-21 00:36:55 +000012170static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012171s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
12172 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012173{
12174 IRTemp op2 = newTemp(Ity_I32);
12175
12176 assign(op2, get_gpr_w1(r2));
12177 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
12178
12179 return "cxfbr";
12180}
12181
florian55085f82012-11-21 00:36:55 +000012182static const HChar *
floriand2129202012-09-01 20:01:39 +000012183s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
12184 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012185{
floriane75dafa2012-09-01 17:54:09 +000012186 if (! s390_host_has_fpext) {
12187 emulation_failure(EmFail_S390X_fpext);
12188 } else {
12189 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000012190
floriane75dafa2012-09-01 17:54:09 +000012191 assign(op2, get_gpr_w1(r2));
12192 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
12193 }
florian1c8f7ff2012-09-01 00:12:11 +000012194 return "cxlfbr";
12195}
12196
12197
florian55085f82012-11-21 00:36:55 +000012198static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012199s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
12200 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012201{
12202 IRTemp op2 = newTemp(Ity_I64);
12203
12204 assign(op2, get_gpr_dw0(r2));
12205 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
12206
12207 return "cxgbr";
12208}
12209
florian55085f82012-11-21 00:36:55 +000012210static const HChar *
floriand2129202012-09-01 20:01:39 +000012211s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
12212 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012213{
floriane75dafa2012-09-01 17:54:09 +000012214 if (! s390_host_has_fpext) {
12215 emulation_failure(EmFail_S390X_fpext);
12216 } else {
12217 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000012218
floriane75dafa2012-09-01 17:54:09 +000012219 assign(op2, get_gpr_dw0(r2));
12220 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
12221 }
florian1c8f7ff2012-09-01 00:12:11 +000012222 return "cxlgbr";
12223}
12224
florian55085f82012-11-21 00:36:55 +000012225static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012226s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
12227 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012228{
12229 IRTemp op = newTemp(Ity_F128);
12230 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012231 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012232
12233 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012234 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012235 mkexpr(op)));
12236 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012237 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012238
12239 return "cfxbr";
12240}
12241
florian55085f82012-11-21 00:36:55 +000012242static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012243s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12244 UChar r1, UChar r2)
12245{
floriane75dafa2012-09-01 17:54:09 +000012246 if (! s390_host_has_fpext) {
12247 emulation_failure(EmFail_S390X_fpext);
12248 } else {
12249 IRTemp op = newTemp(Ity_F128);
12250 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012251 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012252
floriane75dafa2012-09-01 17:54:09 +000012253 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012254 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012255 mkexpr(op)));
12256 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012257 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012258 }
florian1c8f7ff2012-09-01 00:12:11 +000012259 return "clfxbr";
12260}
12261
12262
florian55085f82012-11-21 00:36:55 +000012263static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012264s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12265 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012266{
12267 IRTemp op = newTemp(Ity_F128);
12268 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012269 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012270
12271 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012272 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012273 mkexpr(op)));
12274 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012275 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012276
12277 return "cgxbr";
12278}
12279
florian55085f82012-11-21 00:36:55 +000012280static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012281s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12282 UChar r1, UChar r2)
12283{
floriane75dafa2012-09-01 17:54:09 +000012284 if (! s390_host_has_fpext) {
12285 emulation_failure(EmFail_S390X_fpext);
12286 } else {
12287 IRTemp op = newTemp(Ity_F128);
12288 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012289 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012290
floriane75dafa2012-09-01 17:54:09 +000012291 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012292 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012293 mkexpr(op)));
12294 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012295 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12296 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012297 }
florian1c8f7ff2012-09-01 00:12:11 +000012298 return "clgxbr";
12299}
12300
florian55085f82012-11-21 00:36:55 +000012301static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012302s390_irgen_DXBR(UChar r1, UChar r2)
12303{
12304 IRTemp op1 = newTemp(Ity_F128);
12305 IRTemp op2 = newTemp(Ity_F128);
12306 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012307 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012308
12309 assign(op1, get_fpr_pair(r1));
12310 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012311 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012312 mkexpr(op2)));
12313 put_fpr_pair(r1, mkexpr(result));
12314
12315 return "dxbr";
12316}
12317
florian55085f82012-11-21 00:36:55 +000012318static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012319s390_irgen_LTXBR(UChar r1, UChar r2)
12320{
12321 IRTemp result = newTemp(Ity_F128);
12322
12323 assign(result, get_fpr_pair(r2));
12324 put_fpr_pair(r1, mkexpr(result));
12325 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12326
12327 return "ltxbr";
12328}
12329
florian55085f82012-11-21 00:36:55 +000012330static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012331s390_irgen_LCXBR(UChar r1, UChar r2)
12332{
12333 IRTemp result = newTemp(Ity_F128);
12334
12335 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
12336 put_fpr_pair(r1, mkexpr(result));
12337 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12338
12339 return "lcxbr";
12340}
12341
florian55085f82012-11-21 00:36:55 +000012342static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012343s390_irgen_LXDBR(UChar r1, UChar r2)
12344{
12345 IRTemp op = newTemp(Ity_F64);
12346
12347 assign(op, get_fpr_dw0(r2));
12348 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12349
12350 return "lxdbr";
12351}
12352
florian55085f82012-11-21 00:36:55 +000012353static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012354s390_irgen_LXEBR(UChar r1, UChar r2)
12355{
12356 IRTemp op = newTemp(Ity_F32);
12357
12358 assign(op, get_fpr_w0(r2));
12359 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12360
12361 return "lxebr";
12362}
12363
florian55085f82012-11-21 00:36:55 +000012364static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012365s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12366{
12367 IRTemp op = newTemp(Ity_F64);
12368
12369 assign(op, load(Ity_F64, mkexpr(op2addr)));
12370 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12371
12372 return "lxdb";
12373}
12374
florian55085f82012-11-21 00:36:55 +000012375static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012376s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12377{
12378 IRTemp op = newTemp(Ity_F32);
12379
12380 assign(op, load(Ity_F32, mkexpr(op2addr)));
12381 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12382
12383 return "lxeb";
12384}
12385
florian55085f82012-11-21 00:36:55 +000012386static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012387s390_irgen_LNEBR(UChar r1, UChar r2)
12388{
12389 IRTemp result = newTemp(Ity_F32);
12390
12391 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12392 put_fpr_w0(r1, mkexpr(result));
12393 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12394
12395 return "lnebr";
12396}
12397
florian55085f82012-11-21 00:36:55 +000012398static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012399s390_irgen_LNDBR(UChar r1, UChar r2)
12400{
12401 IRTemp result = newTemp(Ity_F64);
12402
12403 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12404 put_fpr_dw0(r1, mkexpr(result));
12405 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12406
12407 return "lndbr";
12408}
12409
florian55085f82012-11-21 00:36:55 +000012410static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012411s390_irgen_LNXBR(UChar r1, UChar r2)
12412{
12413 IRTemp result = newTemp(Ity_F128);
12414
12415 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12416 put_fpr_pair(r1, mkexpr(result));
12417 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12418
12419 return "lnxbr";
12420}
12421
florian55085f82012-11-21 00:36:55 +000012422static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012423s390_irgen_LPEBR(UChar r1, UChar r2)
12424{
12425 IRTemp result = newTemp(Ity_F32);
12426
12427 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12428 put_fpr_w0(r1, mkexpr(result));
12429 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12430
12431 return "lpebr";
12432}
12433
florian55085f82012-11-21 00:36:55 +000012434static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012435s390_irgen_LPDBR(UChar r1, UChar r2)
12436{
12437 IRTemp result = newTemp(Ity_F64);
12438
12439 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12440 put_fpr_dw0(r1, mkexpr(result));
12441 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12442
12443 return "lpdbr";
12444}
12445
florian55085f82012-11-21 00:36:55 +000012446static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012447s390_irgen_LPXBR(UChar r1, UChar r2)
12448{
12449 IRTemp result = newTemp(Ity_F128);
12450
12451 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12452 put_fpr_pair(r1, mkexpr(result));
12453 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12454
12455 return "lpxbr";
12456}
12457
florian55085f82012-11-21 00:36:55 +000012458static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012459s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12460 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012461{
florian125e20d2012-10-07 15:42:37 +000012462 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012463 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012464 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012465 }
sewardj2019a972011-03-07 16:04:07 +000012466 IRTemp result = newTemp(Ity_F64);
12467
floriandb4fcaa2012-09-05 19:54:08 +000012468 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012469 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012470 put_fpr_dw0(r1, mkexpr(result));
12471
12472 return "ldxbr";
12473}
12474
florian55085f82012-11-21 00:36:55 +000012475static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012476s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12477 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012478{
florian125e20d2012-10-07 15:42:37 +000012479 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012480 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012481 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012482 }
sewardj2019a972011-03-07 16:04:07 +000012483 IRTemp result = newTemp(Ity_F32);
12484
floriandb4fcaa2012-09-05 19:54:08 +000012485 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012486 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012487 put_fpr_w0(r1, mkexpr(result));
12488
12489 return "lexbr";
12490}
12491
florian55085f82012-11-21 00:36:55 +000012492static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012493s390_irgen_MXBR(UChar r1, UChar r2)
12494{
12495 IRTemp op1 = newTemp(Ity_F128);
12496 IRTemp op2 = newTemp(Ity_F128);
12497 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012498 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012499
12500 assign(op1, get_fpr_pair(r1));
12501 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012502 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012503 mkexpr(op2)));
12504 put_fpr_pair(r1, mkexpr(result));
12505
12506 return "mxbr";
12507}
12508
florian55085f82012-11-21 00:36:55 +000012509static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012510s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12511{
florian125e20d2012-10-07 15:42:37 +000012512 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012513
floriandb4fcaa2012-09-05 19:54:08 +000012514 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012515 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012516
12517 return "maebr";
12518}
12519
florian55085f82012-11-21 00:36:55 +000012520static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012521s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12522{
florian125e20d2012-10-07 15:42:37 +000012523 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012524
floriandb4fcaa2012-09-05 19:54:08 +000012525 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012526 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012527
12528 return "madbr";
12529}
12530
florian55085f82012-11-21 00:36:55 +000012531static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012532s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12533{
12534 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012535 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012536
floriandb4fcaa2012-09-05 19:54:08 +000012537 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012538 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012539
12540 return "maeb";
12541}
12542
florian55085f82012-11-21 00:36:55 +000012543static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012544s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12545{
12546 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012547 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012548
floriandb4fcaa2012-09-05 19:54:08 +000012549 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012550 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012551
12552 return "madb";
12553}
12554
florian55085f82012-11-21 00:36:55 +000012555static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012556s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12557{
florian125e20d2012-10-07 15:42:37 +000012558 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012559
floriandb4fcaa2012-09-05 19:54:08 +000012560 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012561 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012562
12563 return "msebr";
12564}
12565
florian55085f82012-11-21 00:36:55 +000012566static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012567s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12568{
florian125e20d2012-10-07 15:42:37 +000012569 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012570
floriandb4fcaa2012-09-05 19:54:08 +000012571 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012572 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012573
12574 return "msdbr";
12575}
12576
florian55085f82012-11-21 00:36:55 +000012577static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012578s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12579{
12580 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012581 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012582
floriandb4fcaa2012-09-05 19:54:08 +000012583 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012584 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012585
12586 return "mseb";
12587}
12588
florian55085f82012-11-21 00:36:55 +000012589static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012590s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12591{
12592 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012593 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012594
floriandb4fcaa2012-09-05 19:54:08 +000012595 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012596 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012597
12598 return "msdb";
12599}
12600
florian55085f82012-11-21 00:36:55 +000012601static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012602s390_irgen_SQEBR(UChar r1, UChar r2)
12603{
12604 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012605 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012606
floriandb4fcaa2012-09-05 19:54:08 +000012607 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012608 put_fpr_w0(r1, mkexpr(result));
12609
12610 return "sqebr";
12611}
12612
florian55085f82012-11-21 00:36:55 +000012613static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012614s390_irgen_SQDBR(UChar r1, UChar r2)
12615{
12616 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012617 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012618
floriandb4fcaa2012-09-05 19:54:08 +000012619 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012620 put_fpr_dw0(r1, mkexpr(result));
12621
12622 return "sqdbr";
12623}
12624
florian55085f82012-11-21 00:36:55 +000012625static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012626s390_irgen_SQXBR(UChar r1, UChar r2)
12627{
12628 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012629 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012630
floriandb4fcaa2012-09-05 19:54:08 +000012631 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12632 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012633 put_fpr_pair(r1, mkexpr(result));
12634
12635 return "sqxbr";
12636}
12637
florian55085f82012-11-21 00:36:55 +000012638static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012639s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12640{
12641 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012642 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012643
12644 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012645 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012646
12647 return "sqeb";
12648}
12649
florian55085f82012-11-21 00:36:55 +000012650static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012651s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12652{
12653 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012654 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012655
12656 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012657 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012658
12659 return "sqdb";
12660}
12661
florian55085f82012-11-21 00:36:55 +000012662static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012663s390_irgen_SXBR(UChar r1, UChar r2)
12664{
12665 IRTemp op1 = newTemp(Ity_F128);
12666 IRTemp op2 = newTemp(Ity_F128);
12667 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012668 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012669
12670 assign(op1, get_fpr_pair(r1));
12671 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012672 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012673 mkexpr(op2)));
12674 put_fpr_pair(r1, mkexpr(result));
12675 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12676
12677 return "sxbr";
12678}
12679
florian55085f82012-11-21 00:36:55 +000012680static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012681s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12682{
12683 IRTemp value = newTemp(Ity_F32);
12684
12685 assign(value, get_fpr_w0(r1));
12686
12687 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12688
12689 return "tceb";
12690}
12691
florian55085f82012-11-21 00:36:55 +000012692static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012693s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12694{
12695 IRTemp value = newTemp(Ity_F64);
12696
12697 assign(value, get_fpr_dw0(r1));
12698
12699 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12700
12701 return "tcdb";
12702}
12703
florian55085f82012-11-21 00:36:55 +000012704static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012705s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12706{
12707 IRTemp value = newTemp(Ity_F128);
12708
12709 assign(value, get_fpr_pair(r1));
12710
12711 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12712
12713 return "tcxb";
12714}
12715
florian55085f82012-11-21 00:36:55 +000012716static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012717s390_irgen_LCDFR(UChar r1, UChar r2)
12718{
12719 IRTemp result = newTemp(Ity_F64);
12720
12721 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12722 put_fpr_dw0(r1, mkexpr(result));
12723
12724 return "lcdfr";
12725}
12726
florian55085f82012-11-21 00:36:55 +000012727static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012728s390_irgen_LNDFR(UChar r1, UChar r2)
12729{
12730 IRTemp result = newTemp(Ity_F64);
12731
12732 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12733 put_fpr_dw0(r1, mkexpr(result));
12734
12735 return "lndfr";
12736}
12737
florian55085f82012-11-21 00:36:55 +000012738static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012739s390_irgen_LPDFR(UChar r1, UChar r2)
12740{
12741 IRTemp result = newTemp(Ity_F64);
12742
12743 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12744 put_fpr_dw0(r1, mkexpr(result));
12745
12746 return "lpdfr";
12747}
12748
florian55085f82012-11-21 00:36:55 +000012749static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012750s390_irgen_LDGR(UChar r1, UChar r2)
12751{
12752 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12753
12754 return "ldgr";
12755}
12756
florian55085f82012-11-21 00:36:55 +000012757static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012758s390_irgen_LGDR(UChar r1, UChar r2)
12759{
12760 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12761
12762 return "lgdr";
12763}
12764
12765
florian55085f82012-11-21 00:36:55 +000012766static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012767s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12768{
12769 IRTemp sign = newTemp(Ity_I64);
12770 IRTemp value = newTemp(Ity_I64);
12771
12772 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12773 mkU64(1ULL << 63)));
12774 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12775 mkU64((1ULL << 63) - 1)));
12776 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12777 mkexpr(sign))));
12778
12779 return "cpsdr";
12780}
12781
12782
sewardj2019a972011-03-07 16:04:07 +000012783static IRExpr *
12784s390_call_cvb(IRExpr *in)
12785{
12786 IRExpr **args, *call;
12787
12788 args = mkIRExprVec_1(in);
12789 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12790 "s390_do_cvb", &s390_do_cvb, args);
12791
12792 /* Nothing is excluded from definedness checking. */
12793 call->Iex.CCall.cee->mcx_mask = 0;
12794
12795 return call;
12796}
12797
florian55085f82012-11-21 00:36:55 +000012798static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012799s390_irgen_CVB(UChar r1, IRTemp op2addr)
12800{
12801 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12802
12803 return "cvb";
12804}
12805
florian55085f82012-11-21 00:36:55 +000012806static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012807s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12808{
12809 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12810
12811 return "cvby";
12812}
12813
12814
sewardj2019a972011-03-07 16:04:07 +000012815static IRExpr *
12816s390_call_cvd(IRExpr *in)
12817{
12818 IRExpr **args, *call;
12819
12820 args = mkIRExprVec_1(in);
12821 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12822 "s390_do_cvd", &s390_do_cvd, args);
12823
12824 /* Nothing is excluded from definedness checking. */
12825 call->Iex.CCall.cee->mcx_mask = 0;
12826
12827 return call;
12828}
12829
florian55085f82012-11-21 00:36:55 +000012830static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012831s390_irgen_CVD(UChar r1, IRTemp op2addr)
12832{
florian11b8ee82012-08-06 13:35:33 +000012833 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012834
12835 return "cvd";
12836}
12837
florian55085f82012-11-21 00:36:55 +000012838static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012839s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12840{
12841 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12842
12843 return "cvdy";
12844}
12845
florian55085f82012-11-21 00:36:55 +000012846static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012847s390_irgen_FLOGR(UChar r1, UChar r2)
12848{
12849 IRTemp input = newTemp(Ity_I64);
12850 IRTemp not_zero = newTemp(Ity_I64);
12851 IRTemp tmpnum = newTemp(Ity_I64);
12852 IRTemp num = newTemp(Ity_I64);
12853 IRTemp shift_amount = newTemp(Ity_I8);
12854
12855 /* We use the "count leading zeroes" operator because the number of
12856 leading zeroes is identical with the bit position of the first '1' bit.
12857 However, that operator does not work when the input value is zero.
12858 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12859 the modified value. If input == 0, then the result is 64. Otherwise,
12860 the result of Clz64 is what we want. */
12861
12862 assign(input, get_gpr_dw0(r2));
12863 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12864 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12865
12866 /* num = (input == 0) ? 64 : tmpnum */
12867 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12868 /* == 0 */ mkU64(64),
12869 /* != 0 */ mkexpr(tmpnum)));
12870
12871 put_gpr_dw0(r1, mkexpr(num));
12872
12873 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12874 is to first shift the input value by NUM + 1 bits to the left which
12875 causes the leftmost '1' bit to disappear. Then we shift logically to
12876 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12877 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12878 the width of the value-to-be-shifted, we need to special case
12879 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12880 For both such INPUT values the result will be 0. */
12881
12882 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12883 mkU64(1))));
12884
12885 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012886 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12887 /* == 0 || == 1*/ mkU64(0),
12888 /* otherwise */
12889 binop(Iop_Shr64,
12890 binop(Iop_Shl64, mkexpr(input),
12891 mkexpr(shift_amount)),
12892 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012893
12894 /* Compare the original value as an unsigned integer with 0. */
12895 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12896 mktemp(Ity_I64, mkU64(0)), False);
12897
12898 return "flogr";
12899}
12900
florian55085f82012-11-21 00:36:55 +000012901static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012902s390_irgen_STCK(IRTemp op2addr)
12903{
12904 IRDirty *d;
12905 IRTemp cc = newTemp(Ity_I64);
12906
12907 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12908 &s390x_dirtyhelper_STCK,
12909 mkIRExprVec_1(mkexpr(op2addr)));
12910 d->mFx = Ifx_Write;
12911 d->mAddr = mkexpr(op2addr);
12912 d->mSize = 8;
12913 stmt(IRStmt_Dirty(d));
12914 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12915 mkexpr(cc), mkU64(0), mkU64(0));
12916 return "stck";
12917}
12918
florian55085f82012-11-21 00:36:55 +000012919static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012920s390_irgen_STCKF(IRTemp op2addr)
12921{
florianc5c669b2012-08-26 14:32:28 +000012922 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012923 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012924 } else {
12925 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012926
florianc5c669b2012-08-26 14:32:28 +000012927 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12928 &s390x_dirtyhelper_STCKF,
12929 mkIRExprVec_1(mkexpr(op2addr)));
12930 d->mFx = Ifx_Write;
12931 d->mAddr = mkexpr(op2addr);
12932 d->mSize = 8;
12933 stmt(IRStmt_Dirty(d));
12934 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12935 mkexpr(cc), mkU64(0), mkU64(0));
12936 }
sewardj1e5fea62011-05-17 16:18:36 +000012937 return "stckf";
12938}
12939
florian55085f82012-11-21 00:36:55 +000012940static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012941s390_irgen_STCKE(IRTemp op2addr)
12942{
12943 IRDirty *d;
12944 IRTemp cc = newTemp(Ity_I64);
12945
12946 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12947 &s390x_dirtyhelper_STCKE,
12948 mkIRExprVec_1(mkexpr(op2addr)));
12949 d->mFx = Ifx_Write;
12950 d->mAddr = mkexpr(op2addr);
12951 d->mSize = 16;
12952 stmt(IRStmt_Dirty(d));
12953 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12954 mkexpr(cc), mkU64(0), mkU64(0));
12955 return "stcke";
12956}
12957
florian55085f82012-11-21 00:36:55 +000012958static const HChar *
florian933065d2011-07-11 01:48:02 +000012959s390_irgen_STFLE(IRTemp op2addr)
12960{
florian4e0083e2012-08-26 03:41:56 +000012961 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012962 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012963 return "stfle";
12964 }
12965
florian933065d2011-07-11 01:48:02 +000012966 IRDirty *d;
12967 IRTemp cc = newTemp(Ity_I64);
12968
florian90419562013-08-15 20:54:52 +000012969 /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper */
florian933065d2011-07-11 01:48:02 +000012970 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12971 &s390x_dirtyhelper_STFLE,
florian90419562013-08-15 20:54:52 +000012972 mkIRExprVec_2(IRExpr_BBPTR(), mkexpr(op2addr)));
florian933065d2011-07-11 01:48:02 +000012973
sewardjc9069f22012-06-01 16:09:50 +000012974 d->nFxState = 1;
12975 vex_bzero(&d->fxState, sizeof(d->fxState));
12976
florian933065d2011-07-11 01:48:02 +000012977 d->fxState[0].fx = Ifx_Modify; /* read then write */
12978 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12979 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012980
12981 d->mAddr = mkexpr(op2addr);
12982 /* Pretend all double words are written */
12983 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12984 d->mFx = Ifx_Write;
12985
12986 stmt(IRStmt_Dirty(d));
12987
12988 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12989
12990 return "stfle";
12991}
12992
florian55085f82012-11-21 00:36:55 +000012993static const HChar *
floriana4384a32011-08-11 16:58:45 +000012994s390_irgen_CKSM(UChar r1,UChar r2)
12995{
12996 IRTemp addr = newTemp(Ity_I64);
12997 IRTemp op = newTemp(Ity_I32);
12998 IRTemp len = newTemp(Ity_I64);
12999 IRTemp oldval = newTemp(Ity_I32);
13000 IRTemp mask = newTemp(Ity_I32);
13001 IRTemp newop = newTemp(Ity_I32);
13002 IRTemp result = newTemp(Ity_I32);
13003 IRTemp result1 = newTemp(Ity_I32);
13004 IRTemp inc = newTemp(Ity_I64);
13005
13006 assign(oldval, get_gpr_w1(r1));
13007 assign(addr, get_gpr_dw0(r2));
13008 assign(len, get_gpr_dw0(r2+1));
13009
13010 /* Condition code is always zero. */
13011 s390_cc_set(0);
13012
13013 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000013014 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000013015
13016 /* Assiging the increment variable to adjust address and length
13017 later on. */
13018 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
13019 mkexpr(len), mkU64(4)));
13020
13021 /* If length < 4 the final 4-byte 2nd operand value is computed by
13022 appending the remaining bytes to the right with 0. This is done
13023 by AND'ing the 4 bytes loaded from memory with an appropriate
13024 mask. If length >= 4, that mask is simply 0xffffffff. */
13025
13026 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
13027 /* Mask computation when len < 4:
13028 0xffffffff << (32 - (len % 4)*8) */
13029 binop(Iop_Shl32, mkU32(0xffffffff),
13030 unop(Iop_32to8,
13031 binop(Iop_Sub32, mkU32(32),
13032 binop(Iop_Shl32,
13033 unop(Iop_64to32,
13034 binop(Iop_And64,
13035 mkexpr(len), mkU64(3))),
13036 mkU8(3))))),
13037 mkU32(0xffffffff)));
13038
13039 assign(op, load(Ity_I32, mkexpr(addr)));
13040 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
13041 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
13042
13043 /* Checking for carry */
13044 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
13045 binop(Iop_Add32, mkexpr(result), mkU32(1)),
13046 mkexpr(result)));
13047
13048 put_gpr_w1(r1, mkexpr(result1));
13049 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
13050 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
13051
florian6820ba52012-07-26 02:01:50 +000013052 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000013053
13054 return "cksm";
13055}
13056
florian55085f82012-11-21 00:36:55 +000013057static const HChar *
florian9af37692012-01-15 21:01:16 +000013058s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
13059{
13060 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13061 src_addr = newTemp(Ity_I64);
13062 des_addr = newTemp(Ity_I64);
13063 tab_addr = newTemp(Ity_I64);
13064 test_byte = newTemp(Ity_I8);
13065 src_len = newTemp(Ity_I64);
13066
13067 assign(src_addr, get_gpr_dw0(r2));
13068 assign(des_addr, get_gpr_dw0(r1));
13069 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000013070 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000013071 assign(test_byte, get_gpr_b7(0));
13072
13073 IRTemp op = newTemp(Ity_I8);
13074 IRTemp op1 = newTemp(Ity_I8);
13075 IRTemp result = newTemp(Ity_I64);
13076
13077 /* End of source string? We're done; proceed to next insn */
13078 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013079 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000013080
13081 /* Load character from source string, index translation table and
13082 store translated character in op1. */
13083 assign(op, load(Ity_I8, mkexpr(src_addr)));
13084
13085 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13086 mkexpr(tab_addr)));
13087 assign(op1, load(Ity_I8, mkexpr(result)));
13088
13089 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13090 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013091 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000013092 }
13093 store(get_gpr_dw0(r1), mkexpr(op1));
13094
13095 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13096 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13097 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13098
florian6820ba52012-07-26 02:01:50 +000013099 iterate();
florian9af37692012-01-15 21:01:16 +000013100
13101 return "troo";
13102}
13103
florian55085f82012-11-21 00:36:55 +000013104static const HChar *
florian730448f2012-02-04 17:07:07 +000013105s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
13106{
13107 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13108 src_addr = newTemp(Ity_I64);
13109 des_addr = newTemp(Ity_I64);
13110 tab_addr = newTemp(Ity_I64);
13111 test_byte = newTemp(Ity_I8);
13112 src_len = newTemp(Ity_I64);
13113
13114 assign(src_addr, get_gpr_dw0(r2));
13115 assign(des_addr, get_gpr_dw0(r1));
13116 assign(tab_addr, get_gpr_dw0(1));
13117 assign(src_len, get_gpr_dw0(r1+1));
13118 assign(test_byte, get_gpr_b7(0));
13119
13120 IRTemp op = newTemp(Ity_I16);
13121 IRTemp op1 = newTemp(Ity_I8);
13122 IRTemp result = newTemp(Ity_I64);
13123
13124 /* End of source string? We're done; proceed to next insn */
13125 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013126 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013127
13128 /* Load character from source string, index translation table and
13129 store translated character in op1. */
13130 assign(op, load(Ity_I16, mkexpr(src_addr)));
13131
13132 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13133 mkexpr(tab_addr)));
13134
13135 assign(op1, load(Ity_I8, mkexpr(result)));
13136
13137 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13138 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013139 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013140 }
13141 store(get_gpr_dw0(r1), mkexpr(op1));
13142
13143 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13144 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13145 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13146
florian6820ba52012-07-26 02:01:50 +000013147 iterate();
florian730448f2012-02-04 17:07:07 +000013148
13149 return "trto";
13150}
13151
florian55085f82012-11-21 00:36:55 +000013152static const HChar *
florian730448f2012-02-04 17:07:07 +000013153s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
13154{
13155 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13156 src_addr = newTemp(Ity_I64);
13157 des_addr = newTemp(Ity_I64);
13158 tab_addr = newTemp(Ity_I64);
13159 test_byte = newTemp(Ity_I16);
13160 src_len = newTemp(Ity_I64);
13161
13162 assign(src_addr, get_gpr_dw0(r2));
13163 assign(des_addr, get_gpr_dw0(r1));
13164 assign(tab_addr, get_gpr_dw0(1));
13165 assign(src_len, get_gpr_dw0(r1+1));
13166 assign(test_byte, get_gpr_hw3(0));
13167
13168 IRTemp op = newTemp(Ity_I8);
13169 IRTemp op1 = newTemp(Ity_I16);
13170 IRTemp result = newTemp(Ity_I64);
13171
13172 /* End of source string? We're done; proceed to next insn */
13173 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013174 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013175
13176 /* Load character from source string, index translation table and
13177 store translated character in op1. */
13178 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
13179
13180 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13181 mkexpr(tab_addr)));
13182 assign(op1, load(Ity_I16, mkexpr(result)));
13183
13184 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13185 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013186 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013187 }
13188 store(get_gpr_dw0(r1), mkexpr(op1));
13189
13190 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13191 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13192 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13193
florian6820ba52012-07-26 02:01:50 +000013194 iterate();
florian730448f2012-02-04 17:07:07 +000013195
13196 return "trot";
13197}
13198
florian55085f82012-11-21 00:36:55 +000013199static const HChar *
florian730448f2012-02-04 17:07:07 +000013200s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
13201{
13202 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13203 src_addr = newTemp(Ity_I64);
13204 des_addr = newTemp(Ity_I64);
13205 tab_addr = newTemp(Ity_I64);
13206 test_byte = newTemp(Ity_I16);
13207 src_len = newTemp(Ity_I64);
13208
13209 assign(src_addr, get_gpr_dw0(r2));
13210 assign(des_addr, get_gpr_dw0(r1));
13211 assign(tab_addr, get_gpr_dw0(1));
13212 assign(src_len, get_gpr_dw0(r1+1));
13213 assign(test_byte, get_gpr_hw3(0));
13214
13215 IRTemp op = newTemp(Ity_I16);
13216 IRTemp op1 = newTemp(Ity_I16);
13217 IRTemp result = newTemp(Ity_I64);
13218
13219 /* End of source string? We're done; proceed to next insn */
13220 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013221 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013222
13223 /* Load character from source string, index translation table and
13224 store translated character in op1. */
13225 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
13226
13227 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13228 mkexpr(tab_addr)));
13229 assign(op1, load(Ity_I16, mkexpr(result)));
13230
13231 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13232 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013233 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013234 }
13235
13236 store(get_gpr_dw0(r1), mkexpr(op1));
13237
13238 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13239 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13240 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13241
florian6820ba52012-07-26 02:01:50 +000013242 iterate();
florian730448f2012-02-04 17:07:07 +000013243
13244 return "trtt";
13245}
13246
florian55085f82012-11-21 00:36:55 +000013247static const HChar *
florian730448f2012-02-04 17:07:07 +000013248s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13249{
florianf87d4fb2012-05-05 02:55:24 +000013250 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000013251
florianf87d4fb2012-05-05 02:55:24 +000013252 assign(len, mkU64(length));
13253 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000013254
13255 return "tr";
13256}
13257
florian55085f82012-11-21 00:36:55 +000013258static const HChar *
florian730448f2012-02-04 17:07:07 +000013259s390_irgen_TRE(UChar r1,UChar r2)
13260{
13261 IRTemp src_addr, tab_addr, src_len, test_byte;
13262 src_addr = newTemp(Ity_I64);
13263 tab_addr = newTemp(Ity_I64);
13264 src_len = newTemp(Ity_I64);
13265 test_byte = newTemp(Ity_I8);
13266
13267 assign(src_addr, get_gpr_dw0(r1));
13268 assign(src_len, get_gpr_dw0(r1+1));
13269 assign(tab_addr, get_gpr_dw0(r2));
13270 assign(test_byte, get_gpr_b7(0));
13271
13272 IRTemp op = newTemp(Ity_I8);
13273 IRTemp op1 = newTemp(Ity_I8);
13274 IRTemp result = newTemp(Ity_I64);
13275
13276 /* End of source string? We're done; proceed to next insn */
13277 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013278 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013279
13280 /* Load character from source string and compare with test byte */
13281 assign(op, load(Ity_I8, mkexpr(src_addr)));
13282
13283 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013284 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013285
13286 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13287 mkexpr(tab_addr)));
13288
13289 assign(op1, load(Ity_I8, mkexpr(result)));
13290
13291 store(get_gpr_dw0(r1), mkexpr(op1));
13292 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13293 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13294
florian6820ba52012-07-26 02:01:50 +000013295 iterate();
florian730448f2012-02-04 17:07:07 +000013296
13297 return "tre";
13298}
13299
floriana0100c92012-07-20 00:06:35 +000013300static IRExpr *
13301s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13302{
13303 IRExpr **args, *call;
13304 args = mkIRExprVec_2(srcval, low_surrogate);
13305 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13306 "s390_do_cu21", &s390_do_cu21, args);
13307
13308 /* Nothing is excluded from definedness checking. */
13309 call->Iex.CCall.cee->mcx_mask = 0;
13310
13311 return call;
13312}
13313
florian55085f82012-11-21 00:36:55 +000013314static const HChar *
floriana0100c92012-07-20 00:06:35 +000013315s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13316{
13317 IRTemp addr1 = newTemp(Ity_I64);
13318 IRTemp addr2 = newTemp(Ity_I64);
13319 IRTemp len1 = newTemp(Ity_I64);
13320 IRTemp len2 = newTemp(Ity_I64);
13321
13322 assign(addr1, get_gpr_dw0(r1));
13323 assign(addr2, get_gpr_dw0(r2));
13324 assign(len1, get_gpr_dw0(r1 + 1));
13325 assign(len2, get_gpr_dw0(r2 + 1));
13326
13327 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13328 there are less than 2 bytes left, then the 2nd operand is exhausted
13329 and we're done here. cc = 0 */
13330 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013331 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000013332
13333 /* There are at least two bytes there. Read them. */
13334 IRTemp srcval = newTemp(Ity_I32);
13335 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13336
13337 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13338 inside the interval [0xd800 - 0xdbff] */
13339 IRTemp is_high_surrogate = newTemp(Ity_I32);
13340 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13341 mkU32(1), mkU32(0));
13342 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13343 mkU32(1), mkU32(0));
13344 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13345
13346 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13347 then the 2nd operand is exhausted and we're done here. cc = 0 */
13348 IRExpr *not_enough_bytes =
13349 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13350
florian6820ba52012-07-26 02:01:50 +000013351 next_insn_if(binop(Iop_CmpEQ32,
13352 binop(Iop_And32, mkexpr(is_high_surrogate),
13353 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000013354
13355 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13356 surrogate, read the next two bytes (low surrogate). */
13357 IRTemp low_surrogate = newTemp(Ity_I32);
13358 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13359
13360 assign(low_surrogate,
13361 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13362 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13363 mkU32(0))); // any value is fine; it will not be used
13364
13365 /* Call the helper */
13366 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013367 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13368 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000013369
13370 /* Before we can test whether the 1st operand is exhausted we need to
13371 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13372 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13373 IRExpr *invalid_low_surrogate =
13374 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13375
13376 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013377 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000013378 }
13379
13380 /* Now test whether the 1st operand is exhausted */
13381 IRTemp num_bytes = newTemp(Ity_I64);
13382 assign(num_bytes, binop(Iop_And64,
13383 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13384 mkU64(0xff)));
13385 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013386 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000013387
13388 /* Extract the bytes to be stored at addr1 */
13389 IRTemp data = newTemp(Ity_I64);
13390 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13391
13392 /* To store the bytes construct 4 dirty helper calls. The helper calls
13393 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13394 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013395 UInt i;
floriana0100c92012-07-20 00:06:35 +000013396 for (i = 1; i <= 4; ++i) {
13397 IRDirty *d;
13398
13399 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13400 &s390x_dirtyhelper_CUxy,
13401 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13402 mkexpr(num_bytes)));
13403 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13404 d->mFx = Ifx_Write;
13405 d->mAddr = mkexpr(addr1);
13406 d->mSize = i;
13407 stmt(IRStmt_Dirty(d));
13408 }
13409
13410 /* Update source address and length */
13411 IRTemp num_src_bytes = newTemp(Ity_I64);
13412 assign(num_src_bytes,
13413 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13414 mkU64(4), mkU64(2)));
13415 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13416 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13417
13418 /* Update destination address and length */
13419 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13420 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13421
florian6820ba52012-07-26 02:01:50 +000013422 iterate();
floriana0100c92012-07-20 00:06:35 +000013423
13424 return "cu21";
13425}
13426
florian2a415a12012-07-21 17:41:36 +000013427static IRExpr *
13428s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13429{
13430 IRExpr **args, *call;
13431 args = mkIRExprVec_2(srcval, low_surrogate);
13432 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13433 "s390_do_cu24", &s390_do_cu24, args);
13434
13435 /* Nothing is excluded from definedness checking. */
13436 call->Iex.CCall.cee->mcx_mask = 0;
13437
13438 return call;
13439}
13440
florian55085f82012-11-21 00:36:55 +000013441static const HChar *
florian2a415a12012-07-21 17:41:36 +000013442s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13443{
13444 IRTemp addr1 = newTemp(Ity_I64);
13445 IRTemp addr2 = newTemp(Ity_I64);
13446 IRTemp len1 = newTemp(Ity_I64);
13447 IRTemp len2 = newTemp(Ity_I64);
13448
13449 assign(addr1, get_gpr_dw0(r1));
13450 assign(addr2, get_gpr_dw0(r2));
13451 assign(len1, get_gpr_dw0(r1 + 1));
13452 assign(len2, get_gpr_dw0(r2 + 1));
13453
13454 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13455 there are less than 2 bytes left, then the 2nd operand is exhausted
13456 and we're done here. cc = 0 */
13457 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013458 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000013459
13460 /* There are at least two bytes there. Read them. */
13461 IRTemp srcval = newTemp(Ity_I32);
13462 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13463
13464 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13465 inside the interval [0xd800 - 0xdbff] */
13466 IRTemp is_high_surrogate = newTemp(Ity_I32);
13467 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13468 mkU32(1), mkU32(0));
13469 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13470 mkU32(1), mkU32(0));
13471 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13472
13473 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13474 then the 2nd operand is exhausted and we're done here. cc = 0 */
13475 IRExpr *not_enough_bytes =
13476 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13477
florian6820ba52012-07-26 02:01:50 +000013478 next_insn_if(binop(Iop_CmpEQ32,
13479 binop(Iop_And32, mkexpr(is_high_surrogate),
13480 not_enough_bytes),
13481 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000013482
13483 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13484 surrogate, read the next two bytes (low surrogate). */
13485 IRTemp low_surrogate = newTemp(Ity_I32);
13486 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13487
13488 assign(low_surrogate,
13489 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13490 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13491 mkU32(0))); // any value is fine; it will not be used
13492
13493 /* Call the helper */
13494 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013495 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13496 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000013497
13498 /* Before we can test whether the 1st operand is exhausted we need to
13499 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13500 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13501 IRExpr *invalid_low_surrogate =
13502 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13503
13504 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013505 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000013506 }
13507
13508 /* Now test whether the 1st operand is exhausted */
13509 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013510 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000013511
13512 /* Extract the bytes to be stored at addr1 */
13513 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13514
13515 store(mkexpr(addr1), data);
13516
13517 /* Update source address and length */
13518 IRTemp num_src_bytes = newTemp(Ity_I64);
13519 assign(num_src_bytes,
13520 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13521 mkU64(4), mkU64(2)));
13522 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13523 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13524
13525 /* Update destination address and length */
13526 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13527 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
13528
florian6820ba52012-07-26 02:01:50 +000013529 iterate();
florian2a415a12012-07-21 17:41:36 +000013530
13531 return "cu24";
13532}
floriana4384a32011-08-11 16:58:45 +000013533
florian956194b2012-07-28 22:18:32 +000013534static IRExpr *
13535s390_call_cu42(IRExpr *srcval)
13536{
13537 IRExpr **args, *call;
13538 args = mkIRExprVec_1(srcval);
13539 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13540 "s390_do_cu42", &s390_do_cu42, args);
13541
13542 /* Nothing is excluded from definedness checking. */
13543 call->Iex.CCall.cee->mcx_mask = 0;
13544
13545 return call;
13546}
13547
florian55085f82012-11-21 00:36:55 +000013548static const HChar *
florian956194b2012-07-28 22:18:32 +000013549s390_irgen_CU42(UChar r1, UChar r2)
13550{
13551 IRTemp addr1 = newTemp(Ity_I64);
13552 IRTemp addr2 = newTemp(Ity_I64);
13553 IRTemp len1 = newTemp(Ity_I64);
13554 IRTemp len2 = newTemp(Ity_I64);
13555
13556 assign(addr1, get_gpr_dw0(r1));
13557 assign(addr2, get_gpr_dw0(r2));
13558 assign(len1, get_gpr_dw0(r1 + 1));
13559 assign(len2, get_gpr_dw0(r2 + 1));
13560
13561 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13562 there are less than 4 bytes left, then the 2nd operand is exhausted
13563 and we're done here. cc = 0 */
13564 s390_cc_set(0);
13565 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13566
13567 /* Read the 2nd operand. */
13568 IRTemp srcval = newTemp(Ity_I32);
13569 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13570
13571 /* Call the helper */
13572 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013573 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000013574
13575 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13576 cc=2 outranks cc=1 (1st operand exhausted) */
13577 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13578
13579 s390_cc_set(2);
13580 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13581
13582 /* Now test whether the 1st operand is exhausted */
13583 IRTemp num_bytes = newTemp(Ity_I64);
13584 assign(num_bytes, binop(Iop_And64,
13585 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13586 mkU64(0xff)));
13587 s390_cc_set(1);
13588 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13589
13590 /* Extract the bytes to be stored at addr1 */
13591 IRTemp data = newTemp(Ity_I64);
13592 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13593
13594 /* To store the bytes construct 2 dirty helper calls. The helper calls
13595 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13596 that only one of them will be called at runtime. */
13597
13598 Int i;
13599 for (i = 2; i <= 4; ++i) {
13600 IRDirty *d;
13601
13602 if (i == 3) continue; // skip this one
13603
13604 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13605 &s390x_dirtyhelper_CUxy,
13606 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13607 mkexpr(num_bytes)));
13608 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13609 d->mFx = Ifx_Write;
13610 d->mAddr = mkexpr(addr1);
13611 d->mSize = i;
13612 stmt(IRStmt_Dirty(d));
13613 }
13614
13615 /* Update source address and length */
13616 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13617 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13618
13619 /* Update destination address and length */
13620 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13621 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13622
13623 iterate();
13624
13625 return "cu42";
13626}
13627
florian6d9b9b22012-08-03 18:35:39 +000013628static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000013629s390_call_cu41(IRExpr *srcval)
13630{
13631 IRExpr **args, *call;
13632 args = mkIRExprVec_1(srcval);
13633 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13634 "s390_do_cu41", &s390_do_cu41, args);
13635
13636 /* Nothing is excluded from definedness checking. */
13637 call->Iex.CCall.cee->mcx_mask = 0;
13638
13639 return call;
13640}
13641
florian55085f82012-11-21 00:36:55 +000013642static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013643s390_irgen_CU41(UChar r1, UChar r2)
13644{
13645 IRTemp addr1 = newTemp(Ity_I64);
13646 IRTemp addr2 = newTemp(Ity_I64);
13647 IRTemp len1 = newTemp(Ity_I64);
13648 IRTemp len2 = newTemp(Ity_I64);
13649
13650 assign(addr1, get_gpr_dw0(r1));
13651 assign(addr2, get_gpr_dw0(r2));
13652 assign(len1, get_gpr_dw0(r1 + 1));
13653 assign(len2, get_gpr_dw0(r2 + 1));
13654
13655 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13656 there are less than 4 bytes left, then the 2nd operand is exhausted
13657 and we're done here. cc = 0 */
13658 s390_cc_set(0);
13659 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13660
13661 /* Read the 2nd operand. */
13662 IRTemp srcval = newTemp(Ity_I32);
13663 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13664
13665 /* Call the helper */
13666 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013667 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013668
13669 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13670 cc=2 outranks cc=1 (1st operand exhausted) */
13671 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13672
13673 s390_cc_set(2);
13674 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13675
13676 /* Now test whether the 1st operand is exhausted */
13677 IRTemp num_bytes = newTemp(Ity_I64);
13678 assign(num_bytes, binop(Iop_And64,
13679 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13680 mkU64(0xff)));
13681 s390_cc_set(1);
13682 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13683
13684 /* Extract the bytes to be stored at addr1 */
13685 IRTemp data = newTemp(Ity_I64);
13686 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13687
13688 /* To store the bytes construct 4 dirty helper calls. The helper calls
13689 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13690 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013691 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013692 for (i = 1; i <= 4; ++i) {
13693 IRDirty *d;
13694
13695 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13696 &s390x_dirtyhelper_CUxy,
13697 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13698 mkexpr(num_bytes)));
13699 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13700 d->mFx = Ifx_Write;
13701 d->mAddr = mkexpr(addr1);
13702 d->mSize = i;
13703 stmt(IRStmt_Dirty(d));
13704 }
13705
13706 /* Update source address and length */
13707 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13708 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13709
13710 /* Update destination address and length */
13711 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13712 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13713
13714 iterate();
13715
13716 return "cu41";
13717}
13718
13719static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013720s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013721{
13722 IRExpr **args, *call;
13723 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013724 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13725 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013726
13727 /* Nothing is excluded from definedness checking. */
13728 call->Iex.CCall.cee->mcx_mask = 0;
13729
13730 return call;
13731}
13732
13733static IRExpr *
13734s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13735 IRExpr *byte4, IRExpr *stuff)
13736{
13737 IRExpr **args, *call;
13738 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13739 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13740 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13741
13742 /* Nothing is excluded from definedness checking. */
13743 call->Iex.CCall.cee->mcx_mask = 0;
13744
13745 return call;
13746}
13747
florian3f8a96a2012-08-05 02:59:55 +000013748static IRExpr *
13749s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13750 IRExpr *byte4, IRExpr *stuff)
13751{
13752 IRExpr **args, *call;
13753 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13754 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13755 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13756
13757 /* Nothing is excluded from definedness checking. */
13758 call->Iex.CCall.cee->mcx_mask = 0;
13759
13760 return call;
13761}
13762
13763static void
13764s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013765{
13766 IRTemp addr1 = newTemp(Ity_I64);
13767 IRTemp addr2 = newTemp(Ity_I64);
13768 IRTemp len1 = newTemp(Ity_I64);
13769 IRTemp len2 = newTemp(Ity_I64);
13770
13771 assign(addr1, get_gpr_dw0(r1));
13772 assign(addr2, get_gpr_dw0(r2));
13773 assign(len1, get_gpr_dw0(r1 + 1));
13774 assign(len2, get_gpr_dw0(r2 + 1));
13775
13776 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13777
13778 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13779 there is less than 1 byte left, then the 2nd operand is exhausted
13780 and we're done here. cc = 0 */
13781 s390_cc_set(0);
13782 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13783
13784 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013785 IRTemp byte1 = newTemp(Ity_I64);
13786 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013787
13788 /* Call the helper to get number of bytes and invalid byte indicator */
13789 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013790 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013791 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013792
13793 /* Check for invalid 1st byte */
13794 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13795 s390_cc_set(2);
13796 next_insn_if(is_invalid);
13797
13798 /* How many bytes do we have to read? */
13799 IRTemp num_src_bytes = newTemp(Ity_I64);
13800 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13801
13802 /* Now test whether the 2nd operand is exhausted */
13803 s390_cc_set(0);
13804 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13805
13806 /* Read the remaining bytes */
13807 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13808
13809 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13810 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013811 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013812 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13813 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013814 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013815 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13816 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013817 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013818
13819 /* Call the helper to get the converted value and invalid byte indicator.
13820 We can pass at most 5 arguments; therefore some encoding is needed
13821 here */
13822 IRExpr *stuff = binop(Iop_Or64,
13823 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13824 mkU64(extended_checking));
13825 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013826
13827 if (is_cu12) {
13828 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13829 byte4, stuff));
13830 } else {
13831 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13832 byte4, stuff));
13833 }
florian6d9b9b22012-08-03 18:35:39 +000013834
13835 /* Check for invalid character */
13836 s390_cc_set(2);
13837 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13838 next_insn_if(is_invalid);
13839
13840 /* Now test whether the 1st operand is exhausted */
13841 IRTemp num_bytes = newTemp(Ity_I64);
13842 assign(num_bytes, binop(Iop_And64,
13843 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13844 mkU64(0xff)));
13845 s390_cc_set(1);
13846 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13847
13848 /* Extract the bytes to be stored at addr1 */
13849 IRTemp data = newTemp(Ity_I64);
13850 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13851
florian3f8a96a2012-08-05 02:59:55 +000013852 if (is_cu12) {
13853 /* To store the bytes construct 2 dirty helper calls. The helper calls
13854 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13855 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013856
florian3f8a96a2012-08-05 02:59:55 +000013857 Int i;
13858 for (i = 2; i <= 4; ++i) {
13859 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013860
florian3f8a96a2012-08-05 02:59:55 +000013861 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013862
florian3f8a96a2012-08-05 02:59:55 +000013863 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13864 &s390x_dirtyhelper_CUxy,
13865 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13866 mkexpr(num_bytes)));
13867 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13868 d->mFx = Ifx_Write;
13869 d->mAddr = mkexpr(addr1);
13870 d->mSize = i;
13871 stmt(IRStmt_Dirty(d));
13872 }
13873 } else {
13874 // cu14
13875 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013876 }
13877
13878 /* Update source address and length */
13879 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13880 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13881
13882 /* Update destination address and length */
13883 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13884 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13885
13886 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013887}
13888
florian55085f82012-11-21 00:36:55 +000013889static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013890s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13891{
13892 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013893
13894 return "cu12";
13895}
13896
florian55085f82012-11-21 00:36:55 +000013897static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013898s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13899{
13900 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13901
13902 return "cu14";
13903}
13904
florian8c88cb62012-08-26 18:58:13 +000013905static IRExpr *
13906s390_call_ecag(IRExpr *op2addr)
13907{
13908 IRExpr **args, *call;
13909
13910 args = mkIRExprVec_1(op2addr);
13911 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13912 "s390_do_ecag", &s390_do_ecag, args);
13913
13914 /* Nothing is excluded from definedness checking. */
13915 call->Iex.CCall.cee->mcx_mask = 0;
13916
13917 return call;
13918}
13919
florian55085f82012-11-21 00:36:55 +000013920static const HChar *
floriand2129202012-09-01 20:01:39 +000013921s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013922{
13923 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013924 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013925 } else {
13926 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13927 }
13928
13929 return "ecag";
13930}
13931
13932
florianb7def222012-12-04 04:45:32 +000013933/* New insns are added here.
13934 If an insn is contingent on a facility being installed also
13935 check whether the list of supported facilities in function
13936 s390x_dirtyhelper_STFLE needs updating */
13937
sewardj2019a972011-03-07 16:04:07 +000013938/*------------------------------------------------------------*/
13939/*--- Build IR for special instructions ---*/
13940/*------------------------------------------------------------*/
13941
florianb4df7682011-07-05 02:09:01 +000013942static void
sewardj2019a972011-03-07 16:04:07 +000013943s390_irgen_client_request(void)
13944{
13945 if (0)
13946 vex_printf("%%R3 = client_request ( %%R2 )\n");
13947
florianf9e1ed72012-04-17 02:41:56 +000013948 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13949 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013950
florianf9e1ed72012-04-17 02:41:56 +000013951 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013952 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013953
13954 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013955}
13956
florianb4df7682011-07-05 02:09:01 +000013957static void
sewardj2019a972011-03-07 16:04:07 +000013958s390_irgen_guest_NRADDR(void)
13959{
13960 if (0)
13961 vex_printf("%%R3 = guest_NRADDR\n");
13962
floriane88b3c92011-07-05 02:48:39 +000013963 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013964}
13965
florianb4df7682011-07-05 02:09:01 +000013966static void
sewardj2019a972011-03-07 16:04:07 +000013967s390_irgen_call_noredir(void)
13968{
florianf9e1ed72012-04-17 02:41:56 +000013969 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13970 + S390_SPECIAL_OP_SIZE;
13971
sewardj2019a972011-03-07 16:04:07 +000013972 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013973 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013974
13975 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013976 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013977
13978 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013979 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013980}
13981
13982/* Force proper alignment for the structures below. */
13983#pragma pack(1)
13984
13985
13986static s390_decode_t
florian8462d112014-09-24 15:18:09 +000013987s390_decode_2byte_and_irgen(const UChar *bytes)
sewardj2019a972011-03-07 16:04:07 +000013988{
13989 typedef union {
13990 struct {
13991 unsigned int op : 16;
13992 } E;
13993 struct {
13994 unsigned int op : 8;
13995 unsigned int i : 8;
13996 } I;
13997 struct {
13998 unsigned int op : 8;
13999 unsigned int r1 : 4;
14000 unsigned int r2 : 4;
14001 } RR;
14002 } formats;
14003 union {
14004 formats fmt;
14005 UShort value;
14006 } ovl;
14007
14008 vassert(sizeof(formats) == 2);
14009
florianffbd84d2012-12-09 02:06:29 +000014010 ((UChar *)(&ovl.value))[0] = bytes[0];
14011 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000014012
14013 switch (ovl.value & 0xffff) {
14014 case 0x0101: /* PR */ goto unimplemented;
14015 case 0x0102: /* UPT */ goto unimplemented;
14016 case 0x0104: /* PTFF */ goto unimplemented;
14017 case 0x0107: /* SCKPF */ goto unimplemented;
florian78d5ef72013-05-11 15:02:58 +000014018 case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014019 case 0x010b: /* TAM */ goto unimplemented;
14020 case 0x010c: /* SAM24 */ goto unimplemented;
14021 case 0x010d: /* SAM31 */ goto unimplemented;
14022 case 0x010e: /* SAM64 */ goto unimplemented;
14023 case 0x01ff: /* TRAP2 */ goto unimplemented;
14024 }
14025
14026 switch ((ovl.value & 0xff00) >> 8) {
14027 case 0x04: /* SPM */ goto unimplemented;
14028 case 0x05: /* BALR */ goto unimplemented;
14029 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14030 goto ok;
14031 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14032 goto ok;
14033 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
14034 case 0x0b: /* BSM */ goto unimplemented;
14035 case 0x0c: /* BASSM */ goto unimplemented;
14036 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14037 goto ok;
florianb0c9a132011-09-08 15:37:39 +000014038 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14039 goto ok;
14040 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14041 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014042 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14043 goto ok;
14044 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14045 goto ok;
14046 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14047 goto ok;
14048 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14049 goto ok;
14050 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14051 goto ok;
14052 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14053 goto ok;
14054 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14055 goto ok;
14056 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14057 goto ok;
14058 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14059 goto ok;
14060 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14061 goto ok;
14062 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14063 goto ok;
14064 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14065 goto ok;
14066 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14067 goto ok;
14068 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14069 goto ok;
14070 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14071 goto ok;
14072 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14073 goto ok;
14074 case 0x20: /* LPDR */ goto unimplemented;
14075 case 0x21: /* LNDR */ goto unimplemented;
14076 case 0x22: /* LTDR */ goto unimplemented;
14077 case 0x23: /* LCDR */ goto unimplemented;
14078 case 0x24: /* HDR */ goto unimplemented;
14079 case 0x25: /* LDXR */ goto unimplemented;
14080 case 0x26: /* MXR */ goto unimplemented;
14081 case 0x27: /* MXDR */ goto unimplemented;
14082 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14083 goto ok;
14084 case 0x29: /* CDR */ goto unimplemented;
14085 case 0x2a: /* ADR */ goto unimplemented;
14086 case 0x2b: /* SDR */ goto unimplemented;
14087 case 0x2c: /* MDR */ goto unimplemented;
14088 case 0x2d: /* DDR */ goto unimplemented;
14089 case 0x2e: /* AWR */ goto unimplemented;
14090 case 0x2f: /* SWR */ goto unimplemented;
14091 case 0x30: /* LPER */ goto unimplemented;
14092 case 0x31: /* LNER */ goto unimplemented;
14093 case 0x32: /* LTER */ goto unimplemented;
14094 case 0x33: /* LCER */ goto unimplemented;
14095 case 0x34: /* HER */ goto unimplemented;
14096 case 0x35: /* LEDR */ goto unimplemented;
14097 case 0x36: /* AXR */ goto unimplemented;
14098 case 0x37: /* SXR */ goto unimplemented;
14099 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14100 goto ok;
14101 case 0x39: /* CER */ goto unimplemented;
14102 case 0x3a: /* AER */ goto unimplemented;
14103 case 0x3b: /* SER */ goto unimplemented;
14104 case 0x3c: /* MDER */ goto unimplemented;
14105 case 0x3d: /* DER */ goto unimplemented;
14106 case 0x3e: /* AUR */ goto unimplemented;
14107 case 0x3f: /* SUR */ goto unimplemented;
14108 }
14109
14110 return S390_DECODE_UNKNOWN_INSN;
14111
14112ok:
14113 return S390_DECODE_OK;
14114
14115unimplemented:
14116 return S390_DECODE_UNIMPLEMENTED_INSN;
14117}
14118
14119static s390_decode_t
florian8462d112014-09-24 15:18:09 +000014120s390_decode_4byte_and_irgen(const UChar *bytes)
sewardj2019a972011-03-07 16:04:07 +000014121{
14122 typedef union {
14123 struct {
14124 unsigned int op1 : 8;
14125 unsigned int r1 : 4;
14126 unsigned int op2 : 4;
14127 unsigned int i2 : 16;
14128 } RI;
14129 struct {
14130 unsigned int op : 16;
14131 unsigned int : 8;
14132 unsigned int r1 : 4;
14133 unsigned int r2 : 4;
14134 } RRE;
14135 struct {
14136 unsigned int op : 16;
14137 unsigned int r1 : 4;
14138 unsigned int : 4;
14139 unsigned int r3 : 4;
14140 unsigned int r2 : 4;
14141 } RRF;
14142 struct {
14143 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000014144 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000014145 unsigned int m4 : 4;
14146 unsigned int r1 : 4;
14147 unsigned int r2 : 4;
14148 } RRF2;
14149 struct {
14150 unsigned int op : 16;
14151 unsigned int r3 : 4;
14152 unsigned int : 4;
14153 unsigned int r1 : 4;
14154 unsigned int r2 : 4;
14155 } RRF3;
14156 struct {
14157 unsigned int op : 16;
14158 unsigned int r3 : 4;
14159 unsigned int : 4;
14160 unsigned int r1 : 4;
14161 unsigned int r2 : 4;
14162 } RRR;
14163 struct {
14164 unsigned int op : 16;
14165 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000014166 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000014167 unsigned int r1 : 4;
14168 unsigned int r2 : 4;
14169 } RRF4;
14170 struct {
floriane38f6412012-12-21 17:32:12 +000014171 unsigned int op : 16;
14172 unsigned int : 4;
14173 unsigned int m4 : 4;
14174 unsigned int r1 : 4;
14175 unsigned int r2 : 4;
14176 } RRF5;
14177 struct {
sewardj2019a972011-03-07 16:04:07 +000014178 unsigned int op : 8;
14179 unsigned int r1 : 4;
14180 unsigned int r3 : 4;
14181 unsigned int b2 : 4;
14182 unsigned int d2 : 12;
14183 } RS;
14184 struct {
14185 unsigned int op : 8;
14186 unsigned int r1 : 4;
14187 unsigned int r3 : 4;
14188 unsigned int i2 : 16;
14189 } RSI;
14190 struct {
14191 unsigned int op : 8;
14192 unsigned int r1 : 4;
14193 unsigned int x2 : 4;
14194 unsigned int b2 : 4;
14195 unsigned int d2 : 12;
14196 } RX;
14197 struct {
14198 unsigned int op : 16;
14199 unsigned int b2 : 4;
14200 unsigned int d2 : 12;
14201 } S;
14202 struct {
14203 unsigned int op : 8;
14204 unsigned int i2 : 8;
14205 unsigned int b1 : 4;
14206 unsigned int d1 : 12;
14207 } SI;
14208 } formats;
14209 union {
14210 formats fmt;
14211 UInt value;
14212 } ovl;
14213
14214 vassert(sizeof(formats) == 4);
14215
florianffbd84d2012-12-09 02:06:29 +000014216 ((UChar *)(&ovl.value))[0] = bytes[0];
14217 ((UChar *)(&ovl.value))[1] = bytes[1];
14218 ((UChar *)(&ovl.value))[2] = bytes[2];
14219 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000014220
14221 switch ((ovl.value & 0xff0f0000) >> 16) {
14222 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
14223 ovl.fmt.RI.i2); goto ok;
14224 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
14225 ovl.fmt.RI.i2); goto ok;
14226 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14227 ovl.fmt.RI.i2); goto ok;
14228 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14229 ovl.fmt.RI.i2); goto ok;
14230 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14231 ovl.fmt.RI.i2); goto ok;
14232 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14233 ovl.fmt.RI.i2); goto ok;
14234 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14235 ovl.fmt.RI.i2); goto ok;
14236 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14237 ovl.fmt.RI.i2); goto ok;
14238 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14239 ovl.fmt.RI.i2); goto ok;
14240 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14241 ovl.fmt.RI.i2); goto ok;
14242 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14243 ovl.fmt.RI.i2); goto ok;
14244 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14245 ovl.fmt.RI.i2); goto ok;
14246 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14247 ovl.fmt.RI.i2); goto ok;
14248 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14249 ovl.fmt.RI.i2); goto ok;
14250 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14251 ovl.fmt.RI.i2); goto ok;
14252 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14253 ovl.fmt.RI.i2); goto ok;
14254 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14255 ovl.fmt.RI.i2); goto ok;
14256 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14257 ovl.fmt.RI.i2); goto ok;
14258 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14259 ovl.fmt.RI.i2); goto ok;
14260 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14261 ovl.fmt.RI.i2); goto ok;
14262 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14263 goto ok;
14264 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14265 ovl.fmt.RI.i2); goto ok;
14266 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14267 ovl.fmt.RI.i2); goto ok;
14268 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14269 ovl.fmt.RI.i2); goto ok;
14270 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14271 goto ok;
14272 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14273 ovl.fmt.RI.i2); goto ok;
14274 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14275 goto ok;
14276 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14277 ovl.fmt.RI.i2); goto ok;
14278 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14279 goto ok;
14280 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14281 ovl.fmt.RI.i2); goto ok;
14282 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14283 goto ok;
14284 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14285 ovl.fmt.RI.i2); goto ok;
14286 }
14287
14288 switch ((ovl.value & 0xffff0000) >> 16) {
14289 case 0x8000: /* SSM */ goto unimplemented;
14290 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014291 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014292 case 0xb202: /* STIDP */ goto unimplemented;
14293 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014294 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14295 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014296 case 0xb206: /* SCKC */ goto unimplemented;
14297 case 0xb207: /* STCKC */ goto unimplemented;
14298 case 0xb208: /* SPT */ goto unimplemented;
14299 case 0xb209: /* STPT */ goto unimplemented;
14300 case 0xb20a: /* SPKA */ goto unimplemented;
14301 case 0xb20b: /* IPK */ goto unimplemented;
14302 case 0xb20d: /* PTLB */ goto unimplemented;
14303 case 0xb210: /* SPX */ goto unimplemented;
14304 case 0xb211: /* STPX */ goto unimplemented;
14305 case 0xb212: /* STAP */ goto unimplemented;
14306 case 0xb214: /* SIE */ goto unimplemented;
14307 case 0xb218: /* PC */ goto unimplemented;
14308 case 0xb219: /* SAC */ goto unimplemented;
14309 case 0xb21a: /* CFC */ goto unimplemented;
14310 case 0xb221: /* IPTE */ goto unimplemented;
14311 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
14312 case 0xb223: /* IVSK */ goto unimplemented;
14313 case 0xb224: /* IAC */ goto unimplemented;
14314 case 0xb225: /* SSAR */ goto unimplemented;
14315 case 0xb226: /* EPAR */ goto unimplemented;
14316 case 0xb227: /* ESAR */ goto unimplemented;
14317 case 0xb228: /* PT */ goto unimplemented;
14318 case 0xb229: /* ISKE */ goto unimplemented;
14319 case 0xb22a: /* RRBE */ goto unimplemented;
14320 case 0xb22b: /* SSKE */ goto unimplemented;
14321 case 0xb22c: /* TB */ goto unimplemented;
14322 case 0xb22d: /* DXR */ goto unimplemented;
14323 case 0xb22e: /* PGIN */ goto unimplemented;
14324 case 0xb22f: /* PGOUT */ goto unimplemented;
14325 case 0xb230: /* CSCH */ goto unimplemented;
14326 case 0xb231: /* HSCH */ goto unimplemented;
14327 case 0xb232: /* MSCH */ goto unimplemented;
14328 case 0xb233: /* SSCH */ goto unimplemented;
14329 case 0xb234: /* STSCH */ goto unimplemented;
14330 case 0xb235: /* TSCH */ goto unimplemented;
14331 case 0xb236: /* TPI */ goto unimplemented;
14332 case 0xb237: /* SAL */ goto unimplemented;
14333 case 0xb238: /* RSCH */ goto unimplemented;
14334 case 0xb239: /* STCRW */ goto unimplemented;
14335 case 0xb23a: /* STCPS */ goto unimplemented;
14336 case 0xb23b: /* RCHP */ goto unimplemented;
14337 case 0xb23c: /* SCHM */ goto unimplemented;
14338 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000014339 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14340 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014341 case 0xb244: /* SQDR */ goto unimplemented;
14342 case 0xb245: /* SQER */ goto unimplemented;
14343 case 0xb246: /* STURA */ goto unimplemented;
14344 case 0xb247: /* MSTA */ goto unimplemented;
14345 case 0xb248: /* PALB */ goto unimplemented;
14346 case 0xb249: /* EREG */ goto unimplemented;
14347 case 0xb24a: /* ESTA */ goto unimplemented;
14348 case 0xb24b: /* LURA */ goto unimplemented;
14349 case 0xb24c: /* TAR */ goto unimplemented;
14350 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14351 ovl.fmt.RRE.r2); goto ok;
14352 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14353 goto ok;
14354 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14355 goto ok;
14356 case 0xb250: /* CSP */ goto unimplemented;
14357 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14358 ovl.fmt.RRE.r2); goto ok;
14359 case 0xb254: /* MVPG */ goto unimplemented;
14360 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14361 ovl.fmt.RRE.r2); goto ok;
14362 case 0xb257: /* CUSE */ goto unimplemented;
14363 case 0xb258: /* BSG */ goto unimplemented;
14364 case 0xb25a: /* BSA */ goto unimplemented;
14365 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14366 ovl.fmt.RRE.r2); goto ok;
14367 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14368 ovl.fmt.RRE.r2); goto ok;
14369 case 0xb263: /* CMPSC */ goto unimplemented;
14370 case 0xb274: /* SIGA */ goto unimplemented;
14371 case 0xb276: /* XSCH */ goto unimplemented;
14372 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014373 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 +000014374 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014375 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 +000014376 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014377 case 0xb280: /* LPP */ goto unimplemented;
14378 case 0xb284: /* LCCTL */ goto unimplemented;
14379 case 0xb285: /* LPCTL */ goto unimplemented;
14380 case 0xb286: /* QSI */ goto unimplemented;
14381 case 0xb287: /* LSCTL */ goto unimplemented;
14382 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014383 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14384 goto ok;
14385 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14386 goto ok;
14387 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14388 goto ok;
florian730448f2012-02-04 17:07:07 +000014389 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 +000014390 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14391 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14392 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000014393 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14394 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14395 goto ok;
florian933065d2011-07-11 01:48:02 +000014396 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14397 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014398 case 0xb2b1: /* STFL */ goto unimplemented;
14399 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000014400 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14401 goto ok;
florian82cdba62013-03-12 01:31:24 +000014402 case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14403 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014404 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014405 case 0xb2e0: /* SCCTR */ goto unimplemented;
14406 case 0xb2e1: /* SPCTR */ goto unimplemented;
14407 case 0xb2e4: /* ECCTR */ goto unimplemented;
14408 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014409 case 0xb2e8: /* PPA */ goto unimplemented;
14410 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014411 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014412 case 0xb2f8: /* TEND */ goto unimplemented;
14413 case 0xb2fa: /* NIAI */ goto unimplemented;
14414 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014415 case 0xb2ff: /* TRAP4 */ goto unimplemented;
14416 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14417 ovl.fmt.RRE.r2); goto ok;
14418 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14419 ovl.fmt.RRE.r2); goto ok;
14420 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14421 ovl.fmt.RRE.r2); goto ok;
14422 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14423 ovl.fmt.RRE.r2); goto ok;
14424 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14425 ovl.fmt.RRE.r2); goto ok;
14426 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14427 ovl.fmt.RRE.r2); goto ok;
14428 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14429 ovl.fmt.RRE.r2); goto ok;
14430 case 0xb307: /* MXDBR */ goto unimplemented;
14431 case 0xb308: /* KEBR */ goto unimplemented;
14432 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14433 ovl.fmt.RRE.r2); goto ok;
14434 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14435 ovl.fmt.RRE.r2); goto ok;
14436 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14437 ovl.fmt.RRE.r2); goto ok;
14438 case 0xb30c: /* MDEBR */ goto unimplemented;
14439 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14440 ovl.fmt.RRE.r2); goto ok;
14441 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14442 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14443 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14444 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14445 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14446 ovl.fmt.RRE.r2); goto ok;
14447 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14448 ovl.fmt.RRE.r2); goto ok;
14449 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14450 ovl.fmt.RRE.r2); goto ok;
14451 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14452 ovl.fmt.RRE.r2); goto ok;
14453 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14454 ovl.fmt.RRE.r2); goto ok;
14455 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14456 ovl.fmt.RRE.r2); goto ok;
14457 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14458 ovl.fmt.RRE.r2); goto ok;
14459 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14460 ovl.fmt.RRE.r2); goto ok;
14461 case 0xb318: /* KDBR */ goto unimplemented;
14462 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14463 ovl.fmt.RRE.r2); goto ok;
14464 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14465 ovl.fmt.RRE.r2); goto ok;
14466 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14467 ovl.fmt.RRE.r2); goto ok;
14468 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14469 ovl.fmt.RRE.r2); goto ok;
14470 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14471 ovl.fmt.RRE.r2); goto ok;
14472 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14473 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14474 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14475 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14476 case 0xb324: /* LDER */ goto unimplemented;
14477 case 0xb325: /* LXDR */ goto unimplemented;
14478 case 0xb326: /* LXER */ goto unimplemented;
14479 case 0xb32e: /* MAER */ goto unimplemented;
14480 case 0xb32f: /* MSER */ goto unimplemented;
14481 case 0xb336: /* SQXR */ goto unimplemented;
14482 case 0xb337: /* MEER */ goto unimplemented;
14483 case 0xb338: /* MAYLR */ goto unimplemented;
14484 case 0xb339: /* MYLR */ goto unimplemented;
14485 case 0xb33a: /* MAYR */ goto unimplemented;
14486 case 0xb33b: /* MYR */ goto unimplemented;
14487 case 0xb33c: /* MAYHR */ goto unimplemented;
14488 case 0xb33d: /* MYHR */ goto unimplemented;
14489 case 0xb33e: /* MADR */ goto unimplemented;
14490 case 0xb33f: /* MSDR */ goto unimplemented;
14491 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14492 ovl.fmt.RRE.r2); goto ok;
14493 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14494 ovl.fmt.RRE.r2); goto ok;
14495 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14496 ovl.fmt.RRE.r2); goto ok;
14497 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14498 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014499 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14500 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14501 ovl.fmt.RRF2.r2); goto ok;
14502 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14503 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14504 ovl.fmt.RRF2.r2); goto ok;
14505 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14506 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14507 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014508 case 0xb347: /* FIXBR */ goto unimplemented;
14509 case 0xb348: /* KXBR */ goto unimplemented;
14510 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14511 ovl.fmt.RRE.r2); goto ok;
14512 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14513 ovl.fmt.RRE.r2); goto ok;
14514 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14515 ovl.fmt.RRE.r2); goto ok;
14516 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14517 ovl.fmt.RRE.r2); goto ok;
14518 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14519 ovl.fmt.RRE.r2); goto ok;
14520 case 0xb350: /* TBEDR */ goto unimplemented;
14521 case 0xb351: /* TBDR */ goto unimplemented;
14522 case 0xb353: /* DIEBR */ goto unimplemented;
14523 case 0xb357: /* FIEBR */ goto unimplemented;
14524 case 0xb358: /* THDER */ goto unimplemented;
14525 case 0xb359: /* THDR */ goto unimplemented;
14526 case 0xb35b: /* DIDBR */ goto unimplemented;
14527 case 0xb35f: /* FIDBR */ goto unimplemented;
14528 case 0xb360: /* LPXR */ goto unimplemented;
14529 case 0xb361: /* LNXR */ goto unimplemented;
14530 case 0xb362: /* LTXR */ goto unimplemented;
14531 case 0xb363: /* LCXR */ goto unimplemented;
14532 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14533 ovl.fmt.RRE.r2); goto ok;
14534 case 0xb366: /* LEXR */ goto unimplemented;
14535 case 0xb367: /* FIXR */ goto unimplemented;
14536 case 0xb369: /* CXR */ goto unimplemented;
14537 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14538 ovl.fmt.RRE.r2); goto ok;
14539 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14540 ovl.fmt.RRE.r2); goto ok;
14541 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14542 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14543 goto ok;
14544 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14545 ovl.fmt.RRE.r2); goto ok;
14546 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
14547 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
14548 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
14549 case 0xb377: /* FIER */ goto unimplemented;
14550 case 0xb37f: /* FIDR */ goto unimplemented;
14551 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
14552 case 0xb385: /* SFASR */ goto unimplemented;
14553 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014554 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14555 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14556 ovl.fmt.RRF2.r2); goto ok;
14557 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14558 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14559 ovl.fmt.RRF2.r2); goto ok;
14560 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14561 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14562 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014563 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14564 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14565 ovl.fmt.RRF2.r2); goto ok;
14566 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14567 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14568 ovl.fmt.RRF2.r2); goto ok;
14569 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14570 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14571 ovl.fmt.RRF2.r2); goto ok;
14572 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14573 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14574 ovl.fmt.RRF2.r2); goto ok;
14575 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14576 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14577 ovl.fmt.RRF2.r2); goto ok;
14578 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14579 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14580 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014581 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14582 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14583 ovl.fmt.RRF2.r2); goto ok;
14584 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14585 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14586 ovl.fmt.RRF2.r2); goto ok;
14587 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14588 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14589 ovl.fmt.RRF2.r2); goto ok;
14590 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14591 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14592 ovl.fmt.RRF2.r2); goto ok;
14593 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14594 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14595 ovl.fmt.RRF2.r2); goto ok;
14596 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14597 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14598 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014599 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14600 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14601 ovl.fmt.RRF2.r2); goto ok;
14602 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14603 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14604 ovl.fmt.RRF2.r2); goto ok;
14605 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14606 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14607 ovl.fmt.RRF2.r2); goto ok;
14608 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14609 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14610 ovl.fmt.RRF2.r2); goto ok;
14611 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14612 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14613 ovl.fmt.RRF2.r2); goto ok;
14614 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14615 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14616 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014617 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14618 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14619 ovl.fmt.RRF2.r2); goto ok;
14620 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14621 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14622 ovl.fmt.RRF2.r2); goto ok;
14623 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14624 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14625 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014626 case 0xb3b4: /* CEFR */ goto unimplemented;
14627 case 0xb3b5: /* CDFR */ goto unimplemented;
14628 case 0xb3b6: /* CXFR */ goto unimplemented;
14629 case 0xb3b8: /* CFER */ goto unimplemented;
14630 case 0xb3b9: /* CFDR */ goto unimplemented;
14631 case 0xb3ba: /* CFXR */ goto unimplemented;
14632 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14633 ovl.fmt.RRE.r2); goto ok;
14634 case 0xb3c4: /* CEGR */ goto unimplemented;
14635 case 0xb3c5: /* CDGR */ goto unimplemented;
14636 case 0xb3c6: /* CXGR */ goto unimplemented;
14637 case 0xb3c8: /* CGER */ goto unimplemented;
14638 case 0xb3c9: /* CGDR */ goto unimplemented;
14639 case 0xb3ca: /* CGXR */ goto unimplemented;
14640 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14641 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014642 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14643 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14644 ovl.fmt.RRF4.r2); goto ok;
14645 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14646 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14647 ovl.fmt.RRF4.r2); goto ok;
14648 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14649 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14650 ovl.fmt.RRF4.r2); goto ok;
14651 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14652 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14653 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014654 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14655 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14656 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14657 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14658 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014659 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14660 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014661 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014662 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14663 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14664 ovl.fmt.RRF4.r2); goto ok;
14665 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14666 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14667 ovl.fmt.RRF4.r2); goto ok;
14668 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14669 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14670 ovl.fmt.RRF4.r2); goto ok;
14671 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14672 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14673 ovl.fmt.RRF4.r2); goto ok;
14674 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14675 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14676 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14677 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14678 ovl.fmt.RRF2.r2); goto ok;
14679 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14680 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014681 case 0xb3df: /* FIXTR */ goto unimplemented;
14682 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014683 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14684 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14685 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014686 case 0xb3e2: /* CUDTR */ goto unimplemented;
14687 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014688 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14689 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014690 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14691 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014692 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14693 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014694 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014695 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14696 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14697 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014698 case 0xb3ea: /* CUXTR */ goto unimplemented;
14699 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014700 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14701 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014702 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14703 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014704 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14705 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014706 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14707 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14708 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014709 case 0xb3f2: /* CDUTR */ goto unimplemented;
14710 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014711 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14712 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014713 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14714 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14715 ovl.fmt.RRF4.r2); goto ok;
14716 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14717 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14718 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14719 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14720 ovl.fmt.RRF4.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014721 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14722 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14723 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014724 case 0xb3fa: /* CXUTR */ goto unimplemented;
14725 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014726 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14727 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014728 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14729 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14730 ovl.fmt.RRF4.r2); goto ok;
14731 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14732 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14733 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14734 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14735 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014736 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14737 ovl.fmt.RRE.r2); goto ok;
14738 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14739 ovl.fmt.RRE.r2); goto ok;
14740 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14741 ovl.fmt.RRE.r2); goto ok;
14742 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14743 ovl.fmt.RRE.r2); goto ok;
14744 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14745 ovl.fmt.RRE.r2); goto ok;
14746 case 0xb905: /* LURAG */ goto unimplemented;
14747 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14748 ovl.fmt.RRE.r2); goto ok;
14749 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14750 ovl.fmt.RRE.r2); goto ok;
14751 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14752 ovl.fmt.RRE.r2); goto ok;
14753 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14754 ovl.fmt.RRE.r2); goto ok;
14755 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14756 ovl.fmt.RRE.r2); goto ok;
14757 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14758 ovl.fmt.RRE.r2); goto ok;
14759 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14760 ovl.fmt.RRE.r2); goto ok;
14761 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14762 ovl.fmt.RRE.r2); goto ok;
14763 case 0xb90e: /* EREGG */ goto unimplemented;
14764 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14765 ovl.fmt.RRE.r2); goto ok;
14766 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14767 ovl.fmt.RRE.r2); goto ok;
14768 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14769 ovl.fmt.RRE.r2); goto ok;
14770 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14771 ovl.fmt.RRE.r2); goto ok;
14772 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14773 ovl.fmt.RRE.r2); goto ok;
14774 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14775 ovl.fmt.RRE.r2); goto ok;
14776 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14777 ovl.fmt.RRE.r2); goto ok;
14778 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14779 ovl.fmt.RRE.r2); goto ok;
14780 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14781 ovl.fmt.RRE.r2); goto ok;
14782 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14783 ovl.fmt.RRE.r2); goto ok;
14784 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14785 ovl.fmt.RRE.r2); goto ok;
14786 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14787 ovl.fmt.RRE.r2); goto ok;
14788 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14789 ovl.fmt.RRE.r2); goto ok;
14790 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14791 ovl.fmt.RRE.r2); goto ok;
14792 case 0xb91e: /* KMAC */ goto unimplemented;
14793 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14794 ovl.fmt.RRE.r2); goto ok;
14795 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14796 ovl.fmt.RRE.r2); goto ok;
14797 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14798 ovl.fmt.RRE.r2); goto ok;
14799 case 0xb925: /* STURG */ goto unimplemented;
14800 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14801 ovl.fmt.RRE.r2); goto ok;
14802 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14803 ovl.fmt.RRE.r2); goto ok;
14804 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014805 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014806 case 0xb92b: /* KMO */ goto unimplemented;
14807 case 0xb92c: /* PCC */ goto unimplemented;
14808 case 0xb92d: /* KMCTR */ goto unimplemented;
14809 case 0xb92e: /* KM */ goto unimplemented;
14810 case 0xb92f: /* KMC */ goto unimplemented;
14811 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14812 ovl.fmt.RRE.r2); goto ok;
14813 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14814 ovl.fmt.RRE.r2); goto ok;
14815 case 0xb93e: /* KIMD */ goto unimplemented;
14816 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014817 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14818 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14819 ovl.fmt.RRF2.r2); goto ok;
14820 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14821 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14822 ovl.fmt.RRF2.r2); goto ok;
14823 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14824 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14825 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014826 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14827 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014828 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14829 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14830 ovl.fmt.RRF2.r2); goto ok;
14831 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14832 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14833 ovl.fmt.RRF2.r2); goto ok;
14834 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14835 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14836 ovl.fmt.RRF2.r2); goto ok;
14837 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14838 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14839 ovl.fmt.RRF2.r2); goto ok;
14840 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14841 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14842 ovl.fmt.RRF2.r2); goto ok;
14843 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14844 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14845 ovl.fmt.RRF2.r2); goto ok;
14846 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14847 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14848 ovl.fmt.RRF2.r2); goto ok;
14849 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14850 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14851 ovl.fmt.RRF2.r2); goto ok;
14852 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14853 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14854 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014855 case 0xb960: /* CGRT */ goto unimplemented;
14856 case 0xb961: /* CLGRT */ goto unimplemented;
14857 case 0xb972: /* CRT */ goto unimplemented;
14858 case 0xb973: /* CLRT */ goto unimplemented;
14859 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14860 ovl.fmt.RRE.r2); goto ok;
14861 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14862 ovl.fmt.RRE.r2); goto ok;
14863 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14864 ovl.fmt.RRE.r2); goto ok;
14865 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14866 ovl.fmt.RRE.r2); goto ok;
14867 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14868 ovl.fmt.RRE.r2); goto ok;
14869 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14870 ovl.fmt.RRE.r2); goto ok;
14871 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14872 ovl.fmt.RRE.r2); goto ok;
14873 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14874 ovl.fmt.RRE.r2); goto ok;
14875 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14876 ovl.fmt.RRE.r2); goto ok;
14877 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14878 ovl.fmt.RRE.r2); goto ok;
14879 case 0xb98a: /* CSPG */ goto unimplemented;
14880 case 0xb98d: /* EPSW */ goto unimplemented;
14881 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014882 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014883 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14884 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14885 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14886 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14887 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14888 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014889 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14890 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014891 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14892 ovl.fmt.RRE.r2); goto ok;
14893 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14894 ovl.fmt.RRE.r2); goto ok;
14895 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14896 ovl.fmt.RRE.r2); goto ok;
14897 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14898 ovl.fmt.RRE.r2); goto ok;
14899 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14900 ovl.fmt.RRE.r2); goto ok;
14901 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14902 ovl.fmt.RRE.r2); goto ok;
14903 case 0xb99a: /* EPAIR */ goto unimplemented;
14904 case 0xb99b: /* ESAIR */ goto unimplemented;
14905 case 0xb99d: /* ESEA */ goto unimplemented;
14906 case 0xb99e: /* PTI */ goto unimplemented;
14907 case 0xb99f: /* SSAIR */ goto unimplemented;
14908 case 0xb9a2: /* PTF */ goto unimplemented;
14909 case 0xb9aa: /* LPTEA */ goto unimplemented;
14910 case 0xb9ae: /* RRBM */ goto unimplemented;
14911 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014912 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14913 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14914 goto ok;
florian2a415a12012-07-21 17:41:36 +000014915 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14916 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14917 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014918 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14919 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014920 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14921 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014922 case 0xb9bd: /* TRTRE */ goto unimplemented;
14923 case 0xb9be: /* SRSTU */ goto unimplemented;
14924 case 0xb9bf: /* TRTE */ goto unimplemented;
14925 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14926 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14927 goto ok;
14928 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14929 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14930 goto ok;
14931 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14932 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14933 goto ok;
14934 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14935 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14936 goto ok;
14937 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14938 ovl.fmt.RRE.r2); goto ok;
14939 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14940 ovl.fmt.RRE.r2); goto ok;
14941 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14942 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14943 goto ok;
14944 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14945 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14946 goto ok;
14947 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14948 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14949 goto ok;
14950 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14951 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14952 goto ok;
14953 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14954 ovl.fmt.RRE.r2); goto ok;
14955 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14956 ovl.fmt.RRE.r2); goto ok;
14957 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014958 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14959 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14960 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014961 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14962 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14963 goto ok;
14964 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14965 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14966 goto ok;
14967 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14968 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14969 goto ok;
14970 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14971 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14972 goto ok;
14973 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14974 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14975 goto ok;
14976 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14977 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14978 goto ok;
14979 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14980 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14981 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014982 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14983 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14984 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014985 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14986 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14987 goto ok;
14988 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14989 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14990 goto ok;
14991 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14992 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14993 goto ok;
14994 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14995 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14996 goto ok;
14997 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14998 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14999 goto ok;
15000 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
15001 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15002 goto ok;
15003 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
15004 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
15005 goto ok;
15006 }
15007
15008 switch ((ovl.value & 0xff000000) >> 24) {
15009 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15010 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15011 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15012 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15013 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15014 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15015 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15016 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15017 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15018 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15019 case 0x45: /* BAL */ goto unimplemented;
15020 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15021 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15022 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15023 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15024 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15025 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15026 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15027 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15028 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15029 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15030 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15031 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15032 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15033 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15034 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15035 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15036 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15037 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15038 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15039 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15040 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15041 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15042 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15043 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15044 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15045 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15046 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15047 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15048 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15049 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15050 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15051 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15052 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15053 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15054 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15055 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15056 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15057 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15058 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15059 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15060 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15061 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15062 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15063 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15064 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15065 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15066 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15067 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15068 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15069 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15070 case 0x67: /* MXD */ goto unimplemented;
15071 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15072 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15073 case 0x69: /* CD */ goto unimplemented;
15074 case 0x6a: /* AD */ goto unimplemented;
15075 case 0x6b: /* SD */ goto unimplemented;
15076 case 0x6c: /* MD */ goto unimplemented;
15077 case 0x6d: /* DD */ goto unimplemented;
15078 case 0x6e: /* AW */ goto unimplemented;
15079 case 0x6f: /* SW */ goto unimplemented;
15080 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15081 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15082 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15083 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15084 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15085 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15086 case 0x79: /* CE */ goto unimplemented;
15087 case 0x7a: /* AE */ goto unimplemented;
15088 case 0x7b: /* SE */ goto unimplemented;
15089 case 0x7c: /* MDE */ goto unimplemented;
15090 case 0x7d: /* DE */ goto unimplemented;
15091 case 0x7e: /* AU */ goto unimplemented;
15092 case 0x7f: /* SU */ goto unimplemented;
15093 case 0x83: /* DIAG */ goto unimplemented;
15094 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
15095 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15096 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
15097 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15098 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15099 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15100 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15101 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15102 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15103 ovl.fmt.RS.d2); goto ok;
15104 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15105 ovl.fmt.RS.d2); goto ok;
15106 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15107 ovl.fmt.RS.d2); goto ok;
15108 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15109 ovl.fmt.RS.d2); goto ok;
15110 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15111 ovl.fmt.RS.d2); goto ok;
15112 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15113 ovl.fmt.RS.d2); goto ok;
15114 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15115 ovl.fmt.RS.d2); goto ok;
15116 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15117 ovl.fmt.RS.d2); goto ok;
15118 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15119 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15120 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15121 ovl.fmt.SI.d1); goto ok;
15122 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15123 ovl.fmt.SI.d1); goto ok;
15124 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15125 ovl.fmt.SI.d1); goto ok;
15126 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15127 ovl.fmt.SI.d1); goto ok;
15128 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15129 ovl.fmt.SI.d1); goto ok;
15130 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15131 ovl.fmt.SI.d1); goto ok;
15132 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15133 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15134 case 0x99: /* TRACE */ goto unimplemented;
15135 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15136 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15137 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15138 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15139 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
15140 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15141 goto ok;
15142 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
15143 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15144 goto ok;
15145 case 0xac: /* STNSM */ goto unimplemented;
15146 case 0xad: /* STOSM */ goto unimplemented;
15147 case 0xae: /* SIGP */ goto unimplemented;
15148 case 0xaf: /* MC */ goto unimplemented;
15149 case 0xb1: /* LRA */ goto unimplemented;
15150 case 0xb6: /* STCTL */ goto unimplemented;
15151 case 0xb7: /* LCTL */ goto unimplemented;
15152 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15153 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015154 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15155 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015156 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15157 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15158 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15159 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15160 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15161 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15162 }
15163
15164 return S390_DECODE_UNKNOWN_INSN;
15165
15166ok:
15167 return S390_DECODE_OK;
15168
15169unimplemented:
15170 return S390_DECODE_UNIMPLEMENTED_INSN;
15171}
15172
15173static s390_decode_t
florian8462d112014-09-24 15:18:09 +000015174s390_decode_6byte_and_irgen(const UChar *bytes)
sewardj2019a972011-03-07 16:04:07 +000015175{
15176 typedef union {
15177 struct {
15178 unsigned int op1 : 8;
15179 unsigned int r1 : 4;
15180 unsigned int r3 : 4;
15181 unsigned int i2 : 16;
15182 unsigned int : 8;
15183 unsigned int op2 : 8;
15184 } RIE;
15185 struct {
15186 unsigned int op1 : 8;
15187 unsigned int r1 : 4;
15188 unsigned int r2 : 4;
15189 unsigned int i3 : 8;
15190 unsigned int i4 : 8;
15191 unsigned int i5 : 8;
15192 unsigned int op2 : 8;
15193 } RIE_RRUUU;
15194 struct {
15195 unsigned int op1 : 8;
15196 unsigned int r1 : 4;
15197 unsigned int : 4;
15198 unsigned int i2 : 16;
15199 unsigned int m3 : 4;
15200 unsigned int : 4;
15201 unsigned int op2 : 8;
15202 } RIEv1;
15203 struct {
15204 unsigned int op1 : 8;
15205 unsigned int r1 : 4;
15206 unsigned int r2 : 4;
15207 unsigned int i4 : 16;
15208 unsigned int m3 : 4;
15209 unsigned int : 4;
15210 unsigned int op2 : 8;
15211 } RIE_RRPU;
15212 struct {
15213 unsigned int op1 : 8;
15214 unsigned int r1 : 4;
15215 unsigned int m3 : 4;
15216 unsigned int i4 : 16;
15217 unsigned int i2 : 8;
15218 unsigned int op2 : 8;
15219 } RIEv3;
15220 struct {
15221 unsigned int op1 : 8;
15222 unsigned int r1 : 4;
15223 unsigned int op2 : 4;
15224 unsigned int i2 : 32;
15225 } RIL;
15226 struct {
15227 unsigned int op1 : 8;
15228 unsigned int r1 : 4;
15229 unsigned int m3 : 4;
15230 unsigned int b4 : 4;
15231 unsigned int d4 : 12;
15232 unsigned int i2 : 8;
15233 unsigned int op2 : 8;
15234 } RIS;
15235 struct {
15236 unsigned int op1 : 8;
15237 unsigned int r1 : 4;
15238 unsigned int r2 : 4;
15239 unsigned int b4 : 4;
15240 unsigned int d4 : 12;
15241 unsigned int m3 : 4;
15242 unsigned int : 4;
15243 unsigned int op2 : 8;
15244 } RRS;
15245 struct {
15246 unsigned int op1 : 8;
15247 unsigned int l1 : 4;
15248 unsigned int : 4;
15249 unsigned int b1 : 4;
15250 unsigned int d1 : 12;
15251 unsigned int : 8;
15252 unsigned int op2 : 8;
15253 } RSL;
15254 struct {
15255 unsigned int op1 : 8;
15256 unsigned int r1 : 4;
15257 unsigned int r3 : 4;
15258 unsigned int b2 : 4;
15259 unsigned int dl2 : 12;
15260 unsigned int dh2 : 8;
15261 unsigned int op2 : 8;
15262 } RSY;
15263 struct {
15264 unsigned int op1 : 8;
15265 unsigned int r1 : 4;
15266 unsigned int x2 : 4;
15267 unsigned int b2 : 4;
15268 unsigned int d2 : 12;
15269 unsigned int : 8;
15270 unsigned int op2 : 8;
15271 } RXE;
15272 struct {
15273 unsigned int op1 : 8;
15274 unsigned int r3 : 4;
15275 unsigned int x2 : 4;
15276 unsigned int b2 : 4;
15277 unsigned int d2 : 12;
15278 unsigned int r1 : 4;
15279 unsigned int : 4;
15280 unsigned int op2 : 8;
15281 } RXF;
15282 struct {
15283 unsigned int op1 : 8;
15284 unsigned int r1 : 4;
15285 unsigned int x2 : 4;
15286 unsigned int b2 : 4;
15287 unsigned int dl2 : 12;
15288 unsigned int dh2 : 8;
15289 unsigned int op2 : 8;
15290 } RXY;
15291 struct {
15292 unsigned int op1 : 8;
15293 unsigned int i2 : 8;
15294 unsigned int b1 : 4;
15295 unsigned int dl1 : 12;
15296 unsigned int dh1 : 8;
15297 unsigned int op2 : 8;
15298 } SIY;
15299 struct {
15300 unsigned int op : 8;
15301 unsigned int l : 8;
15302 unsigned int b1 : 4;
15303 unsigned int d1 : 12;
15304 unsigned int b2 : 4;
15305 unsigned int d2 : 12;
15306 } SS;
15307 struct {
15308 unsigned int op : 8;
15309 unsigned int l1 : 4;
15310 unsigned int l2 : 4;
15311 unsigned int b1 : 4;
15312 unsigned int d1 : 12;
15313 unsigned int b2 : 4;
15314 unsigned int d2 : 12;
15315 } SS_LLRDRD;
15316 struct {
15317 unsigned int op : 8;
15318 unsigned int r1 : 4;
15319 unsigned int r3 : 4;
15320 unsigned int b2 : 4;
15321 unsigned int d2 : 12;
15322 unsigned int b4 : 4;
15323 unsigned int d4 : 12;
15324 } SS_RRRDRD2;
15325 struct {
15326 unsigned int op : 16;
15327 unsigned int b1 : 4;
15328 unsigned int d1 : 12;
15329 unsigned int b2 : 4;
15330 unsigned int d2 : 12;
15331 } SSE;
15332 struct {
15333 unsigned int op1 : 8;
15334 unsigned int r3 : 4;
15335 unsigned int op2 : 4;
15336 unsigned int b1 : 4;
15337 unsigned int d1 : 12;
15338 unsigned int b2 : 4;
15339 unsigned int d2 : 12;
15340 } SSF;
15341 struct {
15342 unsigned int op : 16;
15343 unsigned int b1 : 4;
15344 unsigned int d1 : 12;
15345 unsigned int i2 : 16;
15346 } SIL;
15347 } formats;
15348 union {
15349 formats fmt;
15350 ULong value;
15351 } ovl;
15352
15353 vassert(sizeof(formats) == 6);
15354
florianffbd84d2012-12-09 02:06:29 +000015355 ((UChar *)(&ovl.value))[0] = bytes[0];
15356 ((UChar *)(&ovl.value))[1] = bytes[1];
15357 ((UChar *)(&ovl.value))[2] = bytes[2];
15358 ((UChar *)(&ovl.value))[3] = bytes[3];
15359 ((UChar *)(&ovl.value))[4] = bytes[4];
15360 ((UChar *)(&ovl.value))[5] = bytes[5];
15361 ((UChar *)(&ovl.value))[6] = 0x0;
15362 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000015363
15364 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15365 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15366 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15367 ovl.fmt.RXY.dl2,
15368 ovl.fmt.RXY.dh2); goto ok;
15369 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15370 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15371 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15372 ovl.fmt.RXY.dl2,
15373 ovl.fmt.RXY.dh2); goto ok;
15374 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15375 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15376 ovl.fmt.RXY.dl2,
15377 ovl.fmt.RXY.dh2); goto ok;
15378 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15379 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15380 ovl.fmt.RXY.dl2,
15381 ovl.fmt.RXY.dh2); goto ok;
15382 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15383 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15384 ovl.fmt.RXY.dl2,
15385 ovl.fmt.RXY.dh2); goto ok;
15386 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15387 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15388 ovl.fmt.RXY.dl2,
15389 ovl.fmt.RXY.dh2); goto ok;
15390 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15391 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15392 ovl.fmt.RXY.dl2,
15393 ovl.fmt.RXY.dh2); goto ok;
15394 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15395 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15396 ovl.fmt.RXY.dl2,
15397 ovl.fmt.RXY.dh2); goto ok;
15398 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15399 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15400 ovl.fmt.RXY.dl2,
15401 ovl.fmt.RXY.dh2); goto ok;
15402 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15403 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
15404 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15405 ovl.fmt.RXY.dl2,
15406 ovl.fmt.RXY.dh2); goto ok;
15407 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
15408 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15409 ovl.fmt.RXY.dl2,
15410 ovl.fmt.RXY.dh2); goto ok;
15411 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15412 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15413 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15414 ovl.fmt.RXY.dl2,
15415 ovl.fmt.RXY.dh2); goto ok;
15416 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15417 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15418 ovl.fmt.RXY.dl2,
15419 ovl.fmt.RXY.dh2); goto ok;
15420 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15421 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15422 ovl.fmt.RXY.dl2,
15423 ovl.fmt.RXY.dh2); goto ok;
15424 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15425 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15426 ovl.fmt.RXY.dl2,
15427 ovl.fmt.RXY.dh2); goto ok;
15428 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15429 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15430 ovl.fmt.RXY.dl2,
15431 ovl.fmt.RXY.dh2); goto ok;
15432 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15433 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15434 ovl.fmt.RXY.dl2,
15435 ovl.fmt.RXY.dh2); goto ok;
15436 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15437 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15438 ovl.fmt.RXY.dl2,
15439 ovl.fmt.RXY.dh2); goto ok;
15440 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15441 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15442 ovl.fmt.RXY.dl2,
15443 ovl.fmt.RXY.dh2); goto ok;
15444 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15445 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15446 ovl.fmt.RXY.dl2,
15447 ovl.fmt.RXY.dh2); goto ok;
15448 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15449 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15450 ovl.fmt.RXY.dl2,
15451 ovl.fmt.RXY.dh2); goto ok;
15452 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15453 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15454 ovl.fmt.RXY.dl2,
15455 ovl.fmt.RXY.dh2); goto ok;
15456 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15457 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15458 ovl.fmt.RXY.dl2,
15459 ovl.fmt.RXY.dh2); goto ok;
15460 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15461 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15462 ovl.fmt.RXY.dl2,
15463 ovl.fmt.RXY.dh2); goto ok;
15464 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15465 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15466 ovl.fmt.RXY.dl2,
15467 ovl.fmt.RXY.dh2); goto ok;
15468 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15469 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15470 ovl.fmt.RXY.dl2,
15471 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015472 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015473 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15474 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15475 ovl.fmt.RXY.dl2,
15476 ovl.fmt.RXY.dh2); goto ok;
15477 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15478 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15479 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15480 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15481 ovl.fmt.RXY.dh2); goto ok;
15482 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15483 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15484 ovl.fmt.RXY.dl2,
15485 ovl.fmt.RXY.dh2); goto ok;
15486 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15487 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15488 ovl.fmt.RXY.dl2,
15489 ovl.fmt.RXY.dh2); goto ok;
15490 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15491 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15492 ovl.fmt.RXY.dl2,
15493 ovl.fmt.RXY.dh2); goto ok;
15494 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15495 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15496 ovl.fmt.RXY.dl2,
15497 ovl.fmt.RXY.dh2); goto ok;
15498 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15499 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15500 ovl.fmt.RXY.dl2,
15501 ovl.fmt.RXY.dh2); goto ok;
15502 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15503 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15504 ovl.fmt.RXY.dl2,
15505 ovl.fmt.RXY.dh2); goto ok;
15506 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15507 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15508 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15509 ovl.fmt.RXY.dh2); goto ok;
15510 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15511 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15512 ovl.fmt.RXY.dl2,
15513 ovl.fmt.RXY.dh2); goto ok;
15514 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15515 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15516 ovl.fmt.RXY.dl2,
15517 ovl.fmt.RXY.dh2); goto ok;
15518 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15519 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15520 ovl.fmt.RXY.dl2,
15521 ovl.fmt.RXY.dh2); goto ok;
15522 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15523 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15524 ovl.fmt.RXY.dl2,
15525 ovl.fmt.RXY.dh2); goto ok;
15526 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15527 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15528 ovl.fmt.RXY.dl2,
15529 ovl.fmt.RXY.dh2); goto ok;
15530 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15531 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15532 ovl.fmt.RXY.dl2,
15533 ovl.fmt.RXY.dh2); goto ok;
15534 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15535 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15536 ovl.fmt.RXY.dl2,
15537 ovl.fmt.RXY.dh2); goto ok;
15538 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15539 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15540 ovl.fmt.RXY.dl2,
15541 ovl.fmt.RXY.dh2); goto ok;
15542 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15543 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15544 ovl.fmt.RXY.dl2,
15545 ovl.fmt.RXY.dh2); goto ok;
15546 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15547 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15548 ovl.fmt.RXY.dl2,
15549 ovl.fmt.RXY.dh2); goto ok;
15550 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15551 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15552 ovl.fmt.RXY.dl2,
15553 ovl.fmt.RXY.dh2); goto ok;
15554 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15555 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15556 ovl.fmt.RXY.dl2,
15557 ovl.fmt.RXY.dh2); goto ok;
15558 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15559 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15560 ovl.fmt.RXY.dl2,
15561 ovl.fmt.RXY.dh2); goto ok;
15562 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15563 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15564 ovl.fmt.RXY.dl2,
15565 ovl.fmt.RXY.dh2); goto ok;
15566 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15567 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15568 ovl.fmt.RXY.dl2,
15569 ovl.fmt.RXY.dh2); goto ok;
15570 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15571 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15572 ovl.fmt.RXY.dl2,
15573 ovl.fmt.RXY.dh2); goto ok;
15574 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15575 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15576 ovl.fmt.RXY.dl2,
15577 ovl.fmt.RXY.dh2); goto ok;
15578 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15579 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15580 ovl.fmt.RXY.dl2,
15581 ovl.fmt.RXY.dh2); goto ok;
15582 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15583 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15584 ovl.fmt.RXY.dl2,
15585 ovl.fmt.RXY.dh2); goto ok;
15586 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15587 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15588 ovl.fmt.RXY.dl2,
15589 ovl.fmt.RXY.dh2); goto ok;
15590 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15591 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15592 ovl.fmt.RXY.dl2,
15593 ovl.fmt.RXY.dh2); goto ok;
15594 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15595 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15596 ovl.fmt.RXY.dl2,
15597 ovl.fmt.RXY.dh2); goto ok;
15598 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15599 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15600 ovl.fmt.RXY.dl2,
15601 ovl.fmt.RXY.dh2); goto ok;
15602 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15603 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15604 ovl.fmt.RXY.dl2,
15605 ovl.fmt.RXY.dh2); goto ok;
15606 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15607 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15608 ovl.fmt.RXY.dl2,
15609 ovl.fmt.RXY.dh2); goto ok;
15610 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15611 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15612 ovl.fmt.RXY.dl2,
15613 ovl.fmt.RXY.dh2); goto ok;
15614 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15615 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15616 ovl.fmt.RXY.dl2,
15617 ovl.fmt.RXY.dh2); goto ok;
15618 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15619 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15620 ovl.fmt.RXY.dl2,
15621 ovl.fmt.RXY.dh2); goto ok;
15622 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15623 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15624 ovl.fmt.RXY.dl2,
15625 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015626 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015627 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15628 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15629 ovl.fmt.RXY.dl2,
15630 ovl.fmt.RXY.dh2); goto ok;
15631 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15632 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15633 ovl.fmt.RXY.dl2,
15634 ovl.fmt.RXY.dh2); goto ok;
15635 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15636 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15637 ovl.fmt.RXY.dl2,
15638 ovl.fmt.RXY.dh2); goto ok;
15639 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15640 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15641 ovl.fmt.RXY.dl2,
15642 ovl.fmt.RXY.dh2); goto ok;
15643 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15644 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15645 ovl.fmt.RXY.dl2,
15646 ovl.fmt.RXY.dh2); goto ok;
15647 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15648 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15649 ovl.fmt.RXY.dl2,
15650 ovl.fmt.RXY.dh2); goto ok;
15651 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15652 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15653 ovl.fmt.RXY.dl2,
15654 ovl.fmt.RXY.dh2); goto ok;
15655 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15656 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15657 ovl.fmt.RXY.dl2,
15658 ovl.fmt.RXY.dh2); goto ok;
15659 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15660 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15661 ovl.fmt.RXY.dl2,
15662 ovl.fmt.RXY.dh2); goto ok;
15663 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15664 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15665 ovl.fmt.RXY.dl2,
15666 ovl.fmt.RXY.dh2); goto ok;
15667 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15668 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15669 ovl.fmt.RXY.dl2,
15670 ovl.fmt.RXY.dh2); goto ok;
15671 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15672 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15673 ovl.fmt.RXY.dl2,
15674 ovl.fmt.RXY.dh2); goto ok;
15675 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15676 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15677 ovl.fmt.RXY.dl2,
15678 ovl.fmt.RXY.dh2); goto ok;
15679 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15680 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15681 ovl.fmt.RXY.dl2,
15682 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015683 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15684 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15685 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015686 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15687 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15688 ovl.fmt.RXY.dl2,
15689 ovl.fmt.RXY.dh2); goto ok;
15690 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15691 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15692 ovl.fmt.RXY.dl2,
15693 ovl.fmt.RXY.dh2); goto ok;
15694 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15695 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15696 ovl.fmt.RXY.dl2,
15697 ovl.fmt.RXY.dh2); goto ok;
15698 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15699 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15700 ovl.fmt.RXY.dl2,
15701 ovl.fmt.RXY.dh2); goto ok;
15702 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15703 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15704 ovl.fmt.RXY.dl2,
15705 ovl.fmt.RXY.dh2); goto ok;
15706 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15707 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15708 ovl.fmt.RXY.dl2,
15709 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015710 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015711 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15712 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15713 ovl.fmt.RXY.dl2,
15714 ovl.fmt.RXY.dh2); goto ok;
15715 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15716 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15717 ovl.fmt.RXY.dl2,
15718 ovl.fmt.RXY.dh2); goto ok;
15719 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15720 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15721 ovl.fmt.RXY.dl2,
15722 ovl.fmt.RXY.dh2); goto ok;
15723 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15724 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15725 ovl.fmt.RXY.dl2,
15726 ovl.fmt.RXY.dh2); goto ok;
15727 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15728 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15729 ovl.fmt.RSY.dl2,
15730 ovl.fmt.RSY.dh2); goto ok;
15731 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15732 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15733 ovl.fmt.RSY.dl2,
15734 ovl.fmt.RSY.dh2); goto ok;
15735 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15736 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15737 ovl.fmt.RSY.dl2,
15738 ovl.fmt.RSY.dh2); goto ok;
15739 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15740 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15741 ovl.fmt.RSY.dl2,
15742 ovl.fmt.RSY.dh2); goto ok;
15743 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15744 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15745 ovl.fmt.RSY.dl2,
15746 ovl.fmt.RSY.dh2); goto ok;
15747 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15748 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15749 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15750 ovl.fmt.RSY.dl2,
15751 ovl.fmt.RSY.dh2); goto ok;
15752 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15753 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15754 ovl.fmt.RSY.dl2,
15755 ovl.fmt.RSY.dh2); goto ok;
15756 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15757 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15758 ovl.fmt.RSY.dl2,
15759 ovl.fmt.RSY.dh2); goto ok;
15760 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15761 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15762 ovl.fmt.RSY.dl2,
15763 ovl.fmt.RSY.dh2); goto ok;
15764 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15765 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15766 ovl.fmt.RSY.dl2,
15767 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015768 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015769 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15770 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15771 ovl.fmt.RSY.dl2,
15772 ovl.fmt.RSY.dh2); goto ok;
15773 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15774 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15775 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15776 ovl.fmt.RSY.dl2,
15777 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015778 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015779 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15780 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15781 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15782 ovl.fmt.RSY.dh2); goto ok;
15783 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15784 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15785 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15786 ovl.fmt.RSY.dh2); goto ok;
15787 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15788 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15789 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15790 ovl.fmt.RSY.dl2,
15791 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015792 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15793 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15794 ovl.fmt.RSY.dl2,
15795 ovl.fmt.RSY.dh2); goto ok;
15796 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15797 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15798 ovl.fmt.RSY.dl2,
15799 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015800 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15801 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15802 ovl.fmt.RSY.dl2,
15803 ovl.fmt.RSY.dh2); goto ok;
15804 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15805 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15806 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15807 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015808 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15809 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15810 ovl.fmt.RSY.dl2,
15811 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015812 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15813 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15814 ovl.fmt.SIY.dh1); goto ok;
15815 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15816 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15817 ovl.fmt.SIY.dh1); goto ok;
15818 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15819 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15820 ovl.fmt.SIY.dh1); goto ok;
15821 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15822 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15823 ovl.fmt.SIY.dh1); goto ok;
15824 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15825 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15826 ovl.fmt.SIY.dh1); goto ok;
15827 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15828 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15829 ovl.fmt.SIY.dh1); goto ok;
15830 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15831 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15832 ovl.fmt.SIY.dh1); goto ok;
15833 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15834 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15835 ovl.fmt.SIY.dh1); goto ok;
15836 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15837 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15838 ovl.fmt.SIY.dh1); goto ok;
15839 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15840 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15841 ovl.fmt.SIY.dh1); goto ok;
15842 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15843 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15844 ovl.fmt.RSY.dl2,
15845 ovl.fmt.RSY.dh2); goto ok;
15846 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15847 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15848 ovl.fmt.RSY.dl2,
15849 ovl.fmt.RSY.dh2); goto ok;
15850 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15851 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15852 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15853 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15854 ovl.fmt.RSY.dl2,
15855 ovl.fmt.RSY.dh2); goto ok;
15856 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15857 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15858 ovl.fmt.RSY.dl2,
15859 ovl.fmt.RSY.dh2); goto ok;
15860 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15861 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15862 ovl.fmt.RSY.dl2,
15863 ovl.fmt.RSY.dh2); goto ok;
15864 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15865 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15866 ovl.fmt.RSY.dl2,
15867 ovl.fmt.RSY.dh2); goto ok;
15868 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15869 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15870 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15871 ovl.fmt.RSY.dh2); goto ok;
15872 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15873 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15874 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15875 ovl.fmt.RSY.dl2,
15876 ovl.fmt.RSY.dh2); goto ok;
15877 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15878 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15879 ovl.fmt.RSY.dl2,
15880 ovl.fmt.RSY.dh2); goto ok;
15881 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15882 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15883 ovl.fmt.RSY.dl2,
15884 ovl.fmt.RSY.dh2); goto ok;
15885 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15886 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15887 ovl.fmt.RSY.dl2,
15888 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015889 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15890 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15891 ovl.fmt.RSY.dl2,
15892 ovl.fmt.RSY.dh2,
15893 S390_XMNM_LOCG); goto ok;
15894 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15895 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15896 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15897 ovl.fmt.RSY.dh2,
15898 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015899 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15900 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15901 ovl.fmt.RSY.dl2,
15902 ovl.fmt.RSY.dh2); goto ok;
15903 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15904 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15905 ovl.fmt.RSY.dl2,
15906 ovl.fmt.RSY.dh2); goto ok;
15907 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15908 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15909 ovl.fmt.RSY.dl2,
15910 ovl.fmt.RSY.dh2); goto ok;
15911 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15912 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15913 ovl.fmt.RSY.dl2,
15914 ovl.fmt.RSY.dh2); goto ok;
15915 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15916 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15917 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15918 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015919 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15920 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15921 ovl.fmt.RSY.dl2,
15922 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15923 goto ok;
15924 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15925 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15926 ovl.fmt.RSY.dl2,
15927 ovl.fmt.RSY.dh2,
15928 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015929 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15930 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15931 ovl.fmt.RSY.dl2,
15932 ovl.fmt.RSY.dh2); goto ok;
15933 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15934 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15935 ovl.fmt.RSY.dl2,
15936 ovl.fmt.RSY.dh2); goto ok;
15937 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15938 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15939 ovl.fmt.RSY.dl2,
15940 ovl.fmt.RSY.dh2); goto ok;
15941 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, 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 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, 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 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15950 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15951 goto ok;
15952 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15953 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15954 goto ok;
15955 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15956 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15957 ovl.fmt.RIE_RRUUU.r1,
15958 ovl.fmt.RIE_RRUUU.r2,
15959 ovl.fmt.RIE_RRUUU.i3,
15960 ovl.fmt.RIE_RRUUU.i4,
15961 ovl.fmt.RIE_RRUUU.i5);
15962 goto ok;
15963 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15964 ovl.fmt.RIE_RRUUU.r1,
15965 ovl.fmt.RIE_RRUUU.r2,
15966 ovl.fmt.RIE_RRUUU.i3,
15967 ovl.fmt.RIE_RRUUU.i4,
15968 ovl.fmt.RIE_RRUUU.i5);
15969 goto ok;
15970 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15971 ovl.fmt.RIE_RRUUU.r1,
15972 ovl.fmt.RIE_RRUUU.r2,
15973 ovl.fmt.RIE_RRUUU.i3,
15974 ovl.fmt.RIE_RRUUU.i4,
15975 ovl.fmt.RIE_RRUUU.i5);
15976 goto ok;
15977 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15978 ovl.fmt.RIE_RRUUU.r1,
15979 ovl.fmt.RIE_RRUUU.r2,
15980 ovl.fmt.RIE_RRUUU.i3,
15981 ovl.fmt.RIE_RRUUU.i4,
15982 ovl.fmt.RIE_RRUUU.i5);
15983 goto ok;
florian2289cd42012-12-05 04:23:42 +000015984 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015985 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15986 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15987 ovl.fmt.RIE_RRPU.r1,
15988 ovl.fmt.RIE_RRPU.r2,
15989 ovl.fmt.RIE_RRPU.i4,
15990 ovl.fmt.RIE_RRPU.m3); goto ok;
15991 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15992 ovl.fmt.RIE_RRPU.r1,
15993 ovl.fmt.RIE_RRPU.r2,
15994 ovl.fmt.RIE_RRPU.i4,
15995 ovl.fmt.RIE_RRPU.m3); goto ok;
15996 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15997 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15998 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15999 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
16000 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
16001 ovl.fmt.RIE_RRPU.r1,
16002 ovl.fmt.RIE_RRPU.r2,
16003 ovl.fmt.RIE_RRPU.i4,
16004 ovl.fmt.RIE_RRPU.m3); goto ok;
16005 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
16006 ovl.fmt.RIE_RRPU.r1,
16007 ovl.fmt.RIE_RRPU.r2,
16008 ovl.fmt.RIE_RRPU.i4,
16009 ovl.fmt.RIE_RRPU.m3); goto ok;
16010 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
16011 ovl.fmt.RIEv3.r1,
16012 ovl.fmt.RIEv3.m3,
16013 ovl.fmt.RIEv3.i4,
16014 ovl.fmt.RIEv3.i2); goto ok;
16015 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
16016 ovl.fmt.RIEv3.r1,
16017 ovl.fmt.RIEv3.m3,
16018 ovl.fmt.RIEv3.i4,
16019 ovl.fmt.RIEv3.i2); goto ok;
16020 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
16021 ovl.fmt.RIEv3.r1,
16022 ovl.fmt.RIEv3.m3,
16023 ovl.fmt.RIEv3.i4,
16024 ovl.fmt.RIEv3.i2); goto ok;
16025 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
16026 ovl.fmt.RIEv3.r1,
16027 ovl.fmt.RIEv3.m3,
16028 ovl.fmt.RIEv3.i4,
16029 ovl.fmt.RIEv3.i2); goto ok;
16030 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
16031 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
16032 goto ok;
16033 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
16034 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16035 ovl.fmt.RIE.i2); goto ok;
16036 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
16037 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16038 ovl.fmt.RIE.i2); goto ok;
16039 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
16040 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
16041 ovl.fmt.RIE.i2); goto ok;
16042 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
16043 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16044 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16045 goto ok;
16046 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
16047 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16048 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16049 goto ok;
16050 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
16051 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16052 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16053 goto ok;
16054 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
16055 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
16056 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
16057 goto ok;
16058 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
16059 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16060 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16061 ovl.fmt.RIS.i2); goto ok;
16062 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
16063 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16064 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16065 ovl.fmt.RIS.i2); goto ok;
16066 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
16067 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
16068 ovl.fmt.RIS.d4,
16069 ovl.fmt.RIS.i2); goto ok;
16070 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
16071 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
16072 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
16073 ovl.fmt.RIS.i2); goto ok;
16074 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
16075 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16076 ovl.fmt.RXE.d2); goto ok;
16077 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
16078 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16079 ovl.fmt.RXE.d2); goto ok;
16080 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
16081 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16082 ovl.fmt.RXE.d2); goto ok;
16083 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
16084 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
16085 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
16086 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16087 ovl.fmt.RXE.d2); goto ok;
16088 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
16089 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16090 ovl.fmt.RXE.d2); goto ok;
16091 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
16092 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16093 ovl.fmt.RXE.d2); goto ok;
16094 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
16095 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
16096 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16097 ovl.fmt.RXE.d2); goto ok;
16098 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
16099 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16100 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16101 ovl.fmt.RXF.r1); goto ok;
16102 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
16103 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16104 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16105 ovl.fmt.RXF.r1); goto ok;
16106 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
16107 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16108 ovl.fmt.RXE.d2); goto ok;
16109 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
16110 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16111 ovl.fmt.RXE.d2); goto ok;
16112 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
16113 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16114 ovl.fmt.RXE.d2); goto ok;
16115 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
16116 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16117 ovl.fmt.RXE.d2); goto ok;
16118 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
16119 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16120 ovl.fmt.RXE.d2); goto ok;
16121 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
16122 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16123 ovl.fmt.RXE.d2); goto ok;
16124 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
16125 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
16126 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16127 ovl.fmt.RXE.d2); goto ok;
16128 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
16129 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16130 ovl.fmt.RXE.d2); goto ok;
16131 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
16132 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16133 ovl.fmt.RXE.d2); goto ok;
16134 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
16135 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16136 ovl.fmt.RXE.d2); goto ok;
16137 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
16138 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16139 ovl.fmt.RXE.d2); goto ok;
16140 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
16141 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16142 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16143 ovl.fmt.RXF.r1); goto ok;
16144 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
16145 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16146 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16147 ovl.fmt.RXF.r1); goto ok;
16148 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
16149 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
16150 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
16151 case 0xed000000002eULL: /* MAE */ goto unimplemented;
16152 case 0xed000000002fULL: /* MSE */ goto unimplemented;
16153 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
16154 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
16155 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
16156 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
16157 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
16158 case 0xed000000003aULL: /* MAY */ goto unimplemented;
16159 case 0xed000000003bULL: /* MY */ goto unimplemented;
16160 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
16161 case 0xed000000003dULL: /* MYH */ goto unimplemented;
16162 case 0xed000000003eULL: /* MAD */ goto unimplemented;
16163 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000016164 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
16165 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16166 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16167 ovl.fmt.RXF.r1); goto ok;
16168 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
16169 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16170 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16171 ovl.fmt.RXF.r1); goto ok;
16172 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
16173 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16174 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16175 ovl.fmt.RXF.r1); goto ok;
16176 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
16177 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16178 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16179 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000016180 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
16181 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16182 ovl.fmt.RXE.d2); goto ok;
16183 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
16184 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16185 ovl.fmt.RXE.d2); goto ok;
16186 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
16187 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16188 ovl.fmt.RXE.d2); goto ok;
16189 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
16190 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16191 ovl.fmt.RXE.d2); goto ok;
16192 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
16193 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16194 ovl.fmt.RXE.d2); goto ok;
16195 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
16196 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16197 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016198 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
16199 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16200 ovl.fmt.RXY.dl2,
16201 ovl.fmt.RXY.dh2); goto ok;
16202 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
16203 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16204 ovl.fmt.RXY.dl2,
16205 ovl.fmt.RXY.dh2); goto ok;
16206 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
16207 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16208 ovl.fmt.RXY.dl2,
16209 ovl.fmt.RXY.dh2); goto ok;
16210 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
16211 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16212 ovl.fmt.RXY.dl2,
16213 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000016214 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
16215 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
16216 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
16217 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016218 }
16219
16220 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
16221 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
16222 ovl.fmt.RIL.i2); goto ok;
16223 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
16224 ovl.fmt.RIL.i2); goto ok;
16225 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
16226 ovl.fmt.RIL.i2); goto ok;
16227 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16228 ovl.fmt.RIL.i2); goto ok;
16229 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16230 ovl.fmt.RIL.i2); goto ok;
16231 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16232 ovl.fmt.RIL.i2); goto ok;
16233 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16234 ovl.fmt.RIL.i2); goto ok;
16235 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16236 ovl.fmt.RIL.i2); goto ok;
16237 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16238 ovl.fmt.RIL.i2); goto ok;
16239 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16240 ovl.fmt.RIL.i2); goto ok;
16241 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16242 ovl.fmt.RIL.i2); goto ok;
16243 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16244 ovl.fmt.RIL.i2); goto ok;
16245 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16246 ovl.fmt.RIL.i2); goto ok;
16247 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16248 ovl.fmt.RIL.i2); goto ok;
16249 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16250 ovl.fmt.RIL.i2); goto ok;
16251 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16252 ovl.fmt.RIL.i2); goto ok;
16253 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16254 ovl.fmt.RIL.i2); goto ok;
16255 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16256 ovl.fmt.RIL.i2); goto ok;
16257 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16258 ovl.fmt.RIL.i2); goto ok;
16259 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16260 ovl.fmt.RIL.i2); goto ok;
16261 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16262 ovl.fmt.RIL.i2); goto ok;
16263 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16264 ovl.fmt.RIL.i2); goto ok;
16265 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16266 ovl.fmt.RIL.i2); goto ok;
16267 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16268 ovl.fmt.RIL.i2); goto ok;
16269 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16270 ovl.fmt.RIL.i2); goto ok;
16271 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16272 ovl.fmt.RIL.i2); goto ok;
16273 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16274 ovl.fmt.RIL.i2); goto ok;
16275 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16276 ovl.fmt.RIL.i2); goto ok;
16277 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16278 ovl.fmt.RIL.i2); goto ok;
16279 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16280 ovl.fmt.RIL.i2); goto ok;
16281 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16282 ovl.fmt.RIL.i2); goto ok;
16283 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16284 ovl.fmt.RIL.i2); goto ok;
16285 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16286 ovl.fmt.RIL.i2); goto ok;
16287 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16288 ovl.fmt.RIL.i2); goto ok;
16289 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16290 ovl.fmt.RIL.i2); goto ok;
16291 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16292 ovl.fmt.RIL.i2); goto ok;
16293 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16294 ovl.fmt.RIL.i2); goto ok;
16295 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16296 ovl.fmt.RIL.i2); goto ok;
16297 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16298 ovl.fmt.RIL.i2); goto ok;
16299 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16300 ovl.fmt.RIL.i2); goto ok;
16301 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16302 ovl.fmt.RIL.i2); goto ok;
16303 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16304 ovl.fmt.RIL.i2); goto ok;
16305 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16306 ovl.fmt.RIL.i2); goto ok;
16307 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16308 ovl.fmt.RIL.i2); goto ok;
16309 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16310 ovl.fmt.RIL.i2); goto ok;
16311 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16312 ovl.fmt.RIL.i2); goto ok;
16313 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16314 ovl.fmt.RIL.i2); goto ok;
16315 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16316 ovl.fmt.RIL.i2); goto ok;
16317 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16318 ovl.fmt.RIL.i2); goto ok;
16319 case 0xc800ULL: /* MVCOS */ goto unimplemented;
16320 case 0xc801ULL: /* ECTG */ goto unimplemented;
16321 case 0xc802ULL: /* CSST */ goto unimplemented;
16322 case 0xc804ULL: /* LPD */ goto unimplemented;
16323 case 0xc805ULL: /* LPDG */ goto unimplemented;
16324 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
16325 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16326 ovl.fmt.RIL.i2); goto ok;
16327 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16328 ovl.fmt.RIL.i2); goto ok;
16329 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16330 ovl.fmt.RIL.i2); goto ok;
16331 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16332 ovl.fmt.RIL.i2); goto ok;
16333 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16334 ovl.fmt.RIL.i2); goto ok;
16335 }
16336
16337 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000016338 case 0xc5ULL: /* BPRP */ goto unimplemented;
16339 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016340 case 0xd0ULL: /* TRTR */ goto unimplemented;
16341 case 0xd1ULL: /* MVN */ goto unimplemented;
16342 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16343 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16344 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16345 case 0xd3ULL: /* MVZ */ goto unimplemented;
16346 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16347 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16348 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16349 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16350 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16351 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16352 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16353 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16354 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000016355 case 0xd7ULL:
16356 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16357 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16358 else
16359 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16360 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16361 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16362 goto ok;
sewardj2019a972011-03-07 16:04:07 +000016363 case 0xd9ULL: /* MVCK */ goto unimplemented;
16364 case 0xdaULL: /* MVCP */ goto unimplemented;
16365 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000016366 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16367 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16368 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016369 case 0xddULL: /* TRT */ goto unimplemented;
16370 case 0xdeULL: /* ED */ goto unimplemented;
16371 case 0xdfULL: /* EDMK */ goto unimplemented;
16372 case 0xe1ULL: /* PKU */ goto unimplemented;
16373 case 0xe2ULL: /* UNPKU */ goto unimplemented;
16374 case 0xe8ULL: /* MVCIN */ goto unimplemented;
16375 case 0xe9ULL: /* PKA */ goto unimplemented;
16376 case 0xeaULL: /* UNPKA */ goto unimplemented;
16377 case 0xeeULL: /* PLO */ goto unimplemented;
16378 case 0xefULL: /* LMD */ goto unimplemented;
16379 case 0xf0ULL: /* SRP */ goto unimplemented;
16380 case 0xf1ULL: /* MVO */ goto unimplemented;
16381 case 0xf2ULL: /* PACK */ goto unimplemented;
16382 case 0xf3ULL: /* UNPK */ goto unimplemented;
16383 case 0xf8ULL: /* ZAP */ goto unimplemented;
16384 case 0xf9ULL: /* CP */ goto unimplemented;
16385 case 0xfaULL: /* AP */ goto unimplemented;
16386 case 0xfbULL: /* SP */ goto unimplemented;
16387 case 0xfcULL: /* MP */ goto unimplemented;
16388 case 0xfdULL: /* DP */ goto unimplemented;
16389 }
16390
16391 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16392 case 0xe500ULL: /* LASP */ goto unimplemented;
16393 case 0xe501ULL: /* TPROT */ goto unimplemented;
16394 case 0xe502ULL: /* STRAG */ goto unimplemented;
16395 case 0xe50eULL: /* MVCSK */ goto unimplemented;
16396 case 0xe50fULL: /* MVCDK */ goto unimplemented;
16397 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16398 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16399 goto ok;
16400 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16401 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16402 goto ok;
16403 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16404 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16405 goto ok;
16406 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16407 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16408 goto ok;
16409 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16410 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16411 goto ok;
16412 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16413 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16414 goto ok;
16415 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16416 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16417 goto ok;
16418 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16419 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16420 goto ok;
16421 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16422 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16423 goto ok;
florian2289cd42012-12-05 04:23:42 +000016424 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16425 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016426 }
16427
16428 return S390_DECODE_UNKNOWN_INSN;
16429
16430ok:
16431 return S390_DECODE_OK;
16432
16433unimplemented:
16434 return S390_DECODE_UNIMPLEMENTED_INSN;
16435}
16436
16437/* Handle "special" instructions. */
16438static s390_decode_t
florian8462d112014-09-24 15:18:09 +000016439s390_decode_special_and_irgen(const UChar *bytes)
sewardj2019a972011-03-07 16:04:07 +000016440{
16441 s390_decode_t status = S390_DECODE_OK;
16442
16443 /* Got a "Special" instruction preamble. Which one is it? */
16444 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16445 s390_irgen_client_request();
16446 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16447 s390_irgen_guest_NRADDR();
16448 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16449 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000016450 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16451 vex_inject_ir(irsb, Iend_BE);
16452
16453 /* Invalidate the current insn. The reason is that the IRop we're
16454 injecting here can change. In which case the translation has to
16455 be redone. For ease of handling, we simply invalidate all the
16456 time. */
sewardj05f5e012014-05-04 10:52:11 +000016457 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian2245ce92012-08-28 16:49:30 +000016458 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000016459 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN),
florian2245ce92012-08-28 16:49:30 +000016460 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16461 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16462 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16463
16464 put_IA(mkaddr_expr(guest_IA_next_instr));
16465 dis_res->whatNext = Dis_StopHere;
sewardj05f5e012014-05-04 10:52:11 +000016466 dis_res->jk_StopHere = Ijk_InvalICache;
sewardj2019a972011-03-07 16:04:07 +000016467 } else {
16468 /* We don't know what it is. */
16469 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16470 }
16471
16472 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16473
16474 return status;
16475}
16476
16477
16478/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000016479static UInt
florian8462d112014-09-24 15:18:09 +000016480s390_decode_and_irgen(const UChar *bytes, UInt insn_length, DisResult *dres)
sewardj2019a972011-03-07 16:04:07 +000016481{
16482 s390_decode_t status;
16483
16484 dis_res = dres;
16485
16486 /* Spot the 8-byte preamble: 18ff lr r15,r15
16487 1811 lr r1,r1
16488 1822 lr r2,r2
16489 1833 lr r3,r3 */
16490 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16491 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16492 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16493
16494 /* Handle special instruction that follows that preamble. */
16495 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000016496
16497 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16498 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16499
16500 status =
16501 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000016502 } else {
16503 /* Handle normal instructions. */
16504 switch (insn_length) {
16505 case 2:
16506 status = s390_decode_2byte_and_irgen(bytes);
16507 break;
16508
16509 case 4:
16510 status = s390_decode_4byte_and_irgen(bytes);
16511 break;
16512
16513 case 6:
16514 status = s390_decode_6byte_and_irgen(bytes);
16515 break;
16516
16517 default:
16518 status = S390_DECODE_ERROR;
16519 break;
16520 }
16521 }
florian5fcbba22011-07-27 20:40:22 +000016522 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000016523 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16524 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000016525 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000016526 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000016527 }
16528
16529 if (status == S390_DECODE_OK) return insn_length; /* OK */
16530
16531 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000016532 if (sigill_diag) {
16533 vex_printf("vex s390->IR: ");
16534 switch (status) {
16535 case S390_DECODE_UNKNOWN_INSN:
16536 vex_printf("unknown insn: ");
16537 break;
sewardj2019a972011-03-07 16:04:07 +000016538
sewardj442e51a2012-12-06 18:08:04 +000016539 case S390_DECODE_UNIMPLEMENTED_INSN:
16540 vex_printf("unimplemented insn: ");
16541 break;
sewardj2019a972011-03-07 16:04:07 +000016542
sewardj442e51a2012-12-06 18:08:04 +000016543 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16544 vex_printf("unimplemented special insn: ");
16545 break;
sewardj2019a972011-03-07 16:04:07 +000016546
sewardj442e51a2012-12-06 18:08:04 +000016547 case S390_DECODE_ERROR:
16548 vex_printf("decoding error: ");
16549 break;
florian2580da42014-09-16 21:49:45 +000016550
16551 default:
16552 vpanic("s390_decode_and_irgen");
sewardj442e51a2012-12-06 18:08:04 +000016553 }
16554
16555 vex_printf("%02x%02x", bytes[0], bytes[1]);
16556 if (insn_length > 2) {
16557 vex_printf(" %02x%02x", bytes[2], bytes[3]);
16558 }
16559 if (insn_length > 4) {
16560 vex_printf(" %02x%02x", bytes[4], bytes[5]);
16561 }
16562 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000016563 }
16564
sewardj2019a972011-03-07 16:04:07 +000016565 return 0; /* Failed */
16566}
16567
16568
sewardj2019a972011-03-07 16:04:07 +000016569/* Disassemble a single instruction INSN into IR. */
16570static DisResult
florian8462d112014-09-24 15:18:09 +000016571disInstr_S390_WRK(const UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000016572{
16573 UChar byte;
16574 UInt insn_length;
16575 DisResult dres;
16576
16577 /* ---------------------------------------------------- */
16578 /* --- Compute instruction length -- */
16579 /* ---------------------------------------------------- */
16580
16581 /* Get the first byte of the insn. */
16582 byte = insn[0];
16583
16584 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16585 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16586 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16587
16588 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16589
16590 /* ---------------------------------------------------- */
16591 /* --- Initialise the DisResult data -- */
16592 /* ---------------------------------------------------- */
16593 dres.whatNext = Dis_Continue;
16594 dres.len = insn_length;
16595 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016596 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000016597
floriana99f20e2011-07-17 14:16:41 +000016598 /* fixs390: consider chasing of conditional jumps */
16599
sewardj2019a972011-03-07 16:04:07 +000016600 /* Normal and special instruction handling starts here. */
16601 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16602 /* All decode failures end up here. The decoder has already issued an
16603 error message.
16604 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000016605 not been executed, and (is currently) the next to be executed.
16606 The insn address in the guest state needs to be set to
16607 guest_IA_curr_instr, otherwise the complaint will report an
16608 incorrect address. */
16609 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000016610
philippe2faf5912014-08-11 22:45:47 +000016611 dres.len = 0;
florian8844a632012-04-13 04:04:06 +000016612 dres.whatNext = Dis_StopHere;
16613 dres.jk_StopHere = Ijk_NoDecode;
16614 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016615 } else {
16616 /* Decode success */
16617 switch (dres.whatNext) {
16618 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000016619 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000016620 break;
16621 case Dis_ResteerU:
16622 case Dis_ResteerC:
16623 put_IA(mkaddr_expr(dres.continueAt));
16624 break;
16625 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000016626 if (dres.jk_StopHere == Ijk_EmWarn ||
16627 dres.jk_StopHere == Ijk_EmFail) {
16628 /* We assume here, that emulation warnings are not given for
16629 insns that transfer control. There is no good way to
16630 do that. */
16631 put_IA(mkaddr_expr(guest_IA_next_instr));
16632 }
florian8844a632012-04-13 04:04:06 +000016633 break;
16634 default:
florian2580da42014-09-16 21:49:45 +000016635 vpanic("disInstr_S390_WRK");
florian8844a632012-04-13 04:04:06 +000016636 }
sewardj2019a972011-03-07 16:04:07 +000016637 }
16638
16639 return dres;
16640}
16641
16642
16643/*------------------------------------------------------------*/
16644/*--- Top-level fn ---*/
16645/*------------------------------------------------------------*/
16646
16647/* Disassemble a single instruction into IR. The instruction
16648 is located in host memory at &guest_code[delta]. */
16649
16650DisResult
16651disInstr_S390(IRSB *irsb_IN,
florianbeac5302014-12-31 12:09:38 +000016652 Bool (*resteerOkFn)(void *, Addr),
sewardj2019a972011-03-07 16:04:07 +000016653 Bool resteerCisOk,
16654 void *callback_opaque,
florian8462d112014-09-24 15:18:09 +000016655 const UChar *guest_code,
sewardj2019a972011-03-07 16:04:07 +000016656 Long delta,
floriand4cc0de2015-01-02 11:44:12 +000016657 Addr guest_IP,
sewardj2019a972011-03-07 16:04:07 +000016658 VexArch guest_arch,
floriancacba8e2014-12-15 18:58:07 +000016659 const VexArchInfo *archinfo,
16660 const VexAbiInfo *abiinfo,
sewardj9b769162014-07-24 12:42:03 +000016661 VexEndness host_endness,
sewardj442e51a2012-12-06 18:08:04 +000016662 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016663{
16664 vassert(guest_arch == VexArchS390X);
16665
16666 /* The instruction decoder requires a big-endian machine. */
sewardj9b769162014-07-24 12:42:03 +000016667 vassert(host_endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +000016668
16669 /* Set globals (see top of this file) */
16670 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016671 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016672 resteer_fn = resteerOkFn;
16673 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016674 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016675
florian420c5012011-07-22 02:12:28 +000016676 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016677}
16678
16679/*---------------------------------------------------------------*/
16680/*--- end guest_s390_toIR.c ---*/
16681/*---------------------------------------------------------------*/